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
108
109
110
111
112
113
extern crate libsqlite3_sys as ffi;
use std::os::raw as libc;
use std::ptr::{self, NonNull};
use sqlite::SqliteType;
pub struct SerializedValue {
pub ty: SqliteType,
pub data: Option<Vec<u8>>,
}
impl SerializedValue {
#[allow(clippy::cast_ptr_alignment)]
pub(crate) fn bind_to(self, stmt: NonNull<ffi::sqlite3_stmt>, idx: libc::c_int) -> libc::c_int {
unsafe {
match (self.ty, self.data) {
(_, None) => ffi::sqlite3_bind_null(stmt.as_ptr(), idx),
(SqliteType::Binary, Some(bytes)) => ffi::sqlite3_bind_blob(
stmt.as_ptr(),
idx,
bytes.as_ptr() as *const libc::c_void,
bytes.len() as libc::c_int,
ffi::SQLITE_TRANSIENT(),
),
(SqliteType::Text, Some(bytes)) => ffi::sqlite3_bind_text(
stmt.as_ptr(),
idx,
bytes.as_ptr() as *const libc::c_char,
bytes.len() as libc::c_int,
ffi::SQLITE_TRANSIENT(),
),
(SqliteType::Float, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const f32);
ffi::sqlite3_bind_double(stmt.as_ptr(), idx, libc::c_double::from(value))
}
(SqliteType::Double, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const f64);
ffi::sqlite3_bind_double(stmt.as_ptr(), idx, value as libc::c_double)
}
(SqliteType::SmallInt, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i16);
ffi::sqlite3_bind_int(stmt.as_ptr(), idx, libc::c_int::from(value))
}
(SqliteType::Integer, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i32);
ffi::sqlite3_bind_int(stmt.as_ptr(), idx, value as libc::c_int)
}
(SqliteType::Long, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i64);
ffi::sqlite3_bind_int64(stmt.as_ptr(), idx, value)
}
}
}
}
#[allow(clippy::cast_ptr_alignment)]
pub fn result_of(self, ctx: *mut ffi::sqlite3_context) {
unsafe {
match (self.ty, self.data) {
(_, None) => ffi::sqlite3_result_null(ctx),
(SqliteType::Binary, Some(bytes)) => ffi::sqlite3_result_blob(
ctx,
bytes.as_ptr() as *const libc::c_void,
bytes.len() as libc::c_int,
ffi::SQLITE_TRANSIENT(),
),
(SqliteType::Text, Some(bytes)) => ffi::sqlite3_result_text(
ctx,
bytes.as_ptr() as *const libc::c_char,
bytes.len() as libc::c_int,
ffi::SQLITE_TRANSIENT(),
),
(SqliteType::Float, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const f32);
ffi::sqlite3_result_double(ctx, libc::c_double::from(value))
}
(SqliteType::Double, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const f64);
ffi::sqlite3_result_double(ctx, value as libc::c_double)
}
(SqliteType::SmallInt, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i16);
ffi::sqlite3_result_int(ctx, libc::c_int::from(value))
}
(SqliteType::Integer, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i32);
ffi::sqlite3_result_int(ctx, value as libc::c_int)
}
(SqliteType::Long, Some(bytes)) => {
let value = ptr::read_unaligned(bytes.as_ptr() as *const i64);
ffi::sqlite3_result_int64(ctx, value)
}
}
}
}
}