SQLx SQLite support
This commit is contained in:
parent
cdc8056d4b
commit
ec290156c5
@ -39,6 +39,7 @@ serde_json = { version = "^1", optional = true }
|
|||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
async-std = { version = "^1.9", features = [ "attributes" ] }
|
async-std = { version = "^1.9", features = [ "attributes" ] }
|
||||||
maplit = { version = "^1" }
|
maplit = { version = "^1" }
|
||||||
|
sea-orm = { path = ".", features = ["sqlx-sqlite", "runtime-async-std-native-tls"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
debug-print = []
|
debug-print = []
|
||||||
@ -49,6 +50,7 @@ with-json = [ "serde_json", "sea-query/with-json" ]
|
|||||||
sqlx-dep = [ "sqlx", "sqlx/json" ]
|
sqlx-dep = [ "sqlx", "sqlx/json" ]
|
||||||
sqlx-mysql = [ "sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql" ]
|
sqlx-mysql = [ "sqlx-dep", "sea-query/sqlx-mysql", "sqlx/mysql" ]
|
||||||
sqlx-postgres = [ "sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres" ]
|
sqlx-postgres = [ "sqlx-dep", "sea-query/sqlx-postgres", "sqlx/postgres" ]
|
||||||
|
sqlx-sqlite = [ "sqlx-dep", "sea-query/sqlx-sqlite", "sqlx/sqlite" ]
|
||||||
runtime-actix-native-tls = [ "sqlx/runtime-actix-native-tls" ]
|
runtime-actix-native-tls = [ "sqlx/runtime-actix-native-tls" ]
|
||||||
runtime-async-std-native-tls = [ "sqlx/runtime-async-std-native-tls" ]
|
runtime-async-std-native-tls = [ "sqlx/runtime-async-std-native-tls" ]
|
||||||
runtime-tokio-native-tls = [ "sqlx/runtime-tokio-native-tls" ]
|
runtime-tokio-native-tls = [ "sqlx/runtime-tokio-native-tls" ]
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement};
|
use crate::{ExecErr, ExecResult, QueryErr, QueryResult, Statement};
|
||||||
use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder};
|
use sea_query::{MysqlQueryBuilder, PostgresQueryBuilder, QueryStatementBuilder, SqliteQueryBuilder};
|
||||||
use std::{error::Error, fmt};
|
use std::{error::Error, fmt};
|
||||||
|
|
||||||
pub enum DatabaseConnection {
|
pub enum DatabaseConnection {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),
|
SqlxMySqlPoolConnection(crate::SqlxMySqlPoolConnection),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
SqlxSqlitePoolConnection(crate::SqlxSqlitePoolConnection),
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
MockDatabaseConnection(crate::MockDatabaseConnection),
|
MockDatabaseConnection(crate::MockDatabaseConnection),
|
||||||
Disconnected,
|
Disconnected,
|
||||||
@ -15,6 +17,7 @@ pub type DbConn = DatabaseConnection;
|
|||||||
pub enum QueryBuilderBackend {
|
pub enum QueryBuilderBackend {
|
||||||
MySql,
|
MySql,
|
||||||
Postgres,
|
Postgres,
|
||||||
|
Sqlite,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -42,6 +45,8 @@ impl std::fmt::Debug for DatabaseConnection {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection",
|
Self::SqlxMySqlPoolConnection(_) => "SqlxMySqlPoolConnection",
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
Self::SqlxSqlitePoolConnection(_) => "SqlxSqlitePoolConnection",
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
Self::MockDatabaseConnection(_) => "MockDatabaseConnection",
|
Self::MockDatabaseConnection(_) => "MockDatabaseConnection",
|
||||||
Self::Disconnected => "Disconnected",
|
Self::Disconnected => "Disconnected",
|
||||||
@ -55,6 +60,8 @@ impl DatabaseConnection {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
DatabaseConnection::SqlxMySqlPoolConnection(_) => QueryBuilderBackend::MySql,
|
DatabaseConnection::SqlxMySqlPoolConnection(_) => QueryBuilderBackend::MySql,
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
DatabaseConnection::SqlxSqlitePoolConnection(_) => QueryBuilderBackend::Sqlite,
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
DatabaseConnection::MockDatabaseConnection(_) => QueryBuilderBackend::Postgres,
|
DatabaseConnection::MockDatabaseConnection(_) => QueryBuilderBackend::Postgres,
|
||||||
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
||||||
@ -65,6 +72,8 @@ impl DatabaseConnection {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await,
|
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.execute(stmt).await,
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
DatabaseConnection::SqlxSqlitePoolConnection(conn) => conn.execute(stmt).await,
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
DatabaseConnection::MockDatabaseConnection(conn) => conn.execute(stmt).await,
|
DatabaseConnection::MockDatabaseConnection(conn) => conn.execute(stmt).await,
|
||||||
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
||||||
@ -75,6 +84,8 @@ impl DatabaseConnection {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await,
|
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_one(stmt).await,
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
DatabaseConnection::SqlxSqlitePoolConnection(conn) => conn.query_one(stmt).await,
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
DatabaseConnection::MockDatabaseConnection(conn) => conn.query_one(stmt).await,
|
DatabaseConnection::MockDatabaseConnection(conn) => conn.query_one(stmt).await,
|
||||||
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
||||||
@ -85,6 +96,8 @@ impl DatabaseConnection {
|
|||||||
match self {
|
match self {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await,
|
DatabaseConnection::SqlxMySqlPoolConnection(conn) => conn.query_all(stmt).await,
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
DatabaseConnection::SqlxSqlitePoolConnection(conn) => conn.query_all(stmt).await,
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
DatabaseConnection::MockDatabaseConnection(conn) => conn.query_all(stmt).await,
|
DatabaseConnection::MockDatabaseConnection(conn) => conn.query_all(stmt).await,
|
||||||
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
DatabaseConnection::Disconnected => panic!("Disconnected"),
|
||||||
@ -113,6 +126,7 @@ impl QueryBuilderBackend {
|
|||||||
match self {
|
match self {
|
||||||
Self::MySql => statement.build(MysqlQueryBuilder),
|
Self::MySql => statement.build(MysqlQueryBuilder),
|
||||||
Self::Postgres => statement.build(PostgresQueryBuilder),
|
Self::Postgres => statement.build(PostgresQueryBuilder),
|
||||||
|
Self::Sqlite => statement.build(SqliteQueryBuilder),
|
||||||
}
|
}
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,10 @@ impl Database {
|
|||||||
if crate::SqlxMySqlConnector::accepts(string) {
|
if crate::SqlxMySqlConnector::accepts(string) {
|
||||||
return Ok(crate::SqlxMySqlConnector::connect(string).await?);
|
return Ok(crate::SqlxMySqlConnector::connect(string).await?);
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
if crate::SqlxSqliteConnector::accepts(string) {
|
||||||
|
return Ok(crate::SqlxSqliteConnector::connect(string).await?);
|
||||||
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
if crate::MockDatabaseConnector::accepts(string) {
|
if crate::MockDatabaseConnector::accepts(string) {
|
||||||
return Ok(crate::MockDatabaseConnector::connect(string).await?);
|
return Ok(crate::MockDatabaseConnector::connect(string).await?);
|
||||||
|
@ -2,8 +2,16 @@
|
|||||||
mod mock;
|
mod mock;
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
mod sqlx_mysql;
|
mod sqlx_mysql;
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
mod sqlx_sqlite;
|
||||||
|
#[cfg(feature = "sqlx-dep")]
|
||||||
|
mod sqlx_types;
|
||||||
|
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
pub use mock::*;
|
pub use mock::*;
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
pub use sqlx_mysql::*;
|
pub use sqlx_mysql::*;
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
pub use sqlx_sqlite::*;
|
||||||
|
#[cfg(feature = "sqlx-dep")]
|
||||||
|
pub use sqlx_types::*;
|
||||||
|
@ -93,18 +93,6 @@ impl From<MySqlQueryResult> for ExecResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<sqlx::Error> for TypeErr {
|
|
||||||
fn from(_: sqlx::Error) -> TypeErr {
|
|
||||||
TypeErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<sqlx::Error> for ExecErr {
|
|
||||||
fn from(_: sqlx::Error) -> ExecErr {
|
|
||||||
ExecErr
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySqlArguments> {
|
fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, MySql, MySqlArguments> {
|
||||||
let mut query = sqlx::query(&stmt.sql);
|
let mut query = sqlx::query(&stmt.sql);
|
||||||
if let Some(values) = &stmt.values {
|
if let Some(values) = &stmt.values {
|
||||||
|
102
src/driver/sqlx_sqlite.rs
Normal file
102
src/driver/sqlx_sqlite.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
use sqlx::{
|
||||||
|
sqlite::{SqliteArguments, SqliteQueryResult, SqliteRow},
|
||||||
|
Sqlite, SqlitePool,
|
||||||
|
};
|
||||||
|
|
||||||
|
sea_query::sea_query_driver_sqlite!();
|
||||||
|
use sea_query_driver_sqlite::bind_query;
|
||||||
|
|
||||||
|
use crate::{debug_print, executor::*, ConnectionErr, DatabaseConnection, Statement};
|
||||||
|
|
||||||
|
pub struct SqlxSqliteConnector;
|
||||||
|
|
||||||
|
pub struct SqlxSqlitePoolConnection {
|
||||||
|
pool: SqlitePool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqlxSqliteConnector {
|
||||||
|
pub fn accepts(string: &str) -> bool {
|
||||||
|
string.starts_with("sqlite:")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn connect(string: &str) -> Result<DatabaseConnection, ConnectionErr> {
|
||||||
|
if let Ok(pool) = SqlitePool::connect(string).await {
|
||||||
|
Ok(DatabaseConnection::SqlxSqlitePoolConnection(
|
||||||
|
SqlxSqlitePoolConnection { pool },
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
Err(ConnectionErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqlxSqliteConnector {
|
||||||
|
pub fn from_sqlx_sqlite_pool(pool: SqlitePool) -> DatabaseConnection {
|
||||||
|
DatabaseConnection::SqlxSqlitePoolConnection(SqlxSqlitePoolConnection { pool })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SqlxSqlitePoolConnection {
|
||||||
|
pub async fn execute(&self, stmt: Statement) -> Result<ExecResult, ExecErr> {
|
||||||
|
debug_print!("{}", stmt);
|
||||||
|
|
||||||
|
let query = sqlx_query(&stmt);
|
||||||
|
if let Ok(conn) = &mut self.pool.acquire().await {
|
||||||
|
if let Ok(res) = query.execute(conn).await {
|
||||||
|
return Ok(res.into());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(ExecErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn query_one(&self, stmt: Statement) -> Result<Option<QueryResult>, QueryErr> {
|
||||||
|
debug_print!("{}", stmt);
|
||||||
|
|
||||||
|
let query = sqlx_query(&stmt);
|
||||||
|
if let Ok(conn) = &mut self.pool.acquire().await {
|
||||||
|
if let Ok(row) = query.fetch_one(conn).await {
|
||||||
|
Ok(Some(row.into()))
|
||||||
|
} else {
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(QueryErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn query_all(&self, stmt: Statement) -> Result<Vec<QueryResult>, QueryErr> {
|
||||||
|
debug_print!("{}", stmt);
|
||||||
|
|
||||||
|
let query = sqlx_query(&stmt);
|
||||||
|
if let Ok(conn) = &mut self.pool.acquire().await {
|
||||||
|
if let Ok(rows) = query.fetch_all(conn).await {
|
||||||
|
return Ok(rows.into_iter().map(|r| r.into()).collect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(QueryErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SqliteRow> for QueryResult {
|
||||||
|
fn from(row: SqliteRow) -> QueryResult {
|
||||||
|
QueryResult {
|
||||||
|
row: QueryResultRow::SqlxSqlite(row),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<SqliteQueryResult> for ExecResult {
|
||||||
|
fn from(result: SqliteQueryResult) -> ExecResult {
|
||||||
|
ExecResult {
|
||||||
|
result: ExecResultHolder::SqlxSqlite(result),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sqlx_query(stmt: &Statement) -> sqlx::query::Query<'_, Sqlite, SqliteArguments> {
|
||||||
|
let mut query = sqlx::query(&stmt.sql);
|
||||||
|
if let Some(values) = &stmt.values {
|
||||||
|
query = bind_query(query, values);
|
||||||
|
}
|
||||||
|
query
|
||||||
|
}
|
13
src/driver/sqlx_types.rs
Normal file
13
src/driver/sqlx_types.rs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
use crate::{ExecErr, TypeErr};
|
||||||
|
|
||||||
|
impl From<sqlx::Error> for TypeErr {
|
||||||
|
fn from(_: sqlx::Error) -> TypeErr {
|
||||||
|
TypeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<sqlx::Error> for ExecErr {
|
||||||
|
fn from(_: sqlx::Error) -> ExecErr {
|
||||||
|
ExecErr
|
||||||
|
}
|
||||||
|
}
|
@ -9,6 +9,8 @@ pub struct ExecResult {
|
|||||||
pub(crate) enum ExecResultHolder {
|
pub(crate) enum ExecResultHolder {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
SqlxMySql(sqlx::mysql::MySqlQueryResult),
|
SqlxMySql(sqlx::mysql::MySqlQueryResult),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
SqlxSqlite(sqlx::sqlite::SqliteQueryResult),
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
Mock(crate::MockExecResult),
|
Mock(crate::MockExecResult),
|
||||||
}
|
}
|
||||||
@ -23,6 +25,15 @@ impl ExecResult {
|
|||||||
match &self.result {
|
match &self.result {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),
|
ExecResultHolder::SqlxMySql(result) => result.last_insert_id(),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
ExecResultHolder::SqlxSqlite(result) => {
|
||||||
|
let last_insert_rowid = result.last_insert_rowid();
|
||||||
|
if last_insert_rowid < 0 {
|
||||||
|
panic!("negative last_insert_rowid")
|
||||||
|
} else {
|
||||||
|
last_insert_rowid as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
ExecResultHolder::Mock(result) => result.last_insert_id,
|
ExecResultHolder::Mock(result) => result.last_insert_id,
|
||||||
}
|
}
|
||||||
@ -32,6 +43,8 @@ impl ExecResult {
|
|||||||
match &self.result {
|
match &self.result {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
ExecResultHolder::SqlxMySql(result) => result.rows_affected(),
|
ExecResultHolder::SqlxMySql(result) => result.rows_affected(),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
ExecResultHolder::SqlxSqlite(result) => result.rows_affected(),
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
ExecResultHolder::Mock(result) => result.rows_affected,
|
ExecResultHolder::Mock(result) => result.rows_affected,
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@ pub struct QueryResult {
|
|||||||
pub(crate) row: QueryResultRow,
|
pub(crate) row: QueryResultRow,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) enum QueryResultRow {
|
pub(crate) enum QueryResultRow {
|
||||||
#[cfg(feature = "sqlx-mysql")]
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
SqlxMySql(sqlx::mysql::MySqlRow),
|
SqlxMySql(sqlx::mysql::MySqlRow),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
SqlxSqlite(sqlx::sqlite::SqliteRow),
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
Mock(crate::MockRow),
|
Mock(crate::MockRow),
|
||||||
}
|
}
|
||||||
@ -36,6 +37,19 @@ impl QueryResult {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Debug for QueryResultRow {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match self {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
Self::SqlxMySql(row) => write!(f, "{:?}", row),
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
Self::SqlxSqlite(_) => panic!("QueryResultRow::SqlxSqlite cannot be inspected"),
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
Self::Mock(row) => write!(f, "{:?}", row),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// QueryErr //
|
// QueryErr //
|
||||||
|
|
||||||
impl Error for QueryErr {}
|
impl Error for QueryErr {}
|
||||||
@ -64,7 +78,7 @@ impl fmt::Display for TypeErr {
|
|||||||
|
|
||||||
// TryGetable //
|
// TryGetable //
|
||||||
|
|
||||||
macro_rules! try_getable {
|
macro_rules! try_getable_all {
|
||||||
( $type: ty ) => {
|
( $type: ty ) => {
|
||||||
impl TryGetable for $type {
|
impl TryGetable for $type {
|
||||||
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TypeErr> {
|
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TypeErr> {
|
||||||
@ -75,6 +89,11 @@ macro_rules! try_getable {
|
|||||||
use sqlx::Row;
|
use sqlx::Row;
|
||||||
Ok(row.try_get(column.as_str())?)
|
Ok(row.try_get(column.as_str())?)
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
Ok(row.try_get(column.as_str())?)
|
||||||
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
|
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
|
||||||
}
|
}
|
||||||
@ -93,6 +112,14 @@ macro_rules! try_getable {
|
|||||||
Err(_) => Ok(None),
|
Err(_) => Ok(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
match row.try_get(column.as_str()) {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(_) => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) {
|
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) {
|
||||||
Ok(v) => Ok(Some(v)),
|
Ok(v) => Ok(Some(v)),
|
||||||
@ -104,15 +131,59 @@ macro_rules! try_getable {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
try_getable!(bool);
|
macro_rules! try_getable_mysql {
|
||||||
try_getable!(i8);
|
( $type: ty ) => {
|
||||||
try_getable!(i16);
|
impl TryGetable for $type {
|
||||||
try_getable!(i32);
|
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TypeErr> {
|
||||||
try_getable!(i64);
|
let column = format!("{}{}", pre, col);
|
||||||
try_getable!(u8);
|
match &res.row {
|
||||||
try_getable!(u16);
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
try_getable!(u32);
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
try_getable!(u64);
|
use sqlx::Row;
|
||||||
try_getable!(f32);
|
Ok(row.try_get(column.as_str())?)
|
||||||
try_getable!(f64);
|
}
|
||||||
try_getable!(String);
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(_) => panic!("{} unsupported by sqlx-sqlite", stringify!($type)),
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
QueryResultRow::Mock(row) => Ok(row.try_get(column.as_str())?),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryGetable for Option<$type> {
|
||||||
|
fn try_get(res: &QueryResult, pre: &str, col: &str) -> Result<Self, TypeErr> {
|
||||||
|
let column = format!("{}{}", pre, col);
|
||||||
|
match &res.row {
|
||||||
|
#[cfg(feature = "sqlx-mysql")]
|
||||||
|
QueryResultRow::SqlxMySql(row) => {
|
||||||
|
use sqlx::Row;
|
||||||
|
match row.try_get(column.as_str()) {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(_) => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(_) => panic!("{} unsupported by sqlx-sqlite", stringify!($type)),
|
||||||
|
#[cfg(feature = "mock")]
|
||||||
|
QueryResultRow::Mock(row) => match row.try_get(column.as_str()) {
|
||||||
|
Ok(v) => Ok(Some(v)),
|
||||||
|
Err(_) => Ok(None),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try_getable_all!(bool);
|
||||||
|
try_getable_all!(i8);
|
||||||
|
try_getable_all!(i16);
|
||||||
|
try_getable_all!(i32);
|
||||||
|
try_getable_all!(i64);
|
||||||
|
try_getable_all!(u8);
|
||||||
|
try_getable_all!(u16);
|
||||||
|
try_getable_all!(u32);
|
||||||
|
try_getable_mysql!(u64);
|
||||||
|
try_getable_all!(f32);
|
||||||
|
try_getable_all!(f64);
|
||||||
|
try_getable_all!(String);
|
||||||
|
@ -43,6 +43,44 @@ impl FromQueryResult for JsonValue {
|
|||||||
}
|
}
|
||||||
Ok(JsonValue::Object(map))
|
Ok(JsonValue::Object(map))
|
||||||
}
|
}
|
||||||
|
#[cfg(feature = "sqlx-sqlite")]
|
||||||
|
QueryResultRow::SqlxSqlite(row) => {
|
||||||
|
use serde_json::json;
|
||||||
|
use sqlx::{Column, Sqlite, Row, Type};
|
||||||
|
let mut map = Map::new();
|
||||||
|
for column in row.columns() {
|
||||||
|
let col = if !column.name().starts_with(pre) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
column.name().replacen(pre, "", 1)
|
||||||
|
};
|
||||||
|
let col_type = column.type_info();
|
||||||
|
macro_rules! match_sqlite_type {
|
||||||
|
( $type: ty ) => {
|
||||||
|
if <$type as Type<Sqlite>>::type_info().eq(col_type) {
|
||||||
|
map.insert(
|
||||||
|
col.to_owned(),
|
||||||
|
json!(res.try_get::<Option<$type>>(pre, &col)?),
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
match_sqlite_type!(bool);
|
||||||
|
match_sqlite_type!(i8);
|
||||||
|
match_sqlite_type!(i16);
|
||||||
|
match_sqlite_type!(i32);
|
||||||
|
match_sqlite_type!(i64);
|
||||||
|
match_sqlite_type!(u8);
|
||||||
|
match_sqlite_type!(u16);
|
||||||
|
match_sqlite_type!(u32);
|
||||||
|
// match_sqlite_type!(u64); // unsupported by SQLx Sqlite
|
||||||
|
match_sqlite_type!(f32);
|
||||||
|
match_sqlite_type!(f64);
|
||||||
|
match_sqlite_type!(String);
|
||||||
|
}
|
||||||
|
Ok(JsonValue::Object(map))
|
||||||
|
}
|
||||||
#[cfg(feature = "mock")]
|
#[cfg(feature = "mock")]
|
||||||
QueryResultRow::Mock(row) => {
|
QueryResultRow::Mock(row) => {
|
||||||
let mut map = Map::new();
|
let mut map = Map::new();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user