diff --git a/plugins/sql/src/plugin.rs b/plugins/sql/src/plugin.rs index e7deb885..c33e81e6 100644 --- a/plugins/sql/src/plugin.rs +++ b/plugins/sql/src/plugin.rs @@ -10,7 +10,7 @@ use sqlx::{ migrate::{ MigrateDatabase, Migration as SqlxMigration, MigrationSource, MigrationType, Migrator, }, - Column, Pool, Row, TypeInfo, + Column, Pool, Row, TypeInfo, ValueRef, }; use tauri::{ command, @@ -44,6 +44,8 @@ pub enum Error { Migration(#[from] sqlx::migrate::MigrateError), #[error("database {0} not loaded")] DatabaseNotLoaded(String), + #[error("unsupported datatype: {0}")] + UnsupportedDatatype(String), } impl Serialize for Error { @@ -246,12 +248,16 @@ async fn select( for row in rows { let mut value = HashMap::default(); for (i, column) in row.columns().iter().enumerate() { - let info = column.type_info(); - let v = if info.is_null() { + let v = row.try_get_raw(i)?; + + let v = if v.is_null() { JsonValue::Null } else { - match info.name() { - "VARCHAR" | "STRING" | "TEXT" | "DATETIME" | "JSON" => { + // TODO: postgresql's JSON type + match v.type_info().name() { + "VARCHAR" | "STRING" | "TEXT" | "TINYTEXT" | "LONGTEXT" | "NVARCHAR" + | "BIGVARCHAR" | "CHAR" | "BIGCHAR" | "NCHAR" | "DATETIME" | "DATE" + | "TIME" | "YEAR" | "TIMESTAMP" => { if let Ok(s) = row.try_get(i) { JsonValue::String(s) } else { @@ -266,22 +272,25 @@ async fn select( JsonValue::Bool(x.to_lowercase() == "true") } } - "INT" | "NUMBER" | "INTEGER" | "BIGINT" | "INT8" => { + "INT" | "NUMBER" | "INTEGER" | "BIGINT" | "INT2" | "INT4" | "INT8" + | "NUMERIC" | "TINYINT" | "SMALLINT" | "MEDIUMINT" | "TINYINT UNSINGED" + | "SMALLINT UNSINGED" | "INT UNSINGED" | "MEDIUMINT UNSINGED" + | "BIGINT UNSINGED" => { if let Ok(n) = row.try_get::(i) { JsonValue::Number(n.into()) } else { JsonValue::Null } } - "REAL" => { + "REAL" | "FLOAT" | "DOUBLE" | "FLOAT4" | "FLOAT8" => { if let Ok(n) = row.try_get::(i) { JsonValue::from(n) } else { JsonValue::Null } } - // "JSON" => JsonValue::Object(row.get(i)), - "BLOB" => { + "BLOB" | "TINYBLOB" | "MEDIUMBLOB" | "LONGBLOB" | "BINARY" | "VARBINARY" + | "BYTEA" => { if let Ok(n) = row.try_get::, usize>(i) { JsonValue::Array( n.into_iter().map(|n| JsonValue::Number(n.into())).collect(), @@ -290,13 +299,16 @@ async fn select( JsonValue::Null } } - _ => JsonValue::Null, + _ => return Err(Error::UnsupportedDatatype(v.type_info().name().to_string())), } }; + value.insert(column.name().to_string(), v); } + values.push(value); } + Ok(values) }