summary refs log tree commit diff
diff options
context:
space:
mode:
authorPierre Neidhardt <mail@ambrevar.xyz>2020-09-26 13:48:35 +0200
committerPierre Neidhardt <mail@ambrevar.xyz>2020-09-26 15:57:17 +0200
commit0127cfa5d0898222257a716bf7b0a167f31cc6dd (patch)
tree392eb3d16152483077c14f680b0690a43d6e6f0c
parent25147f983bdf432b03e8271abe0318f4812f94ba (diff)
downloadguix-0127cfa5d0898222257a716bf7b0a167f31cc6dd.tar.gz
guix: Include synopsis and description in filesearch database.
-rw-r--r--guix/scripts/filesearch.scm78
-rw-r--r--guix/scripts/schema.sql8
2 files changed, 73 insertions, 13 deletions
diff --git a/guix/scripts/filesearch.scm b/guix/scripts/filesearch.scm
index 3cb542d7b7..8b582023da 100644
--- a/guix/scripts/filesearch.scm
+++ b/guix/scripts/filesearch.scm
@@ -59,17 +59,37 @@ string SQL for DB."
                     (path (error "Missing argument"))
                     (files (error "Missing argument"))
                     (version (error "Missing argument"))
+                    (synopsis (error "Missing argument"))
+                    (description (error "Missing argument"))
                     (guix-version (error "Missing argument")))
   "FILES is a list of path underneath PATH."
-  (sqlite-exec
-   db
-   (string-append "insert into Packages (name, system, output, path, version, guix)"
-                  ;; "insert or replace into Packages (name, system, output, path, version, guix)"
-                  (format #f " values (~s, ~s, ~s, ~s, ~s, ~s)"
-                          name system output path version guix-version)
-                  ;; " on conflict (path) do nothing"
-                  ))
+  (with-statement
+      db
+      (string-append "insert into Packages (name, system, output, version, path, guix)"
+                     " values (:name, :system, :output, :version, :path, :guix)")
+      stmt
+    (sqlite-bind-arguments stmt
+                           #:name name
+                           #:system system
+                           #:output output
+                           #:path path
+                           #:version version
+                           #:guix guix-version)
+    (map vector->list
+         (sqlite-fold cons '() stmt)))
   (let ((id ((@@ (guix store database) last-insert-row-id) db))) ; TODO: Export?
+    (with-statement
+        db
+        (string-append "insert into Info (name, synopsis, description, package)"
+                       " values (:name, :synopsis, :description, :id)")
+        stmt
+      (sqlite-bind-arguments stmt
+                             #:name name
+                             #:synopsis synopsis
+                             #:description description
+                             #:id id)
+      (map vector->list
+           (sqlite-fold cons '() stmt)))
     (for-each
      (lambda (file)
        (sqlite-exec
@@ -134,6 +154,8 @@ matches both \"/bin/foo\" and \"/usr/bin/foo\" but not \"barbin\"."
                          #:output output
                          #:path path ; Storing /gnu/store for all packages has no significant size cost.
                          #:version (package-version package)
+                         #:synopsis (package-synopsis package)
+                         #:description (package-description package)
                          #:guix-version %guix-version
                          #:files (directory-files path)))))
          output-path-pairs)))
@@ -166,6 +188,29 @@ Example patterns:
       (map vector->list
            (sqlite-fold cons '() stmt)))))
 
+(define (search-package pattern . more-patterns)
+  "Return corresponding packages.
+Search is performed over name, synopsis, description.
+Packages or ordered by most relevant last.
+Search is subject to SQLite \"full-text search\" pattern matching.
+See https://www.sqlite.org/fts5.html."
+  (let ((pattern (string-concatenate
+                  (map (lambda (s)
+                         (format #f "~s*" s))
+                       (cons pattern more-patterns)))))
+    (with-database %db db
+      (with-statement
+          db
+          (string-append
+           "SELECT name FROM Info WHERE Info MATCH :pattern ORDER BY RANK")
+          stmt
+        (sqlite-bind-arguments
+         stmt
+         #:pattern (format #f "name:~a OR synopsis:~a OR description:~a"
+                           pattern pattern pattern))
+        (map vector->list
+             (sqlite-fold cons '() stmt))))))
+
 (define (format-search search-result)
   (for-each
    (match-lambda
@@ -213,14 +258,21 @@ Example patterns:
 ;; Measures
 ;;
 ;; Context:
-;; - 14,000 packages
-;; - 1700 store items
+;; - 15005 packages
+;; - 1796 store items
 ;; - CPU 3.5 GHz
 ;; - SSD
 ;;
-;; Results:
+;; Data with synopsis and description:
+;; - Database generation time: 30 seconds.
+;; - Database size: 37 MiB.
+;; - Database Zstd-compressed size: 6.4 MiB.
+;; - Zstd-compression time: 0.13 seconds.
+;; - FTS queries: < 0.01 seconds.
+;;
+;; Data without synopsis and description:
 ;; - Database generation time: 30 seconds.
-;; - Database size: 31 MiB.
-;; - Database Zstd-compressed size: 6.1 MiB.
+;; - Database size: 36 MiB.
+;; - Database Zstd-compressed size: 6.0 MiB.
 ;; - Zstd-compression time: 0.13 seconds.
 ;; - FTS queries: < 0.01 seconds.
diff --git a/guix/scripts/schema.sql b/guix/scripts/schema.sql
index ce90de2b86..5c7925cdf7 100644
--- a/guix/scripts/schema.sql
+++ b/guix/scripts/schema.sql
@@ -9,6 +9,14 @@ create table if not exists Packages (
     guix        text not null
 );
 
+
+create virtual table if not exists Info using fts5(
+    name,
+    synopsis,
+    description,
+    package
+);
+
 create virtual table if not exists Files using fts5(
     subpath,
     package