Subject: [PATCH -v2] services: dict.scm: Support more dicod configuration

From: Huang Ying <[email-masked]>
Date: Thu, 30 Mar 2017 19:13:34 +0800

* gnu/services/dict.scm (<dicod-configuration>): Add handlers to configure
  handlers (module instances).
  (<dicod-handler>): Add new record type to describe handler (module instance).
  (<dicod-database>): Add more fields.
  (dicod-configuration-file): Support convert handlers and enhanced databases
  configuration to config file.

* doc/guix.text: Add description of newly added dicod configuration.
---
 doc/guix.texi         | 57 ++++++++++++++++++++++++++++++++++++++++++++++-----
 gnu/services/dict.scm | 52 ++++++++++++++++++++++++++++++++++++++--------
 2 files changed, 96 insertions(+), 13 deletions(-)

diff --git a/doc/guix.texi b/doc/guix.texi
index 57595b95e..f1a063581 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -14370,25 +14370,49 @@ This is the list of IP addresses and ports and possibly socket file
 names to listen to (@pxref{Server Settings, @code{listen} directive,,
 dico, GNU Dico Manual}).
 
+@item @code{handlers} (default: @var{'()})
+List of @code{<dicod-handler>} objects denoting handlers (module instances).
+
 @item @code{databases} (default: @var{(list %dicod-database:gcide)})
 List of @code{<dicod-database>} objects denoting dictionaries to be served.
 @end table
 @end deftp
 
-@deftp {Data Type} dicod-database
-Data type representing a dictionary database.
+@deftp {Data Type} dicod-handler
+Data type representing a dictionary handler (module instance).
 
 @table @asis
 @item @code{name}
-Name of the database, will be used in DICT commands.
+Name of the handler (module instance).
 
-@item @code{module}
-Name of the dicod module used by this database
+@item @code{module} (default: @var{#f})
+Name of the dicod module of the handler (instance).  If it is @code{#f},
+the module has the same name as the handler.
 (@pxref{Modules,,, dico, GNU Dico Manual}).
 
 @item @code{options}
 List of strings or gexps representing the arguments for the module handler
+@end table
+@end deftp
+
+@deftp {Data Type} dicod-database
+Data type representing a dictionary database.
+
+@table @asis
+@item @code{name}
+Name of the database, will be used in DICT commands.
+
+@item @code{handler}
+Name of the dicod handler (module instance) used by this database
 (@pxref{Handlers,,, dico, GNU Dico Manual}).
+
+@item @code{complex} (default: @var{#f})
+Whether the database configuration complex.  The complex configuration
+will need a corresponding @code{<dicod-handler>} object, otherwise not.
+
+@item @code{options}
+List of strings or gexps representing the arguments for the database
+(@pxref{Databases,,, dico, GNU Dico Manual}).
 @end table
 @end deftp
 
@@ -14397,6 +14421,29 @@ A @code{<dicod-database>} object serving the GNU Collaborative International
 Dictonary of English using the @code{gcide} package.
 @end defvr
 
+The following is an example @code{dicod-service} configuration.
+
+@example
+(dicod-service #:config
+ (dicod-configuration
+  (handlers
+   (list
+    (dicod-handler
+     (name "wordnet")
+     (module "dictorg")
+     (options
+      '("dbdir=/gnu/store/xxxx-wordnet")))))
+  (databases
+   (list
+    (dicod-database
+     (name "wordnet")
+     (complex #t)
+     (handler "wordnet")
+     (options
+      '("database=wn")))
+    %dicod-database:gcide))))
+@end example
+
 @subsubsection Version Control
 
 The @code{(gnu services version-control)} module provides the following services:
diff --git a/gnu/services/dict.scm b/gnu/services/dict.scm
index 303067037..596f901f3 100644
--- a/gnu/services/dict.scm
+++ b/gnu/services/dict.scm
@@ -1,6 +1,7 @@
 ;;; GNU Guix --- Functional package management for GNU
 ;;; Copyright © 2016 Sou Bunnbu <[email-masked]>
 ;;; Copyright © 2016 Ludovic Courtès <[email-masked]>
+;;; Copyright © 2017 Huang Ying <[email-masked]>
 ;;;
 ;;; This file is part of GNU Guix.
 ;;;
@@ -32,6 +33,7 @@
   #:export (dicod-service
             dicod-service-type
             dicod-configuration
+            dicod-handler
             dicod-database
             %dicod-database:gcide))
 
@@ -46,21 +48,30 @@
   (dico        dicod-configuration-dico       (default dico))
   (interfaces  dicod-configuration-interfaces     ;list of strings
                (default '("localhost")))
-  (databases   dicod-configuration-databases
-               ;; list of <dicod-database>
+  (handlers    dicod-configuration-handlers       ;list of <dicod-handler>
+               (default '()))
+  (databases   dicod-configuration-databases      ;list of <dicod-database>
                (default (list %dicod-database:gcide))))
 
+(define-record-type* <dicod-handler>
+  dicod-handler make-dicod-handler
+  dicod-handler?
+  (name        dicod-handler-name)
+  (module      dicod-handler-module          (default #f))
+  (options     dicod-handler-options         (default '())))
+
 (define-record-type* <dicod-database>
   dicod-database make-dicod-database
   dicod-database?
   (name        dicod-database-name)
-  (module      dicod-database-module)
+  (handler     dicod-database-handler)
+  (complex     dicod-database-complex        (default #f))
   (options     dicod-database-options        (default '())))
 
 (define %dicod-database:gcide
   (dicod-database
    (name "gcide")
-   (module "gcide")
+   (handler "gcide")
    (options (list #~(string-append "dbdir=" #$gcide "/share/gcide")
                   "idxdir=/var/run/dicod"))))
 
@@ -76,22 +87,47 @@
          (shell (file-append shadow "/sbin/nologin")))))
 
 (define (dicod-configuration-file config)
+  (define handler->text
+    (match-lambda
+      (($ <dicod-handler> name #f '())
+       `("
+load-module " ,name ";"))
+      (($ <dicod-handler> name #f options)
+       (handler->text (dicod-handler
+                       (name name)
+                       (module name)
+                       (options options))))
+      (($ <dicod-handler> name module options)
+       `("
+load-module " ,name " {
+   command \"" ,module (string-join (list ,@options) " " 'prefix) "\";
+}\n"))))
+
   (define database->text
     (match-lambda
-      (($ <dicod-database> name module options)
+      (($ <dicod-database> name handler #f options)
+       (append
+        (handler->text (dicod-handler
+                        (name handler)))
+        (database->text (dicod-database
+                         (name name)
+                         (handler handler)
+                         (complex #t)
+                         (options options)))))
+      (($ <dicod-database> name handler complex options)
        `("
-load-module " ,module ";
 database {
    name \"" ,name "\";
-   handler \"" ,module
+   handler \"" ,handler
    (string-join (list ,@options) " " 'prefix) "\";
 }\n"))))
 
   (define configuration->text
     (match-lambda
-      (($ <dicod-configuration> dico (interfaces ...) databases)
+      (($ <dicod-configuration> dico (interfaces ...) handlers databases)
        (append `("listen ("
                  ,(string-join interfaces ", ") ");\n")
+               (append-map handler->text handlers)
                (append-map database->text databases)))))
 
   (apply mixed-text-file "dicod.conf" (configuration->text config)))
-- 
2.12.2