4fb4f475f7738c983f0c14e1348e0a5ad38b8145
[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.2 2002/03/24 04:01:26 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 database-initialize-database-type ((database-type (eql :aodbc)))
29   t)
30
31 (defclass aodbc-database (database)
32   ((aodbc-conn :accessor database-aodbc-conn :initarg :aodbc-conn)))
33
34 (defmethod database-name-from-spec (connection-spec
35                                     (database-type (eql :aodbc)))
36   (check-connection-spec connection-spec database-type (dsn user password))
37   (destructuring-bind (dsn user password) connection-spec
38     (declare (ignore password))
39     (concatenate 'string dsn "/" user)))
40
41 (defmethod database-connect (connection-spec (database-type (eql :aodbc)))
42   (check-connection-spec connection-spec database-type (dsn user password))
43   (destructuring-bind (dsn user password) connection-spec
44     (handler-case
45         (make-instance 'aodbc-database
46           :name (database-name-from-spec connection-spec :aodbc)
47           :aodbc-conn
48           (dbi:connect :user user
49                        :password password
50                        :data-source-name dsn))
51       (error ()         ;; Init or Connect failed
52         (error 'clsql-connect-error
53                :database-type database-type
54                :connection-spec connection-spec
55                :errno nil
56                :error "Connection failed")))))
57
58 (defmethod database-disconnect ((database aodbc-database))
59   (dbi:disconnect (database-aodbc-conn database))
60   (setf (database-aodbc-conn database) nil)
61   t)
62
63 (defmethod database-query (query-expression (database aodbc-database))
64   (handler-case
65       (dbi:sql query-expression :db (database-aodbc-conn database))
66     (error ()
67       (error 'clsql-sql-error
68              :database database
69              :expression query-expression
70              :errno nil
71              :error "Query failed"))))
72
73 (defmethod database-execute-command (sql-expression 
74                                      (database aodbc-database))
75   (handler-case
76       (dbi:sql sql-expression :db (database-aodbc-conn database))
77     (error ()
78       (error 'clsql-sql-error
79              :database database
80              :expression sql-expression
81              :errno nil
82              :error "Execute command failed"))))
83
84 (defstruct aodbc-result-set
85   (query nil)
86   (full-set nil))
87
88 (defmethod database-query-result-set (query-expression
89                                       (database aodbc-database) 
90                                       &optional full-set)
91   (handler-case 
92       (multiple-value-bind (query column-names)
93           (dbi:sql query-expression 
94                    :db (database-aodbc-conn database) 
95                    :row-count nil
96                    :column-names t
97                    :query t
98                    )
99         (values
100          (make-aodbc-result-set :query query :full-set full-set)
101          (length column-names)
102          nil ;; not able to return number of rows with aodbc
103          ))
104     (error ()
105       (error 'clsql-sql-error
106              :database database
107              :expression query-expression
108              :errno nil
109              :error "Query result set failed"))))
110
111 (defmethod database-dump-result-set (result-set (database aodbc-database))
112   (dbi:close-query (aodbc-result-set-query result-set))
113   t)
114
115 (defmethod database-store-next-row (result-set
116                                     (database aodbc-database)
117                                     list)
118   (let ((row (dbi:fetch-row (aodbc-result-set-query result-set) nil 'eof)))
119     (if (eq row 'eof)
120         nil
121       (progn
122         (loop for elem in row
123             for rest on list
124             do
125               (setf (car rest) elem))
126         list))))
127
128