@@ -69,7 +69,8 @@ UPDATE ps_oplog SET
69
69
data = NULL
70
70
WHERE ps_oplog.superseded = 0
71
71
AND unlikely(ps_oplog.bucket = ?1)
72
- AND ps_oplog.key = ?2" ,
72
+ AND ps_oplog.key = ?2
73
+ RETURNING op_id" ,
73
74
) ?;
74
75
supersede_statement. bind_text ( 1 , bucket, sqlite:: Destructor :: STATIC ) ?;
75
76
@@ -110,21 +111,36 @@ INSERT INTO ps_oplog(bucket, op_id, op, key, row_type, row_id, data, hash, super
110
111
111
112
last_op = Some ( op_id) ;
112
113
113
- let mut key: String = "" . to_string ( ) ;
114
-
115
114
if op == "PUT" || op == "REMOVE" {
115
+ let key: String ;
116
116
if let ( Ok ( object_type) , Ok ( object_id) ) = ( object_type. as_ref ( ) , object_id. as_ref ( ) ) {
117
117
let subkey = iterate_statement. column_text ( 6 ) . unwrap_or ( "null" ) ;
118
- let populated_key = format ! ( "{}/{}/{}" , & object_type, & object_id, subkey) ;
118
+ key = format ! ( "{}/{}/{}" , & object_type, & object_id, subkey) ;
119
+ } else {
120
+ key = String :: from ( "" ) ;
121
+ }
119
122
120
- supersede_statement. bind_text ( 2 , & populated_key, sqlite:: Destructor :: STATIC ) ?;
121
- supersede_statement. exec ( ) ?;
123
+ // TODO: Instead of "superseding" the previous operation, we could delete
124
+ // it directly.
125
+ supersede_statement. bind_text ( 2 , & key, sqlite:: Destructor :: STATIC ) ?;
122
126
123
- key = populated_key;
127
+ let mut should_skip_remove = true ;
128
+ if ( supersede_statement. step ( ) ? == ResultCode :: ROW ) {
129
+ // Superseded an operation, only skip if the bucket was empty
130
+ should_skip_remove = is_empty;
131
+ }
132
+ supersede_statement. reset ( ) ?;
133
+
134
+ if ( should_skip_remove && op == "REMOVE" ) {
135
+ // If a REMOVE statement did not replace (supersede) any previous
136
+ // operations, we do not need to persist it.
137
+ // The same applies if the bucket was not synced to the local db yet,
138
+ // even if it did supersede another operation.
139
+ // Handle the same as MOVE.
140
+ add_checksum = add_checksum. wrapping_add ( checksum) ;
141
+ continue ;
124
142
}
125
- }
126
143
127
- if op == "PUT" || ( op == "REMOVE" && !is_empty) {
128
144
let opi = if op == "PUT" { 3 } else { 4 } ;
129
145
insert_statement. bind_int64 ( 2 , op_id) ?;
130
146
insert_statement. bind_int ( 3 , opi) ?;
@@ -149,7 +165,7 @@ INSERT INTO ps_oplog(bucket, op_id, op, key, row_type, row_id, data, hash, super
149
165
150
166
insert_statement. bind_int ( 8 , checksum) ?;
151
167
insert_statement. exec ( ) ?;
152
- } else if op == "MOVE" || ( is_empty && op == "REMOVE" ) {
168
+ } else if op == "MOVE" {
153
169
add_checksum = add_checksum. wrapping_add ( checksum) ;
154
170
} else if op == "CLEAR" {
155
171
// Any remaining PUT operations should get an implicit REMOVE
0 commit comments