From 2135bfa98887e609e060f30c0b04130075089788 Mon Sep 17 00:00:00 2001 From: "nathan@acceleration.net" Date: Fri, 22 Feb 2008 17:21:51 -0500 Subject: [PATCH] darcs patch: * Implementing bigint support for odbc + mssql Thu Jun 14 15:25:43 EDT 2007 Nathan Bird --- db-odbc/odbc-api.lisp | 15 +++++++++++---- db-odbc/odbc-constants.lisp | 2 ++ db-odbc/odbc-dbi.lisp | 32 +++++++++++++++----------------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/db-odbc/odbc-api.lisp b/db-odbc/odbc-api.lisp index 2d3e234..49a6e1f 100644 --- a/db-odbc/odbc-api.lisp +++ b/db-odbc/odbc-api.lisp @@ -240,7 +240,7 @@ as possible second argument) to the desired representation of date/time/timestam (SQLTransact henv hdbc $SQL_ROLLBACK))) -; col-nr is zero-based in Lisp +; col-nr is zero-based in Lisp but 1 based in sql ; col-nr = :bookmark retrieves a bookmark. (defun %bind-column (hstmt column-nr c-type data-ptr precision out-len-ptr) (with-error-handling @@ -493,6 +493,7 @@ as possible second argument) to the desired representation of date/time/timestam (deref-pointer column-scale-ptr :short) (deref-pointer column-nullable-p-ptr :short))))))) +;; this function isn't used, which is good because FreeTDS dosn't support it. ;; parameter counting is 1-based (defun %describe-parameter (hstmt parameter-nr) (with-foreign-objects ((column-sql-type-ptr :short) @@ -584,9 +585,10 @@ 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 -10) $SQL_C_CHAR) ;; Added -10 for MSSQL ntext type + #.$SQL_NUMERIC #.$SQL_DECIMAL -8 -9 -10) $SQL_C_CHAR) ;; Added -10 for MSSQL ntext type (#.$SQL_INTEGER $SQL_C_SLONG) (#.$SQL_SMALLINT $SQL_C_SSHORT) + (#.$SQL_BIGINT $SQL_C_SBIGINT) (#.$SQL_DOUBLE $SQL_C_DOUBLE) (#.$SQL_FLOAT $SQL_C_DOUBLE) (#.$SQL_REAL $SQL_C_FLOAT) @@ -604,6 +606,7 @@ as possible second argument) to the desired representation of date/time/timestam (def-type short-pointer-type (* :short)) (def-type int-pointer-type (* :int)) (def-type long-pointer-type (* #.$ODBC-LONG-TYPE)) +(def-type big-pointer-type (* #.$ODBC-BIG-TYPE)) (def-type float-pointer-type (* :float)) (def-type double-pointer-type (* :double)) (def-type string-pointer-type (* :unsigned-char)) @@ -624,6 +627,10 @@ as possible second argument) to the desired representation of date/time/timestam (locally (declare (type long-pointer-type ptr)) (deref-pointer ptr #.$ODBC-LONG-TYPE))) +(defun get-cast-big (ptr) + (locally (declare (type big-pointer-type ptr)) + (deref-pointer ptr #.$ODBC-BIG-TYPE))) + (defun get-cast-single-float (ptr) (locally (declare (type float-pointer-type ptr)) (deref-pointer ptr :float))) @@ -670,8 +677,7 @@ as possible second argument) to the desired representation of date/time/timestam (#.$SQL_C_SSHORT (get-cast-short data-ptr)) ;; ? (#.$SQL_SMALLINT (get-cast-short data-ptr)) ;; ?? (#.$SQL_INTEGER (get-cast-int data-ptr)) - (#.$SQL_BIGINT (read-from-string - (get-cast-foreign-string data-ptr))) + (#.$SQL_BIGINT (get-cast-big data-ptr)) (#.$SQL_DECIMAL (let ((*read-base* 10)) (read-from-string (get-cast-foreign-string data-ptr)))) @@ -741,6 +747,7 @@ as possible second argument) to the desired representation of date/time/timestam (#.$SQL_C_BIT (uffi:allocate-foreign-object :byte)) (#.$SQL_C_STINYINT (uffi:allocate-foreign-object :byte)) (#.$SQL_C_SSHORT (uffi:allocate-foreign-object :short)) + (#.$SQL_C_SBIGINT (uffi:allocate-foreign-object #.$ODBC-BIG-TYPE)) (#.$SQL_C_CHAR (uffi:allocate-foreign-string (1+ size))) (#.$SQL_C_BINARY (uffi:allocate-foreign-string (1+ (* 2 size)))) (t diff --git a/db-odbc/odbc-constants.lisp b/db-odbc/odbc-constants.lisp index 4dfef88..479c6fa 100644 --- a/db-odbc/odbc-constants.lisp +++ b/db-odbc/odbc-constants.lisp @@ -21,6 +21,7 @@ ;; on SuSE AMD64 9.0, unixODBC is compiled with with SQLLEN being 4 bytes long (defconstant $ODBC-LONG-TYPE :int) (defconstant $ODBC-ULONG-TYPE :unsigned-int) +(defconstant $ODBC-BIG-TYPE :long-long) ;; (defconstant $ODBCVER #x0210) @@ -934,6 +935,7 @@ (defconstant $SQL_C_BINARY $SQL_BINARY) (defconstant $SQL_C_BIT $SQL_BIT) (defconstant $SQL_C_TINYINT $SQL_TINYINT) +(defconstant $SQL_C_SBIGINT (+ $SQL_BIGINT $SQL_SIGNED_OFFSET)) (defconstant $SQL_C_SLONG (+ $SQL_C_LONG $SQL_SIGNED_OFFSET)) ;; SIGNED INTEGER (defconstant $SQL_C_SSHORT (+ $SQL_C_SHORT $SQL_SIGNED_OFFSET)) ;; SIGNED SMALLINT (defconstant $SQL_C_STINYINT (+ $SQL_TINYINT $SQL_SIGNED_OFFSET)) ;; SIGNED TINYINT diff --git a/db-odbc/odbc-dbi.lisp b/db-odbc/odbc-dbi.lisp index 6723a1a..caa549e 100644 --- a/db-odbc/odbc-dbi.lisp +++ b/db-odbc/odbc-dbi.lisp @@ -454,22 +454,19 @@ This makes the functions db-execute-command and db-query thread safe." (setf computed-result-types (make-array column-count)) (dotimes (i column-count) (setf (aref computed-result-types i) - (cond - ((consp result-types) - (nth i result-types)) - ((eq result-types :auto) - (if (eq (aref column-sql-types i) odbc::$SQL_BIGINT) - :number - (case (aref column-c-types i) - (#.odbc::$SQL_C_SLONG :int) - (#.odbc::$SQL_C_DOUBLE :double) - (#.odbc::$SQL_C_FLOAT :float) - (#.odbc::$SQL_C_SSHORT :short) - (#.odbc::$SQL_C_STINYINT :short) - (#.odbc::$SQL_BIGINT :short) - (t t)))) - (t - t))))) + (cond + ((consp result-types) + (nth i result-types)) + ((eq result-types :auto) + (case (aref column-c-types i) + (#.odbc::$SQL_C_SLONG :int) + (#.odbc::$SQL_C_DOUBLE :double) + (#.odbc::$SQL_C_FLOAT :float) + (#.odbc::$SQL_C_SSHORT :short) + (#.odbc::$SQL_C_STINYINT :short) + (#.odbc::$SQL_C_SBIGINT #.odbc::$ODBC-BIG-TYPE) + (t t))) + (t t))))) query) (defun db-close-query (query &key drop-p) @@ -564,7 +561,8 @@ This makes the functions db-execute-command and db-query thread safe." (defun sql-to-lisp-type (sql-type) (ecase sql-type ((#.odbc::$SQL_CHAR #.odbc::$SQL_VARCHAR #.odbc::$SQL_LONGVARCHAR) :string) - ((#.odbc::$SQL_NUMERIC #.odbc::$SQL_DECIMAL #.odbc::$SQL_BIGINT) :string) ; ?? + ((#.odbc::$SQL_NUMERIC #.odbc::$SQL_DECIMAL ) :string) ; ?? + (#.odbc::$SQL_BIGINT #.odbc::$ODBC-BIG-TYPE) (#.odbc::$SQL_INTEGER #.odbc::$ODBC-LONG-TYPE) (#.odbc::$SQL_SMALLINT :short) ((#.odbc::$SQL_FLOAT #.odbc::$SQL_DOUBLE) #.odbc::$ODBC-LONG-TYPE) -- 2.34.1