@@ -16,7 +16,6 @@ public class SqliteBucketStorage : EventStream<BucketStorageEvent>, IBucketStora
1616 public static readonly string MAX_OP_ID = "9223372036854775807" ;
1717
1818 private readonly IDBAdapter db ;
19- private bool hasCompletedSync ;
2019 private bool pendingBucketDeletes ;
2120 private readonly HashSet < string > tableNames ;
2221 private string ? clientId ;
@@ -34,8 +33,6 @@ public SqliteBucketStorage(IDBAdapter db, ILogger? logger = null)
3433 {
3534 this . db = db ;
3635 this . logger = logger ?? NullLogger . Instance ;
37- ;
38- hasCompletedSync = false ;
3936 pendingBucketDeletes = true ;
4037 tableNames = [ ] ;
4138
@@ -59,7 +56,6 @@ public SqliteBucketStorage(IDBAdapter db, ILogger? logger = null)
5956
6057 public async Task Init ( )
6158 {
62- hasCompletedSync = false ;
6359 var existingTableRows =
6460 await db . GetAll < ExistingTableRowsResult > (
6561 "SELECT name FROM sqlite_master WHERE type='table' AND name GLOB 'ps_data_*'" ) ;
@@ -93,171 +89,7 @@ public string GetMaxOpId()
9389 {
9490 return MAX_OP_ID ;
9591 }
96-
97- public void StartSession ( )
98- {
99- }
100-
101- public async Task < BucketState [ ] > GetBucketStates ( )
102- {
103- return
104- await db . GetAll < BucketState > (
105- "SELECT name as bucket, cast(last_op as TEXT) as op_id FROM ps_buckets WHERE pending_delete = 0 AND name != '$local'" ) ;
106- }
107-
108- public async Task SaveSyncData ( SyncDataBatch batch )
109- {
110- await db . WriteTransaction ( async tx =>
111- {
112- int count = 0 ;
113- foreach ( var b in batch . Buckets )
114- {
115- var result = await tx . Execute ( "INSERT INTO powersync_operations(op, data) VALUES(?, ?)" ,
116- [ "save" , JsonConvert . SerializeObject ( new { buckets = new [ ] { b . ToJSON ( ) } } ) ] ) ;
117- logger . LogDebug ( "saveSyncData {message}" , JsonConvert . SerializeObject ( result ) ) ;
118- count += b . Data . Length ;
119- }
120-
121- compactCounter += count ;
122- } ) ;
123- }
124-
125- public async Task RemoveBuckets ( string [ ] buckets )
126- {
127- foreach ( var bucket in buckets )
128- {
129- await DeleteBucket ( bucket ) ;
130- }
131- }
132-
133- private async Task DeleteBucket ( string bucket )
134- {
135- await db . WriteTransaction ( async tx =>
136- {
137- await tx . Execute ( "INSERT INTO powersync_operations(op, data) VALUES(?, ?)" ,
138- [ "delete_bucket" , bucket ] ) ;
139- } ) ;
140-
141- logger . LogDebug ( "Done deleting bucket" ) ;
142- pendingBucketDeletes = true ;
143- }
144-
145- private record LastSyncedResult ( string ? synced_at ) ;
146-
147- public async Task < bool > HasCompletedSync ( )
148- {
149- if ( hasCompletedSync ) return true ;
150-
151- var result = await db . Get < LastSyncedResult > ( "SELECT powersync_last_synced_at() as synced_at" ) ;
152-
153- hasCompletedSync = result . synced_at != null ;
154- return hasCompletedSync ;
155- }
156-
157- public async Task < SyncLocalDatabaseResult > SyncLocalDatabase ( Checkpoint checkpoint )
158- {
159- var validation = await ValidateChecksums ( checkpoint ) ;
160- if ( ! validation . CheckpointValid )
161- {
162- logger . LogError ( "Checksums failed for {failures}" ,
163- JsonConvert . SerializeObject ( validation . CheckpointFailures ) ) ;
164- foreach ( var failedBucket in validation . CheckpointFailures ?? [ ] )
165- {
166- await DeleteBucket ( failedBucket ) ;
167- }
168-
169- return new SyncLocalDatabaseResult
170- {
171- Ready = false ,
172- CheckpointValid = false ,
173- CheckpointFailures = validation . CheckpointFailures
174- } ;
175- }
176-
177- var bucketNames = checkpoint . Buckets . Select ( b => b . Bucket ) . ToArray ( ) ;
178- await db . WriteTransaction ( async tx =>
179- {
180- await tx . Execute (
181- "UPDATE ps_buckets SET last_op = ? WHERE name IN (SELECT json_each.value FROM json_each(?))" ,
182- [ checkpoint . LastOpId , JsonConvert . SerializeObject ( bucketNames ) ]
183- ) ;
184-
185- if ( checkpoint . WriteCheckpoint != null )
186- {
187- await tx . Execute (
188- "UPDATE ps_buckets SET last_op = ? WHERE name = '$local'" ,
189- [ checkpoint . WriteCheckpoint ]
190- ) ;
191- }
192- } ) ;
193-
194- var valid = await UpdateObjectsFromBuckets ( checkpoint ) ;
195- if ( ! valid )
196- {
197- logger . LogDebug ( "Not at a consistent checkpoint - cannot update local db" ) ;
198- return new SyncLocalDatabaseResult
199- {
200- Ready = false ,
201- CheckpointValid = true
202- } ;
203- }
204-
205- await ForceCompact ( ) ;
206-
207- return new SyncLocalDatabaseResult
208- {
209- Ready = true ,
210- CheckpointValid = true
211- } ;
212- }
213-
214- private async Task < bool > UpdateObjectsFromBuckets ( Checkpoint checkpoint )
215- {
216- return await db . WriteTransaction ( async tx =>
217- {
218- var result = await tx . Execute ( "INSERT INTO powersync_operations(op, data) VALUES(?, ?)" ,
219- [ "sync_local" , "" ] ) ;
220-
221- return result . InsertId == 1 ;
222- } ) ;
223- }
224-
225- private record ResultResult ( object result ) ;
226-
227- public class ResultDetail
228- {
229- [ JsonProperty ( "valid" ) ] public bool Valid { get ; set ; }
230-
231- [ JsonProperty ( "failed_buckets" ) ] public List < string > ? FailedBuckets { get ; set ; }
232- }
233-
234- public async Task < SyncLocalDatabaseResult > ValidateChecksums (
235- Checkpoint checkpoint )
236- {
237- var result = await db . Get < ResultResult > ( "SELECT powersync_validate_checkpoint(?) as result" ,
238- [ JsonConvert . SerializeObject ( checkpoint ) ] ) ;
239-
240- logger . LogDebug ( "validateChecksums result item {message}" , JsonConvert . SerializeObject ( result ) ) ;
241-
242- if ( result == null ) return new SyncLocalDatabaseResult { CheckpointValid = false , Ready = false } ;
243-
244- var resultDetail = JsonConvert . DeserializeObject < ResultDetail > ( result . result . ToString ( ) ?? "{}" ) ;
245-
246- if ( resultDetail ? . Valid == true )
247- {
248- return new SyncLocalDatabaseResult { Ready = true , CheckpointValid = true } ;
249- }
250- else
251- {
252- return new SyncLocalDatabaseResult
253- {
254- CheckpointValid = false ,
255- Ready = false ,
256- CheckpointFailures = resultDetail ? . FailedBuckets ? . ToArray ( ) ?? [ ]
257- } ;
258- }
259- }
260-
92+
26193 /// <summary>
26294 /// Force a compact operation, primarily for testing purposes.
26395 /// </summary>
@@ -435,12 +267,7 @@ public async Task<bool> HasCrud()
435267 {
436268 return await db . GetOptional < object > ( "SELECT 1 as ignore FROM ps_crud LIMIT 1" ) != null ;
437269 }
438-
439- public async Task SetTargetCheckpoint ( Checkpoint checkpoint )
440- {
441- // No Op
442- await Task . CompletedTask ;
443- }
270+
444271
445272 record ControlResult ( string ? r ) ;
446273
0 commit comments