I'm trying to build a function to access records in a database as such:
(select :title "milk" :rating 7)
However, it's just returning all of the records in the database. I believe this is because I'm passing &rest
arguments to a macro and it's interpreting the parameter name "fields" literally. I've tried removing &rest
from my macro, but then I get an error about not passing a list. I've tried calling (list fields) in various places to no avail (in the macro, in the function that calls the macro, in the function that the macro calls).
The following code works as expected:
(select-custom (where :title "milk" :rating 7))
And returns only the records which match the arguments.
source code:
(defun select (&rest fields)
(select-custom (where fields)))
(defun select-custom (selector-function)
(remove-if-not selector-function *db*))
(defmacro where (&rest fields)
`#'(lambda (cd) (and ,@(make-comparison-list fields))))
(defun make-comparison-list (fields)
(loop while fields
collecting (make-comparison-exp (pop fields) (pop fields))))
(defun make-comparison-exp (field value)
`(equal (getf cd ,field) ,value))
You could just make select
a macro instead
(defmacro select (&rest fields)
`(select-custom (where ,@fields)))
You can check that
(macroexpand-1 '(select :title "milk" :rating 7))
returns
(SELECT-CUSTOM (WHERE :TITLE "milk" :RATING 7))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With