scheme-dql/README.org

111 lines
4 KiB
Org Mode
Raw Normal View History

2025-06-27 13:20:24 +02:00
* scheme-dql
A library that exposes an interface for processing data, written as a proof of
concept for fixing SQL syntax in the same sense as how [[https://synthcode.com/scheme/irregex/][irregex]] fixed regular
expression syntax in a scheme way.
The data is in lists of alists stored and read by the calling application in the same
way as how json is used. [[https://github.com/aconchillo/guile-json][guile-json]] could be used to convert to and from json data.
The interface is implemented thru a macro that will compile the query lambda in
the calling code. That function is then called to execute the query on the data.
The idea is to have this as an [[https://sqlite.org/index.html][SQLite]] for scheme but implemented like a header
only library in c/c++ via the macro. Most of the logic is done by calling a function
supplied in the query to keep it simple but powerful.
This is still alpha software, only used in [[https://www.gnu.org/software/guile/][guile]] and not fully tested. The purpose is
to determine how feasible a polish noted data query language could be.
** License
You can redistribute and/or modify [[https://www.cor.za.net/code/scheme-dql][scheme-dql]] under the terms of the GNU
Affero General Public License as published by the Free Software Foundation,
version 3 of the License. Please see =COPYING= file for the terms of GNU Affero
General Public License.
** query language
Each method consist of a list with the first atom a symbol for the method like in
scheme, the second parameter is either the return from a sub query or the
``implied'' data fed thru the function call.
The ~<key-path>~ is multiple string values to follow in order to reach the final
association that contain the data to use.
*** Methods
**** filter
#+begin_src scheme
(filter ;; other query or implied data.
(where <callback> <key-path>))
#+end_src
This will return only the alists that return a ~#true~ from the ~where~ method.
All the where clauses are passed true an ~and~ to the where sub method.
**** sort
#+begin_src scheme
(sort ;; other query or implied data.
(by <callback> <key-path>))
#+end_src
The ~<callback>~ should be a function with two parameters that return
~#true~ if the first parameter should be before the second parameter
~#false~ otherwise.
**** alter
#+begin_src scheme
(alter ;; other query or implied data.
(where <callback> <key-path>)
(insert <data> <key>)
(update <data> <key>)
(drop <key>))
#+end_src
~where~ will act as a filter for application but the returned data is the full
alist, if you want to filter the data use the ~filter~ method.
- ~insert~ will call ~acons~ on the alist.
- ~update~ will call ~assoc-set!~ on the alist.
- ~drop~ will call ~assoc-remove!~ on the alist.
**** select
#+begin_src scheme
(select ;; other query or implied data.
(parm <key-path>)
(parm-as <key> <key-path>)
(parm-val <key-path>))
#+end_src
- ~parm~ will return the association as is.
- ~parm-as~ will return an assosiation with the value represented by the
path but the key will be the ~<key>~ paramter.
- ~parm-val~ will return only the value represented by the path.
*** sub methods
**** where
#+begin_src scheme
(where <callback> <key-path>)
(where (and (where <callback> <key-path>)
(or (where <callback> <key-path>)
(where <callback> <key-path>))))
#+end_src
The ~<callback>~ should be a function with a single parameter that return
~#true~ if the data in the parameter passes the filter and ~#false~ otherwise.
Boolean ~and~ and ~or~ combinations are allowed.
*** example
#+begin_src scheme
(use-modules (dql dql))
(define my-filter
(lambda (val)
(if (string=? val "test") #t #f)))
((dql (select (filter (where my-filter "name"))
(parm "name")
(parm-as "date" "created_at"))
#:print-query "test-query")
data)
#+end_src
** extras
*** write to file
#+begin_src scheme
(dql-write <data> <file-path>)
#+end_src
*** read from file
#+begin_src scheme
(dql-read <file-path>)
#+end_src