︙ | | |
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
-
+
-
+
-
+
-
+
-
+
|
(define (db:get-db dbstruct area-dat run-id)
(if (sqlite3:database? dbstruct) ;; pass sqlite3 databases on through
dbstruct
(begin
(mutex-lock! *rundb-mutex*)
(let ((dbdat (if (or (not run-id)
(eq? run-id 0))
(db:open-main dbstruct)
(db:open-main dbstruct area-dat)
(db:open-rundb dbstruct area-dat run-id)
)))
;; db prunning would go here
(mutex-unlock! *rundb-mutex*)
dbdat))))
(define (db:dbdat-get-db dbdat)
(if (pair? dbdat)
(car dbdat)
dbdat))
(define (db:dbdat-get-path dbdat)
(if (pair? dbdat)
(cdr dbdat)
#f))
;; mod-read:
;; 'mod modified data
;; 'read read data
;;
(define (db:done-with dbstruct area-dat run-id mod-read)
(define (db:done-with dbstruct run-id mod-read)
(if (not (sqlite3:database? dbstruct))
(begin
(mutex-lock! *rundb-mutex*)
(if (eq? mod-read 'mod)
(dbr:dbstruct-set-mtime! dbstruct (current-milliseconds))
(dbr:dbstruct-set-rtime! dbstruct (current-milliseconds)))
(dbr:dbstruct-set-inuse! dbstruct #f)
(mutex-unlock! *rundb-mutex*))))
;; (db:with-db dbstruct run-id sqlite3:exec "select blah from blaz;")
;; r/w is a flag to indicate if the db is modified by this query #t = yes, #f = no
;;
(define (db:with-db dbstruct area-dat area-dat run-id r/w proc . params)
(define (db:with-db dbstruct area-dat run-id r/w proc . params)
(let* ((dbdat (if (vector? dbstruct)
(db:get-db dbstruct run-id)
(db:get-db dbstruct area-dat run-id)
dbstruct)) ;; cheat, allow for passing in a dbdat
(db (db:dbdat-get-db dbdat area-dat)))
(db (db:dbdat-get-db dbdat)))
(db:delay-if-busy dbdat area-dat)
(handle-exceptions
exn
(begin
(debug:print 0 "ERROR: sqlite3 issue in db:with-db, dbstruct=" dbstruct ", run-id=" run-id ", proc=" proc ", params=" params " error: " ((condition-property-accessor 'exn 'message) exn))
(print-call-chain (current-error-port)))
(let ((res (apply proc db params)))
|
︙ | | |
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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
|
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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
|
-
+
-
+
-
+
-
+
+
-
+
-
+
|
(let ((syncprag (configf:lookup (megatest:area-configdat area-dat) "setup" "sychronous")))
(sqlite3:execute db (conc "PRAGMA synchronous = " (or syncprag 1) ";"))))
;; open an sql database inside a file lock
;;
;; returns: db existed-prior-to-opening
;;
(define (db:lock-create-open fname initproc)
(define (db:lock-create-open fname initproc area-dat)
(if (file-exists? fname)
(let ((db (sqlite3:open-database fname)))
(sqlite3:set-busy-handler! db (make-busy-timeout 136000))
(db:set-sync db) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
(db:set-sync db area-dat) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
db)
(let* ((parent-dir (pathname-directory fname))
(dir-writable (file-write-access? parent-dir)))
(if dir-writable
(let ((exists (file-exists? fname))
(lock (obtain-dot-lock fname 1 5 10))
(db (sqlite3:open-database fname)))
(sqlite3:set-busy-handler! db (make-busy-timeout 136000))
(db:set-sync db) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
(db:set-sync db area-dat) ;; (sqlite3:execute db "PRAGMA synchronous = 0;")
(if (not exists)(initproc db))
(release-dot-lock fname)
db)
(begin
(debug:print 0 "ERROR: no such db in non-writable dir " fname)
(sqlite3:open-database fname))))))
;; This routine creates the db. It is only called if the db is not already opened
;;
(define (db:open-rundb dbstruct area-dat run-id #!key (attemptnum 0)(do-not-open #f)) ;; (conc toppath "/megatest.db") (car configinfo)))
(let* ((local (dbr:dbstruct-get-local dbstruct))
(rdb (if local
(dbr:dbstruct-get-localdb dbstruct run-id)
(dbr:dbstruct-get-inmem dbstruct)))) ;; (dbr:dbstruct-get-runrec dbstruct run-id 'inmem)))
(if (or rdb
do-not-open)
rdb
(let* ((dbpath (db:dbfile-path run-id)) ;; (conc toppath "/db/" run-id ".db"))
(let* ((dbpath (db:dbfile-path run-id area-dat)) ;; (conc toppath "/db/" run-id ".db"))
(dbexists (file-exists? dbpath))
(inmem (if local #f (db:open-inmem-db)))
(refdb (if local #f (db:open-inmem-db)))
(db (db:lock-create-open dbpath ;; this is the database physically on disk
(lambda (db)
(handle-exceptions
exn
(begin
(release-dot-lock dbpath)
(if (> attemptnum 2)
(debug:print 0 "ERROR: tried twice, cannot create/initialize db for run-id " run-id ", at path " dbpath)
(db:open-rundb dbstruct area-dat run-id attemptnum (+ attemptnum 1))))
(db:initialize-run-id-db db)
(sqlite3:execute
db
"INSERT OR IGNORE INTO tests (id,run_id,testname,event_time,item_path,state,status) VALUES (?,?,'bogustest',strftime('%s','now'),'nowherepath','DELETED','n/a');"
(* run-id 30000) ;; allow for up to 30k tests per run
run-id)
;; do a dummy query to test that the table exists and the db is truly readable
(sqlite3:execute db "SELECT * FROM tests WHERE id=?;" (* run-id 30000))
))
)))) ;; add strings db to rundb, not in use yet
area-dat)) ;; add strings db to rundb, not in use yet
;; )) ;; (sqlite3:open-database dbpath))
(olddb (if *megatest-db*
*megatest-db*
(let ((db (db:open-megatest-db)))
(let ((db (db:open-megatest-db area-dat)))
(set! *megatest-db* db)
db)))
(write-access (file-write-access? dbpath))
;; (handler (make-busy-timeout 136000))
)
(if (and dbexists (not write-access))
(set! *db-write-access* #f)) ;; only unset so other db's also can use this control
|
︙ | | |
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
-
+
-
-
+
+
+
+
+
-
+
-
-
+
+
+
|
;; This routine creates the db. It is only called if the db is not already ls opened
;;
(define (db:open-main dbstruct area-dat) ;; (conc toppath "/megatest.db") (car configinfo)))
(let ((mdb (dbr:dbstruct-get-main dbstruct)))
(if mdb
mdb
(let* ((dbpath (db:dbfile-path 0))
(let* ((dbpath (db:dbfile-path 0 area-dat))
(dbexists (file-exists? dbpath))
(db (db:lock-create-open dbpath db:initialize-main-db))
(olddb (db:open-megatest-db))
(db (db:lock-create-open dbpath
(lambda (db)
(db:initialize-main-db db area-dat))
area-dat))
(olddb (db:open-megatest-db area-dat))
(write-access (file-write-access? dbpath))
(dbdat (cons db dbpath)))
(if (and dbexists (not write-access))
(set! *db-write-access* #f))
(dbr:dbstruct-set-main! dbstruct dbdat)
(dbr:dbstruct-set-olddb! dbstruct olddb) ;; olddb is already a (cons db path)
dbdat))))
;; Make the dbstruct, setup up auxillary db's and call for main db at least once
;;
(define (db:setup run-id #!key (local #f))
(let* ((dbdir (db:dbfile-path #f)) ;; (conc (configf:lookup configdat "setup" "linktree") "/.db"))
(let* ((dbdir (db:dbfile-path #f area-dat)) ;; (conc (configf:lookup configdat "setup" "linktree") "/.db"))
(dbstruct (make-dbr:dbstruct path: dbdir local: local)))
dbstruct))
;; Open the classic megatest.db file in toppath
;;
(define (db:open-megatest-db area-dat)
(let* ((toppath (megatest:area-path area-dat))
(dbpath (conc toppath "/megatest.db"))
(dbexists (file-exists? dbpath))
(db (db:lock-create-open dbpath
(lambda (db)
(db:initialize-main-db db)
(db:initialize-run-id-db db))))
(db:initialize-main-db db area-dat)
(db:initialize-run-id-db db))
area-dat))
(write-access (file-write-access? dbpath)))
(if (and dbexists (not write-access))
(set! *db-write-access* #f))
(cons db dbpath)))
;; sync run to disk if touched
;;
|
︙ | | |
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
|
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
-
+
|
(if (or (not (number? mtime))
(not (number? stime))
(> mtime stime)
force-sync)
(begin
(db:delay-if-busy maindb area-dat)
(db:delay-if-busy olddb area-dat)
(let ((num-synced (db:sync-tables area-dat (db:sync-main-list maindb) maindb olddb)))
(let ((num-synced (db:sync-tables area-dat (db:sync-main-list maindb area-dat) maindb olddb)))
(dbr:dbstruct-set-stime! dbstruct (current-milliseconds))
num-synced)
0))
(begin
;; this can occur when using local access (i.e. not in a server)
;; need a flag to turn it off.
;;
|
︙ | | |
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
|
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
|
-
-
+
+
|
'("units" #f)
'("comment" #f)
'("status" #f)
'("type" #f))))
;; needs db to get keys, this is for syncing all tables
;;
(define (db:sync-main-list db)
(let ((keys (db:get-keys db)))
(define (db:sync-main-list db area-dat)
(let ((keys (db:get-keys db area-dat)))
(list
(list "keys"
'("id" #f)
'("fieldname" #f)
'("fieldtype" #f))
(list "metadat" '("var" #f) '("val" #f))
(append (list "runs"
|
︙ | | |
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
|
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
|
-
+
|
(full-sel (conc "SELECT " (string-intersperse (map car fields) ",")
" FROM " tablename ";"))
(full-ins (conc "INSERT OR REPLACE INTO " tablename " ( " (string-intersperse (map car fields) ",") " ) "
" VALUES ( " (string-intersperse (make-list num-fields "?") ",") " );"))
(fromdat '())
(fromdats '())
(totrecords 0)
(batch-len (string->number (or (configf:lookup configdat "sync" "batchsize") "10")))
(batch-len (string->number (or (configf:lookup (megatest:area-configdat area-dat) "sync" "batchsize") "10")))
(todat (make-hash-table))
(count 0))
;; set up the field->num table
(for-each
(lambda (field)
(hash-table-set! field->num field count)
|
︙ | | |
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
|
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
|
-
+
-
+
|
;; 'adj-testids - move test-ids into correct ranges
;; 'old2new - sync megatest.db records to .db/{main,1,2 ...}.db
;; 'new2old - sync .db/{main,1,2,3 ...}.db to megatest.db
;; 'closeall - close all opened dbs
;;
;; run-ids: '(1 2 3 ...) or #f (for all)
;;
(define (db:multi-db-sync run-ids . options)
(define (db:multi-db-sync run-ids area-dat . options)
(let* ((toppath (launch:setup-for-run))
(dbstruct (if toppath (make-dbr:dbstruct path: toppath) #f))
(mtdb (if toppath (db:open-megatest-db)))
(mtdb (if toppath (db:open-megatest-db area-dat)))
(allow-cleanup (if run-ids #f #t))
(run-ids (if run-ids
run-ids
(if toppath (begin
(db:delay-if-busy mtdb area-dat)
(db:get-all-run-ids mtdb)))))
(tdbdat (tasks:open-db))
|
︙ | | |
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
|
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
|
-
+
-
+
-
+
-
-
+
+
-
-
+
+
|
(db:delay-if-busy mtdb area-dat)
(db:prep-megatest.db-for-migration mtdb)))
;; sync runs, test_meta etc.
;;
(if (member 'old2new options)
(begin
(db:sync-tables area-dat (db:sync-main-list mtdb) mtdb (db:get-db dbstruct area-dat #f))
(db:sync-tables area-dat (db:sync-main-list mtdb area-dat) mtdb (db:get-db dbstruct area-dat #f))
(for-each
(lambda (run-id)
(db:delay-if-busy mtdb area-dat)
(let ((testrecs (db:get-all-tests-info-by-run-id mtdb run-id))
(dbstruct (if toppath (make-dbr:dbstruct path: toppath local: #t) #f)))
(debug:print 0 "INFO: Propagating " (length testrecs) " records for run-id=" run-id " to run specific db")
(db:replace-test-records dbstruct run-id testrecs)
(sqlite3:finalize! (db:dbdat-get-db (dbr:dbstruct-get-rundb dbstruct)))))
run-ids)))
;; now ensure all newdb data are synced to megatest.db
;; do not use the run-ids list passed in to the function
;;
(if (member 'new2old options)
(let* ((maindb (make-dbr:dbstruct path: toppath local: #t))
(src-run-ids (db:get-all-run-ids (db:dbdat-get-db (db:get-db maindb 0))))
(src-run-ids (db:get-all-run-ids (db:dbdat-get-db (db:get-db maindb area-dat 0))))
(all-run-ids (sort (delete-duplicates (cons 0 src-run-ids)) <))
(count 1)
(total (length all-run-ids))
(dead-runs '()))
(for-each
(lambda (run-id)
(debug:print 0 "Processing run " (if (eq? run-id 0) " main.db " run-id) ", " count " of " total)
(set! count (+ count 1))
(let* ((fromdb (if toppath (make-dbr:dbstruct path: toppath local: #t) #f))
(frundb (db:dbdat-get-db (db:get-db fromdb run-id))))
(frundb (db:dbdat-get-db (db:get-db fromdb area-dat run-id))))
;; (db:delay-if-busy frundb)
;; (db:delay-if-busy mtdb)
;; (db:clean-up frundb)
(if (eq? run-id 0)
(begin
(db:sync-tables area-dat (db:sync-main-list dbstruct area-dat) (db:get-db fromdb #f) mtdb)
(set! dead-runs (db:clean-up-maindb (db:get-db fromdb #f))))
(db:sync-tables area-dat (db:sync-main-list dbstruct area-dat) (db:get-db fromdb area-dat #f) mtdb)
(set! dead-runs (db:clean-up-maindb (db:get-db fromdb area-dat #f))))
(begin
;; NB// must sync first to ensure deleted tests get marked as such in megatest.db
(db:sync-tables area-dat db:sync-tests-only (db:get-db fromdb run-id) mtdb)
(db:clean-up-rundb (db:get-db fromdb run-id))
(db:sync-tables area-dat db:sync-tests-only (db:get-db fromdb area-dat run-id) mtdb)
(db:clean-up-rundb (db:get-db fromdb area-dat run-id))
))))
all-run-ids)
;; removed deleted runs
(let ((dbdir (tasks:get-task-db-path)))
(for-each (lambda (run-id)
(let ((fullname (conc dbdir "/" run-id ".db")))
(if (file-exists? fullname)
|
︙ | | |
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
|
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
|
-
+
|
(handler (make-busy-timeout (if (args:get-arg "-override-timeout")
(string->number (args:get-arg "-override-timeout"))
136000)))) ;; 136000)))
(sqlite3:set-busy-handler! db handler)
(if (not dbexists)
(begin
(sqlite3:execute db "CREATE TABLE IF NOT EXISTS log (id INTEGER PRIMARY KEY,event_time TIMESTAMP DEFAULT (strftime('%s','now')),logline TEXT,pwd TEXT,cmdline TEXT,pid INTEGER);")
(db:set-sync db) ;; (sqlite3:execute db (conc "PRAGMA synchronous = 0;"))
(db:set-sync db area-dat) ;; (sqlite3:execute db (conc "PRAGMA synchronous = 0;"))
))
db))
(define (db:log-local-event . loglst)
(let ((logline (apply conc loglst)))
(db:log-event logline)))
|
︙ | | |
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
|
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
|
-
+
|
;; can use wildcards. Also can likely be factored in with get test paths?
;;
;; Run this remotely!!
;;
(define (db:get-matching-previous-test-run-records dbstruct area-dat run-id test-name item-path)
(let* ((dbdat (db:get-db dbstruct area-dat #f))
(db (db:dbdat-get-db dbdat))
(keys (db:get-keys db))
(keys (db:get-keys db area-dat))
(selstr (string-intersperse (map (lambda (x)(vector-ref x 0)) keys) ","))
(qrystr (string-intersperse (map (lambda (x)(conc (vector-ref x 0) "=?")) keys) " AND "))
(keyvals #f)
(tests-hash (make-hash-table)))
;; first look up the key values from the run selected by run-id
(db:delay-if-busy dbdat area-dat)
(sqlite3:for-each-row
|
︙ | | |
︙ | | |
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
|
-
+
|
(for-each
(lambda (run-id)
(mutex-lock! *db-multi-sync-mutex*)
(if (and (not (equal? legacy-sync "no"))
(hash-table-ref/default *db-local-sync* run-id #f))
;; (if (> (- start-time last-write) 5) ;; every five seconds
(begin ;; let ((sync-time (- (current-seconds) start-time)))
(db:multi-db-sync (list run-id) 'new2old)
(db:multi-db-sync (list run-id) *area-dat* 'new2old)
(if (common:low-noise-print 30 "sync new to old")
(let ((sync-time (- (current-seconds) start-time)))
(debug:print-info 0 "Sync of newdb to olddb for run-id " run-id " completed in " sync-time " seconds")))
;; (if (> sync-time 10) ;; took more than ten seconds, start a server for this run
;; (begin
;; (debug:print-info 0 "Sync is taking a long time, start up a server to assist for run " run-id)
;; (server:kind-run run-id)))))
|
︙ | | |
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
|
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
|
+
|
(begin
(debug:print 0 "Failed to setup, exiting")
(exit 1)))
;; keep this one local
;; (open-run-close db:clean-up #f)
(db:multi-db-sync
#f ;; do all run-ids
*area-dat*
;; 'new2old
'killservers
'dejunk
;; 'adj-testids
;; 'old2new
'new2old
)
|
︙ | | |
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
|
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
|
+
+
|
;; ;; ;; redo me (list "uname" "rundir" "final_logf" "comment"))
;; ;; ;; redo me (set! *didsomething* #t)))
(if (args:get-arg "-import-megatest.db")
(begin
(db:multi-db-sync
#f ;; do all run-ids
*area-dat*
'killservers
'dejunk
'adj-testids
'old2new
;; 'new2old
)
(set! *didsomething* #t)))
(if (args:get-arg "-sync-to-megatest.db")
(begin
(db:multi-db-sync
#f ;; do all run-ids
*area-dat*
'new2old
)
(set! *didsomething* #t)))
;;======================================================================
;; Exit and clean up
;;======================================================================
|
︙ | | |