Repository navigation
Expand file tree
/
Copy pathexecutor.rs
More file actions
107 lines (84 loc) · 3.12 KB
/
Copy pathexecutor.rs
File metadata and controls
107 lines (84 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
use core::i32;
use core::ptr::{null_mut, NonNull};
use std::convert::TryInto;
use std::marker::PhantomData;
use std::sync::Arc;
use futures_core::future::BoxFuture;
use futures_core::stream::BoxStream;
use libsqlite3_sys::{
sqlite3_prepare_v3, sqlite3_stmt, SQLITE_OK, SQLITE_PREPARE_NO_VTAB, SQLITE_PREPARE_PERSISTENT,
};
use crate::describe::Describe;
use crate::executor::Executor;
use crate::sqlite::statement::{Statement, Step};
use crate::sqlite::{Sqlite, SqliteArguments, SqliteConnection, SqliteCursor, SqliteRow};
impl SqliteConnection {
fn prepare(&mut self, query: &str) -> crate::Result<Statement> {
// TODO: Cache?
let mut statement: *mut sqlite3_stmt = null_mut();
// TODO: Handle the error when there are internal NULs in the query
let mut sql = query.as_bytes();
let sql_len = query.len();
if sql_len > (i32::MAX as usize) {
panic!("query too large");
}
// TODO: Contribute this back to libsqlite3-sys, these flags should be u32
let flags = (SQLITE_PREPARE_PERSISTENT | SQLITE_PREPARE_NO_VTAB) as u32;
// <https://www.sqlite.org/c3ref/prepare.html>
#[allow(unsafe_code)]
let status = unsafe {
sqlite3_prepare_v3(
self.handle.as_ptr(),
sql.as_ptr() as *const i8,
sql.len() as i32,
flags,
&mut statement,
null_mut(),
)
};
if status != SQLITE_OK {
// TODO: Add handling of sqlite errors
// We need to bubble up as a [DatabaseError]
panic!("not ok: {}", status);
}
// TODO: Handle the error when NULL is returned
Ok(Statement(NonNull::new(statement).unwrap()))
}
}
impl Executor for SqliteConnection {
type Database = Sqlite;
fn send<'e, 'q: 'e>(&'e mut self, query: &'q str) -> BoxFuture<'e, crate::Result<()>> {
todo!()
}
fn execute<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
args: SqliteArguments,
) -> BoxFuture<'e, crate::Result<u64>> {
// let mut statement = self.prepare(query).unwrap();
// statement.step().unwrap();
// statement.reset();
todo!();
}
fn fetch<'e, 'q: 'e>(&'e mut self, query: &'q str, args: SqliteArguments) -> SqliteCursor<'e> {
let statement = self.prepare(query);
SqliteCursor::<'e>::new(statement)
// Box::pin(async_stream::try_stream! {
// let mut statement = self.prepare(query)?;
// let columns = self.column_names(&mut statement)?;
// while let Step::Row = { statement.step()? } {
// let row = SqliteRow {
// stmt: &mut statement,
// columns: Arc::clone(&columns),
// };
// yield row;
// . }
// })
}
fn describe<'e, 'q: 'e>(
&'e mut self,
query: &'q str,
) -> BoxFuture<'e, crate::Result<Describe<Self::Database>>> {
todo!()
}
}