I wrote some code to manage a postgresql database, and it is working on the console. Now I wish to put it on my internal network via hunchentoot.
I use clsql and packaged the database code as:
(defpackage :my-database
(:use :common-lisp)
(:documentation "several lines...")
(:export almost-all-functions...))
(in-package #:my-database)
(defun new-patient (name gender height weight)
"adds new patient to the db. all parameters are of type string."
(let* ((height (parse-integer height))
(weight (parse-integer weight))
(corrected-weight (calculate-corrected-weight height weight gender)))
(clsql:insert-records :into 'patients
:attributes '(height weight corrected-weight name gender patient-at-ward)
:values (list height weight corrected-weight name gender t))))
I imported the my-database package, and when I use this handler:
(define-easy-handler (debug :uri "/debug")
(name gender height weight)
(let ((ad (substitute #\space #\+ (string-trim " " ad))))
(progn (format nil "Name:~A, Gender:~A, Height:~A, Weight:~A" name gender height weight)
(redirect "/success"))))
It displays the html just fine. But this handler:
(define-easy-handler (new-patient :uri "/new-patient")
(name gender height weight)
(let ((name (substitute #\space #\+ (string-trim " " name))))
(progn (my-database:new-patient name gender height weight)
(redirect "/success"))))
throws an error:
Incorrect keyword arguments in ("Frank Sinatra" "male" "150" "55")
I noticed that when I type (my-database:new-patient )
at the REPL, emacs command minibuffer shows (my-database:new-patient &key name gender height weight)
. The &key
part looked suspicious to me. Therefore I switched to my-database file, did slime-eval-last-expression-in-repl, which corrected the emacs command minibuffer display.
But this time, I got the following error:
Too few arguments in call to #<Compiled-function MY-DATABASE:NEW-PATIENT #x15870D76>:
0 arguments provided, at least 4 required.
And re-evaluating the hunchentoot handler caused emacs command minibuffer to show the &key again. Lastly, I changed the handler code to (my-database:new-patient :name name :gender gender :height height :weight weight)
, which throws this error:
8 arguments were provided, but at most 4 are accepted by the current global
definition of NEW-PATIENT
What may be the reason?
The reason is the semantics of define-easy-handler
:
The resulting handler will be a Lisp function with the name name and keyword parameters named by the var symbols.
(according to the hunchentoot documentation: http://weitz.de/hunchentoot/), so you should use a different name for the handler, for instance:
(define-easy-handler (do-new-patient :uri "/new-patient")
(name gender height weight)
(let ((name (substitute #\space #\+ (string-trim " " name))))
(progn (my-database:new-patient name gender height weight)
(redirect "/success"))))