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