From 08a70fe76ddda7500817fdb947559de39b0b850d Mon Sep 17 00:00:00 2001 From: utam0k Date: Sun, 12 Sep 2021 00:58:35 +0900 Subject: [PATCH 1/3] reduce duplicate codes bacause of try_get() to make it a little easier to read. --- src/database/mod.rs | 7 +++ src/database/mysql.rs | 108 +++++++++++++++++---------------------- src/database/postgres.rs | 26 +++++----- src/database/sqlite.rs | 22 ++++---- 4 files changed, 81 insertions(+), 82 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index 18014a1..beec60f 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -49,3 +49,10 @@ pub trait TableRow: std::marker::Send { fn fields(&self) -> Vec; fn columns(&self) -> Vec; } + +#[macro_export] +macro_rules! get_or_null { + ($value:expr) => { + return Ok($value.map_or("NULL".to_string(), |v| v.to_string())); + }; +} diff --git a/src/database/mysql.rs b/src/database/mysql.rs index 16d7b6c..a9eaace 100644 --- a/src/database/mysql.rs +++ b/src/database/mysql.rs @@ -1,3 +1,5 @@ +use crate::get_or_null; + use super::{Pool, TableRow, RECORDS_LIMIT_PER_PAGE}; use async_trait::async_trait; use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; @@ -7,6 +9,8 @@ use sqlx::mysql::{MySqlColumn, MySqlPoolOptions, MySqlRow}; use sqlx::{Column as _, Row as _, TypeInfo as _}; use std::time::Duration; +const NULL: &str = "NULL"; + pub struct MySqlPool { pool: sqlx::mysql::MySqlPool, } @@ -353,85 +357,69 @@ impl Pool for MySqlPool { fn convert_column_value_to_string(row: &MySqlRow, column: &MySqlColumn) -> anyhow::Result { let column_name = column.name(); + if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.unwrap_or_else(|| "NULL".to_string())); - } - if let Ok(value) = row.try_get(column_name) { + Ok(value.unwrap_or_else(|| NULL.to_string())) + } else if let Ok(value) = row.try_get(column_name) { let value: Option<&str> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); - } - if let Ok(value) = row.try_get(column_name) { + get_or_null!(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) + } else { + anyhow::bail!( + "column type not implemented: `{}` {}", + column_name, + column.type_info().clone().name() + ) } - Err(anyhow::anyhow!( - "column type not implemented: `{}` {}", - column_name, - column.type_info().clone().name() - )) } diff --git a/src/database/postgres.rs b/src/database/postgres.rs index f8219a8..c574d93 100644 --- a/src/database/postgres.rs +++ b/src/database/postgres.rs @@ -1,3 +1,5 @@ +use crate::get_or_null; + use super::{Pool, TableRow, RECORDS_LIMIT_PER_PAGE}; use async_trait::async_trait; use chrono::{NaiveDate, NaiveDateTime, NaiveTime}; @@ -467,19 +469,19 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res let column_name = column.name(); if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option<&[u8]> = value; @@ -495,7 +497,7 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: String = value; @@ -503,31 +505,31 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res } if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get::, _>(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option> = value; diff --git a/src/database/sqlite.rs b/src/database/sqlite.rs index 6ca8e98..a8144cb 100644 --- a/src/database/sqlite.rs +++ b/src/database/sqlite.rs @@ -1,3 +1,5 @@ +use crate::get_or_null; + use super::{Pool, TableRow, RECORDS_LIMIT_PER_PAGE}; use async_trait::async_trait; use chrono::NaiveDateTime; @@ -351,43 +353,43 @@ fn convert_column_value_to_string( } if let Ok(value) = row.try_get(column_name) { let value: Option<&str> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.map_or("NULL".to_string(), |v| v.to_string())); + get_or_null!(value) } Err(anyhow::anyhow!( "column type not implemented: `{}` {}", From 922c605b39db465ca2a6042dfa8f81e6c9d872f2 Mon Sep 17 00:00:00 2001 From: utam0k Date: Sun, 12 Sep 2021 01:04:11 +0900 Subject: [PATCH 2/3] use else if to ensure that try_get is only called once. --- src/database/mod.rs | 2 +- src/database/mysql.rs | 36 ++++++++--------- src/database/postgres.rs | 85 +++++++++++++++++----------------------- src/database/sqlite.rs | 63 +++++++++++++---------------- 4 files changed, 82 insertions(+), 104 deletions(-) diff --git a/src/database/mod.rs b/src/database/mod.rs index beec60f..91c074a 100644 --- a/src/database/mod.rs +++ b/src/database/mod.rs @@ -53,6 +53,6 @@ pub trait TableRow: std::marker::Send { #[macro_export] macro_rules! get_or_null { ($value:expr) => { - return Ok($value.map_or("NULL".to_string(), |v| v.to_string())); + $value.map_or("NULL".to_string(), |v| v.to_string()) }; } diff --git a/src/database/mysql.rs b/src/database/mysql.rs index a9eaace..f32c7e3 100644 --- a/src/database/mysql.rs +++ b/src/database/mysql.rs @@ -363,58 +363,58 @@ fn convert_column_value_to_string(row: &MySqlRow, column: &MySqlColumn) -> anyho Ok(value.unwrap_or_else(|| NULL.to_string())) } else if let Ok(value) = row.try_get(column_name) { let value: Option<&str> = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) } else { anyhow::bail!( "column type not implemented: `{}` {}", diff --git a/src/database/postgres.rs b/src/database/postgres.rs index c574d93..65cf574 100644 --- a/src/database/postgres.rs +++ b/src/database/postgres.rs @@ -469,23 +469,19 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res let column_name = column.name(); if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option<&[u8]> = value; - return Ok(value.map_or("NULL".to_string(), |values| { + Ok(value.map_or("NULL".to_string(), |values| { format!( "\\x{}", values @@ -493,51 +489,42 @@ fn convert_column_value_to_string(row: &PgRow, column: &PgColumn) -> anyhow::Res .map(|v| format!("{:02x}", v)) .collect::() ) - })); - } - if let Ok(value) = row.try_get(column_name) { + })) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: String = value; - return Ok(value); - } - if let Ok(value) = row.try_get(column_name) { + Ok(value) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get::, _>(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get::, _>(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - return Ok(value.map_or("NULL".to_string(), |v| v.join(","))); + Ok(value.map_or("NULL".to_string(), |v| v.join(","))) + } else { + anyhow::bail!( + "column type not implemented: `{}` {}", + column_name, + column.type_info().clone().name() + ) } - Err(anyhow::anyhow!( - "column type not implemented: `{}` {}", - column_name, - column.type_info().clone().name() - )) } diff --git a/src/database/sqlite.rs b/src/database/sqlite.rs index a8144cb..2e4af68 100644 --- a/src/database/sqlite.rs +++ b/src/database/sqlite.rs @@ -349,51 +349,42 @@ fn convert_column_value_to_string( let column_name = column.name(); if let Ok(value) = row.try_get(column_name) { let value: Option = value; - return Ok(value.unwrap_or_else(|| "NULL".to_string())); - } - if let Ok(value) = row.try_get(column_name) { + Ok(value.unwrap_or_else(|| "NULL".to_string())) + } else if let Ok(value) = row.try_get(column_name) { let value: Option<&str> = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option> = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) - } - if let Ok(value) = row.try_get(column_name) { + Ok(get_or_null!(value)) + } else if let Ok(value) = row.try_get(column_name) { let value: Option = value; - get_or_null!(value) + Ok(get_or_null!(value)) + } else { + anyhow::bail!( + "column type not implemented: `{}` {}", + column_name, + column.type_info().clone().name() + ) } - Err(anyhow::anyhow!( - "column type not implemented: `{}` {}", - column_name, - column.type_info().clone().name() - )) } From 204f3a9d791553d86bcba0c3856a96ccbaa03fba Mon Sep 17 00:00:00 2001 From: utam0k Date: Sun, 12 Sep 2021 01:12:09 +0900 Subject: [PATCH 3/3] remove a unnecessary code. --- src/database/mysql.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/database/mysql.rs b/src/database/mysql.rs index f32c7e3..2da6988 100644 --- a/src/database/mysql.rs +++ b/src/database/mysql.rs @@ -9,8 +9,6 @@ use sqlx::mysql::{MySqlColumn, MySqlPoolOptions, MySqlRow}; use sqlx::{Column as _, Row as _, TypeInfo as _}; use std::time::Duration; -const NULL: &str = "NULL"; - pub struct MySqlPool { pool: sqlx::mysql::MySqlPool, } @@ -360,7 +358,7 @@ fn convert_column_value_to_string(row: &MySqlRow, column: &MySqlColumn) -> anyho if let Ok(value) = row.try_get(column_name) { let value: Option = value; - Ok(value.unwrap_or_else(|| NULL.to_string())) + Ok(value.unwrap_or_else(|| "NULL".to_string())) } else if let Ok(value) = row.try_get(column_name) { let value: Option<&str> = value; Ok(get_or_null!(value))