From b2191fb61b57de37bdd703c1ad9231f87bd5258c Mon Sep 17 00:00:00 2001 From: Nathan Bird Date: Thu, 14 Jun 2007 15:25:43 -0400 Subject: [PATCH] Implementing bigint support for odbc + mssql prev: 2135bfa98887e609e060f30c0b04130075089788 --- db-odbc/odbc-api.lisp | 17 +++++++++++++---- db-odbc/odbc-constants.lisp | 2 ++ db-odbc/odbc-dbi.lisp | 4 +++- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/db-odbc/odbc-api.lisp b/db-odbc/odbc-api.lisp index f14a9d3..b7fd718 100644 --- a/db-odbc/odbc-api.lisp +++ b/db-odbc/odbc-api.lisp @@ -239,7 +239,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-nullable-p-ptr :short))))))) ;; parameter counting is 1-based +;; this function isn't used, which is good because FreeTDS dosn't support it. (defun %describe-parameter (hstmt parameter-nr) (with-foreign-objects ((column-sql-type-ptr :short) (column-precision-ptr #.$ODBC-ULONG-TYPE) @@ -583,8 +584,9 @@ 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_BIGINT $SQL_C_SBIGINT) (#.$SQL_SMALLINT $SQL_C_SSHORT) (#.$SQL_DOUBLE $SQL_C_DOUBLE) (#.$SQL_FLOAT $SQL_C_DOUBLE) @@ -603,6 +605,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)) @@ -623,6 +626,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))) @@ -669,8 +676,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)))) @@ -700,6 +706,8 @@ as possible second argument) to the desired representation of date/time/timestam (get-cast-binary data-ptr out-len *binary-format*)) ((#.$SQL_C_SSHORT #.$SQL_C_STINYINT) ; LMH short ints (get-cast-short data-ptr)) ; LMH + (#.$SQL_C_SBIGINT (uffi:allocate-foreign-object #.$ODBC-BIG-TYPE) + (get-cast-short data-ptr)) #+ignore (#.$SQL_C_CHAR (code-char (get-cast-short data-ptr))) @@ -739,6 +747,7 @@ as possible second argument) to the desired representation of date/time/timestam (#.$SQL_C_DOUBLE (uffi:allocate-foreign-object :double)) (#.$SQL_C_BIT (uffi:allocate-foreign-object :byte)) (#.$SQL_C_STINYINT (uffi:allocate-foreign-object :byte)) + (#.$SQL_C_SBIGINT (uffi:allocate-foreign-object #.$ODBC-BIG-TYPE)) (#.$SQL_C_SSHORT (uffi:allocate-foreign-object :short)) (#.$SQL_C_CHAR (uffi:allocate-foreign-string (1+ size))) (#.$SQL_C_BINARY (uffi:allocate-foreign-string (1+ (* 2 size)))) diff --git a/db-odbc/odbc-constants.lisp b/db-odbc/odbc-constants.lisp index 8f9152e..c4265f4 100644 --- a/db-odbc/odbc-constants.lisp +++ b/db-odbc/odbc-constants.lisp @@ -19,6 +19,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) @@ -932,6 +933,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 bcca4b1..a4d973a 100644 --- a/db-odbc/odbc-dbi.lisp +++ b/db-odbc/odbc-dbi.lisp @@ -462,6 +462,7 @@ This makes the functions db-execute-command and db-query thread safe." (#.odbc::$SQL_C_FLOAT :float) (#.odbc::$SQL_C_SSHORT :short) (#.odbc::$SQL_C_STINYINT :short) + (#.odbc::$SQL_C_SBIGINT #.odbc::$ODBC-BIG-TYPE) (#.odbc::$SQL_C_TYPE_TIMESTAMP :time) (t t))) (t t))))) @@ -559,7 +560,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