Index: db.scm ================================================================== --- db.scm +++ db.scm @@ -107,11 +107,11 @@ (sqlite3:execute db (db:set-var db "MEGATEST_VERSION" megatest-version)))) ;; (if (< mver 1.18) ;; (begin ;; (print "Adding tags column to tests table") ;; (sqlite3:execute db "ALTER TABLE tests ADD COLUMN tags TEXT DEFAULT '';"))) - (if (< mver 1.20) + (if (< mver 1.21) (begin (sqlite3:execute db "CREATE TABLE test_meta (id INTEGER PRIMARY KEY, testname TEXT DEFAULT '', author TEXT DEFAULT '', owner TEXT DEFAULT '', @@ -153,20 +153,28 @@ (if valnum valnum res)) res))) (define (db:set-var db var val) (sqlite3:execute db "INSERT OR REPLACE INTO metadat (var,val) VALUES (?,?);" var val)) + +;; use a global for some primitive caching, it is just silly to re-read the db +;; over and over again for the keys since they never change + +(define *db-keys* #f) (define (db-get-keys db) - (let ((res '())) - (sqlite3:for-each-row - (lambda (key keytype) - (set! res (cons (vector key keytype) res))) - db - "SELECT fieldname,fieldtype FROM keys ORDER BY id DESC;") - res)) - + (if *db-keys* *db-keys* + (let ((res '())) + (sqlite3:for-each-row + (lambda (key keytype) + (set! res (cons (vector key keytype) res))) + db + "SELECT fieldname,fieldtype FROM keys ORDER BY id DESC;") + (set! *db-keys* res) + res))) + +(define db:get-keys db-get-keys) (define-inline (db:get-header vec)(vector-ref vec 0)) (define-inline (db:get-rows vec)(vector-ref vec 1)) (define (db:get-value-by-header row header field) Index: runs.scm ================================================================== --- runs.scm +++ runs.scm @@ -87,16 +87,28 @@ pth ;; (conc "," (string-intersperse tags ",") ",") )) item-paths ))) -;; (define db (open-db)) -;; (test-set-status! db 2 "runfirst" "COMPLETED" "PASS" "summer") +;; get the previous record for when this test was run where all keys match but runname +(define (test:get-previous-test-run-record db run-id test-name item-path) + (let* ((keys (db:get-keys db)) + (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) + + + (define (test-set-status! db run-id test-name state status itemdat-or-path comment dat) (let ((item-path (if (string? itemdat-or-path) itemdat-or-path (item-list->path itemdat-or-path))) - (otherdat (if dat dat (make-hash-table)))) + (otherdat (if dat dat (make-hash-table))) + ;; before proceeding we must find out if the previous test (where all keys matched except runname) + ;; was WAIVED if this test is FAIL + (waived (if (equal? status "FAIL") + (let (( + ;; update the primary record IF state AND status are defined (if (and state status) (sqlite3:execute db "UPDATE tests SET state=?,status=?,event_time=strftime('%s','now') WHERE run_id=? AND testname=? AND item_path=?;" state status run-id test-name item-path)) ;; add metadata (need to do this way to avoid SQL injection issues) @@ -574,11 +586,11 @@ (if (> (- (current-seconds)(+ (db:test-get-event_time testdat) (db:test-get-run_duration testdat))) 100) ;; i.e. no update for more than 100 seconds (begin (debug:print 0 "WARNING: Test " test-name " appears to be dead. Forcing it to state INCOMPLETE and status STUCK/DEAD") - (test-set-status! db run-id test-name "INCOMPLETE" "STUCK/DEAD" itemdat "Test is stuck or dead")) + (test-set-status! db run-id test-name "INCOMPLETE" "STUCK/DEAD" itemdat "Test is stuck or dead" #f)) (debug:print 2 "NOTE: " test-name " is already running"))) (else (debug:print 0 "ERROR: Failed to launch test " new-test-name ". Unrecognised state " (test:get-state testdat)))))) (if (not (null? tal)) (loop (car tal)(cdr tal)))))))))