r9447: * sql/*.lisp: Add db-type parameter to generic functions READ-SQL...
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 23 May 2004 07:56:26 +0000 (07:56 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sun, 23 May 2004 07:56:26 +0000 (07:56 +0000)
        DATABASE-GET-TYPE-SPECIFIER, and OUTPUT-SQL-VALUE-AS-TYPE. Update methods to use these.
        * sql/generic-postgresql.lisp, sql/generic-odbc.lisp: New files

16 files changed:
ChangeLog
clsql.asd
db-aodbc/aodbc-sql.lisp
db-mysql/mysql-objects.lisp
db-odbc/odbc-sql.lisp
db-oracle/oracle-objects.lisp
db-postgresql-socket/postgresql-socket-sql.lisp
db-postgresql/postgresql-sql.lisp
sql/classes.lisp
sql/db-interface.lisp
sql/generic-odbc.lisp [new file with mode: 0644]
sql/generic-postgresql.lisp [new file with mode: 0644]
sql/generics.lisp
sql/objects.lisp
sql/package.lisp
tests/test-init.lisp

index c3143fc69a89462683f295243a7abd559e37f687..c3df25c559bd9071c1721eb588ba8a8dc9217887 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,8 @@
 22 May 2004 Kevin Rosenberg
        * Version 2.10.21 released
 22 May 2004 Kevin Rosenberg
        * Version 2.10.21 released
+       * sql/*.lisp: Add db-type parameter to generic functions READ-SQL-VALUE,
+       DATABASE-GET-TYPE-SPECIFIER, and OUTPUT-SQL-VALUE-AS-TYPE. Update methods to use these.
+       * sql/generic-postgresql.lisp, sql/generic-odbc.lisp: New files
        * sql/classes.lisp: honor case of string tables when outputting queries 
        * sql/objects.lisp: Add database type to default database-get-type-specifier method
        * sql/sql.lisp:  Add database type to default database-abort-transaction method
        * sql/classes.lisp: honor case of string tables when outputting queries 
        * sql/objects.lisp: Add database type to default database-get-type-specifier method
        * sql/sql.lisp:  Add database type to default database-abort-transaction method
index e891452f4ac21ee1006569f96da7b64508ce57d1..bc128ace30178ac20b640245c31da3fb61eb2a84 100644 (file)
--- a/clsql.asd
+++ b/clsql.asd
@@ -65,6 +65,11 @@ oriented interface."
                        :pathname ""
                       :components ((:file "metaclasses")
                                    (:file "objects" :depends-on ("metaclasses")))
                        :pathname ""
                       :components ((:file "metaclasses")
                                    (:file "objects" :depends-on ("metaclasses")))
+                      :depends-on (:functional))
+              (:module :generic
+                       :pathname ""
+                      :components ((:file "generic-postgresql")
+                                   (:file "generic-odbc"))
                       :depends-on (:functional))))))
      
 
                       :depends-on (:functional))))))
      
 
index 060db96d844d8d98c97c529ec3962292617e6d00..4d83206945bb5b9881d06f21e88afbd6cb6829d8 100644 (file)
@@ -33,7 +33,7 @@
 
 ;; AODBC interface
 
 
 ;; AODBC interface
 
-(defclass aodbc-database (database)
+(defclass aodbc-database (generic-odbc-database)
   ((aodbc-conn :accessor database-aodbc-conn :initarg :aodbc-conn)
    (aodbc-db-type :accessor database-aodbc-db-type :initform :unknown)))
 
   ((aodbc-conn :accessor database-aodbc-conn :initarg :aodbc-conn)
    (aodbc-db-type :accessor database-aodbc-db-type :initform :unknown)))
 
index ae24cac37abd2910832c2cf1c528213f145e98ad..bbe52324fe2d0466849e51f49c741f5c02dac7ca 100644 (file)
 
 (in-package #:clsql-mysql)
 
 
 (in-package #:clsql-mysql)
 
-(defmethod database-get-type-specifier ((type (eql 'wall-time)) args (database mysql-database))
-  (declare (ignore args))
+(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database
+                                       (db-type (eql :mysql)))
+  (declare (ignore args database))
   "DATETIME")
 
   "DATETIME")
 
-(defmethod database-output-sql-as-type ((type (eql 'boolean)) val (database mysql-database))
+(defmethod database-output-sql-as-type ((type (eql 'boolean)) val database
+                                       (db-type (eql :mysql)))
+  (declare (ignore database))
   (if val 1 0))
 
   (if val 1 0))
 
-(defmethod read-sql-value (val (type (eql 'boolean)) (database mysql-database))
+(defmethod read-sql-value (val (type (eql 'boolean)) database
+                          (db-type (eql :mysql)))
+  (declare (ignore database)) 
   (etypecase val
     (string (if (string= "0" val) nil t))
     (integer (if (zerop val) nil t))))
   (etypecase val
     (string (if (string= "0" val) nil t))
     (integer (if (zerop val) nil t))))
index 227c217c4392810866a447451eac104065e913ed..0ed1ebeb5042712d8f1d200cc3c07d90b86aafaf 100644 (file)
@@ -25,7 +25,7 @@
 
 ;; ODBC interface
 
 
 ;; ODBC interface
 
-(defclass odbc-database (database)
+(defclass odbc-database (generic-odbc-database)
   ((odbc-conn :accessor database-odbc-conn :initarg :odbc-conn)
    (odbc-db-type :accessor database-odbc-db-type)))
 
   ((odbc-conn :accessor database-odbc-conn :initarg :odbc-conn)
    (odbc-db-type :accessor database-odbc-db-type)))
 
index b4467ca0da792c26982050b40b485b9dc57c601f..5f2651593a5b63fc867433439a63f2a3d6d3e624 100644 (file)
 
 (defparameter *oracle-default-varchar2-length* "512")
 
 
 (defparameter *oracle-default-varchar2-length* "512")
 
-(defmethod database-get-type-specifier (type args (database oracle-database))
-  (declare (ignore type args))
+(defmethod database-get-type-specifier (type args database (db-type (eql :oracle)))
+  (declare (ignore type args database))
   (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")"))
 
   (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")"))
 
-(defmethod database-get-type-specifier ((type (eql 'integer)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'integer)) args 
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database))
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 0))
     "INTEGER"))
 
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 0))
     "INTEGER"))
 
-(defmethod database-get-type-specifier ((type (eql 'bigint)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'bigint)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 0))
     "NUMBER(38,0)"))
 
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 0))
     "NUMBER(38,0)"))
 
-(defmethod database-get-type-specifier ((type (eql 'simple-base-string)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'simple-base-string)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
-(defmethod database-get-type-specifier ((type (eql 'simple-string)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'simple-string)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
-(defmethod database-get-type-specifier ((type (eql 'string)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'string)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
-(defmethod database-get-type-specifier ((type (eql 'raw-string)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'raw-string)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
   (if args
       (format nil "VARCHAR2(~A)" (car args))
     (concatenate 'string "VARCHAR2(" *oracle-default-varchar2-length* ")")))
 
-(defmethod database-get-type-specifier ((type (eql 'float)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'float)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "NUMBER(~A,~A)" (or (first args) 38) (or (second args) 38))
     "double precision"))
 
   (if args
       (format nil "NUMBER(~A,~A)" (or (first args) 38) (or (second args) 38))
     "double precision"))
 
-(defmethod database-get-type-specifier ((type (eql 'long-float)) args (database oracle-database))
+(defmethod database-get-type-specifier ((type (eql 'long-float)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore database)) 
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 38))
     "double precision"))
 
   (if args
       (format nil "NUMBER(~A,~A)"
              (or (first args) 38) (or (second args) 38))
     "double precision"))
 
-(defmethod database-get-type-specifier ((type (eql 'boolean)) args (database oracle-database))
-  (declare (ignore args))
+(defmethod database-get-type-specifier ((type (eql 'boolean)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore args database))
   "CHAR(1)")
 
   "CHAR(1)")
 
-(defmethod read-sql-value (val type (database oracle-database))
+(defmethod read-sql-value (val type
+                          database (db-type (eql :oracle)))
   ;;(format t "value is \"~A\" of type ~A~%" val (type-of val))
   ;;(format t "value is \"~A\" of type ~A~%" val (type-of val))
-  (declare (ignore type))
+  (declare (ignore type database))
   (etypecase val
     (string
      (read-from-string val))
     (symbol
      nil)))
 
   (etypecase val
     (string
      (read-from-string val))
     (symbol
      nil)))
 
-(defmethod read-sql-value
-  (val (type (eql 'integer)) (database oracle-database))
+(defmethod read-sql-value (val (type (eql 'integer))
+                          database (db-type (eql :oracle)))
+  (declare (ignore database))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'float)) (database oracle-database))
+(defmethod read-sql-value (val (type (eql 'float))
+                          database (db-type (eql :oracle)))
+  (declare (ignore database))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'boolean)) (database oracle-database))
+(defmethod read-sql-value (val (type (eql 'boolean))
+                          database (db-type (eql :oracle)))
+  (declare (ignore database))
   (when (char-equal #\t (schar val 0))
     t))
 
   (when (char-equal #\t (schar val 0))
     t))
 
-(defmethod database-get-type-specifier ((type (eql 'wall-time)) args (database oracle-database))
-  (declare (ignore args))
+(defmethod database-get-type-specifier ((type (eql 'wall-time)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore args database))
   "DATE")
 
   "DATE")
 
-(defmethod database-get-type-specifier ((type (eql 'duration)) args (database oracle-database))
-  (declare (ignore args))
+(defmethod database-get-type-specifier ((type (eql 'duration)) args
+                                       database (db-type (eql :oracle)))
+  (declare (ignore args database))
   "NUMBER(38)")
   "NUMBER(38)")
index 0bfc01b5a025796d259c92fc52b17dbc8490b080..f4c1250181ccce5f569e08d83a4f7fc95bfe56e3 100644 (file)
@@ -143,7 +143,7 @@ doesn't depend on UFFI."
                                               (eql :postgresql-socket)))
   t)
 
                                               (eql :postgresql-socket)))
   t)
 
-(defclass postgresql-socket-database (database)
+(defclass postgresql-socket-database (generic-postgresql-database)
   ((connection :accessor database-connection :initarg :connection
               :type postgresql-connection)))
 
   ((connection :accessor database-connection :initarg :connection
               :type postgresql-connection)))
 
@@ -323,148 +323,6 @@ doesn't depend on UFFI."
            (setf (postgresql-socket-result-set-done result-set) t)
            (wait-for-query-results (database-connection database)))))))
 
            (setf (postgresql-socket-result-set-done result-set) t)
            (wait-for-query-results (database-connection database)))))))
 
-;;; Object listing
-
-(defun owner-clause (owner)
-  (cond 
-   ((stringp owner)
-    (format
-     nil
-     " AND (relowner=(SELECT usesysid FROM pg_user WHERE (usename='~A')))" 
-     owner))
-   ((null owner)
-    (format nil " AND (NOT (relowner=1))"))
-   (t "")))
-
-(defun database-list-objects-of-type (database type owner)
-  (mapcar #'car
-         (database-query
-          (format nil
-                  "SELECT relname FROM pg_class WHERE (relkind = '~A')~A"
-                  type
-                  (owner-clause owner))
-          database nil nil)))
-
-(defmethod database-list-tables ((database postgresql-socket-database)
-                                 &key (owner nil))
-  (database-list-objects-of-type database "r" owner))
-  
-(defmethod database-list-views ((database postgresql-socket-database)
-                                &key (owner nil))
-  (database-list-objects-of-type database "v" owner))
-  
-(defmethod database-list-indexes ((database postgresql-socket-database)
-                                  &key (owner nil))
-  (database-list-objects-of-type database "i" owner))
-
-(defmethod database-list-table-indexes (table
-                                       (database postgresql-socket-database)
-                                       &key (owner nil))
-  (let ((indexrelids
-        (database-query
-         (format 
-          nil
-          "select indexrelid from pg_index where indrelid=(select relfilenode from pg_class where relname='~A'~A)"
-          (string-downcase table)
-          (owner-clause owner))
-         database :auto nil))
-       (result nil))
-    (dolist (indexrelid indexrelids (nreverse result))
-      (push 
-       (caar (database-query
-             (format nil "select relname from pg_class where relfilenode='~A'"
-                     (car indexrelid))
-             database nil nil))
-       result))))
-
-(defmethod database-list-attributes ((table string)
-                                    (database postgresql-socket-database)
-                                     &key (owner nil))
-  (let* ((owner-clause
-          (cond ((stringp owner)
-                 (format nil " AND (relowner=(SELECT usesysid FROM pg_user WHERE usename='~A'))" owner))
-                ((null owner) " AND (not (relowner=1))")
-                (t "")))
-         (result
-         (mapcar #'car
-                 (database-query
-                  (format nil "SELECT attname FROM pg_class,pg_attribute WHERE pg_class.oid=attrelid AND relname='~A'~A"
-                           (string-downcase table)
-                           owner-clause)
-                   database nil nil))))
-    (if result
-        (remove-if #'(lambda (it) (member it '("cmin"
-                                               "cmax"
-                                               "xmax"
-                                               "xmin"
-                                               "oid"
-                                               "ctid"
-                                               ;; kmr -- added tableoid
-                                               "tableoid") :test #'equal)) 
-                   result))))
-
-(defmethod database-attribute-type (attribute (table string)
-                                   (database postgresql-socket-database)
-                                    &key (owner nil))
-  (let ((row (car (database-query
-                  (format nil "SELECT pg_type.typname,pg_attribute.attlen,pg_attribute.atttypmod,pg_attribute.attnotnull FROM pg_type,pg_class,pg_attribute WHERE pg_class.oid=pg_attribute.attrelid AND pg_class.relname='~A' AND pg_attribute.attname='~A' AND pg_attribute.atttypid=pg_type.oid~A"
-                          (string-downcase table)
-                          (string-downcase attribute)
-                          (owner-clause owner))
-                  database nil nil))))
-    (when row
-      (values
-       (ensure-keyword (first row))
-       (if (string= "-1" (second row))
-          (- (parse-integer (third row) :junk-allowed t) 4)
-        (parse-integer (second row)))
-       nil
-       (if (string-equal "f" (fourth row))
-          1
-        0)))))
-
-(defmethod database-create-sequence (sequence-name
-                                    (database postgresql-socket-database))
-  (database-execute-command
-   (concatenate 'string "CREATE SEQUENCE " (sql-escape sequence-name))
-   database))
-
-(defmethod database-drop-sequence (sequence-name
-                                  (database postgresql-socket-database))
-  (database-execute-command
-   (concatenate 'string "DROP SEQUENCE " (sql-escape sequence-name)) database))
-
-(defmethod database-list-sequences ((database postgresql-socket-database)
-                                    &key (owner nil))
-  (database-list-objects-of-type database "S" owner))
-
-(defmethod database-set-sequence-position (name (position integer)
-                                          (database postgresql-socket-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (format nil "SELECT SETVAL ('~A', ~A)" name position)
-      database nil nil)))))
-
-(defmethod database-sequence-next (sequence-name 
-                                  (database postgresql-socket-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (concatenate 'string "SELECT NEXTVAL ('" (sql-escape sequence-name) "')")
-      database nil nil)))))
-
-(defmethod database-sequence-last (sequence-name (database postgresql-socket-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (concatenate 'string "SELECT LAST_VALUE ('" sequence-name "')")
-      database nil nil)))))
-  
-
 (defmethod database-create (connection-spec (type (eql :postgresql-socket)))
   (destructuring-bind (host name user password) connection-spec
     (let ((database (database-connect (list host "template1" user password)
 (defmethod database-create (connection-spec (type (eql :postgresql-socket)))
   (destructuring-bind (host name user password) connection-spec
     (let ((database (database-connect (list host "template1" user password)
@@ -487,32 +345,6 @@ doesn't depend on UFFI."
              :key #'car :test #'string-equal)
     t))
 
              :key #'car :test #'string-equal)
     t))
 
-(defmethod database-list (connection-spec (type (eql :postgresql-socket)))
-  (destructuring-bind (host name user password) connection-spec
-    (declare (ignore name))
-    (let ((database (database-connect (list host "template1" user password)
-                                     type)))
-      (unwind-protect
-          (progn
-            (setf (slot-value database 'clsql-sys::state) :open)
-            (mapcar #'car (database-query "select datname from pg_database" 
-                                          database :auto nil)))
-       (progn
-         (database-disconnect database)
-         (setf (slot-value database 'clsql-sys::state) :closed))))))
-
-(defmethod database-describe-table ((database postgresql-socket-database) 
-                                   table)
-  (database-query
-   (format nil "select a.attname, t.typname
-                               from pg_class c, pg_attribute a, pg_type t
-                               where c.relname = '~a'
-                                   and a.attnum > 0
-                                   and a.attrelid = c.oid
-                                   and a.atttypid = t.oid"
-           (sql-escape (string-downcase table)))
-   database :auto nil))
-
 
 ;; Database capabilities
 
 
 ;; Database capabilities
 
@@ -525,5 +357,8 @@ doesn't depend on UFFI."
 (defmethod db-type-default-case ((db-type (eql :postgresql-socket)))
   :lower)
 
 (defmethod db-type-default-case ((db-type (eql :postgresql-socket)))
   :lower)
 
+(defmethod db-underlying-type ((database postgresql-socket-database))
+  :postgresql)
+
 (when (clsql-sys:database-type-library-loaded :postgresql-socket)
   (clsql-sys:initialize-database-type :database-type :postgresql-socket))
 (when (clsql-sys:database-type-library-loaded :postgresql-socket)
   (clsql-sys:initialize-database-type :database-type :postgresql-socket))
index 447bd7e212bb7d91e15d5f2a7432444991183330..bcfda5ecb5ae6ee8b8e295927b3eeb8b8969b076 100644 (file)
@@ -77,7 +77,7 @@
 (uffi:def-type pgsql-result-def pgsql-result)
 
 
 (uffi:def-type pgsql-result-def pgsql-result)
 
 
-(defclass postgresql-database (database)
+(defclass postgresql-database (generic-postgresql-database)
   ((conn-ptr :accessor database-conn-ptr :initarg :conn-ptr
             :type pgsql-conn-def)
    (lock
   ((conn-ptr :accessor database-conn-ptr :initarg :conn-ptr
             :type pgsql-conn-def)
    (lock
 
 ;;; Object listing
 
 
 ;;; Object listing
 
-(defun owner-clause (owner)
-  (cond 
-   ((stringp owner)
-    (format
-     nil
-     " AND (relowner=(SELECT usesysid FROM pg_user WHERE (usename='~A')))" 
-     owner))
-   ((null owner)
-    (format nil " AND (NOT (relowner=1))"))
-   (t "")))
-
-(defun database-list-objects-of-type (database type owner)
-  (mapcar #'car
-         (database-query
-          (format nil
-                  "SELECT relname FROM pg_class WHERE (relkind = '~A')~A"
-                  type
-                  (owner-clause owner))
-          database nil nil)))
-
-(defmethod database-list-tables ((database postgresql-database)
-                                 &key (owner nil))
-  (database-list-objects-of-type database "r" owner))
-  
-(defmethod database-list-views ((database postgresql-database)
-                                &key (owner nil))
-  (database-list-objects-of-type database "v" owner))
-  
-(defmethod database-list-indexes ((database postgresql-database)
-                                  &key (owner nil))
-  (database-list-objects-of-type database "i" owner))
-
-
-(defmethod database-list-table-indexes (table (database postgresql-database)
-                                       &key (owner nil))
-  (let ((indexrelids
-        (database-query
-         (format 
-          nil
-          "select indexrelid from pg_index where indrelid=(select relfilenode from pg_class where relname='~A'~A)"
-          (string-downcase table)
-          (owner-clause owner))
-         database :auto nil))
-       (result nil))
-    (dolist (indexrelid indexrelids (nreverse result))
-      (push 
-       (caar (database-query
-             (format nil "select relname from pg_class where relfilenode='~A'"
-                     (car indexrelid))
-             database nil nil))
-       result))))
-
-(defmethod database-list-attributes ((table string)
-                                    (database postgresql-database)
-                                     &key (owner nil))
-  (let* ((owner-clause
-          (cond ((stringp owner)
-                 (format nil " AND (relowner=(SELECT usesysid FROM pg_user WHERE usename='~A'))" owner))
-                ((null owner) " AND (not (relowner=1))")
-                (t "")))
-         (result
-         (mapcar #'car
-                 (database-query
-                  (format nil "SELECT attname FROM pg_class,pg_attribute WHERE pg_class.oid=attrelid AND relname='~A'~A"
-                           (string-downcase table)
-                           owner-clause)
-                   database nil nil))))
-    (if result
-        (remove-if #'(lambda (it) (member it '("cmin"
-                                               "cmax"
-                                               "xmax"
-                                               "xmin"
-                                               "oid"
-                                               "ctid"
-                                               ;; kmr -- added tableoid
-                                               "tableoid") :test #'equal)) 
-                   result))))
-
-(defmethod database-attribute-type (attribute (table string)
-                                   (database postgresql-database)
-                                    &key (owner nil))
-  (let ((row (car (database-query
-                  (format nil "SELECT pg_type.typname,pg_attribute.attlen,pg_attribute.atttypmod,pg_attribute.attnotnull FROM pg_type,pg_class,pg_attribute WHERE pg_class.oid=pg_attribute.attrelid AND pg_class.relname='~A' AND pg_attribute.attname='~A' AND pg_attribute.atttypid=pg_type.oid~A"
-                          (string-downcase table)
-                          (string-downcase attribute)
-                          (owner-clause owner))
-                  database nil nil))))
-    (when row
-      (values
-       (ensure-keyword (first row))
-       (if (string= "-1" (second row))
-          (- (parse-integer (third row) :junk-allowed t) 4)
-        (parse-integer (second row)))
-       nil
-       (if (string-equal "f" (fourth row))
-          1
-        0)))))
-
-(defmethod database-create-sequence (sequence-name
-                                    (database postgresql-database))
-  (database-execute-command
-   (concatenate 'string "CREATE SEQUENCE " (sql-escape sequence-name))
-   database))
-
-(defmethod database-drop-sequence (sequence-name
-                                  (database postgresql-database))
-  (database-execute-command
-   (concatenate 'string "DROP SEQUENCE " (sql-escape sequence-name)) database))
-
-(defmethod database-list-sequences ((database postgresql-database)
-                                    &key (owner nil))
-  (database-list-objects-of-type database "S" owner))
-
-(defmethod database-set-sequence-position (name (position integer)
-                                                (database postgresql-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (format nil "SELECT SETVAL ('~A', ~A)" name position)
-      database nil nil)))))
-
-(defmethod database-sequence-next (sequence-name 
-                                  (database postgresql-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (concatenate 'string "SELECT NEXTVAL ('" (sql-escape sequence-name) "')")
-      database nil nil)))))
-
-(defmethod database-sequence-last (sequence-name (database postgresql-database))
-  (values
-   (parse-integer
-    (caar
-     (database-query
-      (concatenate 'string "SELECT LAST_VALUE ('" sequence-name "')")
-      database nil nil)))))
+
   
 (defmethod database-create (connection-spec (type (eql :postgresql)))
   (destructuring-bind (host name user password) connection-spec
   
 (defmethod database-create (connection-spec (type (eql :postgresql)))
   (destructuring-bind (host name user password) connection-spec
              :key #'car :test #'string-equal)
     t))
 
              :key #'car :test #'string-equal)
     t))
 
-(defmethod database-list (connection-spec (type (eql :postgresql)))
-  (destructuring-bind (host name user password) connection-spec
-    (declare (ignore name))
-    (let ((database (database-connect (list host "template1" user password)
-                                     type)))
-      (unwind-protect
-          (progn
-            (setf (slot-value database 'clsql-sys::state) :open)
-            (mapcar #'car (database-query "select datname from pg_database" 
-                                          database nil nil)))
-       (progn
-         (database-disconnect database)
-         (setf (slot-value database 'clsql-sys::state) :closed))))))
-
-(defmethod database-describe-table ((database postgresql-database) table)
-  (database-query 
-   (format nil "select a.attname, t.typname
-                               from pg_class c, pg_attribute a, pg_type t
-                               where c.relname = '~a'
-                                   and a.attnum > 0
-                                   and a.attrelid = c.oid
-                                   and a.atttypid = t.oid"
-           (sql-escape (string-downcase table)))
-   database :auto nil))
 
 (defun %pg-database-connection (connection-spec)
   (check-connection-spec connection-spec :postgresql
 
 (defun %pg-database-connection (connection-spec)
   (check-connection-spec connection-spec :postgresql
index bd87f785648f2cebcac80f7e1d9084a90fd97300..3bde105b239238297f8413fd1c38e1670ba97dd9 100644 (file)
@@ -768,7 +768,8 @@ uninclusive, and the args from that keyword to the end."
                (write-char #\Space *sql-stream*)
                (write-string
                 (if (stringp db-type) db-type ; override definition
                (write-char #\Space *sql-stream*)
                (write-string
                 (if (stringp db-type) db-type ; override definition
-                    (database-get-type-specifier (car type) (cdr type) database))
+                 (database-get-type-specifier (car type) (cdr type) database
+                                              (database-underlying-type database)))
                 *sql-stream*)
                (let ((constraints (database-constraint-statement  
                                    (if (and db-type (symbolp db-type))
                 *sql-stream*)
                (let ((constraints (database-constraint-statement  
                                    (if (and db-type (symbolp db-type))
index 7699841dfc45a201e2bddee31c23132f4a0ca256..3c2f7468326d3adc9ce2c9cd67699ca1864f544d 100644 (file)
@@ -172,11 +172,11 @@ if unable to destory."))
   (:method ((database t))
           (signal-no-database-error database)))
 
   (:method ((database t))
           (signal-no-database-error database)))
 
-(defgeneric database-get-type-specifier (type args database)
+(defgeneric database-get-type-specifier (type args database db-underlying-type)
   (:documentation "Return the type SQL type specifier as a string, for
 the given lisp type and parameters.")
   (:documentation "Return the type SQL type specifier as a string, for
 the given lisp type and parameters.")
-  (:method (type args (database t))
-          (declare (ignore type args))
+  (:method (type args database db-underlying-type)
+          (declare (ignore type args db-type))
           (signal-no-database-error database)))
 
 (defgeneric database-list-tables (database &key owner)
           (signal-no-database-error database)))
 
 (defgeneric database-list-tables (database &key owner)
diff --git a/sql/generic-odbc.lisp b/sql/generic-odbc.lisp
new file mode 100644 (file)
index 0000000..a5e8c68
--- /dev/null
@@ -0,0 +1,25 @@
+;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
+;;;; *************************************************************************
+;;;;
+;;;; $Id$
+;;;;
+;;;; Generic ODBC layer, used by db-odbc and db-aodbc backends
+;;;;
+;;;; This file is part of CLSQL.
+;;;;
+;;;; CLSQL users are granted the rights to distribute and use this software
+;;;; as governed by the terms of the Lisp Lesser GNU Public License
+;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
+;;;; *************************************************************************
+
+(in-package #:clsql-sys)
+
+(defclass generic-odbc-database (database)
+  ()
+  (:documentation "Encapsulate same behavior across odbc and aodbc backends."))
+
+(defmethod read-sql-value (val (type (eql 'boolean))
+                          (database generic-odbc-database)
+                          (db-type (eql :postgresql)))
+  (if (string= "0" val) nil t))
+
diff --git a/sql/generic-postgresql.lisp b/sql/generic-postgresql.lisp
new file mode 100644 (file)
index 0000000..af0ef61
--- /dev/null
@@ -0,0 +1,229 @@
+;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
+;;;; *************************************************************************
+;;;;
+;;;; $Id$
+;;;;
+;;;; Generic postgresql layer, used by db-postgresql and db-postgresql-socket
+;;;;
+;;;; This file is part of CLSQL.
+;;;;
+;;;; CLSQL users are granted the rights to distribute and use this software
+;;;; as governed by the terms of the Lisp Lesser GNU Public License
+;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
+;;;; *************************************************************************
+
+(in-package #:clsql-sys)
+
+(defclass generic-postgresql-database (database)
+  ()
+  (:documentation "Encapsulate same behavior across postgresql and postgresql-socket backends."))
+
+
+
+;; Object functions
+
+(defmethod database-get-type-specifier (type args database
+                                       (db-type (eql :postgresql)))
+  (declare (ignore type args database))
+  "VARCHAR")
+
+(defmethod database-get-type-specifier ((type (eql 'simple-base-string)) args database
+                                       (db-type (eql :postgresql)))
+  (declare (ignore database))
+  (if args
+      (format nil "VARCHAR(~A)" (car args))
+      "VARCHAR"))
+
+(defmethod database-get-type-specifier ((type (eql 'simple-string)) args database
+                                       (db-type (eql :postgresql)))
+  (declare (ignore database))
+  (if args
+      (format nil "VARCHAR(~A)" (car args))
+      "VARCHAR"))
+
+(defmethod database-get-type-specifier ((type (eql 'string)) args database
+                                       (db-type (eql :postgresql)))
+  (declare (ignore database))
+  (if args
+      (format nil "VARCHAR(~A)" (car args))
+      "VARCHAR"))
+
+(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database
+                                       (db-type (eql :postgresql)))
+  (declare (ignore args database))
+  "TIMESTAMP WITHOUT TIME ZONE")
+
+
+;;; Backend functions
+
+(defun owner-clause (owner)
+  (cond 
+   ((stringp owner)
+    (format
+     nil
+     " AND (relowner=(SELECT usesysid FROM pg_user WHERE (usename='~A')))" 
+     owner))
+   ((null owner)
+    (format nil " AND (NOT (relowner=1))"))
+   (t "")))
+
+(defun database-list-objects-of-type (database type owner)
+  (mapcar #'car
+         (database-query
+          (format nil
+                  "SELECT relname FROM pg_class WHERE (relkind = '~A')~A"
+                  type
+                  (owner-clause owner))
+          database nil nil)))
+
+(defmethod database-list-tables ((database generic-postgresql-database)
+                                 &key (owner nil))
+  (database-list-objects-of-type database "r" owner))
+  
+(defmethod database-list-views ((database generic-postgresql-database)
+                                &key (owner nil))
+  (database-list-objects-of-type database "v" owner))
+  
+(defmethod database-list-indexes ((database generic-postgresql-database)
+                                  &key (owner nil))
+  (database-list-objects-of-type database "i" owner))
+
+
+(defmethod database-list-table-indexes (table (database generic-postgresql-database)
+                                       &key (owner nil))
+  (let ((indexrelids
+        (database-query
+         (format 
+          nil
+          "select indexrelid from pg_index where indrelid=(select relfilenode from pg_class where relname='~A'~A)"
+          (string-downcase table)
+          (owner-clause owner))
+         database :auto nil))
+       (result nil))
+    (dolist (indexrelid indexrelids (nreverse result))
+      (push 
+       (caar (database-query
+             (format nil "select relname from pg_class where relfilenode='~A'"
+                     (car indexrelid))
+             database nil nil))
+       result))))
+
+(defmethod database-list-attributes ((table string)
+                                    (database generic-postgresql-database)
+                                     &key (owner nil))
+  (let* ((owner-clause
+          (cond ((stringp owner)
+                 (format nil " AND (relowner=(SELECT usesysid FROM pg_user WHERE usename='~A'))" owner))
+                ((null owner) " AND (not (relowner=1))")
+                (t "")))
+         (result
+         (mapcar #'car
+                 (database-query
+                  (format nil "SELECT attname FROM pg_class,pg_attribute WHERE pg_class.oid=attrelid AND relname='~A'~A"
+                           (string-downcase table)
+                           owner-clause)
+                   database nil nil))))
+    (if result
+        (remove-if #'(lambda (it) (member it '("cmin"
+                                               "cmax"
+                                               "xmax"
+                                               "xmin"
+                                               "oid"
+                                               "ctid"
+                                               ;; kmr -- added tableoid
+                                               "tableoid") :test #'equal)) 
+                   result))))
+
+(defmethod database-attribute-type (attribute (table string)
+                                   (database generic-postgresql-database)
+                                    &key (owner nil))
+  (let ((row (car (database-query
+                  (format nil "SELECT pg_type.typname,pg_attribute.attlen,pg_attribute.atttypmod,pg_attribute.attnotnull FROM pg_type,pg_class,pg_attribute WHERE pg_class.oid=pg_attribute.attrelid AND pg_class.relname='~A' AND pg_attribute.attname='~A' AND pg_attribute.atttypid=pg_type.oid~A"
+                          (string-downcase table)
+                          (string-downcase attribute)
+                          (owner-clause owner))
+                  database nil nil))))
+    (when row
+      (values
+       (ensure-keyword (first row))
+       (if (string= "-1" (second row))
+          (- (parse-integer (third row) :junk-allowed t) 4)
+        (parse-integer (second row)))
+       nil
+       (if (string-equal "f" (fourth row))
+          1
+        0)))))
+
+(defmethod database-create-sequence (sequence-name
+                                    (database generic-postgresql-database))
+  (database-execute-command
+   (concatenate 'string "CREATE SEQUENCE " (sql-escape sequence-name))
+   database))
+
+(defmethod database-drop-sequence (sequence-name
+                                  (database generic-postgresql-database))
+  (database-execute-command
+   (concatenate 'string "DROP SEQUENCE " (sql-escape sequence-name)) database))
+
+(defmethod database-list-sequences ((database generic-postgresql-database)
+                                    &key (owner nil))
+  (database-list-objects-of-type database "S" owner))
+
+(defmethod database-set-sequence-position (name (position integer)
+                                                (database generic-postgresql-database))
+  (values
+   (parse-integer
+    (caar
+     (database-query
+      (format nil "SELECT SETVAL ('~A', ~A)" name position)
+      database nil nil)))))
+
+(defmethod database-sequence-next (sequence-name 
+                                  (database generic-postgresql-database))
+  (values
+   (parse-integer
+    (caar
+     (database-query
+      (concatenate 'string "SELECT NEXTVAL ('" (sql-escape sequence-name) "')")
+      database nil nil)))))
+
+(defmethod database-sequence-last (sequence-name (database generic-postgresql-database))
+  (values
+   (parse-integer
+    (caar
+     (database-query
+      (concatenate 'string "SELECT LAST_VALUE ('" sequence-name "')")
+      database nil nil)))))
+
+(defun postgresql-database-list (connection-spec type)
+  (destructuring-bind (host name user password) connection-spec
+    (declare (ignore name))
+    (let ((database (database-connect (list host "template1" user password)
+                                     type)))
+      (unwind-protect
+          (progn
+            (setf (slot-value database 'clsql-sys::state) :open)
+            (mapcar #'car (database-query "select datname from pg_database" 
+                                          database nil nil)))
+       (progn
+         (database-disconnect database)
+         (setf (slot-value database 'clsql-sys::state) :closed))))))
+
+(defmethod database-list (connection-spec (type (eql :postgresql)))
+  (postgresql-database-list connection-spec type))
+
+(defmethod database-list (connection-spec (type (eql :postgresql-socket)))
+  (postgresql-database-list connection-spec type))
+
+
+(defmethod database-describe-table ((database generic-postgresql-database) table)
+  (database-query 
+   (format nil "select a.attname, t.typname
+                               from pg_class c, pg_attribute a, pg_type t
+                               where c.relname = '~a'
+                                   and a.attnum > 0
+                                   and a.attrelid = c.oid
+                                   and a.atttypid = t.oid"
+           (sql-escape (string-downcase table)))
+   database :auto nil))
+
index ac9f0bd2047c4f77c96a8b4611660ff84abaeead..817547d884440e04feb981204a501e5749ef05f3 100644 (file)
@@ -119,8 +119,8 @@ DATABASE-NULL-VALUE on the type of the slot."))
   )
 (defgeneric get-slot-values-from-view  (obj slotdeflist values)
   )
   )
 (defgeneric get-slot-values-from-view  (obj slotdeflist values)
   )
-(defgeneric database-output-sql-as-type  (type val database)
+(defgeneric database-output-sql-as-type  (type val database db-type)
   )
   )
-(defgeneric read-sql-value  (val type database)
+(defgeneric read-sql-value  (val type database db-type)
   )
 
   )
 
index 2111b7aa4c6097ca42942e7019721e0d79b1e2fe..3d031e2cd58c28ad851464b93bc7775a4e4255a1 100644 (file)
@@ -291,8 +291,10 @@ strings."
     (cond ((and value (null slot-reader))
            (setf (slot-value instance slot-name)
                  (read-sql-value value (delistify slot-type)
     (cond ((and value (null slot-reader))
            (setf (slot-value instance slot-name)
                  (read-sql-value value (delistify slot-type)
-                                 (view-database instance))))
-          ((null value)
+                                 (view-database instance)
+                                (database-underlying-type
+                                 (view-database instance)))))
+         ((null value)
            (update-slot-with-null instance slot-name slotdef))
           ((typep slot-reader 'string)
            (setf (slot-value instance slot-name)
            (update-slot-with-null instance slot-name slotdef))
           ((typep slot-reader 'string)
            (setf (slot-value instance slot-name)
@@ -308,7 +310,8 @@ strings."
   (let ((slot-reader (view-class-slot-db-reader slotdef))
         (slot-type (specified-type slotdef)))
     (cond ((and value (null slot-reader))
   (let ((slot-reader (view-class-slot-db-reader slotdef))
         (slot-type (specified-type slotdef)))
     (cond ((and value (null slot-reader))
-           (read-sql-value value (delistify slot-type) database))
+           (read-sql-value value (delistify slot-type) database
+                          (database-underlying-type database)))
           ((null value)
            nil)
           ((typep slot-reader 'string)
           ((null value)
            nil)
           ((typep slot-reader 'string)
@@ -325,11 +328,11 @@ strings."
       (string (format nil dbwriter val))
       (function (apply dbwriter (list val)))
       (t
       (string (format nil dbwriter val))
       (function (apply dbwriter (list val)))
       (t
-       (typecase dbtype
-        (cons
-         (database-output-sql-as-type (car dbtype) val database))
-        (t
-         (database-output-sql-as-type dbtype val database)))))))
+       (database-output-sql-as-type
+       (typecase dbtype
+         (cons (car dbtype))
+         (t dbtype))
+       val database (database-underlying-type database))))))
 
 (defun check-slot-type (slotdef val)
   (let* ((slot-type (specified-type slotdef))
 
 (defun check-slot-type (slotdef val)
   (let* ((slot-type (specified-type slotdef))
@@ -499,16 +502,12 @@ strings."
            (error "No view-table for class ~A"  classname))
          (sql-expression :table (view-table class))))
 
            (error "No view-table for class ~A"  classname))
          (sql-expression :table (view-table class))))
 
-(defmethod database-get-type-specifier (type args (database database))
-  (declare (ignore type args))
-  (if (in (database-underlying-type database)
-                         :postgresql :postgresql-socket)
-          "VARCHAR"
-          "VARCHAR(255)"))
+(defmethod database-get-type-specifier (type args database db-type)
+  (declare (ignore type args database db-type))
+  "VARCHAR(255)")
 
 
-(defmethod database-get-type-specifier ((type (eql 'integer)) args database)
-  (declare (ignore database))
-  ;;"INT8")
+(defmethod database-get-type-specifier ((type (eql 'integer)) args database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "INT(~A)" (car args))
       "INT"))
   (if args
       (format nil "INT(~A)" (car args))
       "INT"))
@@ -517,98 +516,89 @@ strings."
   "An integer larger than a 32-bit integer, this width may vary by SQL implementation."
   'integer)
 
   "An integer larger than a 32-bit integer, this width may vary by SQL implementation."
   'integer)
 
-(defmethod database-get-type-specifier ((type (eql 'bigint)) args database)
-  (declare (ignore args database))
+(defmethod database-get-type-specifier ((type (eql 'bigint)) args database db-type)
+  (declare (ignore args database db-type))
   "BIGINT")
               
 (defmethod database-get-type-specifier ((type (eql 'simple-base-string)) args
   "BIGINT")
               
 (defmethod database-get-type-specifier ((type (eql 'simple-base-string)) args
-                                        database)
+                                        database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "VARCHAR(~A)" (car args))
   (if args
       (format nil "VARCHAR(~A)" (car args))
-    (if (in (database-underlying-type database) 
-                           :postgresql :postgresql-socket)
-       "VARCHAR"
-      "VARCHAR(255)")))
+      "VARCHAR(255)"))
 
 (defmethod database-get-type-specifier ((type (eql 'simple-string)) args
 
 (defmethod database-get-type-specifier ((type (eql 'simple-string)) args
-                                        database)
+                                        database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "VARCHAR(~A)" (car args))
   (if args
       (format nil "VARCHAR(~A)" (car args))
-    (if (in (database-underlying-type database) 
-                           :postgresql :postgresql-socket)
-       "VARCHAR"
-      "VARCHAR(255)")))
+      "VARCHAR(255)"))
 
 
-(defmethod database-get-type-specifier ((type (eql 'string)) args database)
+(defmethod database-get-type-specifier ((type (eql 'string)) args database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "VARCHAR(~A)" (car args))
   (if args
       (format nil "VARCHAR(~A)" (car args))
-    (if (in (database-underlying-type database) 
-                           :postgresql :postgresql-socket)
-       "VARCHAR"
-      "VARCHAR(255)")))
+      "VARCHAR(255)"))
 
 (deftype universal-time () 
   "A positive integer as returned by GET-UNIVERSAL-TIME."
   '(integer 1 *))
 
 
 (deftype universal-time () 
   "A positive integer as returned by GET-UNIVERSAL-TIME."
   '(integer 1 *))
 
-(defmethod database-get-type-specifier ((type (eql 'universal-time)) args database)
-  (declare (ignore args database))
+(defmethod database-get-type-specifier ((type (eql 'universal-time)) args database db-type)
+  (declare (ignore args database db-type))
   "BIGINT")
 
   "BIGINT")
 
-(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database)
-  (declare (ignore args))
-  (case (database-underlying-type database)
-    ((:postgresql :postgresql-socket)
-     "TIMESTAMP WITHOUT TIME ZONE")
-    (t "TIMESTAMP")))
+(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database db-type)
+  (declare (ignore args database db-type))
+  "TIMESTAMP")
 
 
-(defmethod database-get-type-specifier ((type (eql 'duration)) args database)
-  (declare (ignore database args))
+(defmethod database-get-type-specifier ((type (eql 'duration)) args database db-type)
+  (declare (ignore database args db-type))
   "VARCHAR")
 
   "VARCHAR")
 
-(defmethod database-get-type-specifier ((type (eql 'money)) args database)
-  (declare (ignore database args))
+(defmethod database-get-type-specifier ((type (eql 'money)) args database db-type)
+  (declare (ignore database args db-type))
   "INT8")
 
 (deftype raw-string (&optional len)
   "A string which is not trimmed when retrieved from the database"
   `(string ,len))
 
   "INT8")
 
 (deftype raw-string (&optional len)
   "A string which is not trimmed when retrieved from the database"
   `(string ,len))
 
-(defmethod database-get-type-specifier ((type (eql 'raw-string)) args database)
-  (declare (ignore database))
+(defmethod database-get-type-specifier ((type (eql 'raw-string)) args database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "VARCHAR(~A)" (car args))
       "VARCHAR"))
 
   (if args
       (format nil "VARCHAR(~A)" (car args))
       "VARCHAR"))
 
-(defmethod database-get-type-specifier ((type (eql 'float)) args database)
-  (declare (ignore database))
+(defmethod database-get-type-specifier ((type (eql 'float)) args database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "FLOAT(~A)" (car args))
       "FLOAT"))
 
   (if args
       (format nil "FLOAT(~A)" (car args))
       "FLOAT"))
 
-(defmethod database-get-type-specifier ((type (eql 'long-float)) args database)
-  (declare (ignore database))
+(defmethod database-get-type-specifier ((type (eql 'long-float)) args database db-type)
+  (declare (ignore database db-type))
   (if args
       (format nil "FLOAT(~A)" (car args))
       "FLOAT"))
 
   (if args
       (format nil "FLOAT(~A)" (car args))
       "FLOAT"))
 
-(defmethod database-get-type-specifier ((type (eql 'boolean)) args database)
-  (declare (ignore args database))
+(defmethod database-get-type-specifier ((type (eql 'boolean)) args database db-type)
+  (declare (ignore args database db-type))
   "BOOL")
 
   "BOOL")
 
-(defmethod database-output-sql-as-type (type val database)
-  (declare (ignore type database))
+(defmethod database-output-sql-as-type (type val database db-type)
+  (declare (ignore type database db-type))
   val)
 
   val)
 
-(defmethod database-output-sql-as-type ((type (eql 'list)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'list)) val database db-type)
+  (declare (ignore database db-type))
   (progv '(*print-circle* *print-array*) '(t t)
     (let ((escaped (prin1-to-string val)))
       (substitute-char-string
        escaped #\Null " "))))
 
   (progv '(*print-circle* *print-array*) '(t t)
     (let ((escaped (prin1-to-string val)))
       (substitute-char-string
        escaped #\Null " "))))
 
-(defmethod database-output-sql-as-type ((type (eql 'symbol)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'symbol)) val database db-type)
+  (declare (ignore database db-type))
   (if (keywordp val)
       (symbol-name val)
       (if val
   (if (keywordp val)
       (symbol-name val)
       (if val
@@ -618,91 +608,91 @@ strings."
                        (symbol-name val))
           "")))
 
                        (symbol-name val))
           "")))
 
-(defmethod database-output-sql-as-type ((type (eql 'keyword)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'keyword)) val database db-type)
+  (declare (ignore database db-type))
   (if val
       (symbol-name val)
       ""))
 
   (if val
       (symbol-name val)
       ""))
 
-(defmethod database-output-sql-as-type ((type (eql 'vector)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'vector)) val database db-type)
+  (declare (ignore database db-type))
   (progv '(*print-circle* *print-array*) '(t t)
     (prin1-to-string val)))
 
   (progv '(*print-circle* *print-array*) '(t t)
     (prin1-to-string val)))
 
-(defmethod database-output-sql-as-type ((type (eql 'array)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'array)) val database db-type)
+  (declare (ignore database db-type))
   (progv '(*print-circle* *print-array*) '(t t)
     (prin1-to-string val)))
 
   (progv '(*print-circle* *print-array*) '(t t)
     (prin1-to-string val)))
 
-(defmethod database-output-sql-as-type ((type (eql 'boolean)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'boolean)) val database db-type)
+  (declare (ignore database db-type))
   (if val "t" "f"))
 
   (if val "t" "f"))
 
-(defmethod database-output-sql-as-type ((type (eql 'string)) val database)
-  (declare (ignore database))
+(defmethod database-output-sql-as-type ((type (eql 'string)) val database db-type)
+  (declare (ignore database db-type))
   val)
 
 (defmethod database-output-sql-as-type ((type (eql 'simple-string))
   val)
 
 (defmethod database-output-sql-as-type ((type (eql 'simple-string))
-                                       val database)
-  (declare (ignore database))
+                                       val database db-type)
+  (declare (ignore database db-type))
   val)
 
 (defmethod database-output-sql-as-type ((type (eql 'simple-base-string))
   val)
 
 (defmethod database-output-sql-as-type ((type (eql 'simple-base-string))
-                                       val database)
-  (declare (ignore database))
+                                       val database db-type)
+  (declare (ignore database db-type))
   val)
 
   val)
 
-(defmethod read-sql-value (val type database)
-  (declare (ignore type database))
+(defmethod read-sql-value (val type database db-type)
+  (declare (ignore type database db-type))
   (read-from-string val))
 
   (read-from-string val))
 
-(defmethod read-sql-value (val (type (eql 'string)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'string)) database db-type)
+  (declare (ignore database db-type))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'simple-string)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'simple-string)) database db-type)
+  (declare (ignore database db-type))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'simple-base-string)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'simple-base-string)) database db-type)
+  (declare (ignore database db-type))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'raw-string)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'raw-string)) database db-type)
+  (declare (ignore database db-type))
   val)
 
   val)
 
-(defmethod read-sql-value (val (type (eql 'keyword)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'keyword)) database db-type)
+  (declare (ignore database db-type))
   (when (< 0 (length val))
     (intern (symbol-name-default-case val) 
            (find-package '#:keyword))))
 
   (when (< 0 (length val))
     (intern (symbol-name-default-case val) 
            (find-package '#:keyword))))
 
-(defmethod read-sql-value (val (type (eql 'symbol)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'symbol)) database db-type)
+  (declare (ignore database db-type))
   (when (< 0 (length val))
     (unless (string= val (symbol-name-default-case "NIL"))
       (intern (symbol-name-default-case val)
               (symbol-package *update-context*)))))
 
   (when (< 0 (length val))
     (unless (string= val (symbol-name-default-case "NIL"))
       (intern (symbol-name-default-case val)
               (symbol-package *update-context*)))))
 
-(defmethod read-sql-value (val (type (eql 'integer)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'integer)) database db-type)
+  (declare (ignore database db-type))
   (etypecase val
     (string
      (unless (string-equal "NIL" val)
        (parse-integer val)))
     (number val)))
 
   (etypecase val
     (string
      (unless (string-equal "NIL" val)
        (parse-integer val)))
     (number val)))
 
-(defmethod read-sql-value (val (type (eql 'bigint)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'bigint)) database db-type)
+  (declare (ignore database db-type))
   (etypecase val
     (string
      (unless (string-equal "NIL" val)
        (parse-integer val)))
     (number val)))
 
   (etypecase val
     (string
      (unless (string-equal "NIL" val)
        (parse-integer val)))
     (number val)))
 
-(defmethod read-sql-value (val (type (eql 'float)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'float)) database db-type)
+  (declare (ignore database db-type))
   ;; writing 1.0 writes 1, so we we *really* want a float, must do (float ...)
   (etypecase val
     (string
   ;; writing 1.0 writes 1, so we we *really* want a float, must do (float ...)
   (etypecase val
     (string
@@ -710,30 +700,25 @@ strings."
     (float
      val)))
 
     (float
      val)))
 
-(defmethod read-sql-value (val (type (eql 'boolean)) database)
-  (case (database-underlying-type database)
-    (:postgresql
-     (if (eq :odbc (database-type database))
-        (if (string= "0" val) nil t)
-       (equal "t" val)))
-    (t
-     (equal "t" val))))
-
-(defmethod read-sql-value (val (type (eql 'univeral-time)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'boolean)) database db-type)
+  (declare (ignore database db-type))
+  (equal "t" val))
+
+(defmethod read-sql-value (val (type (eql 'univeral-time)) database db-type)
+  (declare (ignore database db-type))
   (unless (eq 'NULL val)
     (etypecase val
       (string
        (parse-integer val))
       (number val))))
 
   (unless (eq 'NULL val)
     (etypecase val
       (string
        (parse-integer val))
       (number val))))
 
-(defmethod read-sql-value (val (type (eql 'wall-time)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'wall-time)) database db-type)
+  (declare (ignore database db-type))
   (unless (eq 'NULL val)
     (parse-timestring val)))
 
   (unless (eq 'NULL val)
     (parse-timestring val)))
 
-(defmethod read-sql-value (val (type (eql 'duration)) database)
-  (declare (ignore database))
+(defmethod read-sql-value (val (type (eql 'duration)) database db-type)
+  (declare (ignore database db-type))
   (unless (or (eq 'NULL val)
               (equal "NIL" val))
     (parse-timestring val)))
   (unless (or (eq 'NULL val)
               (equal "NIL" val))
     (parse-timestring val)))
index 20555d6e28dd82bf1d77df89a5ec0429c844dfba..8b4475ec78dd05e1cc765b31f591e5525a333816 100644 (file)
      #:database-query-result-set
      #:database-dump-result-set
      #:database-store-next-row
      #:database-query-result-set
      #:database-dump-result-set
      #:database-store-next-row
-     #:database-get-type-specifier
      #:database-list-tables
      #:database-table-exists-p
      #:database-list-views
      #:database-list-tables
      #:database-table-exists-p
      #:database-list-views
      #:db-type-default-case
      #:db-type-use-column-on-drop-index? 
      #:database-underlying-type
      #:db-type-default-case
      #:db-type-use-column-on-drop-index? 
      #:database-underlying-type
+     #:database-get-type-specifier
+     #:read-sql-value
+     #:database-output-sql-as-type
 
      ;; Large objects 
      #:database-create-large-object
 
      ;; Large objects 
      #:database-create-large-object
      #:database-type
      #:database-state
      #:attribute-cache
      #:database-type
      #:database-state
      #:attribute-cache
-     
-
+   
      ;; utils.lisp
      #:without-interrupts
      #:make-process-lock
      ;; utils.lisp
      #:without-interrupts
      #:make-process-lock
      #:float-to-sql-string
      #:sql-escape-quotes
      #:in
      #:float-to-sql-string
      #:sql-escape-quotes
      #:in
+
+     ;; Generic backends
+     #:generic-postgresql-database
+     #:generic-odbc-database
      
      .
      ;; Shared exports for re-export by CLSQL package. 
      
      .
      ;; Shared exports for re-export by CLSQL package. 
         #:bigint
         ;;OODML
         #:*db-auto-sync*                    ; objects    xx              
         #:bigint
         ;;OODML
         #:*db-auto-sync*                    ; objects    xx              
-        #:read-sql-value                    ; objects    x
-        #:database-output-sql-as-type       ; objects    x
-        #:database-get-type-specifier       ; objects    x
-        #:database-output-sql               ; sql/class  xx
         
         ;; conditions
         #:clsql-condition
         
         ;; conditions
         #:clsql-condition
index 543ab871f6bfefebd69093f8cadeb4478cfeb3df..9af59da503b6845fbcaee73612eaf5d07998abd1 100644 (file)
       (values (nreverse test-forms) (nreverse skip-tests))))
 
 
       (values (nreverse test-forms) (nreverse skip-tests))))
 
 
-(defun rapid-load (type)
+(defun rapid-load (type &optional (position 0))
   "Rapid load for interactive testing."
   (when *default-database*
       (disconnect :database *default-database*))
   "Rapid load for interactive testing."
   (when *default-database*
       (disconnect :database *default-database*))
-  (test-connect-to-database type (car (db-type-spec type (read-specs))))
+  (test-connect-to-database type (nth position (db-type-spec type (read-specs))))
   (test-initialise-database)
   *default-database*)
 
   (test-initialise-database)
   *default-database*)