X-Git-Url: http://git.kpe.io/?p=clsql.git;a=blobdiff_plain;f=sql%2Fsyntax.lisp;h=4ec07f5f2ce4ae193fe682754882f2343ea98c01;hp=c0e8487ba1edc355e78303ff8260cad0d17143c7;hb=dc107d34212597ed1272cfa21138d384e71b00d2;hpb=ef0416dafb56478c481275abc9325e1ba59ef22f diff --git a/sql/syntax.lisp b/sql/syntax.lisp index c0e8487..4ec07f5 100644 --- a/sql/syntax.lisp +++ b/sql/syntax.lisp @@ -1,8 +1,6 @@ ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; -;;;; $Id$ -;;;; ;;;; CLSQL square bracket symbolic query syntax. Functions for ;;;; enabling and disabling the syntax and for building SQL ;;;; expressions using the syntax. @@ -16,9 +14,7 @@ (in-package #:clsql-sys) -(defvar *original-reader-enter* nil) - -(defvar *original-reader-exit* nil) +(defvar *original-readtable* nil) (defvar *sql-macro-open-char* #\[) @@ -45,10 +41,9 @@ the current syntax state." (%disable-sql-reader-syntax))) (defun %disable-sql-reader-syntax () - (when *original-reader-enter* - (set-macro-character *sql-macro-open-char* *original-reader-enter*)) - (when *original-reader-exit* - (set-macro-character *sql-macro-close-char* *original-reader-exit*)) + (when *original-readtable* + (setf *readtable* *original-readtable* + *original-readtable* nil)) (values)) @@ -69,13 +64,20 @@ the current syntax state." '(eval-when (:compile-toplevel :load-toplevel :execute) (%enable-sql-reader-syntax))) +(defmacro file-enable-sql-reader-syntax () + "Turns on the SQL reader syntax for the rest of the file. +The CL spec says that when finished loading a file the original +*readtable* is restored. clhs COMPILE-FILE" + '(eval-when (:compile-toplevel :load-toplevel :execute) + (setf *readtable* (copy-readtable)) + (set-macro-character *sql-macro-open-char* #'sql-reader-open) + (set-macro-character *sql-macro-close-char* (get-macro-character #\))))) + (defun %enable-sql-reader-syntax () - (unless (eq (get-macro-character *sql-macro-open-char*) #'sql-reader-open) - (setf *original-reader-enter* (get-macro-character *sql-macro-open-char*)) - (set-macro-character *sql-macro-open-char* #'sql-reader-open)) - (unless (eq (get-macro-character *sql-macro-close-char*) - (get-macro-character #\))) - (setf *original-reader-exit* (get-macro-character *sql-macro-close-char*)) + (unless *original-readtable* + (setf *original-readtable* *readtable* + *readtable* (copy-readtable)) + (set-macro-character *sql-macro-open-char* #'sql-reader-open) (set-macro-character *sql-macro-close-char* (get-macro-character #\)))) (values)) @@ -94,42 +96,42 @@ reader syntax is disabled." (let ((sqllist (read-delimited-list #\] stream t))) (unless *read-suppress* (handler-case - (cond ((string= (write-to-string (car sqllist)) "||") - (cons (sql-operator 'concat-op) (cdr sqllist))) - ((and (= (length sqllist) 1) (eql (car sqllist) '*)) - (apply #'generate-sql-reference sqllist)) - ((sql-operator (car sqllist)) - (cons (sql-operator (car sqllist)) (cdr sqllist))) - (t (apply #'generate-sql-reference sqllist))) - (sql-user-error (c) - (error 'sql-user-error - :message (format nil "Error ~A occured while attempting to parse '~A' at file position ~A" - (sql-user-error-message c) sqllist (file-position stream)))))))) + (cond ((string= (write-to-string (car sqllist)) "||") + (cons (sql-operator 'concat-op) (cdr sqllist))) + ((and (= (length sqllist) 1) (eql (car sqllist) '*)) + (apply #'generate-sql-reference sqllist)) + ((sql-operator (car sqllist)) + (cons (sql-operator (car sqllist)) (cdr sqllist))) + (t (apply #'generate-sql-reference sqllist))) + (sql-user-error (c) + (error 'sql-user-error + :message (format nil "Error ~A occured while attempting to parse '~A' at file position ~A" + (sql-user-error-message c) sqllist (file-position stream)))))))) (defun generate-sql-reference (&rest arglist) - (cond ((= (length arglist) 1) ; string, table or attribute - (if (stringp (car arglist)) - (sql-expression :string (car arglist)) + (cond ((= (length arglist) 1) ; string, table or attribute + (if (stringp (car arglist)) + (sql-expression :string (car arglist)) (sql-expression :attribute (car arglist)))) - ((<= 2 (length arglist)) - (let ((sqltype (when (keywordp (caddr arglist)) (caddr arglist) nil))) + ((<= 2 (length arglist)) + (let ((sqltype (when (keywordp (caddr arglist)) (caddr arglist) nil))) (cond ((stringp (cadr arglist)) - (sql-expression :table (car arglist) - :alias (cadr arglist) - :type sqltype)) - ((keywordp (cadr arglist)) - (sql-expression :attribute (car arglist) - :type (cadr arglist))) - (t - (sql-expression :attribute (cadr arglist) - :table (car arglist) - :type sqltype))))) - (t - (error 'sql-user-error :message "bad expression syntax")))) - - -;; Exported functions for dealing with SQL syntax + (sql-expression :table (car arglist) + :alias (cadr arglist) + :type sqltype)) + ((keywordp (cadr arglist)) + (sql-expression :attribute (car arglist) + :type (cadr arglist))) + (t + (sql-expression :attribute (cadr arglist) + :table (car arglist) + :type sqltype))))) + (t + (error 'sql-user-error :message "bad expression syntax")))) + + +;; Exported functions for dealing with SQL syntax (defun sql (&rest args) "Returns an SQL string generated from the expressions ARGS. The @@ -153,7 +155,7 @@ keyword arguments is specified." (string (make-instance 'sql :string string)) (attribute - (make-instance 'sql-ident-attribute :name attribute + (make-instance 'sql-ident-attribute :name attribute :qualifier (or table alias) :type type)) ((and table (not attribute)) @@ -181,8 +183,8 @@ function and the remaining values in ARGS its arguments as strings." (if (sql-operator operator) (apply (symbol-function (sql-operator operator)) args) - (error 'sql-user-error - :message + (error 'sql-user-error + :message (format nil "~A is not a recognized SQL operator." operator))))