From: Danny Milosavljevic <dannym@scratchpost.org>
To: guix-devel@gnu.org, ludo@gnu.org
Subject: [PATCH] database: Simplify 'db-get-builds'.
Date: Mon, 19 Feb 2018 16:35:46 +0100 [thread overview]
Message-ID: <20180219153546.16173-1-dannym@scratchpost.org> (raw)
In-Reply-To: <20180219163506.2037e56e@scratchpost.org>
* src/cuirass/database.scm (db-get-builds): Modify.
(db-get-build): Modify.
---
src/cuirass/database.scm | 165 ++++++++++++++++-------------------------------
1 file changed, 55 insertions(+), 110 deletions(-)
diff --git a/src/cuirass/database.scm b/src/cuirass/database.scm
index dd3e5a2..5a4631f 100644
--- a/src/cuirass/database.scm
+++ b/src/cuirass/database.scm
@@ -26,6 +26,7 @@
#:use-module (ice-9 rdelim)
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-19)
+ #:use-module (srfi srfi-26)
#:use-module (sqlite3)
#:export (;; Procedures.
db-init
@@ -347,15 +348,6 @@ log file for DRV."
(cons `(,name . ((#:path . ,path)))
outputs))))))
-(define db-build-request "\
-SELECT Builds.id, Builds.timestamp, Builds.starttime, Builds.stoptime, Builds.log, Builds.status, Builds.derivation,\
-Derivations.job_name, Derivations.system, Derivations.nix_name,\
-Specifications.repo_name, Specifications.branch \
-FROM Builds \
-INNER JOIN Derivations ON Builds.derivation = Derivations.derivation and Builds.evaluation = Derivations.evaluation \
-INNER JOIN Evaluations ON Derivations.evaluation = Evaluations.id \
-INNER JOIN Specifications ON Evaluations.specification = Specifications.repo_name")
-
(define (db-format-build db build)
(match build
(#(id timestamp starttime stoptime log status derivation job-name system
@@ -374,112 +366,65 @@ INNER JOIN Specifications ON Evaluations.specification = Specifications.repo_nam
(#:outputs . ,(db-get-outputs db id))
(#:branch . ,branch)))))
-(define (db-get-build db id)
- "Retrieve a build in database DB which corresponds to ID."
- (let ((res (sqlite-exec db (string-append db-build-request
- " WHERE Builds.id=")
- id ";")))
- (match res
- ((build)
- (db-format-build db build))
- (() #f))))
-
(define (db-get-builds db filters)
"Retrieve all builds in database DB which are matched by given FILTERS.
FILTERS is an assoc list which possible keys are 'project | 'jobset | 'job |
'system | 'nr | 'order | 'status."
- (define (clauses->query+arguments clauses)
- ;; Given CLAUSES, return two values: a SQL query string, and a list of
- ;; arguments to bind. Each element of CLAUSES must be either a string, or
- ;; a (SQL ARGUMENT) tuple, where SQL is a query fragment and ARGUMENT is
- ;; the argument to be bound for that fragment.
- (let loop ((clauses clauses)
- (query '())
- (arguments '()))
- (match clauses
- (()
- (values (string-concatenate-reverse query)
- (reverse arguments)))
- (((? string? clause) . rest)
- (loop rest
- (cons clause query)
- arguments))
- ((((? string? clause) argument) . rest)
- (loop rest
- (cons clause query)
- (cons argument arguments))))))
-
- (define (where-clauses filters)
- (match (filter-map (match-lambda
- (('project project)
- (list "Specifications.repo_name=?" project))
- (('jobset jobset)
- (list "Specifications.branch=?" jobset))
- (('job job)
- (list "Derivations.job_name=?" job))
- (('system system)
- (list "Derivations.system=?" system))
- (('status 'done)
- "Builds.status >= 0")
- (('status 'pending)
- "Builds.status < 0")
- (_ #f))
- filters)
- (()
- '(""))
- ((clause)
- (list "WHERE " clause))
- ((clause0 rest ...)
- (cons* "WHERE " clause0
- (fold-right (lambda (clause result)
- `(" AND " ,clause ,@result))
- '()
- rest)))))
-
- (define (order-clause filters)
- (or (any (match-lambda
- (('order 'build-id)
- "ORDER BY Builds.id ASC")
- (('order 'decreasing-build-id)
- "ORDER BY Builds.id DESC")
- (('order 'finish-time)
- "ORDER BY Builds.stoptime DESC")
- (('order 'start-time)
- "ORDER BY Builds.start DESC")
- (('order 'submission-time)
- "ORDER BY Builds.timestamp DESC")
- (('order 'status+submission-time)
- ;; With this order, builds in 'running' state (-1) appear
- ;; before those in 'scheduled' state (-2).
- "ORDER BY Builds.status DESC, Builds.timestamp DESC")
- (_ #f))
- filters)
- "ORDER BY Builds.id DESC")) ;default order
-
- (define (limit-clause filters)
- (or (any (match-lambda
- (('nr number)
- (list "LIMIT ?" number))
- (_ #f))
- filters)
- ""))
-
- (call-with-values
- (lambda ()
- (clauses->query+arguments (append (list db-build-request " ")
- (where-clauses filters) '(" ")
- (list (order-clause filters) " ")
- (list (limit-clause filters) " "))))
- (lambda (sql arguments)
- (let loop ((rows (apply %sqlite-exec db sql arguments))
- (outputs '()))
- (match rows
- (()
- (reverse outputs))
- ((row . rest)
- (loop rest
- (cons (db-format-build db row) outputs))))))))
+ ;; XXX Change caller and remove
+ (define (assqx-ref filters key)
+ (if (null? filters)
+ #f
+ (match (car filters)
+ ((xkey xvalue) (if (eq? key xkey)
+ xvalue
+ (assqx-ref (cdr filters) key))))))
+ (let* ((order (if (eq? (assqx-ref filters 'order) 'build-id)
+ "ASC"
+ "DESC"))
+ (order-column-name
+ (match (assqx-ref filters 'order)
+ (('order 'build-id) "Builds.id")
+ (('order 'decreasing-build-id) "Builds.id")
+ (('order 'finish-time) "Builds.stoptime")
+ (('order 'start-time) "Builds.starttime")
+ (('order 'submission-time) "Builds.timestamp")
+ (_ "Builds.id")))
+ (stmt-text (format #f "\
+SELECT Builds.id, Builds.timestamp, Builds.starttime, Builds.stoptime, Builds.log, Builds.status, Builds.derivation,\
+Derivations.job_name, Derivations.system, Derivations.nix_name,\
+Specifications.repo_name, Specifications.branch \
+FROM Builds \
+INNER JOIN Derivations ON Builds.derivation = Derivations.derivation AND Builds.evaluation = Derivations.evaluation \
+INNER JOIN Evaluations ON Derivations.evaluation = Evaluations.id \
+INNER JOIN Specifications ON Evaluations.specification = Specifications.repo_name \
+WHERE (:id IS NULL OR (:id = Builds.id)) \
+OR (:project IS NULL OR (:project = Specifications.repo_name)) \
+OR (:jobset IS NULL OR (:jobset = Specifications.branch)) \
+OR (:job IS NULL OR (:job = Derivations.job_name)) \
+OR (:system IS NULL OR (:system = Derivations.system)) \
+OR (:status IS NULL OR (:status = 'done' AND Builds.status >= 0) OR (:status = 'pending' AND Builds.status < 0)) \
+ORDER BY ~a ~a LIMIT :nr;" order-column-name order))
+ (stmt (sqlite-prepare db stmt-text #:cache? #t)))
+ (sqlite-bind-arguments stmt #:id (assqx-ref filters 'id)
+ #:project (assqx-ref filters 'project)
+ #:jobset (assqx-ref filters 'jobset)
+ #:job (assqx-ref filters 'job)
+ #:system (assqx-ref filters 'system)
+ #:status (and=> (assqx-ref filters 'status)
+ object->string)
+ #:nr (match (assqx-ref filters 'nr)
+ (#f -1)
+ (x x)))
+ (map (cut db-format-build db <>)
+ (sqlite-fold-right cons '() stmt))))
+
+(define (db-get-build db id)
+ "Retrieve a build in database DB which corresponds to ID."
+ (match (db-get-builds db '(('id id)))
+ ((build)
+ build)
+ (() #f)))
(define (db-get-stamp db spec)
"Return a stamp corresponding to specification SPEC in database DB."
next prev parent reply other threads:[~2018-02-19 15:36 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-24 22:12 Cuirass news Ludovic Courtès
2018-01-25 10:55 ` Mathieu Othacehe
2018-01-25 10:59 ` Mathieu Othacehe
2018-01-25 13:09 ` Ludovic Courtès
2018-01-26 14:30 ` Danny Milosavljevic
2018-01-27 16:01 ` Ludovic Courtès
2018-01-27 17:18 ` Danny Milosavljevic
2018-01-27 19:12 ` Danny Milosavljevic
2018-01-28 21:47 ` Ludovic Courtès
2018-01-28 22:23 ` Danny Milosavljevic
2018-01-29 9:57 ` Andy Wingo
2018-02-08 13:37 ` Ludovic Courtès
2018-02-08 16:29 ` Danny Milosavljevic
2018-02-08 22:21 ` Ludovic Courtès
2018-02-08 23:05 ` Danny Milosavljevic
2018-02-09 6:17 ` Gábor Boskovits
2018-02-09 9:41 ` Ludovic Courtès
2018-02-09 11:29 ` Danny Milosavljevic
2018-02-09 16:53 ` Ludovic Courtès
2018-02-09 17:06 ` Danny Milosavljevic
2018-02-10 11:18 ` Ludovic Courtès
2018-02-13 9:12 ` Danny Milosavljevic
2018-02-14 13:43 ` Ludovic Courtès
2018-02-14 23:17 ` Ludovic Courtès
2018-02-19 15:35 ` Danny Milosavljevic
2018-02-19 15:35 ` Danny Milosavljevic [this message]
2018-02-19 17:52 ` [PATCH] database: db-get-builds: Inline output selection Danny Milosavljevic
2018-02-19 22:08 ` Cuirass news Danny Milosavljevic
2018-03-02 13:21 ` Ludovic Courtès
2018-03-02 22:06 ` Ludovic Courtès
2018-03-02 23:29 ` Danny Milosavljevic
2018-02-14 23:21 ` Ludovic Courtès
2018-01-25 21:06 ` Ricardo Wurmus
2018-01-26 11:12 ` Ludovic Courtès
2018-01-25 22:28 ` Danny Milosavljevic
2018-01-26 10:47 ` Ludovic Courtès
2018-01-28 12:33 ` Cuirass frontend Danny Milosavljevic
2018-01-29 17:42 ` Ludovic Courtès
2018-01-26 0:46 ` Cuirass news Danny Milosavljevic
2018-01-27 17:27 ` Danny Milosavljevic
2018-01-28 21:48 ` Ludovic Courtès
2018-01-26 17:55 ` Jan Nieuwenhuizen
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=20180219153546.16173-1-dannym@scratchpost.org \
--to=dannym@scratchpost.org \
--cc=guix-devel@gnu.org \
--cc=ludo@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).