initial version of the autoincrement support for sqlite3 backend
authorVictor <victor@victor-mobi>
Wed, 16 Oct 2013 14:34:08 +0000 (17:34 +0300)
committerVictor <anyakinvictor@yahoo.com>
Wed, 16 Oct 2013 14:34:08 +0000 (17:34 +0300)
clsql-sqlite3.asd
db-sqlite3/sqlite3-methods.lisp [new file with mode: 0644]
db-sqlite3/sqlite3-sql.lisp
sql/expressions.lisp
sql/generics.lisp

index a32130f..f83d2dd 100644 (file)
@@ -32,5 +32,6 @@
            :components
            ((:file "sqlite3-package")
             (:file "sqlite3-loader" :depends-on ("sqlite3-package"))
-            (:file  "sqlite3-api" :depends-on ("sqlite3-loader"))
-            (:file "sqlite3-sql" :depends-on ("sqlite3-api"))))))
+            (:file "sqlite3-api" :depends-on ("sqlite3-loader"))
+            (:file "sqlite3-sql" :depends-on ("sqlite3-api"))
+            (:file "sqlite3-methods" :depends-on ("sqlite3-sql"))))))
diff --git a/db-sqlite3/sqlite3-methods.lisp b/db-sqlite3/sqlite3-methods.lisp
new file mode 100644 (file)
index 0000000..181fca4
--- /dev/null
@@ -0,0 +1,20 @@
+;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*-
+
+(in-package #:clsql-sys)
+
+;; This method generates primary key constraints part of the table
+;; definition. For Sqlite autoincrement primary keys to work properly
+;; this part of the table definition must be left out.
+(defmethod database-pkey-constraint ((class standard-db-class)
+                                    (database clsql-sqlite3:sqlite3-database)))
+
+(defmethod database-translate-constraint (constraint
+                                         (database clsql-sqlite3:sqlite3-database))
+  ;; Primary purpose of this is method is to intecept and translate
+  ;; auto-increment primary keys constraints.
+  (let ((constraint-name (symbol-name constraint)))
+    (if (eql constraint :auto-increment)
+       (cons constraint "PRIMARY KEY AUTOINCREMENT")
+       (call-next-method))))
+
+;; EOF
index 63e48ec..7b16b48 100644 (file)
                   (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)
index 8b6167b..16bf687 100644 (file)
@@ -1111,17 +1111,20 @@ uninclusive, and the args from that keyword to the end."
    ))
 
 (defmethod database-constraint-statement (constraint-list database)
-  (declare (ignore database))
-  (make-constraints-description constraint-list))
+  (make-constraints-description constraint-list database))
+
+(defmethod database-translate-constraint (constraint database)
+  (assoc (symbol-name constraint)
+        *constraint-types*
+        :test #'equal))
 
-(defun make-constraints-description (constraint-list)
+(defun make-constraints-description (constraint-list database)
   (if constraint-list
       (let ((string ""))
         (do ((constraint constraint-list (cdr constraint)))
             ((null constraint) string)
-          (let ((output (assoc (symbol-name (car constraint))
-                               *constraint-types*
-                               :test #'equal)))
+          (let ((output (database-translate-constraint (car constraint)
+                                                      database)))
             (if (null output)
                 (error 'sql-user-error
                        :message (format nil "unsupported column constraint '~A'"
index 748cbd9..7f276fc 100644 (file)
@@ -193,3 +193,8 @@ the arguments EXPR and DATABASE."))
 
 (defgeneric database-constraint-statement  (constraints database)
   )
+
+(defgeneric database-translate-constraint (constraint database)
+  (:documentation "Given a column constraint returns its
+database-specific name. For example, auto-increment constraints can
+have different names in different database engines."))