r9199: fold clsql-base and clsql-base-sys into clsql-base
[clsql.git] / sql / new-objects.lisp
index c633de9ba8c02f1bf968e4a95f7eb75ad27ca4c3..d2013b74009e325b04bf13968e9799bf6922bc1e 100644 (file)
@@ -15,8 +15,6 @@
 
 (in-package #:clsql-sys)
 
-
-
 (defclass standard-db-object ()
   ((stored :db-kind :virtual
            :initarg :stored
   (:metaclass standard-db-class)
   (:documentation "Superclass for all CLSQL View Classes."))
 
-(defvar *deserializing* nil)
-(defvar *initializing* nil)
-
-(defmethod initialize-instance :around ((object standard-db-object)
-                                       &rest all-keys &key &allow-other-keys)
-  (declare (ignore all-keys))
-  (let ((*initializing* t))
-    (call-next-method)
-    (unless *deserializing*
-      #+nil (created-object object)
-      (update-records-from-instance object))))
+(defvar *db-deserializing* nil)
+(defvar *db-initializing* nil)
 
 (defmethod slot-value-using-class ((class standard-db-class) instance slot-def)
   (declare (optimize (speed 3)))
-  (unless *deserializing*
-    (let ((slot-name (%slot-def-name slot-def))
-          (slot-kind (view-class-slot-db-kind slot-def)))
+  (unless *db-deserializing*
+    (let* ((slot-name (%svuc-slot-name slot-def))
+          (slot-object (%svuc-slot-object slot-def class))
+          (slot-kind (view-class-slot-db-kind slot-object)))
       (when (and (eql slot-kind :join)
                  (not (slot-boundp instance slot-name)))
-        (let ((*deserializing* t))
+        (let ((*db-deserializing* t))
           (setf (slot-value instance slot-name)
                 (fault-join-slot class instance slot-def))))))
-  (call-next-method))
+    (call-next-method))
 
 (defmethod (setf slot-value-using-class) :around (new-value (class standard-db-class) instance slot-def)
   (declare (ignore new-value))
-  (let* ((slot-name (%slot-def-name slot-def))
+  (let* ((slot-name (slot-definition-name slot-def))
          (slot-kind (view-class-slot-db-kind slot-def))
          (no-update? (or (eql slot-kind :virtual)
-                         *initializing*
-                         *deserializing*)))
+                         *db-initializing*
+                         *db-deserializing*)))
     (call-next-method)
     (unless no-update?
       (update-record-from-slot instance slot-name))))
 
-(defun %slot-def-name (slot)
-  #+lispworks slot
-  #-lispworks (slot-definition-name slot))
-
-(defun %slot-object (slot class)
-  (declare (ignorable class))
-  #+lispworks (clos:find-slot-definition slot class)
-  #-lispworks slot)
+(defmethod initialize-instance :around ((object standard-db-object)
+                                       &rest all-keys &key &allow-other-keys)
+  (declare (ignore all-keys))
+  (let ((*db-initializing* t))
+    (call-next-method)
+    (unless *db-deserializing*
+      #+nil (created-object object)
+      (update-records-from-instance object))))
 
 (defun sequence-from-class (view-class-name)
   (sql-escape
               (database-output-sql keylist database)))))
 
 
-
-#+noschema
-(progn
-#.(locally-enable-sql-reader-syntax)
-
-(defun ensure-schema-version-table (database)
-  (unless (table-exists-p "clsql_object_v" :database database)
-    (create-table [clsql_object_v] '(([name] string)
-                                    ([vers] integer)
-                                    ([def] string))
-                  :database database)))
-
-(defun update-schema-version-records (view-class-name
-                                      &key (database *default-database*))
-  (let ((schemadef nil)
-        (tclass (find-class view-class-name)))
-    (dolist (slotdef (class-slots tclass))
-      (let ((res (database-generate-column-definition view-class-name
-                                                      slotdef database)))
-        (when res (setf schemadef (cons res schemadef)))))
-    (when schemadef
-      (delete-records :from [clsql_object_v]
-                      :where [= [name] (sql-escape (class-name tclass))]
-                      :database database)
-      (insert-records :into [clsql_object_v]
-                      :av-pairs `(([name] ,(sql-escape (class-name tclass)))
-                                  ([vers] ,(car (object-version tclass)))
-                                  ([def] ,(prin1-to-string
-                                           (object-definition tclass))))
-                      :database database))))
-
-#.(restore-sql-reader-syntax-state)
-)
-
 (defun create-view-from-class (view-class-name
                                &key (database *default-database*))
   "Creates a view in DATABASE based on VIEW-CLASS-NAME which defines
@@ -140,9 +96,7 @@ the view. The argument DATABASE has a default value of
   (let ((tclass (find-class view-class-name)))
     (if tclass
         (let ((*default-database* database))
-          (%install-class tclass database)
-          #+noschema (ensure-schema-version-table database)
-          #+noschema (update-schema-version-records view-class-name :database database))
+          (%install-class tclass database))
         (error "Class ~s not found." view-class-name)))
   (values))
 
@@ -173,10 +127,7 @@ which defines that view. The argument DATABASE has a default value of
   (let ((tclass (find-class view-class-name)))
     (if tclass
         (let ((*default-database* database))
-          (%uninstall-class tclass)
-         #+nil
-          (delete-records :from [clsql_object_v]
-                          :where [= [name] (sql-escape view-class-name)]))
+          (%uninstall-class tclass))
         (error "Class ~s not found." view-class-name)))
   (values))
 
@@ -300,13 +251,7 @@ superclass of the newly-defined View Class."
       list))
 
 (defun slot-type (slotdef)
-  (specified-type slotdef)
-  #+ignore
-  (let ((slot-type (specified-type slotdef)))
-    (if (listp slot-type)
-        (cons (find-symbol (symbol-name (car slot-type)) :clsql-sys)
-              (cdr slot-type))
-        (find-symbol (symbol-name slot-type) :clsql-sys))))
+  (specified-type slotdef))
 
 (defvar *update-context* nil)
 
@@ -379,75 +324,6 @@ superclass of the newly-defined View Class."
       (mapc #'update-slot slotdeflist values)
       obj))
 
-(defun synchronize-keys (src srckey dest destkey)
-  (let ((skeys (if (listp srckey) srckey (list srckey)))
-       (dkeys (if (listp destkey) destkey (list destkey))))
-    (mapcar #'(lambda (sk dk)
-               (setf (slot-value dest dk)
-                     (typecase sk
-                       (symbol
-                        (slot-value src sk))
-                       (t sk))))
-           skeys dkeys)))
-
-(defun desynchronize-keys (dest destkey)
-  (let ((dkeys (if (listp destkey) destkey (list destkey))))
-    (mapcar #'(lambda (dk)
-               (setf (slot-value dest dk) nil))
-           dkeys)))
-
-(defmethod add-to-relation ((target standard-db-object)
-                           slot-name
-                           (value standard-db-object))
-  (let* ((objclass (class-of target))
-        (sdef (or (slotdef-for-slot-with-class slot-name objclass)
-                   (error "~s is not an known slot on ~s" slot-name target)))
-        (dbinfo (view-class-slot-db-info sdef))
-        (join-class (gethash :join-class dbinfo))
-        (homekey (gethash :home-key dbinfo))
-        (foreignkey (gethash :foreign-key dbinfo))
-        (to-many (gethash :set dbinfo)))
-    (unless (equal (type-of value) join-class)
-      (error 'clsql-type-error :slotname slot-name :typespec join-class
-             :value value))
-    (when (gethash :target-slot dbinfo)
-      (error "add-to-relation does not work with many-to-many relations yet."))
-    (if to-many
-       (progn
-         (synchronize-keys target homekey value foreignkey)
-         (if (slot-boundp target slot-name)
-              (unless (member value (slot-value target slot-name))
-                (setf (slot-value target slot-name)
-                      (append (slot-value target slot-name) (list value))))
-              (setf (slot-value target slot-name) (list value))))
-        (progn
-          (synchronize-keys value foreignkey target homekey)
-          (setf (slot-value target slot-name) value)))))
-
-(defmethod remove-from-relation ((target standard-db-object)
-                           slot-name (value standard-db-object))
-  (let* ((objclass (class-of target))
-        (sdef (slotdef-for-slot-with-class slot-name objclass))
-        (dbinfo (view-class-slot-db-info sdef))
-        (homekey (gethash :home-key dbinfo))
-        (foreignkey (gethash :foreign-key dbinfo))
-        (to-many (gethash :set dbinfo)))
-    (when (gethash :target-slot dbinfo)
-      (error "remove-relation does not work with many-to-many relations yet."))
-    (if to-many
-       (progn
-         (desynchronize-keys value foreignkey)
-         (if (slot-boundp target slot-name)
-             (setf (slot-value target slot-name)
-                   (remove value
-                           (slot-value target slot-name)
-                            :test #'equal))))
-        (progn
-          (desynchronize-keys target homekey)
-          (setf (slot-value target slot-name)
-                nil)))))
-
-
 (defgeneric update-record-from-slot (object slot &key database)
   (:documentation
    "The generic function UPDATE-RECORD-FROM-SLOT updates an individual
@@ -468,7 +344,7 @@ are derived from the View Class definition."))
     (let* ((att (view-class-slot-column sd))
            (val (db-value-from-slot sd (slot-value obj slot) database)))
       (cond ((and vct sd stored?)
-             (update-records :table (sql-expression :table vct)
+             (update-records (sql-expression :table vct)
                              :attributes (list (sql-expression :attribute att))
                              :values (list val)
                              :where (key-qualifier-for-instance obj :database database)
@@ -503,7 +379,7 @@ names are derived from the view class definition."))
                                    (db-value-from-slot s val database))))
                        sds)))
     (cond ((and avps stored?)
-           (update-records :table (sql-expression :table vct)
+           (update-records (sql-expression :table vct)
                            :av-pairs avps
                            :where (key-qualifier-for-instance
                                    obj :database database)
@@ -517,7 +393,6 @@ names are derived from the view class definition."))
            (error "Unable to update records"))))
   t)
 
-
 (defgeneric update-records-from-instance (object &key database)
   (:documentation
    "Using an instance of a view class, update the database table that
@@ -544,7 +419,7 @@ associated with that database."))
       (unless record-values
         (error "No settable slots."))
       (if (slot-value obj 'stored)
-          (update-records :table (sql-expression :table view-class-table)
+          (update-records (sql-expression :table view-class-table)
                           :av-pairs record-values
                           :where (key-qualifier-for-instance
                                   obj :database database)
@@ -559,6 +434,12 @@ associated with that database."))
  (setf (symbol-function (intern (symbol-name '#:store-instance)))
    (symbol-function 'update-records-from-instance))
 
+(defgeneric delete-instance-records (instance)
+  (:documentation
+   "Deletes the records represented by INSTANCE from the database
+associated with it. If instance has no associated database, an error
+is signalled."))
+
 (defmethod delete-instance-records ((object standard-db-object))
   (let ((vt (sql-expression :table (view-table (class-of object))))
         (qualifier (key-qualifier-for-instance object :database *default-database*)))
@@ -643,7 +524,7 @@ DATABASE-NULL-VALUE on the type of the slot."))
 
 (defmethod database-get-type-specifier (type args database)
   (declare (ignore type args))
-  (if (member (database-type database) '(:postgresql :postgresql-socket))
+  (if (member (database-underlying-type database) '(:postgresql :postgresql-socket))
           "VARCHAR"
           "VARCHAR(255)"))
 
@@ -658,7 +539,7 @@ DATABASE-NULL-VALUE on the type of the slot."))
                                         database)
   (if args
       (format nil "VARCHAR(~A)" (car args))
-      (if (member (database-type database) '(:postgresql :postgresql-socket))
+      (if (member (database-underlying-type database) '(:postgresql :postgresql-socket))
           "VARCHAR"
           "VARCHAR(255)")))
 
@@ -666,20 +547,20 @@ DATABASE-NULL-VALUE on the type of the slot."))
                                         database)
   (if args
       (format nil "VARCHAR(~A)" (car args))
-      (if (member (database-type database) '(:postgresql :postgresql-socket))
+      (if (member (database-underlying-type database) '(:postgresql :postgresql-socket))
           "VARCHAR"
           "VARCHAR(255)")))
 
 (defmethod database-get-type-specifier ((type (eql 'string)) args database)
   (if args
       (format nil "VARCHAR(~A)" (car args))
-      (if (member (database-type database) '(:postgresql :postgresql-socket))
+      (if (member (database-underlying-type database) '(:postgresql :postgresql-socket))
           "VARCHAR"
           "VARCHAR(255)")))
 
 (defmethod database-get-type-specifier ((type (eql 'wall-time)) args database)
   (declare (ignore args))
-  (case (database-type database)
+  (case (database-underlying-type database)
     (:postgresql
      "TIMESTAMP WITHOUT TIME ZONE")
     (:postgresql-socket
@@ -730,7 +611,7 @@ DATABASE-NULL-VALUE on the type of the slot."))
   (declare (ignore database))
   (progv '(*print-circle* *print-array*) '(t t)
     (let ((escaped (prin1-to-string val)))
-      (clsql-base-sys::substitute-char-string
+      (clsql-base::substitute-char-string
        escaped #\Null " "))))
 
 (defmethod database-output-sql-as-type ((type (eql 'symbol)) val database)
@@ -907,9 +788,9 @@ DATABASE-NULL-VALUE on the type of the slot."))
            (optimize (debug 3) (speed 1)))
   ;; (cmsg "Args = ~s" args)
   (remf args :from)
-  (let* ((*deserializing* t)
+  (let* ((*db-deserializing* t)
          (*default-database* (or database
-                                 (error 'usql-nodb-error))))
+                                 (error 'clsql-no-database-error nil))))
     (flet ((table-sql-expr (table)
              (sql-expression :table (view-table table)))
            (ref-equal (ref1 ref2)
@@ -959,7 +840,7 @@ DATABASE-NULL-VALUE on the type of the slot."))
           (mapcar #'build-object res))))))
 
 (defun %make-fresh-object (class-name slots values)
-  (let* ((*initializing* t)
+  (let* ((*db-initializing* t)
          (obj (make-instance class-name
                              :stored t)))
     (setf obj (get-slot-values-from-view obj slots values))