@@ -2,6 +2,7 @@ import { createError, WSQ_ERROR } from 'pouchdb-errors'
22import { guardedConsole } from 'pouchdb-utils'
33
44import { BY_SEQ_STORE , ATTACH_STORE , ATTACH_AND_SEQ_STORE } from './constants'
5+ import type { Transaction } from '@op-engineering/op-sqlite'
56
67function stringifyDoc ( doc : Record < string , any > ) : string {
78 // don't bother storing the id/rev. it uses lots of space,
@@ -54,97 +55,87 @@ function select(
5455 )
5556}
5657
57- function compactRevs ( revs : string [ ] , docId : string , tx : any ) : void {
58+ async function compactRevs (
59+ revs : string [ ] ,
60+ docId : string ,
61+ tx : Transaction
62+ ) : Promise < void > {
5863 if ( ! revs . length ) {
5964 return
6065 }
6166
62- let numDone = 0
6367 const seqs : number [ ] = [ ]
6468
65- function checkDone ( ) {
66- if ( ++ numDone === revs . length ) {
67- // done
68- deleteOrphans ( )
69- }
70- }
71-
72- function deleteOrphans ( ) {
69+ async function deleteOrphans ( ) {
7370 // find orphaned attachment digests
7471
7572 if ( ! seqs . length ) {
7673 return
7774 }
7875
79- const sql =
76+ let sql =
8077 'SELECT DISTINCT digest AS digest FROM ' +
8178 ATTACH_AND_SEQ_STORE +
8279 ' WHERE seq IN ' +
8380 qMarks ( seqs . length )
8481
85- tx . executeSql ( sql , seqs , function ( tx : any , res : any ) {
86- const digestsToCheck : string [ ] = [ ]
87- for ( let i = 0 ; i < res . rows . length ; i ++ ) {
88- digestsToCheck . push ( res . rows . item ( i ) . digest )
89- }
90- if ( ! digestsToCheck . length ) {
91- return
92- }
82+ let res = await tx . executeAsync ( sql , seqs )
83+ const digestsToCheck : string [ ] = [ ]
84+ for ( let i = 0 ; i < res . rows ! . length ; i ++ ) {
85+ digestsToCheck . push ( res . rows ! . item ( i ) . digest )
86+ }
87+ if ( ! digestsToCheck . length ) {
88+ return
89+ }
9390
94- const sql =
95- 'DELETE FROM ' +
96- ATTACH_AND_SEQ_STORE +
97- ' WHERE seq IN (' +
98- seqs . map ( ( ) => '?' ) . join ( ',' ) +
99- ')'
100- tx . executeSql ( sql , seqs , function ( tx : any ) {
101- const sql =
102- 'SELECT digest FROM ' +
103- ATTACH_AND_SEQ_STORE +
104- ' WHERE digest IN (' +
105- digestsToCheck . map ( ( ) => '?' ) . join ( ',' ) +
106- ')'
107- tx . executeSql ( sql , digestsToCheck , function ( tx : any , res : any ) {
108- const nonOrphanedDigests = new Set < string > ( )
109- for ( let i = 0 ; i < res . rows . length ; i ++ ) {
110- nonOrphanedDigests . add ( res . rows . item ( i ) . digest )
111- }
112- digestsToCheck . forEach ( function ( digest ) {
113- if ( nonOrphanedDigests . has ( digest ) ) {
114- return
115- }
116- tx . executeSql (
117- 'DELETE FROM ' + ATTACH_AND_SEQ_STORE + ' WHERE digest=?' ,
118- [ digest ]
119- )
120- tx . executeSql ( 'DELETE FROM ' + ATTACH_STORE + ' WHERE digest=?' , [
121- digest ,
122- ] )
123- } )
124- } )
125- } )
126- } )
91+ sql =
92+ 'DELETE FROM ' +
93+ ATTACH_AND_SEQ_STORE +
94+ ' WHERE seq IN (' +
95+ seqs . map ( ( ) => '?' ) . join ( ',' ) +
96+ ')'
97+ await tx . executeAsync ( sql , seqs )
98+ sql =
99+ 'SELECT digest FROM ' +
100+ ATTACH_AND_SEQ_STORE +
101+ ' WHERE digest IN (' +
102+ digestsToCheck . map ( ( ) => '?' ) . join ( ',' ) +
103+ ')'
104+ res = await tx . executeAsync ( sql , digestsToCheck )
105+ const nonOrphanedDigests = new Set < string > ( )
106+ for ( let i = 0 ; i < res . rows ! . length ; i ++ ) {
107+ nonOrphanedDigests . add ( res . rows ! . item ( i ) . digest )
108+ }
109+ for ( const digest of digestsToCheck ) {
110+ if ( nonOrphanedDigests . has ( digest ) ) {
111+ continue
112+ }
113+ await tx . executeAsync (
114+ 'DELETE FROM ' + ATTACH_AND_SEQ_STORE + ' WHERE digest=?' ,
115+ [ digest ]
116+ )
117+ await tx . executeAsync ( 'DELETE FROM ' + ATTACH_STORE + ' WHERE digest=?' , [
118+ digest ,
119+ ] )
120+ }
127121 }
128122
129123 // update by-seq and attach stores in parallel
130- revs . forEach ( function ( rev ) {
124+ for ( const rev of revs ) {
131125 const sql = 'SELECT seq FROM ' + BY_SEQ_STORE + ' WHERE doc_id=? AND rev=?'
132126
133- tx . executeSql ( sql , [ docId , rev ] , function ( tx : any , res : any ) {
134- if ( ! res . rows . length ) {
135- // already deleted
136- return checkDone ( )
137- }
138- const seq = res . rows . item ( 0 ) . seq
127+ const res = await tx . executeAsync ( sql , [ docId , rev ] )
128+ if ( res . rows ! . length > 0 ) {
129+ const seq = res . rows ! . item ( 0 ) . seq
139130 seqs . push ( seq )
140131
141- tx . executeSql (
142- 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE seq=?' ,
143- [ seq ] ,
144- checkDone
145- )
146- } )
147- } )
132+ await tx . executeAsync ( 'DELETE FROM ' + BY_SEQ_STORE + ' WHERE seq=?' , [
133+ seq ,
134+ ] )
135+ }
136+ }
137+
138+ await deleteOrphans ( )
148139}
149140
150141export function handleSQLiteError (
0 commit comments