@@ -57,6 +57,27 @@ FROM json_each(?) e",
57
57
) ?;
58
58
iterate_statement. bind_text ( 1 , data, sqlite:: Destructor :: STATIC ) ?;
59
59
60
+ // We do an ON CONFLICT UPDATE simply so that the RETURNING bit works for existing rows.
61
+ // We can consider splitting this into separate SELECT and INSERT statements.
62
+ // language=SQLite
63
+ let bucket_statement = db. prepare_v2 (
64
+ "INSERT INTO ps_buckets(name)
65
+ VALUES(?)
66
+ ON CONFLICT DO UPDATE
67
+ SET last_applied_op = last_applied_op
68
+ RETURNING id, last_applied_op" ,
69
+ ) ?;
70
+ bucket_statement. bind_text ( 1 , bucket, sqlite:: Destructor :: STATIC ) ?;
71
+ bucket_statement. step ( ) ?;
72
+
73
+ let bucket_id = bucket_statement. column_int64 ( 0 ) ?;
74
+
75
+ // This is an optimization for initial sync - we can avoid persisting individual REMOVE
76
+ // operations when last_applied_op = 0.
77
+ // We do still need to do the "supersede_statement" step for this case, since a REMOVE
78
+ // operation can supersede another PUT operation we're syncing at the same time.
79
+ let mut last_applied_op = bucket_statement. column_int64 ( 1 ) ?;
80
+
60
81
// Statement to supersede (replace) operations with the same key.
61
82
// language=SQLite
62
83
let supersede_statement = db. prepare_v2 (
@@ -66,37 +87,18 @@ DELETE FROM ps_oplog
66
87
AND ps_oplog.key = ?2
67
88
RETURNING op_id, hash" ,
68
89
) ?;
69
- supersede_statement. bind_text ( 1 , bucket , sqlite :: Destructor :: STATIC ) ?;
90
+ supersede_statement. bind_int64 ( 1 , bucket_id ) ?;
70
91
71
92
// language=SQLite
72
93
let insert_statement = db. prepare_v2 ( "\
73
94
INSERT INTO ps_oplog(bucket, op_id, key, row_type, row_id, data, hash) VALUES (?, ?, ?, ?, ?, ?, ?)") ?;
74
- insert_statement. bind_text ( 1 , bucket , sqlite :: Destructor :: STATIC ) ?;
95
+ insert_statement. bind_int64 ( 1 , bucket_id ) ?;
75
96
76
97
let updated_row_statement = db. prepare_v2 (
77
98
"\
78
99
INSERT OR IGNORE INTO ps_updated_rows(row_type, row_id) VALUES(?1, ?2)",
79
100
) ?;
80
101
81
- // We do an ON CONFLICT UPDATE simply so that the RETURNING bit works for existing rows.
82
- // We can consider splitting this into separate SELECT and INSERT statements.
83
- // language=SQLite
84
- let bucket_statement = db. prepare_v2 (
85
- "INSERT INTO ps_buckets(name)
86
- VALUES(?)
87
- ON CONFLICT DO UPDATE
88
- SET last_applied_op = last_applied_op
89
- RETURNING last_applied_op" ,
90
- ) ?;
91
- bucket_statement. bind_text ( 1 , bucket, sqlite:: Destructor :: STATIC ) ?;
92
- bucket_statement. step ( ) ?;
93
-
94
- // This is an optimization for initial sync - we can avoid persisting individual REMOVE
95
- // operations when last_applied_op = 0.
96
- // We do still need to do the "supersede_statement" step for this case, since a REMOVE
97
- // operation can supersede another PUT operation we're syncing at the same time.
98
- let mut last_applied_op = bucket_statement. column_int64 ( 0 ) ?;
99
-
100
102
bucket_statement. reset ( ) ?;
101
103
102
104
let mut last_op: Option < i64 > = None ;
@@ -204,22 +206,22 @@ FROM ps_oplog
204
206
WHERE bucket = ?1" ,
205
207
)
206
208
. into_db_result ( db) ?;
207
- clear_statement1. bind_text ( 1 , bucket , sqlite :: Destructor :: STATIC ) ?;
209
+ clear_statement1. bind_int64 ( 1 , bucket_id ) ?;
208
210
clear_statement1. exec ( ) ?;
209
211
210
212
let clear_statement2 = db
211
213
. prepare_v2 ( "DELETE FROM ps_oplog WHERE bucket = ?1" )
212
214
. into_db_result ( db) ?;
213
- clear_statement2. bind_text ( 1 , bucket , sqlite :: Destructor :: STATIC ) ?;
215
+ clear_statement2. bind_int64 ( 1 , bucket_id ) ?;
214
216
clear_statement2. exec ( ) ?;
215
217
216
218
// And we need to re-apply all of those.
217
219
// We also replace the checksum with the checksum of the CLEAR op.
218
220
// language=SQLite
219
221
let clear_statement2 = db. prepare_v2 (
220
- "UPDATE ps_buckets SET last_applied_op = 0, add_checksum = ?1, op_checksum = 0 WHERE name = ?2" ,
222
+ "UPDATE ps_buckets SET last_applied_op = 0, add_checksum = ?1, op_checksum = 0 WHERE id = ?2" ,
221
223
) ?;
222
- clear_statement2. bind_text ( 2 , bucket , sqlite :: Destructor :: STATIC ) ?;
224
+ clear_statement2. bind_int64 ( 2 , bucket_id ) ?;
223
225
clear_statement2. bind_int ( 1 , checksum) ?;
224
226
clear_statement2. exec ( ) ?;
225
227
@@ -236,9 +238,9 @@ WHERE bucket = ?1",
236
238
SET last_op = ?2,
237
239
add_checksum = (add_checksum + ?3) & 0xffffffff,
238
240
op_checksum = (op_checksum + ?4) & 0xffffffff
239
- WHERE name = ?1" ,
241
+ WHERE id = ?1" ,
240
242
) ?;
241
- statement. bind_text ( 1 , bucket , sqlite :: Destructor :: STATIC ) ?;
243
+ statement. bind_int64 ( 1 , bucket_id ) ?;
242
244
statement. bind_int64 ( 2 , * last_op) ?;
243
245
statement. bind_int ( 3 , add_checksum) ?;
244
246
statement. bind_int ( 4 , op_checksum) ?;
@@ -263,26 +265,28 @@ pub fn delete_pending_buckets(db: *mut sqlite::sqlite3, _data: &str) -> Result<(
263
265
264
266
pub fn delete_bucket ( db : * mut sqlite:: sqlite3 , name : & str ) -> Result < ( ) , SQLiteError > {
265
267
// language=SQLite
266
- let statement = db. prepare_v2 (
267
- "\
268
+ let statement = db. prepare_v2 ( "DELETE FROM ps_buckets WHERE name = ?1 RETURNING id" ) ?;
269
+ statement. bind_text ( 1 , name, sqlite:: Destructor :: STATIC ) ?;
270
+
271
+ if statement. step ( ) ? == ResultCode :: ROW {
272
+ let bucket_id = statement. column_int64 ( 0 ) ?;
273
+
274
+ // language=SQLite
275
+ let updated_statement = db. prepare_v2 (
276
+ "\
268
277
INSERT OR IGNORE INTO ps_updated_rows(row_type, row_id)
269
278
SELECT row_type, row_id
270
279
FROM ps_oplog
271
280
WHERE bucket = ?1" ,
272
- ) ?;
273
- statement. bind_text ( 1 , & name, sqlite:: Destructor :: STATIC ) ?;
274
- statement. exec ( ) ?;
275
-
276
- // Rename bucket
277
- // language=SQLite
278
- let statement = db. prepare_v2 ( "DELETE FROM ps_oplog WHERE bucket=?1" ) ?;
279
- statement. bind_text ( 1 , name, sqlite:: Destructor :: STATIC ) ?;
280
- statement. exec ( ) ?;
281
+ ) ?;
282
+ updated_statement. bind_int64 ( 1 , bucket_id) ?;
283
+ updated_statement. exec ( ) ?;
281
284
282
- // language=SQLite
283
- let statement = db. prepare_v2 ( "DELETE FROM ps_buckets WHERE name = ?1" ) ?;
284
- statement. bind_text ( 1 , name, sqlite:: Destructor :: STATIC ) ?;
285
- statement. exec ( ) ?;
285
+ // language=SQLite
286
+ let delete_statement = db. prepare_v2 ( "DELETE FROM ps_oplog WHERE bucket=?1" ) ?;
287
+ delete_statement. bind_int64 ( 1 , bucket_id) ?;
288
+ delete_statement. exec ( ) ?;
289
+ }
286
290
287
291
Ok ( ( ) )
288
292
}
0 commit comments