septeql

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit 1c5e559f907c867fae6c09b7b09c5b347de8e7e0
parent 0d8907b5e851e084ed4fc420d00d69f67df16323
Author: septeql <septeql@telent.net>
Date:   Tue,  7 Aug 2007 15:30:36 +0000

add translation for sql CASE
Diffstat:
Msepteql.lisp | 19+++++++++++++++----
1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/septeql.lisp b/septeql.lisp @@ -70,6 +70,21 @@ interpolated into a SQL statement as a string literal" (define-scalar-translator as (column-expr alias) (format nil "~A AS ~A" (translate-scalar column-expr) (lisp-to-sql-name alias))) +(define-scalar-translator case (&rest clauses) + (with-output-to-string (o) + (princ "(CASE " o) + (loop for (expr result) in clauses + if (and (symbolp expr) (member expr '(t else) :test #'string-equal)) + do (format o "ELSE ~A " (translate-scalar result)) + else do (format o "WHEN ~A THEN ~A " + (translate-scalar expr) + (translate-scalar result))) + (princ "END) " o))) + +;; SQL's CASE is more like CL's COND, so define the latter as an alias +(define-scalar-translator cond (&rest clauses) + (translate-scalar `(case ,@clauses))) + ;;; we *could* use the zero-length symbol for string concatenation, ;;; relying on the printer to render it as ``||'', but that's arguably ;;; kinda tacky. So, ++ for sticking strings together @@ -166,8 +181,6 @@ interpolated into a SQL statement as a string literal" `(rename ,(sv sql 'from) ,name)) sql)))) - - (defun min~ (&rest args) (let ((real-args (remove-if #'not args))) (and (car real-args) (apply #'min real-args)))) @@ -208,7 +221,6 @@ interpolated into a SQL statement as a string literal" (translate-scalar (fourth from)))) (t (error "buggered if I know")))) - (defun as-string (sql) (with-output-to-string (s) (format s "SELECT ~{~A~^,~} " @@ -231,4 +243,3 @@ interpolated into a SQL statement as a string literal" (defun to-sql (relation) (as-string (parse-relation relation))) -