Index: db.scm ================================================================== --- db.scm +++ db.scm @@ -67,10 +67,19 @@ (if (eq? mod-read 'mod) (dbr:dbstruct-set-runvec! dbstruct run-id 'mtime (current-milliseconds)) (dbr:dbstruct-set-runvec! dbstruct run-id 'rtime (current-milliseconds))) (dbr:dbstruct-set-runvec! dbstruct run-id 'inuse #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 run-id r/w proc . params) + (let* ((db (db:get-db dbstruct run-id))) + (let ((res (apply proc db params))) + (db:done-with dbstruct run-id r/w) + res))) ;;====================================================================== ;; K E E P F I L E D B I N dbstruct ;;====================================================================== @@ -169,11 +178,13 @@ ;; finalize main.db (sqlite3:finalize! (db:get-db dbstruct #f)) (for-each (lambda (runvec) (let ((rundb (vector-ref runvec (dbr:dbstruct-field-name->num 'rundb)))) - (sqlite3:finalize! rundb))) + (if (sqlite3:database? rundb) + (sqlite3:finalize! rundb) + (debug:print 0 "WARNING: attempting to close databases but got " rundb " instead of a database")))) (hash-table-values (vector-ref dbstruct 1)))) (define (open-inmem-db) (let* ((db (sqlite3:open-database ":memory:")) (handler (make-busy-timeout 3600))) @@ -420,21 +431,21 @@ (sqlite3:execute db "CREATE TABLE IF NOT EXISTS keys (id INTEGER PRIMARY KEY, fieldname TEXT, fieldtype TEXT, CONSTRAINT keyconstraint UNIQUE (fieldname));") (for-each (lambda (key) (sqlite3:execute db "INSERT INTO keys (fieldname,fieldtype) VALUES (?,?);" key "TEXT")) keys) (sqlite3:execute db (conc - "CREATE TABLE IF NOT EXISTS runs (id INTEGER PRIMARY KEY, " - fieldstr (if havekeys "," "") - "runname TEXT DEFAULT 'norun'," - "state TEXT DEFAULT ''," - "status TEXT DEFAULT ''," - "owner TEXT DEFAULT ''," - "event_time TIMESTAMP DEFAULT (strftime('%s','now'))," - "comment TEXT DEFAULT ''," - "fail_count INTEGER DEFAULT 0," - "pass_count INTEGER DEFAULT 0," - "CONSTRAINT runsconstraint UNIQUE (runname" (if havekeys "," "") keystr "));")) + "CREATE TABLE IF NOT EXISTS runs (id INTEGER PRIMARY KEY, \n " + fieldstr (if havekeys "," "") " + runname TEXT DEFAULT 'norun', + state TEXT DEFAULT '', + status TEXT DEFAULT '', + owner TEXT DEFAULT '', + event_time TIMESTAMP DEFAULT (strftime('%s','now')), + comment TEXT DEFAULT '', + fail_count INTEGER DEFAULT 0, + pass_count INTEGER DEFAULT 0, + CONSTRAINT runsconstraint UNIQUE (runname" (if havekeys "," "") keystr "));")) (sqlite3:execute db "CREATE TABLE IF NOT EXISTS test_meta ( id INTEGER PRIMARY KEY, testname TEXT DEFAULT '', author TEXT DEFAULT '', owner TEXT DEFAULT '', @@ -451,18 +462,19 @@ (sqlite3:execute db "CREATE TABLE IF NOT EXISTS extradat (id INTEGER PRIMARY KEY, run_id INTEGER, key TEXT, val TEXT);") (sqlite3:execute db "CREATE TABLE IF NOT EXISTS metadat (id INTEGER PRIMARY KEY, var TEXT, val TEXT, CONSTRAINT metadat_constraint UNIQUE (var));") (sqlite3:execute db "CREATE TABLE IF NOT EXISTS access_log (id INTEGER PRIMARY KEY, user TEXT, accessed TIMESTAMP, args TEXT);") ;; Must do this *after* running patch db !! No more. - (db:set-var db "MEGATEST_VERSION" megatest-version) + ;; cannot use db:set-var since it will deadlock, hardwire the code here + (sqlite3:execute db "INSERT OR REPLACE INTO metadat (var,val) VALUES (?,?);" "MEGATEST_VERSION" megatest-version) (debug:print-info 11 "db:initialize END"))) ;;====================================================================== ;; R U N S P E C I F I C D B ;;====================================================================== -(define (db:initialized-run-id-db db run-id) +(define (db:initialize-run-id-db db run-id) (sqlite3:execute db "CREATE TABLE IF NOT EXISTS tests (id INTEGER PRIMARY KEY, run_id INTEGER DEFAULT -1, testname TEXT DEFAULT 'noname', host TEXT DEFAULT 'n/a', @@ -715,15 +727,17 @@ ;; using keys:config-get-fields? (define (db:get-keys dbstruct) (if *db-keys* *db-keys* (let ((res '())) - (sqlite3:for-each-row - (lambda (key) - (set! res (cons key res))) - (db:get-db dbstruct #f) - "SELECT fieldname FROM keys ORDER BY id DESC;") + (db:with-db dbstruct #f #f + (lambda (db) + (sqlite3:for-each-row + (lambda (key) + (set! res (cons key res))) + (db:get-db dbstruct #f) + "SELECT fieldname FROM keys ORDER BY id DESC;"))) (set! *db-keys* res) res))) ;; (define (db:get-value-by-header row header field) @@ -961,16 +975,18 @@ (set! qry-str (conc "SELECT " keystr " FROM runs WHERE state != 'deleted' AND runname " runwildtype " ? " key-patt " ORDER BY event_time " (if limit (conc " LIMIT " limit) "") (if offset (conc " OFFSET " offset) "") ";")) (debug:print-info 4 "runs:get-runs-by-patt qry=" qry-str " " runnamepatt) - (sqlite3:for-each-row - (lambda (a . r) - (set! res (cons (list->vector (cons a r)) res))) - (db:get-db dbstruct #f) - qry-str - runnamepatt) + (db:with-db dbstruct #f #f ;; reads db, does not write to it. + (lambda (db) + (sqlite3:for-each-row + (lambda (a . r) + (set! res (cons (list->vector (cons a r)) res))) + (db:get-db dbstruct #f) + qry-str + runnamepatt))) (vector header res))) ;; use (get-value-by-header (db:get-header runinfo)(db:get-row runinfo)) (define (db:get-run-info dbstruct run-id) ;;(if (hash-table-ref/default *run-info-cache* run-id #f) @@ -1090,11 +1106,11 @@ ;; states and statuses are lists, turn them into ("PASS","FAIL"...) and use NOT IN ;; i.e. these lists define what to NOT show. ;; states and statuses are required to be lists, empty is ok ;; not-in #t = above behaviour, #f = must match -(define (db:get-tests-for-run db run-id testpatt states statuses offset limit not-in sort-by sort-order qryvals) +(define (db:get-tests-for-run dbstruct run-id testpatt states statuses offset limit not-in sort-by sort-order qryvals) (let* ((qryvalstr (case qryvals ((shortlist) "id,run_id,testname,item_path,state,status") ((#f) "id,run_id,testname,state,status,event_time,host,cpuload,diskfree,uname,rundir,item_path,run_duration,final_logf,comment") (else qryvals))) (res '()) Index: db_records.scm ================================================================== --- db_records.scm +++ db_records.scm @@ -17,17 +17,17 @@ #f ;; the global string db (use for state, status etc.) path ;; path to database files/megatest area local)) ;; read-only local access ;; get and set main db -(define-inline (dbr:dbstruct-get-main vec) (vector-ref vec 0)) +(define-inline (dbr:dbstruct-get-main vec) (vector-ref vec 0)) (define-inline (dbr:dbstruct-set-main! vec db)(vector-set! vec 0 db)) ;; get a rundb vector (define (dbr:dbstruct-get-rundb-rec vec run-id) (let* ((dbhash (vector-ref vec 1)) - (runvec (hash-table-ref/default dbhash run-id))) + (runvec (hash-table-ref/default dbhash run-id #f))) (if runvec runvec (begin (hash-table-set! dbhash run-id (vector #f #f -1 -1 -1 #f)) (dbr:dbstruct-get-rundb-rec vec run-id))))) @@ -50,11 +50,11 @@ ;; (vector-set! runvec (dbr:dbstruct-field-name->num 'inuse) #t) (vector-ref runvec fieldnum))) (define (dbr:dbstruct-set-runvec! vec run-id field-name val) (let ((runvec (dbr:dbstruct-get-rundb-rec vec run-id))) - (vector-set! runvec (dbr:dbstruct-field-name->num field-name) rundb))) + (vector-set! runvec (dbr:dbstruct-field-name->num field-name) runvec))) ;; get/set inmemdb (define (dbr:dbstruct-get-inmemdb vec run-id) (let ((runvec (dbr:dbstruct-get-rundb-rec vec run-id))) (vector-ref runvec 1))) Index: megatest.scm ================================================================== --- megatest.scm +++ megatest.scm @@ -354,11 +354,12 @@ (if (null? (lset-intersection equal? (hash-table-keys args:arg-hash) '("-list-servers" "-stop-server" - "-show-cmdinfo"))) + "-show-cmdinfo" + "-list-runs"))) (if (setup-for-run) (begin ;; if not list or kill then start a client (if appropriate) (if (or (args-defined? "-h" "-version" "-gen-megatest-area" "-gen-megatest-test") @@ -566,14 +567,17 @@ (let* ((dbstruct (make-dbr:dbstruct path: *toppath* local: #t)) (runpatt (args:get-arg "-list-runs")) (testpatt (if (args:get-arg "-testpatt") (args:get-arg "-testpatt") "%")) - (runsdat (db:get-runs dbstruct runpatt #f #f '())) + (keys (db:get-keys dbstruct)) + ;; (runsdat (db:get-runs dbstruct runpatt #f #f '())) + (runsdat (db:get-runs-by-patt dbstruct keys runpatt (or (args:get-arg "-target") + (args:get-arg "-reqtarg")) #f #f)) + ;; (cdb:remote-run db:get-runs #f runpatt #f #f '())) (runs (db:get-rows runsdat)) (header (db:get-header runsdat)) - (keys (db:get-keys dbstruct)) (db-targets (args:get-arg "-list-db-targets")) (seen (make-hash-table))) ;; Each run (for-each (lambda (run)