r1698: *** empty log message ***
[clsql.git] / interfaces / aodbc / aodbc-sql.cl
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          aodbc-sql.cl
6 ;;;; Purpose:       Low-level interface for CLSQL AODBC backend
7 ;;;; Programmer:    Kevin M. Rosenberg
8 ;;;; Date Started:  Feb 2002
9 ;;;;
10 ;;;; $Id: aodbc-sql.cl,v 1.7 2002/03/29 08:23:38 kevin Exp $
11 ;;;;
12 ;;;; This file, part of CLSQL, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;;
14 ;;;; CLSQL users are granted the rights to distribute and use this software
15 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
16 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
17 ;;;; *************************************************************************
18
19 (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
20 (in-package :clsql-aodbc)
21
22
23 (defmethod database-type-library-loaded ((database-type (eql :aodbc)))
24   "T if foreign library was able to be loaded successfully. "
25   (when (find-package :dbi) ;; finds Allegro's DBI (AODBC) package
26     t))
27
28 (defmethod clsql-sys:database-type-load-foreign ((databae-type (eql :aodbc)))
29   t)
30
31 (when (find-package :dbi)
32   (clsql-sys:database-type-load-foreign :aodbc)) ;; doesn't do anything
33
34 (defmethod database-initialize-database-type ((database-type (eql :aodbc)))
35   t)
36
37 (defclass aodbc-database (database)
38   ((aodbc-conn :accessor database-aodbc-conn :initarg :aodbc-conn)))
39
40 (defmethod database-name-from-spec (connection-spec
41                                     (database-type (eql :aodbc)))
42   (check-connection-spec connection-spec database-type (dsn user password))
43   (destructuring-bind (dsn user password) connection-spec
44     (declare (ignore password))
45     (concatenate 'string dsn "/" user)))
46
47 (defmethod database-connect (connection-spec (database-type (eql :aodbc)))
48   (check-connection-spec connection-spec database-type (dsn user password))
49   (destructuring-bind (dsn user password) connection-spec
50     (handler-case
51         (make-instance 'aodbc-database
52           :name (database-name-from-spec connection-spec :aodbc)
53           :aodbc-conn
54           (dbi:connect :user user
55                        :password password
56                        :data-source-name dsn))
57       (error ()         ;; Init or Connect failed
58         (error 'clsql-connect-error
59                :database-type database-type
60                :connection-spec connection-spec
61                :errno nil
62                :error "Connection failed")))))
63
64 (defmethod database-disconnect ((database aodbc-database))
65   (dbi:disconnect (database-aodbc-conn database))
66   (setf (database-aodbc-conn database) nil)
67   t)
68
69 (defmethod database-query (query-expression (database aodbc-database) types) 
70   (handler-case
71       (dbi:sql query-expression :db (database-aodbc-conn database)
72                :types types)
73     (error ()
74       (error 'clsql-sql-error
75              :database database
76              :expression query-expression
77              :errno nil
78              :error "Query failed"))))
79
80 (defmethod database-execute-command (sql-expression 
81                                      (database aodbc-database))
82   (handler-case
83       (dbi:sql sql-expression :db (database-aodbc-conn database))
84     (error ()
85       (error 'clsql-sql-error
86              :database database
87              :expression sql-expression
88              :errno nil
89              :error "Execute command failed"))))
90
91 (defstruct aodbc-result-set
92   (query nil)
93   (types nil :type cons)
94   (full-set nil :type boolean))
95
96 (defmethod database-query-result-set (query-expression (database aodbc-database) 
97                                       &key full-set types)
98   (handler-case 
99       (multiple-value-bind (query column-names)
100           (dbi:sql query-expression 
101                    :db (database-aodbc-conn database) 
102                    :row-count nil
103                    :column-names t
104                    :query t
105                    :types types
106                    )
107         (values
108          (make-aodbc-result-set :query query :full-set full-set 
109                                 :types types)
110          (length column-names)
111          nil ;; not able to return number of rows with aodbc
112          ))
113     (error ()
114       (error 'clsql-sql-error
115              :database database
116              :expression query-expression
117              :errno nil
118              :error "Query result set failed"))))
119
120 (defmethod database-dump-result-set (result-set (database aodbc-database))
121   (dbi:close-query (aodbc-result-set-query result-set))
122   t)
123
124 (defmethod database-store-next-row (result-set
125                                     (database aodbc-database)
126                                     list)
127   (let ((row (dbi:fetch-row (aodbc-result-set-query result-set) nil 'eof)))
128     (if (eq row 'eof)
129         nil
130       (progn
131         (loop for elem in row
132             for rest on list
133             do
134               (setf (car rest) elem))
135         list))))
136
137