More work on a default encoding so that running through cffi-uffi,
[clsql.git] / db-sqlite3 / sqlite3-sql.lisp
index 1ba6b0ba68649deee35d6a367d1b9bc826095f08..8ce592c6fbe1978f1e0d0ee824b33f4ae9ca05a3 100644 (file)
@@ -4,12 +4,10 @@
 ;;;;
 ;;;; Name:     sqlite-sql.lisp
 ;;;; Purpose:  High-level SQLite3 interface
-;;;; Authors:  Aurelio Bignoli
+;;;; Authors:  Aurelio Bignoli & Kevin Rosenberg
 ;;;; Created:  Oct 2004
 ;;;;
-;;;; $Id$
-;;;;
-;;;; This file, part of CLSQL, is Copyright (c) 2004 by Aurelio Bignoli
+;;;; This file, part of CLSQL, is Copyright (c) 2004-2010 by Aurelio Bignoli & Kevin 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
@@ -33,7 +31,7 @@
 (defmethod database-name-from-spec (connection-spec
                                     (database-type (eql :sqlite3)))
   (check-sqlite3-connection-spec connection-spec)
-  (first connection-spec))
+  (princ-to-string (first connection-spec)))
 
 (defmethod database-connect (connection-spec (database-type (eql :sqlite3)))
   (check-sqlite3-connection-spec connection-spec)
                          (if (eq (first types) :blob)
                              (clsql-uffi:convert-raw-field
                               (sqlite3:sqlite3-column-blob stmt i)
-                              types 0
-                              (sqlite3:sqlite3-column-bytes stmt i))
+                              (car types)
+                              :length (sqlite3:sqlite3-column-bytes stmt i)
+                              :encoding (encoding database))
                              (clsql-uffi:convert-raw-field
                               (sqlite3:sqlite3-column-text stmt i)
-                              types 0))))
+                              (car types)
+                              :encoding (encoding database)))))
           ;; Advance result set cursor.
           (handler-case
               (unless (sqlite3:sqlite3-step stmt)
                                 collect (if (eq (first types) :blob)
                                             (clsql-uffi:convert-raw-field
                                              (sqlite3:sqlite3-column-blob stmt i)
-                                             types 0
-                                             (sqlite3:sqlite3-column-bytes stmt i))
+                                             (car types)
+                                             :length (sqlite3:sqlite3-column-bytes stmt i)
+                                             :encoding (encoding database))
                                             (clsql-uffi:convert-raw-field
                                              (sqlite3:sqlite3-column-text stmt i)
-                                             types 0)))))
+                                             (car types)
+                                             :encoding (encoding database))))))
                    (when field-names
                      (setf col-names (loop for n from 0 below n-col
                                            collect (sqlite3:sqlite3-column-name stmt n))))
 
 (declaim (inline sqlite3-table-info))
 (defun sqlite3-table-info (table database)
-  (database-query (format nil "PRAGMA table_info('~A')" table)
-                  database nil nil))
+  (let ((sql (format nil "PRAGMA table_info('~A')"
+                     (clsql-sys::unescaped-database-identifier table))))
+    (database-query sql database nil nil)))
 
 (defmethod database-list-attributes (table (database sqlite3-database)
                                            &key (owner nil))
   (declare (ignore owner))
   
   (loop for field-info in (sqlite3-table-info table database)
-      when (string= attribute (second field-info))
+      when (string= (clsql-sys::unescaped-database-identifier attribute)
+                    (second field-info))
       return
         (let* ((raw-type (third field-info))
                (start-length (position #\( raw-type))
-               (type (string-trim '(#\space #\tab #\newline)
+               (type (string-trim clsql-sys::+whitespace-chars+
                                  (if start-length
                                      (subseq raw-type 0 start-length)
                                      raw-type)))
                   (if (string-equal (fourth field-info) "0")
                       1 0)))))
 
+(defmethod database-last-auto-increment-id ((database sqlite3-database) table column)
+  (declare (ignore table column))
+  (car (query "SELECT LAST_INSERT_ROWID();"
+             :flatp t :field-names nil
+             :database database)))
+
 (defmethod database-create (connection-spec (type (eql :sqlite3)))
   (declare (ignore connection-spec))
   ;; databases are created automatically by Sqlite3
     (or (string-equal ":memory:" name)
         (and (probe-file name) t))))
 
+(defmethod database-get-type-specifier ((type (eql 'integer))
+                                        args database
+                                        (db-type (eql :sqlite3)))
+  (declare (ignore database))
+  (if args
+      (format nil "INTEGER(~A)" (car args))
+      "INTEGER"))
+
+(defmethod database-get-type-specifier ((type (eql 'integer))
+                                        args database
+                                        (db-type (eql :sqlite3)))
+  (declare (ignore database))
+  (if args
+      (format nil "INTEGER(~A)" (car args))
+      "INTEGER"))
+
 ;;; Database capabilities
 
 (defmethod db-type-has-boolean-where? ((db-type (eql :sqlite3)))
   nil)
+
+(defmethod db-type-has-auto-increment? ((db-type (eql :sqlite3)))
+  t)