r9186: add attribute caching, improve inititialize-database-type
[clsql.git] / db-sqlite / sqlite-sql.lisp
index ca6124ae2bf4e1dfe0c8f46f031e752201f88d06..703eb94928ded58f5e9a54162530c1cfa5782384 100644 (file)
       (multiple-value-bind (data row-n col-n)
          (sqlite:sqlite-get-table (sqlite-db database) query-expression)
        #-clisp (declare (type sqlite:sqlite-row-pointer-type data))
-       (if (= row-n 0)
-           nil
-           (prog1
-               ;; The first col-n elements are column names.
-                (values
-                 (loop for i from col-n below (* (1+ row-n) col-n) by col-n
-                       collect (loop for j from 0 below col-n
-                                     collect
-                                     (#+clisp aref
-                                              #-clisp sqlite:sqlite-aref
-                                              data (+ i j))))
-                 (when field-names
-                   (loop for i from 0 below col-n
-                         collect (#+clisp aref
-                                  #-clisp sqlite:sqlite-aref
-                                  data i))))
-              #-clisp (sqlite:sqlite-free-table data))
-            ))
+       (let ((rows
+              (when (plusp row-n)
+                (loop for i from col-n below (* (1+ row-n) col-n) by col-n
+                    collect (loop for j from 0 below col-n
+                                collect
+                                  (#+clisp aref
+                                           #-clisp sqlite:sqlite-aref
+                                           data (+ i j))))))
+             (names
+              (when field-names
+                (loop for j from 0 below col-n
+                    collect (#+clisp aref
+                                     #-clisp sqlite:sqlite-aref
+                                     data j)))))
+         #-clisp (sqlite:sqlite-free-table data)
+         (values rows names)))
     (sqlite:sqlite-error (err)
                          (error 'clsql-sql-error
                                 :database database
                       (string-equal (subseq s 0 11) "_CLSQL_SEQ_")))
              (mapcar #'car (database-query
                             "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name"
-                            database '()))))
+                            database nil nil))))
 
 (defmethod database-list-views ((database sqlite-database)
                                 &key (owner nil))
   (declare (ignore owner))
   (mapcar #'car (database-query
                  "SELECT name FROM sqlite_master WHERE type='view' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='view' ORDER BY name"
-                 database nil)))
+                 database nil nil)))
 
 (defmethod database-list-indexes ((database sqlite-database)
                                   &key (owner nil))
   (declare (ignore owner))
   (mapcar #'car (database-query
                  "SELECT name FROM sqlite_master WHERE type='index' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' ORDER BY name"
-                 database nil)))
+                 database nil nil)))
 
 (defmethod database-list-table-indexes (table (database sqlite-database)
                                        &key (owner nil))
              nil
              "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name='~A' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='index' AND tbl_name='~A' ORDER BY name"
              table table)
-            database nil))))
+            database nil nil))))
 
 (declaim (inline sqlite-table-info))
 (defun sqlite-table-info (table database)
   (database-query (format nil "PRAGMA table_info('~A')" table)
-                         database '()))
+                 database nil nil))
 
 (defmethod database-list-attributes (table (database sqlite-database)
                                            &key (owner nil))
                                     &key (owner nil))
   (declare (ignore owner))
   (loop for field-info in (sqlite-table-info table database)
-       when (string= attribute (second field-info))
-       return (third field-info)))
+      when (string= attribute (second field-info))
+      return 
+       (let* ((raw-type (third field-info))
+              (start-length (position #\( raw-type))
+              (type (if start-length
+                        (subseq raw-type 0 start-length)
+                      raw-type))
+              (length (if start-length
+                          (parse-integer (subseq raw-type (1+ start-length))
+                                         :junk-allowed t)
+                        nil)))
+         (values (when type (ensure-keyword type)) 
+                 length
+                 nil
+                 (if (string-equal (fourth field-info) "0")
+                     1 0)))))
 
 (defun %sequence-name-to-table-name (sequence-name)
   (concatenate 'string "_CLSQL_SEQ_" (sql-escape sequence-name)))
                 (and sn (list sn))))
           (database-query
            "SELECT name FROM sqlite_master WHERE type='table' UNION ALL SELECT name FROM sqlite_temp_master WHERE type='table' ORDER BY name"
-           database '())))
+           database nil nil)))
 
 (defmethod database-sequence-next (sequence-name (database sqlite-database))
   (without-interrupts
           (car (database-query 
                 (concatenate 'string "SELECT last_value,is_called FROM " 
                              table-name)
-                database
-                :auto))))
+                database :auto nil))))
      (cond
        ((char-equal (schar (second tuple) 0) #\f)
        (database-execute-command
      (caar (database-query 
            (concatenate 'string "SELECT last_value FROM " 
                         (%sequence-name-to-table-name sequence-name))
-           database
-           :auto)))))
+           database :auto nil)))))
 
 (defmethod database-set-sequence-position (sequence-name
                                            (position integer)