sqlite_provider/connection/
extensions.rs1use core::marker::PhantomData;
2use core::ptr::NonNull;
3
4use crate::error::Result;
5use crate::provider::{
6 ColumnMetadata, OwnedBytes, RawBytes, Sqlite3Backup, Sqlite3BlobIo, Sqlite3Metadata,
7 Sqlite3Serialize, Sqlite3Wal,
8};
9use crate::statement::Statement;
10
11use super::core::Connection;
12
13pub struct Backup<'c, 'p, P: Sqlite3Backup> {
18 api: &'p P,
19 handle: NonNull<P::Backup>,
20 _conn: PhantomData<&'c Connection<'p, P>>,
21}
22
23impl<'c, 'p, P: Sqlite3Backup> Backup<'c, 'p, P> {
24 pub fn step(&self, pages: i32) -> Result<()> {
26 unsafe { self.api.backup_step(self.handle, pages) }
27 }
28
29 pub fn remaining(&self) -> i32 {
31 unsafe { self.api.backup_remaining(self.handle) }
32 }
33
34 pub fn pagecount(&self) -> i32 {
36 unsafe { self.api.backup_pagecount(self.handle) }
37 }
38}
39
40impl<'c, 'p, P: Sqlite3Backup> Drop for Backup<'c, 'p, P> {
41 fn drop(&mut self) {
42 let _ = unsafe { self.api.backup_finish(self.handle) };
43 }
44}
45
46impl<'p, P: Sqlite3Backup> Connection<'p, P> {
47 pub fn backup_to<'c>(
49 &'c self,
50 dest: &'c Connection<'p, P>,
51 name: &str,
52 ) -> Result<Backup<'c, 'p, P>> {
53 let handle = unsafe { self.api.backup_init(dest.db, name, self.db, "main")? };
54 Ok(Backup {
55 api: self.api,
56 handle,
57 _conn: PhantomData,
58 })
59 }
60}
61
62pub struct Blob<'c, 'p, P: Sqlite3BlobIo> {
67 api: &'p P,
68 handle: NonNull<P::Blob>,
69 _conn: PhantomData<&'c Connection<'p, P>>,
70}
71
72impl<'c, 'p, P: Sqlite3BlobIo> Blob<'c, 'p, P> {
73 pub fn read(&self, buf: &mut [u8], offset: i32) -> Result<()> {
75 unsafe { self.api.blob_read(self.handle, buf, offset) }
76 }
77
78 pub fn write(&self, buf: &[u8], offset: i32) -> Result<()> {
80 unsafe { self.api.blob_write(self.handle, buf, offset) }
81 }
82
83 pub fn len(&self) -> i32 {
85 unsafe { self.api.blob_bytes(self.handle) }
86 }
87
88 pub fn is_empty(&self) -> bool {
90 self.len() == 0
91 }
92}
93
94impl<'c, 'p, P: Sqlite3BlobIo> Drop for Blob<'c, 'p, P> {
95 fn drop(&mut self) {
96 let _ = unsafe { self.api.blob_close(self.handle) };
97 }
98}
99
100impl<'p, P: Sqlite3BlobIo> Connection<'p, P> {
101 pub fn open_blob<'c>(
103 &'c self,
104 db_name: &str,
105 table: &str,
106 column: &str,
107 rowid: i64,
108 flags: u32,
109 ) -> Result<Blob<'c, 'p, P>> {
110 let handle = unsafe {
111 self.api
112 .blob_open(self.db, db_name, table, column, rowid, flags)?
113 };
114 Ok(Blob {
115 api: self.api,
116 handle,
117 _conn: PhantomData,
118 })
119 }
120}
121
122pub struct SerializedDb<'p, P: Sqlite3Serialize> {
124 api: &'p P,
125 bytes: OwnedBytes,
126}
127
128impl<'p, P: Sqlite3Serialize> SerializedDb<'p, P> {
129 pub fn as_slice(&self) -> &[u8] {
131 unsafe { core::slice::from_raw_parts(self.bytes.ptr.as_ptr(), self.bytes.len) }
132 }
133
134 pub fn into_vec(self) -> Vec<u8> {
136 let me = core::mem::ManuallyDrop::new(self);
137 let vec = me.as_slice().to_vec();
138 unsafe { Sqlite3Serialize::free(me.api, me.bytes) };
139 vec
140 }
141}
142
143impl<'p, P: Sqlite3Serialize> Drop for SerializedDb<'p, P> {
144 fn drop(&mut self) {
145 unsafe { Sqlite3Serialize::free(self.api, self.bytes) };
146 }
147}
148
149impl<'p, P: Sqlite3Serialize> Connection<'p, P> {
150 pub fn serialize(&self, schema: Option<&str>, flags: u32) -> Result<SerializedDb<'p, P>> {
152 let bytes = unsafe { self.api.serialize(self.db, schema, flags)? };
153 Ok(SerializedDb {
154 api: self.api,
155 bytes,
156 })
157 }
158
159 pub fn deserialize(&self, schema: Option<&str>, data: &[u8], flags: u32) -> Result<()> {
161 unsafe { self.api.deserialize(self.db, schema, data, flags) }
162 }
163}
164
165impl<'p, P: Sqlite3Wal> Connection<'p, P> {
166 pub fn wal_checkpoint(&self, db_name: Option<&str>) -> Result<()> {
168 unsafe { self.api.wal_checkpoint(self.db, db_name) }
169 }
170
171 pub fn wal_checkpoint_v2(&self, db_name: Option<&str>, mode: i32) -> Result<(i32, i32)> {
173 unsafe { self.api.wal_checkpoint_v2(self.db, db_name, mode) }
174 }
175
176 pub fn wal_frame_count(&self) -> Result<Option<u32>> {
178 unsafe { self.api.wal_frame_count(self.db) }
179 }
180}
181
182impl<'p, P: Sqlite3Metadata> Connection<'p, P> {
183 pub fn table_column_metadata(
185 &self,
186 db_name: Option<&str>,
187 table: &str,
188 column: &str,
189 ) -> Result<ColumnMetadata> {
190 unsafe {
191 self.api
192 .table_column_metadata(self.db, db_name, table, column)
193 }
194 }
195}
196
197impl<'p, P: Sqlite3Metadata> Statement<'_, 'p, P> {
198 pub fn column_decltype_raw(&self, col: i32) -> Option<RawBytes> {
200 unsafe { self.conn.api.column_decltype(self.stmt, col) }
201 }
202
203 pub fn column_name_raw(&self, col: i32) -> Option<RawBytes> {
205 unsafe { self.conn.api.column_name(self.stmt, col) }
206 }
207
208 pub fn column_table_name_raw(&self, col: i32) -> Option<RawBytes> {
210 unsafe { self.conn.api.column_table_name(self.stmt, col) }
211 }
212}