use with-output-to-string instead of progv
[clsql.git] / sql / expressions.lisp
index bee6faffafa22dfc543255d3892890a2ce4736cd..cb8046fb09b6fb9e38bfbac3a14d8f38a8c4bf13 100644 (file)
   "Top-level call for generating SQL strings. Returns an SQL
   string appropriate for DATABASE which corresponds to the
   supplied lisp expression SQL-EXPR."
-  (progv '(*sql-stream*)
-      `(,(make-string-output-stream))
-    (output-sql sql-expr database)
-    (get-output-stream-string *sql-stream*)))
+  (with-output-to-string (*sql-stream*)
+    (output-sql sql-expr database)))
 
 (defmethod output-sql (expr database)
   (write-string (database-output-sql expr database) *sql-stream*)
 
 
 (defvar *output-hash*
-  #+sbcl
-  (make-hash-table :test #'equal :synchronized T :weakness :key-and-value)
-  #-sbcl
-  (make-hash-table :test #'equal )
-  "For caching generated SQL strings.")
+      (make-weak-hash-table :test #'equal)
+  "For caching generated SQL strings, set to NIL to disable."
+  )
 
 (defmethod output-sql :around ((sql t) database)
   (if (null *output-hash*)
@@ -675,6 +671,20 @@ uninclusive, and the args from that keyword to the end."
                            :group-by group-by :having having :order-by order-by
                            :inner-join inner-join :on on))))))
 
+(defun output-sql-where-clause (where database)
+  "ensure that we do not output a \"where\" sql keyword when we will
+    not output a clause. Also sets *in-subselect* to use SQL
+    parentheticals as needed."
+  (when where
+    (let ((where-out (string-trim
+                     '(#\newline #\space #\tab #\return)
+                     (with-output-to-string (*sql-stream*)
+                       (let ((*in-subselect* t))
+                         (output-sql where database))))))
+      (when (> (length where-out) 0)
+       (write-string " WHERE " *sql-stream*)
+       (write-string where-out *sql-stream*)))))
+
 (defmethod output-sql ((query sql-query) database)
   (with-slots (distinct selections from where group-by having order-by
                         limit offset inner-join on all set-operation)
@@ -714,15 +724,7 @@ uninclusive, and the args from that keyword to the end."
     (when on
       (write-string " ON " *sql-stream*)
       (output-sql on database))
-    (when where
-      (let ((where-out (string-trim
-                        '(#\newline #\space #\tab #\return)
-                        (with-output-to-string (*sql-stream*)
-                          (let ((*in-subselect* t))
-                            (output-sql where database))))))
-        (when (> (length where-out) 0)
-          (write-string " WHERE " *sql-stream*)
-          (write-string where-out *sql-stream*))))
+    (output-sql-where-clause where database)
     (when group-by
       (write-string " GROUP BY " *sql-stream*)
       (if (listp group-by)
@@ -809,7 +811,8 @@ uninclusive, and the args from that keyword to the end."
       (output-sql attributes database))
     (when values
       (write-string " VALUES " *sql-stream*)
-      (output-sql values database))
+      (let ((clsql-sys::*in-subselect* t))
+        (output-sql values database)))
     (when query
       (write-char #\Space *sql-stream*)
       (output-sql query database)))
@@ -834,9 +837,7 @@ uninclusive, and the args from that keyword to the end."
     (typecase from
       ((or symbol string) (write-string (sql-escape from) *sql-stream*))
       (t  (output-sql from database)))
-    (when where
-      (write-string " WHERE " *sql-stream*)
-      (output-sql where database)))
+    (output-sql-where-clause where database))
   t)
 
 ;; UPDATE
@@ -868,10 +869,9 @@ uninclusive, and the args from that keyword to the end."
       (write-string "UPDATE " *sql-stream*)
       (output-sql table database)
       (write-string " SET " *sql-stream*)
-      (output-sql (apply #'vector (update-assignments)) database)
-      (when where
-        (write-string " WHERE " *sql-stream*)
-        (output-sql where database))))
+      (let ((clsql-sys::*in-subselect* t))
+        (output-sql (apply #'vector (update-assignments)) database))
+      (output-sql-where-clause where database)))
   t)
 
 ;; CREATE TABLE
@@ -939,7 +939,7 @@ uninclusive, and the args from that keyword to the end."
       (when (and (eq :mysql (database-underlying-type database))
                  transactions
                  (db-type-transaction-capable? :mysql database))
-        (write-string " Type=InnoDB" *sql-stream*))))
+        (write-string " ENGINE=innodb" *sql-stream*))))
   t)