182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
|
(tmpdir (conc "/tmp/"(current-user-name)))
(tmpdb (let* ((fname (conc tmpdir"/" (string-translate areapath "/" ".")"-"(current-process-id)"-"dbfname)))
(if (not (file-exists? tmpdir))(create-directory tmpdir))
;; check if tmpdb already exists, either delete it or
;; add something to the name
fname))
(inmem (dbmod:open-inmem-db init-proc
(if (eq? (dbfile:cache-method) 'inmem)
#f
tmpdb)
))
(write-access (file-write-access? dbpath))
(db (dbmod:safely-open-db dbfullname init-proc write-access))
(tables (db:sync-all-tables-list keys)))
(if (not (and (sqlite3:database? inmem)
(sqlite3:database? db)))
(begin
(debug:print 0 *default-log-port* "ERROR: Failed to properly open "dbfname-in", exiting immediately.")
(exit)))
;; (assert (sqlite3:database? inmem) "FATAL: open-dbmoddb: inmem is not a db")
;; (assert (sqlite3:database? db) "FATAL: open-dbmoddb: db is not a db")
(dbr:dbstruct-inmem-set! dbstruct inmem)
(dbr:dbstruct-ondiskdb-set! dbstruct db)
(dbr:dbstruct-dbfile-set! dbstruct dbfullname)
(dbr:dbstruct-dbfname-set! dbstruct dbfname)
(dbr:dbstruct-sync-proc-set! dbstruct
(lambda (last-update)
(if *sync-in-progress*
(debug:print 3 *default-log-port* "WARNING: overlapping calls to sync to disk")
(begin
(mutex-lock! *db-with-db-mutex*) ;; this mutex is used when overloaded or during a query that modifies the db
(set! *sync-in-progress* #t)
(dbmod:sync-gasket tables last-update inmem db
dbfullname syncdir keys)
(mutex-unlock! *db-with-db-mutex*)
(thread-sleep! 0.5) ;; ensure at least 1/2 second down time between sync calls
(set! *sync-in-progress* #f)))))
;; (dbmod:sync-tables tables #f db inmem)
;; (if db
(dbmod:sync-gasket tables #f inmem db dbfullname 'fromdest keys) ;; ) ;; load into inmem
(dbr:dbstruct-last-update-set! dbstruct (current-seconds)) ;; should this be offset back in time by one second?
dbstruct))
;; (if (eq? syncdir 'todisk) ;; sync to disk normally, sync from in dashboard
;; (dbmod:sync-tables tables last-update inmem db)
;; (dbmod:sync-tables tables last-update db inmem))))
;; direction: 'fromdest 'todest
;;
(define (dbmod:sync-gasket tables last-update inmem dbh dbfname direction keys)
(assert (sqlite3:database? inmem) "FATAL: sync-gasket: inmem is not a db")
(assert (sqlite3:database? inmem) "FATAL: sync-gasket: dbh is not a db")
(case (dbfile:sync-method)
((none) #f)
((attach)
(dbmod:attach-sync tables inmem dbfname direction))
((newsync)
(dbmod:new-sync tables inmem dbh dbfname direction))
(else
|
|
|
|
>
<
|
|
>
|
|
>
>
>
>
>
|
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
(tmpdir (conc "/tmp/"(current-user-name)))
(tmpdb (let* ((fname (conc tmpdir"/" (string-translate areapath "/" ".")"-"(current-process-id)"-"dbfname)))
(if (not (file-exists? tmpdir))(create-directory tmpdir))
;; check if tmpdb already exists, either delete it or
;; add something to the name
fname))
(inmem (dbmod:open-inmem-db init-proc
;; (if (eq? (dbfile:cache-method) 'inmem)
;; #f
tmpdb
;; )
))
(write-access (file-write-access? dbpath))
(db (dbmod:safely-open-db dbfullname init-proc write-access))
(tables (db:sync-all-tables-list keys)))
(if (not (and (sqlite3:database? inmem)
(sqlite3:database? db)))
(begin
(debug:print 0 *default-log-port* "ERROR: Failed to properly open "dbfname-in", exiting immediately.")
(exit))) ;; (assert (sqlite3:database? inmem) "FATAL: open-dbmoddb: inmem is not a db")
;; (assert (sqlite3:database? db) "FATAL: open-dbmoddb: db is not a db")
(dbr:dbstruct-inmem-set! dbstruct inmem)
(dbr:dbstruct-ondiskdb-set! dbstruct db)
(dbr:dbstruct-dbfile-set! dbstruct dbfullname)
(dbr:dbstruct-dbfname-set! dbstruct dbfname)
(dbr:dbstruct-sync-proc-set! dbstruct
(lambda (last-update)
(if *sync-in-progress*
(debug:print 3 *default-log-port* "WARNING: overlapping calls to sync to disk")
(let* ((sync-cmd (conc "megatest -db2db -from "tmpdb" -to "dbfullname)))
(mutex-lock! *db-with-db-mutex*) ;; this mutex is used when overloaded or during a query that modifies the db
(set! *sync-in-progress* #t)
;; (if (eq? (dbfile:cache-method) 'inmem)
;; (dbmod:sync-gasket tables last-update inmem db
;; dbfullname syncdir keys)
(thread-start! (make-thread
(lambda ()
(debug:print-info "Running "sync-cmd)
(system sync-cmd))))
(mutex-unlock! *db-with-db-mutex*)
(thread-sleep! 0.5) ;; ensure at least 1/2 second down time between sync calls
(set! *sync-in-progress* #f)))))
;; (dbmod:sync-tables tables #f db inmem)
;; (if db
(dbmod:sync-gasket tables #f inmem db dbfullname 'fromdest keys) ;; ) ;; load into inmem
(dbr:dbstruct-last-update-set! dbstruct (current-seconds)) ;; should this be offset back in time by one second?
dbstruct))
;; (if (eq? syncdir 'todisk) ;; sync to disk normally, sync from in dashboard
;; (dbmod:sync-tables tables last-update inmem db)
;; (dbmod:sync-tables tables last-update db inmem))))
;; direction: 'fromdest 'todest
;;
(define (dbmod:sync-gasket tables last-update inmem dbh dbfname direction keys)
(assert (sqlite3:database? inmem) "FATAL: sync-gasket: inmem is not a db")
(assert (sqlite3:database? inmem) "FATAL: sync-gasket: dbh is not a db")
(debug:print-info 0 *default-log-port* "dbmod:sync-gasket called with sync-method="(dbfile:sync-method))
(case (dbfile:sync-method)
((none) #f)
((attach)
(dbmod:attach-sync tables inmem dbfname direction))
((newsync)
(dbmod:new-sync tables inmem dbh dbfname direction))
(else
|
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
|
;; direction = fromdest, todest
;; mode = 'full, 'incr
;;
;; Idea: youngest in dest is last_update time
;;
(define (dbmod:new-sync tables dbh1 dbh2 destdbfile direction #!key
(mode 'full))
(debug:print 0 *default-log-port* "Doing sync "direction" "destdbfile)
(if (not (sqlite3:auto-committing? dbh1))
(debug:print 0 *default-log-port* "Skipping sync due to transaction in flight.")
(let* ((table-names (map car tables))
(dest-exists (file-exists? destdbfile)))
(assert dest-exists "FATAL: sync called with non-existant file, "destdbfile)
(for-each
(lambda (table)
|
|
|
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
|
;; direction = fromdest, todest
;; mode = 'full, 'incr
;;
;; Idea: youngest in dest is last_update time
;;
(define (dbmod:new-sync tables dbh1 dbh2 destdbfile direction #!key
(mode 'full))
(debug:print 0 *default-log-port* "Doing new-sync "direction" "destdbfile)
(if (not (sqlite3:auto-committing? dbh1))
(debug:print 0 *default-log-port* "Skipping sync due to transaction in flight.")
(let* ((table-names (map car tables))
(dest-exists (file-exists? destdbfile)))
(assert dest-exists "FATAL: sync called with non-existant file, "destdbfile)
(for-each
(lambda (table)
|