From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34724) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fRDoT-00088J-HV for guix-patches@gnu.org; Fri, 08 Jun 2018 05:36:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fRDoQ-0006HP-RH for guix-patches@gnu.org; Fri, 08 Jun 2018 05:36:05 -0400 Received: from debbugs.gnu.org ([208.118.235.43]:59111) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fRDoQ-0006GI-NF for guix-patches@gnu.org; Fri, 08 Jun 2018 05:36:02 -0400 Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1fRDoQ-0000bo-Hg for guix-patches@gnu.org; Fri, 08 Jun 2018 05:36:02 -0400 Subject: [bug#31755] [PATCH 02/19] database: Fail registration when encountering unregistered references. Resent-Message-ID: From: Ludovic =?UTF-8?Q?Court=C3=A8s?= Date: Fri, 8 Jun 2018 11:34:34 +0200 Message-Id: <20180608093451.27760-2-ludo@gnu.org> In-Reply-To: <20180608093451.27760-1-ludo@gnu.org> References: <20180608093451.27760-1-ludo@gnu.org> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-patches-bounces+kyle=kyleam.com@gnu.org Sender: "Guix-patches" To: 31755@debbugs.gnu.org * guix/store/database.scm (add-reference-sql): Remove nested SELECT. (add-references): Expect REFERENCES to be a list of ids. (sqlite-register): Call 'path-id' for each of REFERENCES and pass it to 'add-references'. * tests/store-database.scm ("register-path with unregistered references"): New test. --- guix/store/database.scm | 18 +++++++++++------- tests/store-database.scm | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/guix/store/database.scm b/guix/store/database.scm index e81ab3dc9..d5e34ef04 100644 --- a/guix/store/database.scm +++ b/guix/store/database.scm @@ -27,6 +27,7 @@ #:use-module (srfi srfi-1) #:use-module (srfi srfi-11) #:use-module (srfi srfi-19) + #:use-module (srfi srfi-26) #:use-module (rnrs io ports) #:use-module (ice-9 match) #:use-module (system foreign) @@ -139,13 +140,11 @@ of course. Returns the row id of the row that was modified or inserted." (last-insert-row-id db))))) (define add-reference-sql - "INSERT OR IGNORE INTO Refs (referrer, reference) SELECT :referrer, id -FROM ValidPaths WHERE path = :reference") + "INSERT INTO Refs (referrer, reference) VALUES (:referrer, :reference);") (define (add-references db referrer references) "REFERRER is the id of the referring store item, REFERENCES is a list -containing store items being referred to. Note that all of the store items in -REFERENCES must already be registered." +ids of items referred to." (let ((stmt (sqlite-prepare db add-reference-sql #:cache? #t))) (for-each (lambda (reference) (sqlite-reset stmt) @@ -164,15 +163,20 @@ path of some store item, REFERENCES is a list of string paths which the store item PATH refers to (they need to be already registered!), DERIVER is a string path of the derivation that created the store item PATH, HASH is the base16-encoded sha256 hash of the store item denoted by PATH (prefixed with -\"sha256:\") after being converted to nar form, and nar-size is the size in -bytes of the store item denoted by PATH after being converted to nar form." +\"sha256:\") after being converted to nar form, and NAR-SIZE is the size in +bytes of the store item denoted by PATH after being converted to nar form. + +Every store item in REFERENCES must already be registered." (with-database db-file db (let ((id (update-or-insert db #:path path #:deriver deriver #:hash hash #:nar-size nar-size #:time (time-second (current-time time-utc))))) - (add-references db id references)))) + ;; Call 'path-id' on each of REFERENCES. This ensures we get a + ;; "non-NULL constraint" failure if one of REFERENCES is unregistered. + (add-references db id + (map (cut path-id db <>) references))))) ;;; diff --git a/tests/store-database.scm b/tests/store-database.scm index 794736859..9562055fd 100644 --- a/tests/store-database.scm +++ b/tests/store-database.scm @@ -74,4 +74,24 @@ (list (path-id db "/gnu/foo") (path-id db "/gnu/bar"))))))) +(test-assert "register-path with unregistered references" + ;; Make sure we get a "NOT NULL constraint failed: Refs.reference" error + ;; when we try to add references that are not registered yet. Better safe + ;; than sorry. + (call-with-temporary-output-file + (lambda (db-file port) + (delete-file db-file) + (catch 'sqlite-error + (lambda () + (sqlite-register #:db-file db-file + #:path "/gnu/foo" + #:references '("/gnu/bar") + #:deriver "/gnu/foo.drv" + #:hash (string-append "sha256:" (make-string 64 #\e)) + #:nar-size 1234) + #f) + (lambda args + (pk 'welcome-exception! args) + #t))))) + (test-end "store-database") -- 2.17.1