diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm index 91133c2..9c7e69a 100644 --- a/src/cuirass/database.scm +++ b/src/cuirass/database.scm @@ -181,15 +181,30 @@ string." ((char=? char #\') (loop (cons* char char chars))) (else (loop (cons char chars))))))) +;; Extended error codes (see ). +;; XXX: This should be defined by (sqlite3). +(define SQLITE_CONSTRAINT 19) +(define SQLITE_CONSTRAINT_PRIMARYKEY + (logior SQLITE_CONSTRAINT (ash 6 8))) + (define (db-add-build db build) - "Store BUILD in database DB." - (sqlite-exec db "\ + "Store BUILD in database DB. This is idempotent." + (catch 'sqlite-error + (lambda () + (sqlite-exec db "\ INSERT INTO Builds (derivation, evaluation, log, output)\ VALUES ('~A', '~A', '~A', '~A');" - (assq-ref build #:derivation) - (assq-ref build #:eval-id) - (assq-ref build #:log) - (assq-ref build #:output)) + (assq-ref build #:derivation) + (assq-ref build #:eval-id) + (assq-ref build #:log) + (assq-ref build #:output))) + (lambda (key who code . rest) + ;; If we get a primary-key-constraint-violated error, that means we have + ;; already inserted the same (derivation,eval-id,log) tuple, which we + ;; can safely ignore. + (unless (= code SQLITE_CONSTRAINT_PRIMARYKEY) + (apply throw key who code rest)))) + (last-insert-rowid db)) (define (db-get-stamp db spec)