refactored database-get-type-specifier for postgres and mssql
authorRuss Tyndall <russ@acceleration.net>
Tue, 18 Jun 2013 15:40:46 +0000 (11:40 -0400)
committerRuss Tyndall <russ@acceleration.net>
Tue, 18 Jun 2013 15:44:12 +0000 (11:44 -0400)
 * Single methods with a case on the symbol arg (similar to the recent
   refactoring in oodml.lisp)

 * This reduces line count and generally makes it easier to find and
   read all the backend-specific types

ChangeLog
sql/generic-odbc.lisp
sql/generic-postgresql.lisp
sql/oodml.lisp
tests/test-fddl.lisp

index 31f2432..c0e7c5c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2013-06-18 Russ Tyndall <russ@acceleration.net>
+        * sql/generic-odbc.lisp, sql/generic-postgresql.lisp, sql/oodml.lisp
+         tests/test-fddl.lisp
+
+       refactored database-get-type-specifier for postgres and mssql
+
+        Single methods with a case on the symbol arg (similar to the recent
+        refactoring in oodml.lisp)
+
+        This reduces line count and generally makes it easier to find and
+        read all the backend-specific types
+
 2013-06-10 Russ Tyndall <russ@acceleration.net>
         * sql/oodml.lisp, sql/generic-postgresql.lisp, doc/ref-fddl.xml,
          sql/packages.lisp
index 4995c25..60c5d93 100644 (file)
 
 ;;; Type methods
 
-(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database
+(defmethod database-get-type-specifier ((type symbol) args database
                                         (db-type (eql :mssql)))
-  (declare (ignore args database))
-  "DATETIME")
-
-(defmethod database-get-type-specifier ((type (eql 'date)) args database
-                                        (db-type (eql :mssql)))
-  (declare (ignore args database))
-  "SMALLDATETIME")
-
-(defmethod database-get-type-specifier ((type (eql 'boolean)) args database
-                                        (db-type (eql :mssql)))
-  (declare (ignore args database))
-  "BIT")
-
-(defmethod database-get-type-specifier ((type (eql 'generalized-boolean)) args database
-                                        (db-type (eql :mssql)))
-  (declare (ignore args database))
-  "BIT")
+  "Special database types for MSSQL backends"
+  (declare (ignore database db-type args))
+  (case type
+    (wall-time "DATETIME")
+    (date "SMALLDATETIME")
+    ((generalized-boolean boolean) "BIT")
+    ((longchar text) "ntext")
+    ((varchar string)
+     (if args
+         (format nil "NVARCHAR(~A)" (car args))
+         (format nil "NVARCHAR(~D)" *default-string-length*)))
+    (t (call-next-method))))
 
 ;;; Generation of SQL strings from lisp expressions
 
index feeaced..61d7e15 100644 (file)
 
 ;; Object functions
 
-(defmethod database-get-type-specifier (type args database
+(defmethod database-get-type-specifier ((type symbol) args database
                                         (db-type (eql :postgresql)))
-  (warn "Could not determine a valid :postgresqlsql type specifier for ~A ~A ~A, defaulting to VARCHAR "
-        type args database)
-  "VARCHAR")
-
-(defmethod database-get-type-specifier ((type (eql 'string)) args database
-                                        (db-type (eql :postgresql)))
-  (declare (ignore database))
-  (if args
-      (format nil "CHAR(~A)" (car args))
-    "VARCHAR"))
-
-(defmethod database-get-type-specifier ((type (eql 'tinyint)) args database
-                                        (db-type (eql :postgresql)))
-  (declare (ignore args database))
-  "INT2")
-
-(defmethod database-get-type-specifier ((type (eql 'smallint)) args database
-                                        (db-type (eql :postgresql)))
-  (declare (ignore args database))
-  "INT2")
-
-(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database
-                                        (db-type (eql :postgresql)))
-  (declare (ignore args database))
-  "TIMESTAMP WITHOUT TIME ZONE")
-
-(defmethod database-get-type-specifier ((type (eql 'number)) args database
-                                        (db-type (eql :postgresql)))
-  (declare (ignore database))
-  (cond
-   ((and (consp args) (= (length args) 2))
-    (format nil "NUMERIC(~D,~D)" (first args) (second args)))
-   ((and (consp args) (= (length args) 1))
-    (format nil "NUMERIC(~D)" (first args)))
-   (t
-    "NUMERIC")))
+  "Special database types for POSTGRESQL backends"
+  (declare (ignore database db-type))
+  (case type
+    (wall-time ;; TODO: why is this WITHOUT...
+     "TIMESTAMP WITHOUT TIME ZONE")
+    (string
+     ;; TODO: the default to CHAR here seems specious as the PG docs claim
+     ;; that char is slower than varchar
+     (if args
+         (format nil "CHAR(~A)" (car args))
+         "VARCHAR"))
+    (number
+     (cond
+       ((and (consp args) (= (length args) 2))
+        (format nil "NUMERIC(~D,~D)" (first args) (second args)))
+       ((and (consp args) (= (length args) 1))
+        (format nil "NUMERIC(~D)" (first args)))
+       (t "NUMERIC")))
+    ((tinyint smallint) "INT2")
+    (t (call-next-method))))
 
 ;;; Backend functions
 
index 2a15e30..fd59241 100644 (file)
   (declare (ignore args database db-type))
   type)
 
+
 (defmethod database-get-type-specifier ((type symbol) args database db-type)
   (case type
     (char (if args
index 8a6ae88..83eada9 100644 (file)
@@ -168,7 +168,8 @@ B varchar(32))")
     (with-dataset *ds-fddl*
       (multiple-value-bind (type length scale nullable)
          (clsql:attribute-type [c] [alpha])
-       (values (clsql-sys:in type :varchar :varchar2) length scale nullable)))
+       (values (clsql-sys:in type :varchar :varchar2 :nvarchar)
+                length scale nullable)))
   t 30 nil 1)
 
 (deftest :fddl/attributes/5