r10845: 26 Nov 2005 Kevin Rosenberg <kevin@rosenberg.net>
authorKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 26 Nov 2005 16:08:12 +0000 (16:08 +0000)
committerKevin M. Rosenberg <kevin@rosenberg.net>
Sat, 26 Nov 2005 16:08:12 +0000 (16:08 +0000)
        * Version 3.5.0
        * tests/test-init.lisp, tests/test-fddl.lisp, tests/test-fdml.lisp,
        * db-odbc/odbc-api.lisp, db-odbc/odbc-ff-interface.lisp,
        * db-odbc/odbc-package.lisp, db-odbc/odbc-constants.lisp
        * db-odbc/odbc-dbi.lisp, db-odbc/odbc-sql.lisp
        * sql/fddl.lisp, sql/generic-odbc.lisp, sql/db-interface.lisp
        * sql/transaction.lisp, sql/package.lisp, sql/time.lisp
        Commit patch from Dominic Robinson providing support for
        Microsoft SQL Server
        * doc/csql.lisp: Fix typo in slot name

19 files changed:
ChangeLog
db-odbc/odbc-api.lisp
db-odbc/odbc-constants.lisp
db-odbc/odbc-dbi.lisp
db-odbc/odbc-ff-interface.lisp
db-odbc/odbc-package.lisp
db-odbc/odbc-sql.lisp
debian/changelog
debian/control
doc/csql.xml
sql/db-interface.lisp
sql/fddl.lisp
sql/generic-odbc.lisp
sql/package.lisp
sql/time.lisp
sql/transaction.lisp
tests/test-fddl.lisp
tests/test-fdml.lisp
tests/test-init.lisp

index 4e2d6a2ee427e8db0a86af4fb241a2dd5ca22930..04aa5fba7253291be8748570a09fd9dc213ef296 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+26 Nov 2005  Kevin Rosenberg <kevin@rosenberg.net>
+       * Version 3.5.0
+       * tests/test-init.lisp, tests/test-fddl.lisp, tests/test-fdml.lisp, 
+       * db-odbc/odbc-api.lisp, db-odbc/odbc-ff-interface.lisp,
+       * db-odbc/odbc-package.lisp, db-odbc/odbc-constants.lisp
+       * db-odbc/odbc-dbi.lisp, db-odbc/odbc-sql.lisp
+       * sql/fddl.lisp, sql/generic-odbc.lisp, sql/db-interface.lisp
+       * sql/transaction.lisp, sql/package.lisp, sql/time.lisp
+       Commit patch from Dominic Robinson providing support for 
+       Microsoft SQL Server
+       * doc/csql.lisp: Fix typo in slot name
+       
 24 Nov 2005  Kevin Rosenberg <kevin@rosenberg.net>
        * Version 3.4.7
        * sql/time.lisp: Commit patch from Aleksandar Bakic for
index 0dcefa4090491a558299e624ca9586389fd7d2d7..33734bc993450096052fbe1b240587c834d1ac1d 100644 (file)
@@ -198,6 +198,20 @@ as possible second argument) to the desired representation of date/time/timestam
       (SQLConnect hdbc server-ptr $SQL_NTS uid-ptr 
                  $SQL_NTS pwd-ptr $SQL_NTS))))
 
+(defun %sql-driver-connect (hdbc connection-string completion window-handle)
+  (with-cstring (connection-ptr connection-string)
+    (let ((completed-connection-string (allocate-foreign-string $SQL_MAX_CONN_OUT)))
+      (unwind-protect
+          (with-foreign-object (completed-connection-length :short)
+                               (with-error-handling 
+                                   (:hdbc hdbc)
+                                   (SQLDriverConnect hdbc 
+                                                     window-handle 
+                                                     connection-ptr $SQL_NTS
+                                                     completed-connection-string $SQL_MAX_CONN_OUT
+                                                     completed-connection-length
+                                                     completion)))
+        (free-foreign-object completed-connection-string)))))
 
 (defun %disconnect (hdbc)
   (with-error-handling 
@@ -560,7 +574,7 @@ as possible second argument) to the desired representation of date/time/timestam
 (defun sql-to-c-type (sql-type)
   (ecase sql-type
     ((#.$SQL_CHAR #.$SQL_VARCHAR #.$SQL_LONGVARCHAR 
-      #.$SQL_NUMERIC #.$SQL_DECIMAL #.$SQL_BIGINT -8 -9) $SQL_C_CHAR)
+      #.$SQL_NUMERIC #.$SQL_DECIMAL #.$SQL_BIGINT -8 -9 -10) $SQL_C_CHAR) ;; Added -10 for MSSQL ntext type
     (#.$SQL_INTEGER $SQL_C_SLONG)
     (#.$SQL_SMALLINT $SQL_C_SSHORT)
     (#.$SQL_DOUBLE $SQL_C_DOUBLE)
@@ -848,56 +862,59 @@ as possible second argument) to the desired representation of date/time/timestam
 
 (defun read-data-in-chunks (hstmt column-nr data-ptr c-type sql-type 
                                       out-len-ptr result-type)
-  (declare (type long-ptr-type out-len-ptr))
+  (declare (type long-ptr-type out-len-ptr)
+           (ignore result-type))
   (let* ((res (%sql-get-data hstmt column-nr c-type data-ptr 
                              +max-precision+ out-len-ptr))
          (out-len (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE))
-         (offset 0))
-    (case out-len
-      (#.$SQL_NULL_DATA
-       (return-from read-data-in-chunks *null*))
-      (#.$SQL_NO_TOTAL ;; don't know how long it is going to be
-       (let ((str (make-array 0 :element-type 'character :adjustable t)))
-         (loop do (if (= c-type #.$SQL_CHAR)
-                      (let ((data-length (foreign-string-length data-ptr)))
-                        (adjust-array str (+ offset data-length)
-                                      :initial-element #\?)
-                        (setf offset (%cstring-into-vector
-                                      data-ptr str 
-                                      offset 
-                                      data-length)))
-                    (error 'clsql:sql-database-error :message "wrong type. preliminary."))
-               while (and (= res $SQL_SUCCESS_WITH_INFO)
-                          (equal (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
-                                 "01004"))
-               do (setf res (%sql-get-data hstmt column-nr c-type data-ptr 
-                                           +max-precision+ out-len-ptr)))
-         (setf str (coerce str 'string))
-         (if (= sql-type $SQL_DECIMAL)
-             (let ((*read-base* 10))
-               (read-from-string str))
-           str)))
-      (otherwise
-       (let ((str (make-string out-len)))
-         (loop do (if (= c-type #.$SQL_CHAR)
-                      (setf offset (%cstring-into-vector ;string
-                                    data-ptr str 
-                                    offset 
-                                    (min out-len (1- +max-precision+))))
-                    (error 'clsql:sql-database-error :message "wrong type. preliminary."))
-               while 
-               (and (= res $SQL_SUCCESS_WITH_INFO)
-                    #+ingore(eq (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
-                                $sql-data-truncated)
-                    (equal (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
-                           "01004"))
-               do (setf res (%sql-get-data hstmt column-nr c-type data-ptr 
-                                           +max-precision+ out-len-ptr)
-                        out-len (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE)))
-         (if (= sql-type $SQL_DECIMAL)
-             (let ((*read-base* 10))
-               (read-from-string str))
-           str))))))
+         (offset 0)
+         (result (case out-len
+                   (#.$SQL_NULL_DATA
+                    (return-from read-data-in-chunks *null*))
+                   (#.$SQL_NO_TOTAL ;; don't know how long it is going to be
+                                    (let ((str (make-array 0 :element-type 'character :adjustable t)))
+                                      (loop do (if (= c-type #.$SQL_CHAR)
+                                                   (let ((data-length (foreign-string-length data-ptr)))
+                                                     (adjust-array str (+ offset data-length)
+                                                                   :initial-element #\?)
+                                                     (setf offset (%cstring-into-vector
+                                                                   data-ptr str 
+                                                                   offset 
+                                                                   data-length)))
+                                                 (error 'clsql:sql-database-error :message "wrong type. preliminary."))
+                                            while (and (= res $SQL_SUCCESS_WITH_INFO)
+                                                       (equal (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
+                                                              "01004"))
+                                            do (setf res (%sql-get-data hstmt column-nr c-type data-ptr 
+                                                                        +max-precision+ out-len-ptr)))
+                                      (setf str (coerce str 'string))
+                                      (if (= sql-type $SQL_DECIMAL)
+                                          (let ((*read-base* 10))
+                                            (read-from-string str))
+                                        str)))
+                   (otherwise
+                    (let ((str (make-string out-len)))
+                      (loop do (if (= c-type #.$SQL_CHAR)
+                                   (setf offset (%cstring-into-vector ;string
+                                                 data-ptr str 
+                                                 offset 
+                                                 (min out-len (1- +max-precision+))))
+                                 (error 'clsql:sql-database-error :message "wrong type. preliminary."))
+                            while 
+                            (and (= res $SQL_SUCCESS_WITH_INFO)
+                                 #+ingore(eq (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
+                                             $sql-data-truncated)
+                                 (equal (sql-state +null-handle-ptr+ +null-handle-ptr+ hstmt)
+                                        "01004"))
+                            do (setf res (%sql-get-data hstmt column-nr c-type data-ptr 
+                                                        +max-precision+ out-len-ptr)
+                                     out-len (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE)))
+                      (if (= sql-type $SQL_DECIMAL)
+                          (let ((*read-base* 10))
+                            (read-from-string str))
+                        str))))))
+    (setf (deref-pointer out-len-ptr #.$ODBC-LONG-TYPE) #.$SQL_NO_TOTAL) ;; reset the out length for the next row
+    result))
 
 (def-type c-timestamp-ptr-type (* (:struct sql-c-timestamp)))
 (def-type c-time-ptr-type (* (:struct sql-c-time)))
index 0315e444e3a38627b2cd92fb3c8414a1d1b96a0d..6d8a1839a8f32ca2bc35e93ca2ce68a611ea30ce 100644 (file)
 (defconstant $SQL_DRIVER_PROMPT 2)
 (defconstant $SQL_DRIVER_COMPLETE_REQUIRED 3)
 
+(defconstant $SQL_MAX_CONN_OUT 1024)
+
 ;; Level 2 Functions
 
 ;; SQLExtendedFetch "fFetchType" values
index fc8f3000bed3380d7e0677bab1b7b625e398999b..2a60462ae0b8517530b285a2e7df173443a8228c 100644 (file)
@@ -124,12 +124,21 @@ the query against." ))
 
 ;;; AODBC Compatible interface
 
-(defun connect (&key data-source-name user password (autocommit t))
+(defun connect (&key data-source-name user password connection-string completion window-handle (autocommit t))
   (let ((db (make-instance 'odbc-db)))
     (unless (henv db) ;; has class allocation!
       (setf (henv db) (%new-environment-handle)))
     (setf (hdbc db) (%new-db-connection-handle (henv db)))
-    (%sql-connect (hdbc db) data-source-name user password)
+    (if connection-string
+        (%sql-driver-connect (hdbc db) 
+                             connection-string 
+                             (ecase completion
+                               (:no-prompt odbc::$SQL_DRIVER_NOPROMPT)
+                               (:complete odbc::$SQL_DRIVER_COMPLETE)
+                               (:prompt odbc::$SQL_DRIVER_PROMPT)
+                               (:complete-required odbc::$SQL_DRIVER_COMPLETE_REQUIRED))
+                             window-handle)
+      (%sql-connect (hdbc db) data-source-name user password))
     #+ignore (setf (db-hstmt db) (%new-statement-handle (hdbc db)))
     (when (/= (get-odbc-info db odbc::$SQL_TXN_CAPABLE) odbc::$SQL_TC_NONE)
       (if autocommit
@@ -217,7 +226,7 @@ the query against." ))
 
 (defun list-all-table-columns (table &key db hstmt)
   (declare (ignore hstmt))
-  (db-describe-columns db "" "" table ""))
+  (db-describe-columns db nil nil table nil))   ;; use nil rather than "" for unspecified values
 
 (defun list-all-data-sources ()
   (let ((db (make-instance 'odbc-db)))
@@ -424,7 +433,8 @@ This makes the functions db-execute-command and db-query thread safe."
                   ;; allocate space to bind result rows to
                   (multiple-value-bind (c-type data-ptr out-len-ptr size long-p)
                                        (%allocate-bindings sql-type precision)
-                    (unless long-p ;; if long-p we fetch in chunks with %sql-get-data
+                    (if long-p ;; if long-p we fetch in chunks with %sql-get-data but must ensure that out_len_ptr is non zero
+                        (setf (uffi:deref-pointer out-len-ptr #.odbc::$ODBC-LONG-TYPE) #.odbc::$SQL_NO_TOTAL)
                       (%bind-column hstmt col-nr c-type data-ptr (1+ size) out-len-ptr))
                     (vector-push-extend name column-names) 
                     (vector-push-extend sql-type column-sql-types)
index e46db57a021b54e65df0878214fef2e6cd7a256a..9baec6a1431f84fc7c17f25d88c958b128951f43 100644 (file)
@@ -61,7 +61,7 @@
 (def-function "SQLDriverConnect"
     ((hdbc sql-handle)          ; HDBC        hdbc
      (hwnd sql-handle)          ; SQLHWND     hwnd
-     (*szConnStrIn string-ptr)  ; UCHAR  FAR *szConnStrIn
+     (*szConnStrIn :cstring)    ; UCHAR  FAR *szConnStrIn
      (cbConnStrIn :short)       ; SWORD       cbConnStrIn
      (*szConnStrOut string-ptr) ; UCHAR  FAR *szConnStrOut
      (cbConnStrOutMax :short)   ; SWORD       cbConnStrOutMax
index baedbedd0c7eb6406efb8174efffeaf8a7bfcb6b..011b6b4b044f24adc4faaa9e11f7e91f2adc5f72 100644 (file)
@@ -39,6 +39,7 @@
      #:%new-db-connection-handle
      #:%new-environment-handle
      #:%sql-connect
+     #:%sql-driver-connect
      #:disable-autocommit
      #:enable-autocommit
      #:%sql-free-environment
index 1f00008493be1d9ccaf7375c70f6cfd977bc3895..e76b9d0bdf45d13fd3a897d15382d9d4b7e46f4b 100644 (file)
 
 (defmethod database-name-from-spec (connection-spec
                                    (database-type (eql :odbc)))
-  (check-connection-spec connection-spec database-type (dsn user password))
-  (destructuring-bind (dsn user password) connection-spec
-    (declare (ignore password))
+  (check-connection-spec connection-spec database-type (dsn user password &key connection-string completion window-handle))
+  (destructuring-bind (dsn user password &key connection-string completion window-handle) connection-spec
+    (declare (ignore password connection-string completion window-handle))
     (concatenate 'string dsn "/" user)))
 
 (defmethod database-connect (connection-spec (database-type (eql :odbc)))
-  (check-connection-spec connection-spec database-type (dsn user password))
-  (destructuring-bind (dsn user password) connection-spec
+  (check-connection-spec connection-spec database-type (dsn user password &key connection-string completion window-handle))
+  (destructuring-bind (dsn user password &key connection-string (completion :no-prompt) window-handle) connection-spec
     (handler-case
        (let ((db (make-instance 'odbc-database
                                 :name (database-name-from-spec connection-spec :odbc)
                                 :odbc-conn
                                 (odbc-dbi:connect :user user
                                                   :password password
-                                                  :data-source-name dsn))))
+                                                  :data-source-name dsn
+                                                   :connection-string connection-string
+                                                   :completion completion
+                                                   :window-handle window-handle))))
          (store-type-of-connected-database db)
          ;; Ensure this database type is initialized so can check capabilities of
          ;; underlying database
@@ -74,6 +77,9 @@
            (unless (find-package 'clsql-postgresql)
              (ignore-errors (asdf:operate 'asdf:load-op 'clsql-postgresql-socket)))
            :postgresql)
+           ((or (search "Microsoft SQL Server" server-name :test #'char-equal)
+                (search "Microsoft SQL Server" dbms-name :test #'char-equal))
+            :mssql)
           ((or (search "mysql" server-name :test #'char-equal)
                (search "mysql" dbms-name :test #'char-equal))
            (unless (find-package 'clsql-mysql)
        ((null loop-rows) (nreverse results))
       (let* ((row (car loop-rows))
             (col (nth 5 row)))
-       (unless (find col results :test #'string-equal)
+       (unless (or (null col) (find col results :test #'string-equal))
          (push col results))))))
 
 ;;; Database capabilities
index bb531ff9965bdb0c1a3501f30e35bf00dbc61e4d..c67186824563a19a88c172de8335f72d4656692a 100644 (file)
@@ -1,3 +1,10 @@
+cl-sql (3.5.0-1) unstable; urgency=low
+
+  * New upstream (closes: 339842)
+  * Change libmyclient run-time requirement (closes: 339824)
+
+ -- Kevin M. Rosenberg <kmr@debian.org>  Sat, 26 Nov 2005 08:58:22 -0700
+
 cl-sql (3.4.7-1) unstable; urgency=low
 
   * New upstream
index 0140eaf2b06c4e5b8d14437415c0988a20661e01..727fa1fb0a36dff5fd911639c60c24d5c910f2b4 100644 (file)
@@ -2,7 +2,7 @@ Source: cl-sql
 Section: devel
 Priority: extra
 Maintainer: Kevin M. Rosenberg <kmr@debian.org>
-Build-Depends: debhelper (>= 4.0.0), libmysqlclient14-dev | libmysqlclient15-dev, libpq-dev
+Build-Depends: debhelper (>= 4.0.0), libmysqlclient15-dev, libpq-dev
 Build-Depends-Indep: debhelper (>= 4.0.0)
 Standards-Version: 3.6.2.1
 
@@ -26,7 +26,7 @@ Description: Common UFFI functions for CLSQL database backends
 
 Package: cl-sql-mysql
 Architecture: any
-Depends: cl-sql (>= ${Source-Version}), libmysqlclient14-dev | libmysqlclient15-dev, cl-sql-uffi (>= ${Source-Version})
+Depends: cl-sql (>= ${Source-Version}), libmysqlclient15, cl-sql-uffi (>= ${Source-Version})
 Provides: cl-sql-backend
 Description: CLSQL database backend, MySQL
  This package enables you to use the CLSQL data access package
index 272c62536b0674330ef0e90f4cfd0bd74c741ab5..f84dd50691c54b8e748cd2f1ef344caeda7d9df8 100644 (file)
@@ -250,7 +250,7 @@ mapped into a database).  They would be defined as follows:
 
   <listitem>
     <para>
-      <symbol>:column-</symbol> - A string which will be used as the
+      <symbol>:db-type</symbol> - A string which will be used as the
       type specifier for this slots column definition in the database.
       </para></listitem>
 
index 0d67bb0147a25e7a85e581bedbbab6f620cfcee3..298214ae0cdcfd9c734f9428942212bf1c5a7c6b 100644 (file)
@@ -296,6 +296,12 @@ of TYPE_NAME (keyword) PRECISION SCALE NULLABLE.")
           nil)
   (:documentation "NIL [default] if database-type does not use column name on DROP INDEX."))
 
+(defgeneric db-type-use-fully-qualified-column-on-drop-index? (db-type)
+  (:method (db-type)
+          (declare (ignore db-type))
+          nil)
+  (:documentation "NIL [default] if database-type does not require fully qualified column name on DROP INDEX."))
+
 (defgeneric db-type-has-views? (db-type)
   (:method (db-type)
           (declare (ignore db-type))
@@ -359,6 +365,17 @@ of TYPE_NAME (keyword) PRECISION SCALE NULLABLE.")
     nil)
   (:documentation "T if database backend supports prepared statements."))
 
+(defgeneric db-type-has-intersect? (db-type)
+  (:method (db-type)
+          (declare (ignore db-type))
+          t)
+  (:documentation "T [default] if database-type supports INTERSECT."))
+
+(defgeneric db-type-has-except? (db-type)
+  (:method (db-type)
+          (declare (ignore db-type))
+          t)
+  (:documentation "T [default] if database-type supports EXCEPT."))
 
 ;;; Large objects support (Marc Battyani)
 
index 51f8f05d5d5954b9a174d0bcc7bbd362c39fee67..3b5b1bd195b6a7e66a5d0c6626e909452c6565f6 100644 (file)
@@ -216,14 +216,14 @@ the index from."
        (unless (index-exists-p index-name :database database)
          (return-from drop-index)))
       (:error t))
-    (unless (db-type-use-column-on-drop-index? 
-            (database-underlying-type database))
-      (setq on nil))
-    (execute-command (format nil "DROP INDEX ~A~A" index-name
-                             (if (null on) ""
-                                 (concatenate 'string " ON "
-                                              (database-identifier on database))))
-                     :database database)))
+    (let* ((db-type (database-underlying-type database))
+           (index-identifier (cond ((db-type-use-fully-qualified-column-on-drop-index? db-type)
+                                    (format nil "~A.~A" (database-identifier on database) index-name))
+                                   ((db-type-use-column-on-drop-index? db-type)
+                                    (format nil "~A ON ~A" index-name (database-identifier on database)))
+                                   (t index-name))))
+      (execute-command (format nil "DROP INDEX ~A" index-identifier)
+                       :database database))))
 
 (defun list-indexes (&key (owner nil) (database *default-database*) (on nil))
   "Returns a list of strings representing index names in DATABASE
index eb3430f4b4d44dea933f031ba790bea31f729a2d..563e1f8b1ba40513a2194a256f8b2bdcb5374621 100644 (file)
                           (db-type (eql :postgresql)))
   (if (string= "0" val) nil t))
 
-  
+(defmethod read-sql-value (val (type (eql 'boolean)) database
+                          (db-type (eql :mssql)))
+  (declare (ignore database))
+  (etypecase val
+    (string (if (string= "0" val) nil t))
+    (integer (if (zerop val) nil t))))
+
+(defmethod read-sql-value (val (type (eql 'generalized-boolean)) database
+                          (db-type (eql :mssql)))
+  (declare (ignore database))
+  (etypecase val
+    (string (if (string= "0" val) nil t))
+    (integer (if (zerop val) nil t))))
+
+;;; Type methods
+
+(defmethod database-get-type-specifier ((type (eql 'wall-time)) args database
+                                       (db-type (eql :mssql)))
+  (declare (ignore args database))
+  "DATETIME")
+
+(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")
+
+;;; Generation of SQL strings from lisp expressions
+
+(defmethod database-output-sql ((tee (eql t)) (database generic-odbc-database))
+  (case (database-underlying-type database)
+    (:mssql "1")
+    (t "'Y'")))
+
+(defmethod database-output-sql-as-type ((type (eql 'boolean)) val database
+                                       (db-type (eql :mssql)))
+  (declare (ignore database))
+  (if val 1 0))
+
+(defmethod database-output-sql-as-type ((type (eql 'generalized-boolean)) val database
+                                       (db-type (eql :mssql)))
+  (declare (ignore database))
+  (if val 1 0))
+
+;;; Database backend capabilities
+
+(defmethod db-type-use-fully-qualified-column-on-drop-index? ((db-type (eql :mssql)))
+  t)
+
+(defmethod db-type-has-boolean-where? ((db-type (eql :mssql)))
+  nil)
+
+(defmethod db-type-has-intersect? ((db-type (eql :mssql)))
+  nil)
+
+(defmethod db-type-has-except? ((db-type (eql :mssql)))
+  nil)
+
 ;;; Backend methods
 
 (defmethod database-disconnect ((database generic-odbc-database))
   (setf (odbc-conn database) nil)
   t)
 
-(defmethod database-query (query-expression (database generic-odbc-database) 
-                          result-types field-names) 
+(defmethod database-query (query-expression (database generic-odbc-database)
+                          result-types field-names)
   (handler-case
       (funcall (sql-fn database)
               query-expression :db (odbc-conn database)
 
 
 (defmethod database-query-result-set ((query-expression string)
-                                     (database generic-odbc-database) 
+                                     (database generic-odbc-database)
                                      &key full-set result-types)
-  (handler-case 
+  (handler-case
       (multiple-value-bind (query column-names)
          (funcall (sql-fn database)
-                  query-expression 
-                  :db (odbc-conn database) 
+                  query-expression
+                  :db (odbc-conn database)
                   :row-count nil
                   :column-names t
                   :query t
                   :result-types result-types)
        (values
-        (make-odbc-result-set :query query :full-set full-set 
+        (make-odbc-result-set :query query :full-set full-set
                               :types result-types)
         (length column-names)
         nil ;; not able to return number of rows with odbc
     ;; TABLE_NAME in third column, TABLE_TYPE in fourth column
     (loop for row in rows
          when (and (not (string-equal "information_schema" (nth 1 row)))
-                   (string-equal "TABLE" (nth 3 row)))
+                   (string-equal "TABLE" (nth 3 row))
+                    (not (and (eq :mssql (database-underlying-type database))
+                              (string-equal "dtproperties" (nth 2 row)))))
          collect (nth 2 row))))
 
 
     ;; TABLE_NAME in third column, TABLE_TYPE in fourth column
     (loop for row in rows
          when (and (not (string-equal "information_schema" (nth 1 row)))
-                   (string-equal "VIEW" (nth 3 row)))
+                   (string-equal "VIEW" (nth 3 row))
+                    (not (and (eq :mssql (database-underlying-type database))
+                              (member (nth 2 row) '("sysconstraints" "syssegments") :test #'string-equal))))
          collect (nth 2 row))))
 
 
index ad785ecabba8260cea21d0591e2b2f65bde5abde..4c82b0aae4dc683e64d3e8d0c6918a1664a63a50 100644 (file)
      #:db-type-has-fancy-math?
      #:db-type-default-case
      #:db-type-use-column-on-drop-index? 
+     #:db-type-use-fully-qualified-column-on-drop-index?
+     #:db-type-has-intersect?
+     #:db-type-has-except?
      #:database-underlying-type
      #:database-get-type-specifier
      #:read-sql-value
index 464d9cd00506388ee6a6a72de3eb09a728ae4ab6..75f3faafbc9cebef9af607acfa4fa3e35be30333 100644 (file)
@@ -1274,7 +1274,7 @@ Will throw a hissy fit if the date string is a duration. Will ignore any precisi
                      (char= #\. (char string 19))))
              (multiple-value-bind (parsed-usec usec-end)
                  (parse-integer string :start 20 :junk-allowed t)
-               (setf usec          parsed-usec
+               (setf usec          (or parsed-usec 0)
                      gmt-sec-offset (if (<= (+ 3 usec-end)  strlen)
                                         (let ((skip-to (or (position #\+ string :start 19)
                                                            (position #\- string :start 19))))
index 089ce0c2aa899147849a12e939be26b78b779c1a..a9df87fd59f9f579c4aadf19a9b804c832397b30 100644 (file)
@@ -49,8 +49,10 @@ is called on DATABASE which defaults to *DEFAULT-DATABASE*."
       (setf (commit-hooks transaction) nil
             (rollback-hooks transaction) nil
             (transaction-status transaction) nil)
-      (unless (eq :oracle (database-underlying-type database))
-       (execute-command "BEGIN" :database database)))))
+      (case (database-underlying-type database)
+        (:oracle nil)
+        (:mssql (execute-command "BEGIN TRANSACTION" :database database))
+        (t (execute-command "BEGIN" :database database))))))
 
 (defmethod database-commit-transaction ((database database))
   (with-slots (transaction transaction-level autocommit) database
index f5527c773f7cce25f3ff017cc3f6c40cddb7f28f..34c956a79a7918595556303c146beb15aa39d703 100644 (file)
                           '(:postgresql :postgresql-socket))
                   :ignore
                   :warn)))
-         (clsql:create-table [foo] 
-                             '(([bar] integer :not-null :unique :primary-key) 
-                               ([baz] string :not-null :unique))))
+         (case *test-database-underlying-type*
+           (:mssql (clsql:create-table [foo] 
+                                       '(([bar] integer :not-null :primary-key)
+                                         ([baz] string :not-null :unique))))
+           (t (clsql:create-table [foo] 
+                                  '(([bar] integer :not-null :unique :primary-key)
+                                    ([baz] string :not-null :unique))))))
        (clsql:table-exists-p [foo]))
      (progn
        (clsql:drop-table [foo])
index aa887770e3fd250e2052da2445ad2d5e1c060c40..d2606c14b4419f038d8d0eecbb6a6d4a107af670 100644 (file)
  ("Vlad" "Jose" "Leon" "Niki" "Leon" "Yuri" "Kons" "Mikh" "Bori" "Vlad"))
 
 (deftest :fdml/select/22 
-  (clsql:select [|| [first-name] " " [last-name]] :from [employee]
-                :flatp t :order-by [emplid] :field-names nil)
+   (case *test-database-underlying-type*
+     (:mssql (clsql:select [+ [first-name] " " [last-name]] :from [employee]
+                           :flatp t :order-by [emplid] :field-names nil))
+     (t (clsql:select [|| [first-name] " " [last-name]] :from [employee]
+                      :flatp t :order-by [emplid] :field-names nil)))
  ("Vladimir Lenin" "Josef Stalin" "Leon Trotsky" "Nikita Kruschev"
  "Leonid Brezhnev" "Yuri Andropov" "Konstantin Chernenko" "Mikhail Gorbachev"
  "Boris Yeltsin" "Vladimir Putin"))
index d77505476aed0fd3fee86f4a5c97e3629b95f98a..d745ff0698e3823e4b2c7881d7f760e25eaac0a8 100644 (file)
                              '(:postgresql :oracle)))
                (clsql-sys:in test :fddl/owner/1))
            (push (cons test "table ownership not supported") skip-tests))
+          ((and (null (clsql-sys:db-type-has-intersect? db-underlying-type))
+               (clsql-sys:in test :fdml/query/7))
+          (push (cons test "intersect not supported") skip-tests))
+          ((and (null (clsql-sys:db-type-has-except? db-underlying-type))
+               (clsql-sys:in test :fdml/query/8))
+          (push (cons test "except not supported") skip-tests))
+          ((and (eq *test-database-underlying-type* :mssql)
+                (clsql-sys:in test :fdml/select/9))
+           (push (cons test "mssql uses integer math for AVG") skip-tests))
          (t
           (push test-form test-forms)))))
       (values (nreverse test-forms) (nreverse skip-tests))))