Major rewrite of table/column name output escaping system wide.
[clsql.git] / sql / utils.lisp
index fe5a24ce63aa930444708a10bbc233d929b49c67..b43e3180e64f6f8d392446229660c6eed1caaab1 100644 (file)
@@ -7,9 +7,7 @@
 ;;;; Programmer:   Kevin M. Rosenberg
 ;;;; Date Started: Mar 2002
 ;;;;
-;;;; $Id$
-;;;;
-;;;; This file, part of CLSQL, is Copyright (c) 2002-2004 by Kevin M. Rosenberg
+;;;; This file, part of CLSQL, is Copyright (c) 2002-2010 by Kevin M. Rosenberg
 ;;;;
 ;;;; CLSQL users are granted the rights to distribute and use this software
 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
 
 (in-package #:clsql-sys)
 
+(defvar +whitespace-chars+
+  '(#\space #\tab #\newline #\return
+    ;; Tested: sbcl unicode, allegrocl, openmcl,clisp use #\no-break_space
+    ;; lispworks uses #\no-break-space
+    ;; sbcl non-unicode doesn't support no break space
+    ;; AllegroCL 8-bit strings don't fail on reading #\no-break_space,
+    ;; but can't represent such a character
+    ;; CMUCL errors when trying to read #\no-break_space
+    #+(and lispworks unicode) #\no-break-space
+    #+(or (and sbcl sb-unicode) (and allegro ics) (and clisp i18n)
+       (and openmcl openmcl-unicode-strings))
+    #\no-break_space
+    )
+  "List of whitespace characters for this lisp implementation.")
+
 (defun number-to-sql-string (num)
   (etypecase num
     (integer
@@ -353,7 +366,7 @@ list of characters and replacement strings."
     (string-upcase str)))
 
 (defun ensure-keyword (name)
-  "Returns keyword for a name"
+  "Returns keyword for a name."
   (etypecase name
     (keyword name)
     (string (nth-value 0 (intern (symbol-name-default-case name) :keyword)))
@@ -362,3 +375,20 @@ list of characters and replacement strings."
 (eval-when (:compile-toplevel :load-toplevel :execute)
   (setq cl:*features* (delete :clsql-lowercase-reader cl:*features*)))
 
+(defun replace-all (string part replacement &key (test #'char=) stream)
+  "Returns a new string in which all the occurences of the part 
+is replaced with replacement. [FROM http://cl-cookbook.sourceforge.net/strings.html#manip]"
+  (let ((out (or stream (make-string-output-stream))))
+    (loop with part-length = (length part)
+         for old-pos = 0 then (+ pos part-length)
+         for pos = (search part string
+                           :start2 old-pos
+                           :test test)
+         do (write-string string out
+                  :start old-pos
+                  :end (or pos (length string)))
+         when pos do (write-string replacement out)
+           while pos)
+    (unless stream
+      (get-output-stream-string out))))
+