summaryrefslogtreecommitdiff
path: root/src/cuirass/database.scm
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2018-02-14 16:40:50 +0100
committerLudovic Courtès <ludo@gnu.org>2018-02-14 16:41:50 +0100
commit1f31134d33ba6b30e375c9debe792a6c85363313 (patch)
treeee47a285aee67dbb474c4a93954234064f14c308 /src/cuirass/database.scm
parentc47dfdf82b4be62501a7932eaec4c124566a1829 (diff)
downloadcuirass-1f31134d33ba6b30e375c9debe792a6c85363313.tar
cuirass-1f31134d33ba6b30e375c9debe792a6c85363313.tar.gz
database: Make 'db-add-derivation' idempotent.
* src/cuirass/database.scm (db-add-derivation): Catch 'sqlite-error and handle SQLITE_CONSTRAINT_PRIMARYKEY. (SQLITE_CONSTRAINT_UNIQUE): New variable. * tests/database.scm ("database")["db-add-derivation"]: Add extra call to 'db-add-derivation'.
Diffstat (limited to 'src/cuirass/database.scm')
-rw-r--r--src/cuirass/database.scm26
1 files changed, 19 insertions, 7 deletions
diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm
index d3e2666..dd3e5a2 100644
--- a/src/cuirass/database.scm
+++ b/src/cuirass/database.scm
@@ -216,15 +216,25 @@ INSERT OR IGNORE INTO Specifications (repo_name, url, load_path, file, \
(define (db-add-derivation db job)
"Store a derivation result in database DB and return its ID."
- (sqlite-exec db "\
+ (catch 'sqlite-error
+ (lambda ()
+ (sqlite-exec db "\
INSERT INTO Derivations (derivation, job_name, system, nix_name, evaluation)\
VALUES ("
- (assq-ref job #:derivation) ", "
- (assq-ref job #:job-name) ", "
- (assq-ref job #:system) ", "
- (assq-ref job #:nix-name) ", "
- (assq-ref job #:eval-id) ");")
- (last-insert-rowid db))
+ (assq-ref job #:derivation) ", "
+ (assq-ref job #:job-name) ", "
+ (assq-ref job #:system) ", "
+ (assq-ref job #:nix-name) ", "
+ (assq-ref job #:eval-id) ");")
+ (last-insert-rowid db))
+ (lambda (key who code message . rest)
+ ;; If we get a unique-constraint-failed error, that means we have
+ ;; already inserted the same (derivation,eval-id) tuple. That happens
+ ;; when several jobs produce the same derivation, and we can ignore it.
+ (if (= code SQLITE_CONSTRAINT_PRIMARYKEY)
+ (sqlite-exec db "SELECT * FROM Derivations WHERE derivation="
+ (assq-ref job #:derivation) ";")
+ (apply throw key who code rest)))))
(define (db-get-derivation db id)
"Retrieve a job in database DB which corresponds to ID."
@@ -261,6 +271,8 @@ string."
(define SQLITE_CONSTRAINT 19)
(define SQLITE_CONSTRAINT_PRIMARYKEY
(logior SQLITE_CONSTRAINT (ash 6 8)))
+(define SQLITE_CONSTRAINT_UNIQUE
+ (logior SQLITE_CONSTRAINT (ash 8 8)))
(define-enumeration build-status
;; Build status as expected by Hydra's API. Note: the negative values are