summaryrefslogtreecommitdiff
path: root/guix/store/database.scm
Commit message (Collapse)AuthorAge
* database: Validate #:nar-size and #:time when registering store items.Ludovic Courtès2021-01-31
| | | | | | | * guix/store/database.scm (assert-integer): New procedure. (update-or-insert): Use it to validate NAR-SIZE and TIME. * tests/store-database.scm ("sqlite-register with incorrect size"): New test.
* database: Remove workarounds unnecessary with guile-sqlite3 0.1.2.Ludovic Courtès2021-01-31
| | | | * guix/store/database.scm (sqlite-exec, sqlite-finalize): Remove.
* database: Honor 'SOURCE_DATE_EPOCH'.Ludovic Courtès2020-12-15
| | | | | | * guix/store/database.scm (timestamp): New procedure. (sqlite-register): Use it as the default for #:time. (register-items): Likewise for #:registeration-time.
* database: Remove 'register-path'.Ludovic Courtès2020-12-15
| | | | | | | | | | | | * guix/store/database.scm (register-path): Remove. * tests/store-database.scm ("register-path"): Rename to... ("register-items"): ... this, and use 'register-items' instead of 'register-path'. ("register-path, directory"): Rename to... ("register-items, directory"): ... this, and use 'register-items' instead of 'register-path'. ("register-path with unregistered references"): Rename to... ("sqlite-register with unregistered references"): ... this.
* system: 'init' does not recompute the hash of each store item.Ludovic Courtès2020-12-15
| | | | | | | | | | | | | | | Fixes <https://bugs.gnu.org/44760>. Previously, the 'register-path' call would re-traverse ITEM to compute its nar hash, even though that hash is already known in the initial store. This patch also avoids repeated opening/closing of the database. * guix/store/database.scm (call-with-database): Export. * guix/scripts/system.scm (copy-item): Add 'db' parameter. Call 'sqlite-register' instead of 'register-path'. (copy-closure): Remove redundant call to 'references*'. Call 'call-with-database' and pass the database to 'copy-item'.
* database: Remove #:deduplicate? and #:reset-timestamps? from 'register-path'.Ludovic Courtès2020-12-15
| | | | | | | | * guix/store/database.scm (register-path): Remove #:deduplicate? and #:reset-timestamps?. * guix/scripts/system.scm (copy-item): Adjust accordingly. * tests/store-database.scm ("register-path") ("register-path, directory"): Call 'reset-timestamps'.
* database: Remove #:deduplicate? from 'register-items'.Ludovic Courtès2020-12-15
| | | | | | | | | | | | It is now up to the caller to deduplicate store contents. * guix/store/database.scm (register-items): Remove #:deduplicate? parameter and call to 'deduplicate'. (register-path): Call 'deduplicate' when #:deduplicate? is true. * gnu/build/image.scm (register-closure): Adjust call accordingly. * gnu/build/vm.scm (register-closure): Likewise. * guix/nar.scm (finalize-store-file): Likewise. * guix/scripts/pack.scm (store-database): Likewise.
* database: Remove #:reset-timestamps? from 'register-items'.Ludovic Courtès2020-12-15
| | | | | | | | | | | | | | The assumption now is that the caller took care of resetting timestamps and permissions. * guix/store/database.scm (register-items): Remove #:reset-timestamps? parameter and the call to 'reset-timestamps'. (register-path): Adjust accordingly and add call to 'reset-timestamps'. * gnu/build/image.scm (register-closure): Remove #:reset-timestamps? parameter to 'register-items'. * gnu/build/vm.scm (register-closure): Likewise. * guix/nar.scm (finalize-store-file): Adjust accordingly. * guix/scripts/pack.scm (store-database)[build]: Likewise.
* database: Remove unnecessary module imports.Ludovic Courtès2020-12-08
| | | | | * guix/store/database.scm: Remove unnecessary imports added in 4b9eecd322e566783369795ebea63a479b51f486.
* database: register-items: reduce transaction scope.Christopher Baines2020-09-14
| | | | | | | | | | | | | | | | | | | | | | | | | | | It was made transactional in a4678c6ba18d8dbd79d931f80426eebf61be7ebe, with the reasoning to prevent broken intermediate states from being visible. I think this means something like an entry being in ValidPaths, but the Refs not being inserted. Using a transaction for this makes sense, but I think using one single transaction for the whole register-items call is unnecessary to avoid broken states from being visible, and could block other writes to the store database while register-items is running. Because the deduplication and resetting timestamps happens within the transaction as well, even though these things don't involve the database, writes to the database will still be blocked while this is happening. To reduce the potential for register-items to block other writers to the database for extended periods, this commit moves the transaction to just wrap the call to sqlite-register. This is the one place where writes occur, so that should prevent the broken intermediate states issue above. The one difference this will make is some of the registered items will be visible to other connections while others may be still being added. I think this is OK, as it's equivalent to just registering different items. * guix/store/database.scm (register-items): Reduce transaction scope. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
* database: document extra registration requirements.Caleb Ristvedt2020-09-14
| | | | | | | | | | It's necessary that store items be locked and protected from garbage collection while they are being registered. This documents that. * guix/store/database.scm (register-path, register-items): document GC protection and locking requirements. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
* image: Do not set journal_model=WAL for the Hurd.Jan (janneke) Nieuwenhuizen2020-07-11
| | | | | | | | | | | | | | This fixes <https://bugs.gnu.org/42151>. * gnu/system/images/hurd.scm (hurd-initialize-root-partition): Use #:wal-mode #f in call to ... * gnu/build/image.scm (initialize-root-partition): ... this, add #:wal-mode? parameter, pass it to ... (register-closure): ... this, add #:wal-mode? parameter, pass it to ... * guix/store/database.scm (with-database): ... this, add #:wal-mode? parameter, pass it to ... (call-with-database): ... this, add #:wal-mode? parameter; when set to #f, do not set journal_model=WAL.
* database: 'register-items' takes an open database.Ludovic Courtès2020-06-18
| | | | | | | | | | | | * guix/store/database.scm (store-database-directory) (store-database-file): New procedures. (call-with-database): Add call to 'mkdir-p'. (register-items): Add 'db' parameter and remove #:state-directory and #:schema. (register-path): Use 'store-database-file' and 'with-database', and parameterize SQL-SCHEMA. * gnu/build/image.scm (register-closure): Likewise. * gnu/build/vm.scm (register-closure): Likewise. * guix/scripts/pack.scm (store-database)[build]: Likewise.
* database: separate transaction-handling and retry-handling.Caleb Ristvedt2020-06-10
| | | | | | | | | | | | | | | | | | | Previously call-with-transaction would both retry when SQLITE_BUSY errors were thrown and do what its name suggested (start and rollback/commit a transaction). This changes it to do only what its name implies, which simplifies its implementation. Retrying is provided by the new call-with-SQLITE_BUSY-retrying procedure. * guix/store/database.scm (call-with-transaction): no longer restarts, new #:restartable? argument controls whether "begin" or "begin immediate" is used. (call-with-SQLITE_BUSY-retrying, call-with-retrying-transaction, call-with-retrying-savepoint): new procedures. (register-items): use call-with-retrying-transaction to preserve old behavior. * .dir-locals.el (call-with-retrying-transaction, call-with-retrying-savepoint): add indentation information.
* database: ensure update-or-insert is run within a transactionCaleb Ristvedt2020-06-10
| | | | | | | | | | | update-or-insert can break if an insert occurs between when it decides whether to update or insert and when it actually performs that operation. Putting the check and the update/insert operation in the same transaction ensures that the update/insert will only succeed if no other write has occurred in the middle. * guix/store/database.scm (call-with-savepoint): new procedure. (update-or-insert): use call-with-savepoint to ensure the read and the insert/update occur within the same transaction.
* database: rewrite query procedures in terms of with-statement.Caleb Ristvedt2020-06-10
| | | | | | | | | | | | | | | | | | | Most of our queries would fail to finalize their statements properly if sqlite returned an error during their execution. This resolves that, and also makes them somewhat more concise as a side-effect. This also makes some small changes to improve certain queries where behavior was strange or overly verbose. * guix/store/database.scm (call-with-statement): new procedure. (with-statement): new macro. (last-insert-row-id, path-id, update-or-insert, add-references): rewrite to use with-statement. (update-or-insert): factor last-insert-row-id out of the end of both branches. (add-references): remove pointless last-insert-row-id call. * .dir-locals.el (with-statement): add indenting information.
* database: work around guile-sqlite3 bug preventing statement resetCaleb Ristvedt2020-06-10
| | | | | | | | | | | | | guile-sqlite3 provides statement caching, making it unnecessary for sqlite to keep re-preparing statements that are frequently used. Unfortunately it doesn't quite emulate the semantics of sqlite_finalize properly, because it doesn't cause a commit if the statement being finalized is the last "active" statement (see https://notabug.org/guile-sqlite3/guile-sqlite3/issues/12). We work around this by wrapping sqlite-finalize with our own version that ensures sqlite-reset is called, which does The Right Thing™. * guix/store/database.scm (sqlite-finalize): new procedure that shadows the sqlite-finalize from (sqlite3).
* database: 'reset-timestamps' can optionally preserve permissions.Ludovic Courtès2020-04-11
| | | | | * guix/store/database.scm (reset-timestamps): Add #:preserve-permissions? and honor it.
* database: Make 'register-items' transactional.Caleb Ristvedt2019-03-07
| | | | | | | | | | | | | * guix/store/database.scm (SQLITE_BUSY, register-output-sql): New variables. (add-references): Don't try finalizing after each use, only after all the uses (otherwise a finalized statement would be used if #:cache? was #f). (call-with-transaction): New procedure. (register-items): Use call-with-transaction to prevent broken intermediate states from being visible. * .dir-locals.el (call-with-transaction): indent it. Signed-off-by: Ludovic Courtès <ludo@gnu.org>
* database: Use "write-ahead log" mode and set a long "busy timeout".Ludovic Courtès2018-12-21
| | | | | | | | | This should avoid "database is locked" errors when there's a lot of concurrency, for instance when offloading simultaneously a lot of builds. * guix/store/database.scm (call-with-database): Add two 'sqlite-exec' calls to set 'journal_mode' and 'busy_timeout'.
* Update Guile-SQLite3 URL everywhere.Ludovic Courtès2018-11-23
| | | | | | | * README: Update Guile-SQLite3 URL. * doc/guix.texi (Requirements): Likewise. * guix/store/database.scm (sqlite-exec): Likewise. * m4/guix.m4 (GUIX_CHECK_GUILE_SQLITE3): Likewise.
* nar: Access the database instead of connecting to the daemon.Ludovic Courtès2018-11-13
| | | | | | | * guix/store/database.scm (%default-database-file): New variable. (path-id): Export. * guix/nar.scm (finalize-store-file): Use 'with-database' instead of 'with-store', and use 'path-id' instead of 'valid-path?'.
* database: Register each store item only once.Ludovic Courtès2018-09-23
| | | | | | | | | Fixes <https://bugs.gnu.org/32600>. Reported by Leo Famulari. * guix/store/database.scm (register-items): Check whether TO-REGISTER is in DB by calling 'path-id', and skip the reset-timestamps, registration, and deduplication phases when it is.
* database: 'register-items' shows a progress bar.Ludovic Courtès2018-09-23
| | | | | | * guix/store/database.scm (register-items): Add #:log-port. Use 'progress-reporter/bar' to show a progress report. (register-path): Pass #:log-port to 'register-items'.
* database: Reset timestamps to one second after the Epoch.Ludovic Courtès2018-07-20
| | | | | | | | | | | | | | | | | | Previously, store items registered in the database by this code (for instance, store items retrieved by 'guix offload' and passed to 'restore-file-set') would have an mtime of 0 instead of 1. This would cause problems for things like .go files: Guile would consider them to be older than the corresponding .scm file, and consequently it would ignore them and possibly use another (incorrect) .go file. Reported by Ricardo Wurmus. * guix/store/database.scm (reset-timestamps): Pass 1, not 0, to 'utime'. * tests/store-database.scm ("register-path"): Check the mtime of FILE and REF.
* database: 'reset-timestamps' now correctly handles symlinks.Ludovic Courtès2018-07-03
| | | | | * guix/store/database.scm (reset-timestamps): Use 'utime' with AT_SYMLINK_NOFOLLOW for symlinks.
* database: Allow for deterministic database construction.Ludovic Courtès2018-06-14
| | | | | | | | | | Fixes <https://bugs.gnu.org/21073>. * guix/store/database.scm (sqlite-register): Add #:time. (%epoch): New variable. (register-items): Add #:registration-time. Pass #:time to 'sqlite-register'. * gnu/build/install.scm (register-closure): Pass #:registration-time.
* install: Use 'reset-timestamps' from (guix store database).Ludovic Courtès2018-06-14
| | | | | * gnu/build/install.scm (reset-timestamps): Remove. * gnu/build/vm.scm: Use 'reset-timestamps' from (guix store database).
* database: Add 'register-items'.Ludovic Courtès2018-06-14
| | | | | | | | * guix/build/store-copy.scm (store-info): Export. * guix/store/database.scm (register-items): New procedure. (register-path): Implement in terms of 'register-items'. * gnu/build/install.scm (register-closure): Use 'register-items' instead of 'for-each' and 'register-path'.
* database: 'sqlite-register' takes a database, not a file name.Ludovic Courtès2018-06-14
| | | | | | | | | * guix/store/database.scm (sqlite-register): Remove #:db-file and add 'db' parameter. Remove #:schema and 'parameterize'. (register-path): Wrap 'sqlite-register' call in 'with-database' and in 'parameterize'. * tests/store-database.scm ("new database") ("register-path with unregistered references"): Adjust accordingly.
* database: 'reset-timestamps' sets file permissions as well.Ludovic Courtès2018-06-14
| | | | * guix/store/database.scm (reset-timestamps): Add 'chmod' calls.
* database: Replace existing entries in Refs.Ludovic Courtès2018-06-14
| | | | * guix/store/database.scm (add-reference-sql): Add "OR REPLACE".
* database: Add #:reset-timestamps? to 'register-path'.Ludovic Courtès2018-06-14
| | | | | * guix/store/database.scm (register-path): Add #:reset-timestamps? and honor it.
* database: Remove extra SQL parameter in 'update-or-insert'.Ludovic Courtès2018-06-14
| | | | | * guix/store/database.scm (update-or-insert): Remove extra #:path parameter.
* database: 'register-path' creates the database directory if needed.Ludovic Courtès2018-06-14
| | | | * guix/store/database.scm (register-path): Call 'mkdir-p'.
* database: Provide a way to specify the schema location.Ludovic Courtès2018-06-14
| | | | | | * guix/store/database.scm (sqlite-register): Add #:schema. Parameterize 'sql-schema' based on this. (register-path): Add #:schema and pass it to 'sqlite-register'.
* database: Fail registration when encountering unregistered references.Ludovic Courtès2018-06-14
| | | | | | | | | * 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.
* database: 'with-database' can now initialize new databases.Ludovic Courtès2018-06-14
| | | | | | | | | | | | | * nix/libstore/schema.sql: Rename to... * guix/store/schema.sql: ... this. * Makefile.am (nobase_dist_guilemodule_DATA): Add it. * nix/local.mk (%D%/libstore/schema.sql.hh): Adjust accordingly. * guix/store/database.scm (sql-schema): New variable. (sqlite-exec, initialize-database, call-with-database): New procedures. (with-database): Rewrite in terms of 'call-with-database'. * tests/store-database.scm ("new database"): New test. * guix/self.scm (compiled-guix)[*core-modules*]: Add 'schema.sql' to #:extra-files.
* Add (guix store deduplication).Caleb Ristvedt2018-06-01
| | | | | | | | | | | | * guix/store/database.scm (register-path): Add #:deduplicate? and call 'deduplicate' when it's true. (counting-wrapper-port, nar-sha256): Move to... * guix/store/deduplication.scm: ... here. New file. * tests/store-deduplication.scm: New file. * Makefile.am (STORE_MODULES): Add deduplication.scm. (SCM_TESTS) [HAVE_GUILE_SQLITE3]: Add store-deduplication.scm. Co-authored-by: Ludovic Courtès <ludo@gnu.org>
* database: 'register-path' resets timestamps.Ludovic Courtès2018-06-01
| | | | | * guix/store/database.scm (reset-timestamps): New procedure. (register-path): Use it.
* Add (gnu store database).Caleb Ristvedt2018-06-01
* guix/config.scm.in (%store-database-directory): New variable. * guix/store/database.scm: New file. * tests/store-database.scm: New file. * Makefile.am (STORE_MODULES): New variable. (MODULES, MODULES_NOT_COMPILED): Adjust accordingly. (SCM_TESTS) [HAVE_GUILE_SQLITE3]: Add tests/store-database.scm. Co-authored-by: Ludovic Courtès <ludo@gnu.org>