From 2f1e9becafa048960362bd6f9bb0f327045807cd Mon Sep 17 00:00:00 2001 From: "Kevin M. Rosenberg" Date: Mon, 12 Apr 2004 21:42:01 +0000 Subject: [PATCH] r8984: initial odbc files --- ChangeLog | 2 + clsql-odbc.asd | 39 ++++++++ db-odbc/odbc-api.lisp | 39 ++++++++ db-odbc/odbc-loader.lisp | 50 ++++++++++ db-odbc/odbc-package.lisp | 33 +++++++ db-odbc/odbc-sql.lisp | 190 ++++++++++++++++++++++++++++++++++++++ debian/changelog | 2 +- 7 files changed, 354 insertions(+), 1 deletion(-) create mode 100644 clsql-odbc.asd create mode 100644 db-odbc/odbc-api.lisp create mode 100644 db-odbc/odbc-loader.lisp create mode 100644 db-odbc/odbc-package.lisp create mode 100644 db-odbc/odbc-sql.lisp diff --git a/ChangeLog b/ChangeLog index 386351f..40e8d51 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,8 @@ * Version 2.6.10 * db-aodbc: Add methods for generic functions, some are not yet implemented. + * clsql-odbc.asd, db-obcl/*.lisp: Initial start of ODBC + support 12 Apr 2004 Kevin Rosenberg (kevin@rosenberg.net) * Version 2.6.9 diff --git a/clsql-odbc.asd b/clsql-odbc.asd new file mode 100644 index 0000000..ae49148 --- /dev/null +++ b/clsql-odbc.asd @@ -0,0 +1,39 @@ +;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: clsql-odbc.asd +;;;; Purpose: ASDF definition file for CLSQL ODBC backend +;;;; Author: Kevin M. Rosenberg +;;;; Created: April 2004 +;;;; +;;;; $Id: clsql-odbc.asd 8850 2004-04-07 16:07:46Z kevin $ +;;;; +;;;; This file, part of CLSQL, is Copyright (c) 200d42 by Kevin M. Rosenberg +;;;; +;;;; 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. +;;;; ************************************************************************* + +(defpackage #:clsql-odbc-system (:use #:asdf #:cl)) +(in-package #:clsql-odbc-system) + +#+(or allegro lispworks cmu sbcl openmcl mcl scl) +(defsystem :clsql-odbc + :name "clsql-odbc" + :author "Kevin M. Rosenberg " + :maintainer "Kevin M. Rosenberg " + :licence "Lessor Lisp General Public License" + :description "Common Lisp SQL ODBC Driver" + :long-description "cl-sql-odbc package provides a database driver to the ODBC database system." + + :depends-on (uffi clsql-base clsql-uffi) + :components + ((:module :db-odbc + :components + ((:file "odbc-package") + (:file "odbc-loader" :depends-on ("odbc-package")) + (:file "odbc-api" :depends-on ("odbc-loader")) + (:file "odbc-sql" :depends-on ("odbc-api")))))) + diff --git a/db-odbc/odbc-api.lisp b/db-odbc/odbc-api.lisp new file mode 100644 index 0000000..332200c --- /dev/null +++ b/db-odbc/odbc-api.lisp @@ -0,0 +1,39 @@ +;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: odbc-api.lisp +;;;; Purpose: Low-level Odbc interface using UFFI +;;;; Author: Kevin M. Rosenberg based on +;;;; Created: April 2004 +;;;; +;;;; $Id: odbc-api.lisp 8811 2004-04-02 20:45:48Z kevin $ +;;;; +;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg +;;;; +;;;; 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 #:odbc) + +(defun connect (&key user password data-source-name) + (warn "Not implemented.") + nil) + +(defun disconnect (conn) + (warn "Not implemented.")) + + +(defun query (expr &key db result-types row-count column-names) + (warn "Not implemented.")) + +(defun execute (expr conn) + (warn "Not implemented.")) + +(defun close-query (result-set) + (warn "Not implemented.")) + +(defun fetch-row (result-set error-eof eof-value) + (warn "Not implemented.")) diff --git a/db-odbc/odbc-loader.lisp b/db-odbc/odbc-loader.lisp new file mode 100644 index 0000000..658da2e --- /dev/null +++ b/db-odbc/odbc-loader.lisp @@ -0,0 +1,50 @@ +;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: odbc-loader.sql +;;;; Purpose: ODBC library loader using UFFI +;;;; Programmers: Kevin M. Rosenberg +;;;; Date Started: April 2004 +;;;; +;;;; $Id: odbc-loader.lisp 8270 2003-11-25 06:37:14Z kevin $ +;;;; +;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg +;;;; +;;;; 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 #:odbc) + +(defparameter *odbc-library-path* + (uffi:find-foreign-library + '("odbc32" "libodbc" "libiodbc") + `(,(make-pathname :directory (pathname-directory *load-truename*)) + "/usr/lib/" + "/sw/lib/" + "/usr/local/lib/" + "/home/kevin/debian/src/clsql/db-odbc/" + "/odbc/lib/opt/") + :drive-letters '("C"))) + +(defvar *odbc-supporting-libraries* '("c") + "Used only by CMU. List of library flags needed to be passed to ld to +load the Odbc client library succesfully. If this differs at your site, +set to the right path before compiling or loading the system.") + +(defvar *odbc-library-loaded* nil + "T if foreign library was able to be loaded successfully") + +(defmethod clsql-base-sys:database-type-library-loaded ((database-type (eql :odbc))) + *odbc-library-loaded*) + +(defmethod clsql-base-sys:database-type-load-foreign ((database-type (eql :odbc))) + (uffi:load-foreign-library *odbc-library-path*) + (setq *odbc-library-loaded* t)) + +(clsql-base-sys:database-type-load-foreign :odbc) + + + diff --git a/db-odbc/odbc-package.lisp b/db-odbc/odbc-package.lisp new file mode 100644 index 0000000..a2b7b10 --- /dev/null +++ b/db-odbc/odbc-package.lisp @@ -0,0 +1,33 @@ +;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: odbc-package.lisp +;;;; Purpose: Package definition for low-level ODBC interface +;;;; Author: Kevin M. Rosenberg +;;;; Created: April 2004 +;;;; +;;;; $Id: odbc-package.lisp 7061 2003-09-07 06:34:45Z kevin $ +;;;; +;;;; This file, part of CLSQL, is Copyright (c) 2004 by Kevin M. Rosenberg +;;;; +;;;; 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 #:cl-user) + +(defpackage #:odbc + (:use #:cl #:clsql-uffi) + (:export + #:database-library-loaded + + #:connect + #:disconnect + #:query + #:execute + #:close-query + #:fetch-row + ) + (:documentation "This is the low-level interface ODBC.")) diff --git a/db-odbc/odbc-sql.lisp b/db-odbc/odbc-sql.lisp new file mode 100644 index 0000000..474ef8e --- /dev/null +++ b/db-odbc/odbc-sql.lisp @@ -0,0 +1,190 @@ +;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- +;;;; ************************************************************************* +;;;; FILE IDENTIFICATION +;;;; +;;;; Name: odbc-sql.cl +;;;; Purpose: Low-level interface for CLSQL ODBC backend +;;;; Programmer: Kevin M. Rosenberg +;;;; Date Started: Feb 2002 +;;;; +;;;; $Id: odbc-sql.lisp 8983 2004-04-12 21:16:48Z kevin $ +;;;; +;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg +;;;; +;;;; 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. +;;;; ************************************************************************* + +(defpackage #:clsql-odbc + (:use #:common-lisp #:clsql-base-sys) + (:export #:odbc-database) + (:documentation "This is the CLSQL interface to ODBC.")) + +(in-package #:clsql-odbc) + +;; ODBC interface + +(defclass odbc-database (database) + ((odbc-conn :accessor database-odbc-conn :initarg :odbc-conn))) + +(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)) + (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 + (handler-case + (make-instance 'odbc-database + :name (database-name-from-spec connection-spec :odbc) + :odbc-conn + (odbc:connect :user user + :password password + :data-source-name dsn)) + (error () ;; Init or Connect failed + (error 'clsql-connect-error + :database-type database-type + :connection-spec connection-spec + :errno nil + :error "Connection failed"))))) + +(defmethod database-disconnect ((database odbc-database)) + (odbc:disconnect (database-odbc-conn database)) + (setf (database-odbc-conn database) nil) + t) + +(defmethod database-query (query-expression (database odbc-database) result-types) + (handler-case + (odbc:query query-expression :db (database-odbc-conn database) + :types result-types) + (error () + (error 'clsql-sql-error + :database database + :expression query-expression + :errno nil + :error "Query failed")))) + +(defmethod database-execute-command (sql-expression + (database odbc-database)) + (handler-case + (odbc:execute sql-expression (database-odbc-conn database)) + (error () + (error 'clsql-sql-error + :database database + :expression sql-expression + :errno nil + :error "Execute command failed")))) + +(defstruct odbc-result-set + (query nil) + (types nil :type cons) + (full-set nil :type boolean)) + +(defmethod database-query-result-set ((query-expression string) + (database odbc-database) + &key full-set result-types) + (handler-case + (multiple-value-bind (query column-names) + (odbc:query query-expression + :db (database-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 + :types result-types) + (length column-names) + nil ;; not able to return number of rows with odbc + )) + (error () + (error 'clsql-sql-error + :database database + :expression query-expression + :errno nil + :error "Query result set failed")))) + +(defmethod database-dump-result-set (result-set (database odbc-database)) + (odbc:close-query (odbc-result-set-query result-set)) + t) + +(defmethod database-store-next-row (result-set + (database odbc-database) + list) + (let ((row (odbc:fetch-row (odbc-result-set-query result-set) nil 'eof))) + (if (eq row 'eof) + nil + (progn + (loop for elem in row + for rest on list + do + (setf (car rest) elem)) + list)))) + +;;; Sequence functions + +(defun %sequence-name-to-table (sequence-name) + (concatenate 'string "_clsql_seq_" (sql-escape sequence-name))) + +(defun %table-name-to-sequence-name (table-name) + (and (>= (length table-name) 11) + (string= (subseq table-name 0 11) "_clsql_seq_") + (subseq table-name 11))) + +(defmethod database-create-sequence (sequence-name + (database odbc-database)) + (let ((table-name (%sequence-name-to-table sequence-name))) + (database-execute-command + (concatenate 'string "CREATE TABLE " table-name + " (id int NOT NULL PRIMARY KEY AUTO_INCREMENT)") + database) + (database-execute-command + (concatenate 'string "INSERT INTO " table-name + " VALUES (0)") + database))) + +(defmethod database-drop-sequence (sequence-name + (database odbc-database)) + (database-execute-command + (concatenate 'string "DROP TABLE " (%sequence-name-to-table sequence-name)) + database)) + +(defmethod database-list-sequences ((database odbc-database) + &key (owner nil)) + (declare (ignore owner)) + (mapcar #'(lambda (s) (%table-name-to-sequence-name (car s))) + (database-query "SHOW TABLES LIKE '%clsql_seq%'" + database nil))) + +(defmethod database-set-sequence-position (sequence-name + (position integer) + (database odbc-database)) + (database-execute-command + (format nil "UPDATE ~A SET id=~A" (%sequence-name-to-table sequence-name) + position) + database) + position) + +(defmethod database-sequence-next (sequence-name (database odbc-database)) + (warn "Not implemented.")) + +(defmethod database-sequence-last (sequence-name (database odbc-database)) + (declare (ignore sequence-name))) + +(defmethod database-create (connection-spec (type (eql :odbc))) + (warn "Not implemented.")) + +(defmethod database-destroy (connection-spec (type (eql :odbc))) + (warn "Not implemented.")) + +(defmethod database-probe (connection-spec (type (eql :odbc))) + (warn "Not implemented.")) + +#+ignore +(when (clsql-base-sys:database-type-library-loaded :odbc) + (clsql-base-sys:initialize-database-type :database-type :odbc)) diff --git a/debian/changelog b/debian/changelog index 0b75350..39e2bec 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,4 +1,4 @@ -cl-sql (2.6.9-1) unstable; urgency=low +cl-sql (2.6.10-1) unstable; urgency=low * New upstream -- 2.34.1