Skip to content

Commit

Permalink
add matching to kvquery->func, add query language documentation.
Browse files Browse the repository at this point in the history
  • Loading branch information
nicferrier committed Dec 28, 2012
1 parent f8c11b1 commit 446800f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 8 deletions.
7 changes: 6 additions & 1 deletion kv-tests.el
Expand Up @@ -84,7 +84,12 @@
(should
(equal
'("testkey" . "testvalue")
(kvassoq= 'testkey "testvalue" '(("testkey" . "testvalue"))))))
(kvassoq= 'testkey "testvalue" '(("testkey" . "testvalue")))))
;; The nil case, the key isn't present
(should
(equal
nil
(kvassoq= 'blah "testvalue" '(("testkey" . "testvalue"))))))

(ert-deftest kvalist2-filter ()
(should
Expand Down
41 changes: 34 additions & 7 deletions kv.el
Expand Up @@ -96,11 +96,34 @@ Returns the value looked up by KEY that passes, so normally:
(let ((v (kvassoqc key alist)))
(and v (equal (cdr v) value) v)))

(defun* kvquery->func (query &key (equal-func 'kvassoc))
(defun kvmatch (key regex alist)
"Test the value with KEY in ALIST matches REGEX."
(let ((v (kvassoqc key alist)))
(and v (string-match regex (cdr v)) v)))

(defun* kvquery->func (query &key
(equal-func 'kvassoc=)
(match-func 'kvmatch))
"Turn a simple QUERY expression into a filter function.
EQUAL-FUNC is the function that implements the equality
predicate."
predicate.
MATCH-FUNC is the function that implements the match predicate.
The query language is:
| a b - true if a or b is true
& a b - true only if a and b is true
= a b - true if a equals b as per the EQUAL-FUNC
~ a b - true if a matches b as per the MATCH-FUNC
So, for example:
(|(= a b)(= c d))
Means: if `a' equals `b', or if `c' equals `d' then the
expression is true."
(flet ((query-parse (query)
(let ((part (car query))
(rest (cdr query)))
Expand All @@ -113,6 +136,9 @@ predicate."
(cons 'and
(loop for i in rest
collect (query-parse i))))
((eq part '~)
(destructuring-bind (field value) rest
(list match-func field value (quote record))))
((eq part '=)
(destructuring-bind (field value) rest
(list equal-func field value (quote record))))))))
Expand Down Expand Up @@ -190,11 +216,12 @@ Only pairs where the car is a `member' of KEYS will be returned."
"Filter the plist to just those matching KEYS.
`kvalist->filter-keys' is actually used to do this work."
(let ((symkeys (loop for k in keys
collect (let ((strkey (symbol-name k)))
(if (equal (substring strkey 0 1) ":")
(intern (substring strkey 1))
k)))))
(let ((symkeys
(loop for k in keys
collect (let ((strkey (symbol-name k)))
(if (equal (substring strkey 0 1) ":")
(intern (substring strkey 1))
k)))))
(kvalist->plist
(apply
'kvalist->filter-keys
Expand Down

0 comments on commit 446800f

Please sign in to comment.