200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
(let* ((parent-dir (pathname-directory dbfile)))
(if (not (directory-exists? parent-dir))
(create-directory parent-dir #t))
(let* ((exists (file-exists? dbfile))
(db (sqlite3:open-database dbfile))
(handler (sqlite3:make-busy-timeout 3600)))
(sqlite3:set-busy-handler! db handler)
(db:set-sync db)
(if (not exists)
(dbinit-proc db))
db)))
;; open and initialize the inmem db
;; NOTE: Does NOT sync in the data from the disk db
;;
|
|
|
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
|
(let* ((parent-dir (pathname-directory dbfile)))
(if (not (directory-exists? parent-dir))
(create-directory parent-dir #t))
(let* ((exists (file-exists? dbfile))
(db (sqlite3:open-database dbfile))
(handler (sqlite3:make-busy-timeout 3600)))
(sqlite3:set-busy-handler! db handler)
;; (db:set-sync db) ;; we don't mind that this is slow?
(if (not exists)
(dbinit-proc db))
db)))
;; open and initialize the inmem db
;; NOTE: Does NOT sync in the data from the disk db
;;
|
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
(db:with-lock-db dbfile
(lambda (dbh dbfile)
(db:get-iam-server-lock dbh dbfile))))
(define (db:with-lock-db dbfile proc)
(let* ((dbh (db:open-run-db dbfile db:initialize-db))
(res (proc dbh dbfile)))
(sqlite3:finalize! dbh)
res))
;; called before db is open?
;;
(define (db:get-iam-server-lock dbh dbfname)
(sqlite3:with-transaction
dbh
|
|
|
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
|
(db:with-lock-db dbfile
(lambda (dbh dbfile)
(db:get-iam-server-lock dbh dbfile))))
(define (db:with-lock-db dbfile proc)
(let* ((dbh (db:open-run-db dbfile db:initialize-db))
(res (proc dbh dbfile)))
;; (sqlite3:finalize! dbh)
res))
;; called before db is open?
;;
(define (db:get-iam-server-lock dbh dbfname)
(sqlite3:with-transaction
dbh
|
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
|
(define (db:sync-inmem->disk dbstruct apath dbfile #!key (force-sync #f))
(let* ((dbdat (db:get-dbdat dbstruct apath dbfile))
(db (dbr:dbdat-db dbdat))
(inmem (dbr:dbdat-inmem dbdat))
(start-t (current-seconds))
(last-update (dbr:dbdat-last-write dbdat))
(last-sync (dbr:dbdat-last-sync dbdat)))
(debug:print-info 4 *default-log-port* "Syncing for dbfile: " dbfile)
(mutex-lock! *db-multi-sync-mutex*)
(let* ((update_info (cons (if force-sync 0 last-update) "last_update"))
(need-sync (or force-sync (>= last-update last-sync))))
(if need-sync
(db:sync-tables (db:sync-all-tables-list) update_info inmem db)
(debug:print 0 *default-log-port* "Skipping sync as nothing touched.")))
(dbr:dbdat-last-sync-set! dbdat start-t)
(mutex-unlock! *db-multi-sync-mutex*)))
;; TODO: Add final sync to this
;;
(define (db:safely-close-sqlite3-db db stmt-cache #!key (try-num 3))
(if (<= try-num 0)
#f
|
|
|
>
|
>
<
|
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
|
(define (db:sync-inmem->disk dbstruct apath dbfile #!key (force-sync #f))
(let* ((dbdat (db:get-dbdat dbstruct apath dbfile))
(db (dbr:dbdat-db dbdat))
(inmem (dbr:dbdat-inmem dbdat))
(start-t (current-seconds))
(last-update (dbr:dbdat-last-write dbdat))
(last-sync (dbr:dbdat-last-sync dbdat)))
(debug:print-info 0 *default-log-port* "Syncing for dbfile: "dbfile", last-update: "last-update", last-sync: "last-sync)
(mutex-lock! *db-multi-sync-mutex*)
(let* ((update_info (cons "last_update" (if force-sync 0 last-update))) ;; "last_update"))
(need-sync (or force-sync (>= last-update last-sync))))
(if need-sync
(begin
(db:sync-tables (db:sync-all-tables-list) update_info inmem db)
(dbr:dbdat-last-sync-set! dbdat start-t))
(debug:print 0 *default-log-port* "Skipping sync as nothing touched.")))
(mutex-unlock! *db-multi-sync-mutex*)))
;; TODO: Add final sync to this
;;
(define (db:safely-close-sqlite3-db db stmt-cache #!key (try-num 3))
(if (<= try-num 0)
#f
|
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
|
(define (db:sync-one-table fromdb todb tabledat last-update numrecs)
(let* ((tablename (car tabledat))
(fields (cdr tabledat))
(has-last-update (member "last_update" fields))
(use-last-update (cond
((and has-last-update
(member "last_update" fields))
#t) ;; if given a number, just use it for all fields
((number? last-update) #f) ;; if not matched first entry then ignore last-update for this table
((and (pair? last-update)
(member (car last-update) ;; last-update field name
(map car fields)))
#t)
(last-update
(debug:print 0 *default-log-port* "ERROR: parameter last-update for db:sync-tables must be a pair or a number, received: " last-update);; found in fields
#f)
(else
#f)))
(last-update-value (if use-last-update ;; no need to check for has-last-update - it is already accounted for
(if (number? last-update)
|
|
<
>
>
>
>
>
>
>
>
|
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
|
(define (db:sync-one-table fromdb todb tabledat last-update numrecs)
(let* ((tablename (car tabledat))
(fields (cdr tabledat))
(has-last-update (member "last_update" fields))
(use-last-update (cond
((and has-last-update
(number? last-update))
#t) ;; if given a number, just use it for all fields
((and (pair? last-update)
(member (car last-update) ;; last-update field name
(map car fields)))
#t)
((and (pair? last-update)
(not (number? (cdr last-update))))
(debug:print 0 *default-log-port* "ERROR: parameter last-update malformed. last-update="last-update)
#f)
((and (pair? last-update)
(string? (car last-update))) ;; valid format, field not recognised
#f)
((number? last-update) #f) ;; if not matched first entry then ignore last-update for this table
(last-update
(debug:print 0 *default-log-port* "ERROR: parameter last-update for db:sync-tables must be a pair or a number, received: " last-update);; found in fields
#f)
(else
#f)))
(last-update-value (if use-last-update ;; no need to check for has-last-update - it is already accounted for
(if (number? last-update)
|
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
|
(if should-print (debug:print 3 *default-log-port* "INFO: db sync, total run time " runtime " ms"))
(for-each
(lambda (dat)
(let ((tblname (car dat))
(count (cdr dat)))
(set! tot-count (+ tot-count count))
(if (> count 0)
(if should-print (debug:print 0 *default-log-port* (format #f " ~10a ~5a" tblname count))))))
(sort (hash-table->alist numrecs)(lambda (a b)(> (cdr a)(cdr b))))))
tot-count))
(define (db:patch-schema-rundb frundb)
;;
;; remove this some time after September 2016 (added in version v1.6031
;;
|
|
|
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
|
(if should-print (debug:print 3 *default-log-port* "INFO: db sync, total run time " runtime " ms"))
(for-each
(lambda (dat)
(let ((tblname (car dat))
(count (cdr dat)))
(set! tot-count (+ tot-count count))
(if (> count 0)
(if should-print (debug:print 0 *default-log-port* " "tblname" "count))))) ;; (format #f " ~10a ~5a" tblname count))))))
(sort (hash-table->alist numrecs)(lambda (a b)(> (cdr a)(cdr b))))))
tot-count))
(define (db:patch-schema-rundb frundb)
;;
;; remove this some time after September 2016 (added in version v1.6031
;;
|
5535
5536
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
|
(debug:print-info 0 *default-log-port* "Server already running at "sinfo ", while trying to register server " host":"port)
#f) ;; server already registered
(begin
(sqlite3:execute db "INSERT INTO servers (host,port,servkey,pid,ipaddr,apath,dbname) VALUES (?,?,?,?,?,?,?);"
host port servkey pid ipaddr apath dbname)
(db:get-server-info dbstruct apath dbname)))))))))
(define (db:get-server-info dbstruct apath dbname)
(db:with-db
dbstruct
#f #f
(lambda (db)
(sqlite3:fold-row
(lambda (res host port servkey pid ipaddr apath dbpath)
(list host port servkey pid ipaddr apath dbpath))
#f
db
"SELECT host,port,servkey,pid,ipaddr,apath,dbname FROM servers WHERE apath=? AND dbname=?;"
apath dbname))))
)
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
5543
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
|
(debug:print-info 0 *default-log-port* "Server already running at "sinfo ", while trying to register server " host":"port)
#f) ;; server already registered
(begin
(sqlite3:execute db "INSERT INTO servers (host,port,servkey,pid,ipaddr,apath,dbname) VALUES (?,?,?,?,?,?,?);"
host port servkey pid ipaddr apath dbname)
(db:get-server-info dbstruct apath dbname)))))))))
;; run this one in a transaction where first check if host:port is taken
(define (db:deregister-server dbstruct host port servkey pid ipaddr apath dbname)
(db:with-db
dbstruct
#f #f
(lambda (db)
(sqlite3:with-transaction
db
(lambda ()
(let* ((sinfo (db:get-server-info dbstruct apath dbname)))
(if (not sinfo)
(begin
(debug:print-info 0 *default-log-port* "Server already removed for "apath", "dbname) ;; at "sinfo ", while trying to register server " host":"port)
#f) ;; server already deregistered
(begin
(sqlite3:execute db "DELETE FROM servers WHERE apath=? AND dbname=?;" ;; (host,port,servkey,pid,ipaddr,apath,dbname) VALUES (?,?,?,?,?,?,?);"
;; host port servkey pid ipaddr
apath dbname)
#;(db:get-server-info dbstruct apath dbname)))))))))
(define (db:get-server-info dbstruct apath dbname)
(db:with-db
dbstruct
#f #f
(lambda (db)
(sqlite3:fold-row
(lambda (res host port servkey pid ipaddr apath dbpath)
(list host port servkey pid ipaddr apath dbpath))
#f
db
"SELECT host,port,servkey,pid,ipaddr,apath,dbname FROM servers WHERE apath=? AND dbname=?;"
apath dbname))))
(define (db:get-count-servers dbstruct apath)
(db:with-db
dbstruct
#f #f
(lambda (db)
(sqlite3:fold-row
(lambda (res count)
(max res count))
0
db
"SELECT count(*) FROM servers WHERE apath=?;"
apath))))
)
|