unofficial mirror of guix-patches@gnu.org 
 help / color / mirror / code / Atom feed
From: "Ludovic Courtès" <ludo@gnu.org>
To: 31755@debbugs.gnu.org
Subject: [bug#31755] [PATCH 02/19] database: Fail registration when encountering unregistered references.
Date: Fri,  8 Jun 2018 11:34:34 +0200	[thread overview]
Message-ID: <20180608093451.27760-2-ludo@gnu.org> (raw)
In-Reply-To: <20180608093451.27760-1-ludo@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)))))
 
 \f
 ;;;
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

  reply	other threads:[~2018-06-08  9:36 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-08  9:30 [bug#31755] [PATCH 00/19] Use (guix store database) instead of 'guix-register' Ludovic Courtès
2018-06-08  9:34 ` [bug#31755] [PATCH 01/19] database: 'with-database' can now initialize new databases Ludovic Courtès
2018-06-08  9:34   ` Ludovic Courtès [this message]
2018-06-08  9:34   ` [bug#31755] [PATCH 03/19] store-copy: 'read-reference-graph' returns a list of records Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 04/19] build: Require Guile-SQLite3 Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 05/19] database: Provide a way to specify the schema location Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 06/19] database: 'register-path' creates the database directory if needed Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 07/19] deduplicate: Fix a couple of thinkos Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 08/19] database: Remove extra SQL parameter in 'update-or-insert' Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 09/19] database: Add #:reset-timestamps? to 'register-path' Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 10/19] database: Replace existing entries in Refs Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 11/19] database: 'reset-timestamps' sets file permissions as well Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 12/19] vm: 'expression->derivation-in-linux-vm' code can now use dlopen Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 13/19] install: Use (guix store database) instead of 'guix-register' Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 14/19] database: 'sqlite-register' takes a database, not a file name Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 15/19] database: Add 'register-items' Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 16/19] install: Use 'reset-timestamps' from (guix store database) Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 17/19] database: Allow for deterministic database construction Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 18/19] store: Remove 'register-path' Ludovic Courtès
2018-06-08  9:34   ` [bug#31755] [PATCH 19/19] Remove 'guix-register' and its traces Ludovic Courtès
2018-06-14  9:17 ` bug#31755: [PATCH 00/19] Use (guix store database) instead of 'guix-register' Ludovic Courtès
     [not found] ` <handler.31755.D31755.15289678758292.notifdone@debbugs.gnu.org>
2018-06-14  9:30   ` [bug#31755] closed (Re: [bug#31755] [PATCH 00/19] Use (guix store database) instead of 'guix-register') Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://guix.gnu.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180608093451.27760-2-ludo@gnu.org \
    --to=ludo@gnu.org \
    --cc=31755@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).