Skip to main content

rbdc_sqlite/
driver.rs

1use crate::SqliteConnectOptions;
2use futures_core::future::BoxFuture;
3use rbdc::db::{ConnectOptions, Connection, Driver, Placeholder};
4use rbdc::Error;
5use rbs::Value;
6
7#[derive(Debug)]
8pub struct SqliteDriver {}
9
10impl Driver for SqliteDriver {
11    fn name(&self) -> &str {
12        "sqlite"
13    }
14
15    fn connect(&self, url: &str) -> BoxFuture<'_, Result<Box<dyn Connection>, Error>> {
16        let url = url.to_owned();
17        Box::pin(async move {
18            let mut opt = self.default_option();
19            opt.set_uri(&url)?;
20            if let Some(opt) = opt.downcast_ref::<SqliteConnectOptions>() {
21                let conn = opt.connect().await?;
22                Ok(Box::new(conn) as Box<dyn Connection>)
23            } else {
24                Err(Error::from("downcast_ref failure"))
25            }
26        })
27    }
28
29    fn connect_opt<'a>(
30        &'a self,
31        opt: &'a dyn ConnectOptions,
32    ) -> BoxFuture<'a, Result<Box<dyn Connection>, Error>> {
33        let opt: &SqliteConnectOptions = opt.downcast_ref().expect(
34            "SqliteDriver::connect_opt requires SqliteConnectOptions, got a different ConnectOptions type",
35        );
36        Box::pin(async move {
37            let conn = opt.connect().await?;
38            Ok(Box::new(conn) as Box<dyn Connection>)
39        })
40    }
41
42    fn default_option(&self) -> Box<dyn ConnectOptions> {
43        Box::new(SqliteConnectOptions::default())
44    }
45
46    fn column_type(&self, val: &Value) -> String {
47        match val {
48            Value::Null => "NULL",
49            Value::Bool(_) => "BOOLEAN",
50            Value::I32(_) => "INTEGER",
51            Value::I64(_) => "INTEGER",
52            Value::U32(_) => "INTEGER",
53            Value::U64(_) => "INTEGER",
54            Value::F32(_) => "REAL",
55            Value::F64(_) => "REAL",
56            Value::String(_) => "TEXT",
57            Value::Binary(_) => "BLOB",
58            Value::Array(_) => "TEXT",
59            Value::Map(_) => "TEXT",
60            Value::Ext(t, _) => match *t {
61                "Date" => "TEXT",
62                "DateTime" => "TEXT",
63                "Time" => "TEXT",
64                "Timestamp" => "INTEGER",
65                "Decimal" => "NUMERIC",
66                "Json" => "BLOB",
67                "Uuid" => "TEXT",
68                _ => "NULL",
69            },
70        }
71        .to_string()
72    }
73}
74
75impl Placeholder for SqliteDriver {
76    fn exchange(&self, sql: &str) -> String {
77        sql.to_string()
78    }
79}
80
81#[cfg(test)]
82mod test {
83    #[test]
84    fn test_default() {}
85}
86// #[cfg(test)]
87// mod test {
88//     use crate::driver::SqliteDriver;
89//     use crate::SqliteConnectOptions;
90//     use rbdc::block_on;
91//     use rbdc::db::{ConnectOptions, Driver};
92//     use rbdc::decimal::Decimal;
93//     use rbdc::pool::Pool;
94//     use rbs::Value;
95//     use std::fs::File;
96//
97//     #[test]
98//     fn test_sqlite_pool() {
99//         let f = File::create("../target/test.db");
100//         if f.is_err() {
101//             println!("{}", f.err().unwrap());
102//         } else {
103//             drop(f);
104//         }
105//         let f = async move {
106//             let pool = Pool::new_url(SqliteDriver {}, "sqlite://../target/test.db").unwrap();
107//             let mut conn = pool.get().await.unwrap();
108//             conn.exec(
109//                 "CREATE TABLE `biz_activity`
110// (
111//     `id`            TEXT PRIMARY KEY NOT NULL,
112//     `name`          TEXT     DEFAULT NULL,
113//     `pc_link`       TEXT     DEFAULT NULL,
114//     `h5_link`       TEXT     DEFAULT NULL,
115//     `sort`          TEXT     DEFAULT NULL,
116//     `status`        INT      DEFAULT NULL,
117//     `version`       INT      DEFAULT NULL,
118//     `remark`        TEXT     DEFAULT NULL,
119//     `create_time`   datetime DEFAULT NULL,
120//     `delete_flag`   INT(1)   DEFAULT NULL,
121//     `pc_banner_img` TEXT     DEFAULT NULL,
122//     `h5_banner_img` TEXT     DEFAULT NULL
123// );
124//
125// INSERT INTO `biz_activity`
126// VALUES ('1', '活动1', NULL, NULL, '1', 1, 1, 'fff', '2019-12-12 00:00:00', 0, NULL, NULL),
127//        ('178', 'test_insret', '', '', '1', 1, 0, '', '2020-06-17 20:08:13', 0, NULL, NULL),
128//        ('221', 'test', '', '', '0', 0, 0, '', '2020-06-17 20:10:23', 0, NULL, NULL),
129//        ('222', 'test', '', '', '0', 0, 0, '', '2020-06-17 20:10:23', 0, NULL, NULL),
130//        ('223', 'test', '', '', '0', 0, 0, '', '2020-06-17 20:10:23', 0, NULL, NULL);",
131//                 vec![],
132//             )
133//             .await;
134//
135//             let data = conn
136//                 .exec_decode("select * from biz_activity", vec![])
137//                 .await
138//                 .unwrap();
139//             for mut x in data {
140//                 println!("row: {}", x);
141//             }
142//         };
143//         block_on!(f);
144//     }
145//
146//     #[test]
147//     fn test_sqlite_param() {
148//         let task = async move {
149//             let mut d = SqliteDriver {};
150//             let mut c = d.connect("sqlite://../target/test.db").await.unwrap();
151//             let param = vec![
152//                 Decimal("1".to_string()).into(),
153//                 Value::String("1".to_string()),
154//             ];
155//             println!("param => {}", Value::Array(param.clone()));
156//             let data = c
157//                 .exec("update biz_activity set version = ? where id  = ?", param)
158//                 .await
159//                 .unwrap();
160//             println!("{}", data);
161//         };
162//         block_on!(task);
163//     }
164// }