r9220: Added type specifier for universal-time.
[clsql.git] / sql / metaclasses.lisp
index a0b94716461ac2683559dab24189eeb57e79c5a4..d6d92b85ce3595aef251d63779212c3fe69753b1 100644 (file)
     :accessor object-definition
     :initarg :definition
     :initform nil)
-   (version
-    :accessor object-version
-    :initarg :version
-    :initform 0)
    (key-slots
     :accessor key-slots
     :initform nil)
     :initform nil))
   (:documentation "VIEW-CLASS metaclass."))
 
-#+lispworks
-(defmacro push-on-end (value location)
-  `(setf ,location (nconc ,location (list ,value))))
-
-;; As Heiko Kirscke (author of PLOB!) would say:  !@##^@%! Lispworks!
-#+lispworks
-(defconstant +extra-slot-options+ '(:column :db-kind :db-reader :nulls-ok
-                                   :db-writer :db-type :db-info))
-
-#+lispworks 
-(define-setf-expander assoc (key alist &environment env)
-  (multiple-value-bind (temps vals stores store-form access-form)
-      (get-setf-expansion alist env)
-    (let ((new-value (gensym "NEW-VALUE-"))
-          (keyed (gensym "KEYED-"))
-          (accessed (gensym "ACCESSED-"))
-          (store-new-value (car stores)))
-      (values (cons keyed temps)
-              (cons key vals)
-              `(,new-value)
-              `(let* ((,accessed ,access-form)
-                      (,store-new-value (assoc ,keyed ,accessed)))
-               (if ,store-new-value
-                   (rplacd ,store-new-value ,new-value)
-                   (progn
-                     (setq ,store-new-value
-                            (acons ,keyed ,new-value ,accessed))
-                     ,store-form))
-               ,new-value)
-              `(assoc ,new-value ,access-form)))))
-
-#+lispworks 
-(defmethod clos::canonicalize-defclass-slot :around
-  ((prototype standard-db-class) slot)
- "\\lw\\ signals an error on unknown slot options; so this method
-removes any extra allowed options before calling the default method
-and returns the canonicalized extra options concatenated to the result
-of the default method.  The extra allowed options are the value of the
-\\fcite{+extra-slot-options+}."
-  (let ((extra-slot-options ())
-        (rest-options ())
-        (result ()))
-    (do ((olist (cdr slot) (cddr olist)))
-        ((null olist))
-      (let ((option (car olist)))
-        (cond
-         ((find option +extra-slot-options+)
-          ;;(push (cons option (cadr olist)) extra-slot-options))
-          (setf (assoc option extra-slot-options) (cadr olist)))
-         (t
-          (push (cadr olist) rest-options)
-          (push (car olist) rest-options)))))
-    (setf result (call-next-method prototype (cons (car slot) rest-options)))
-    (dolist (option extra-slot-options)
-      (push-on-end (car option) result)
-      (push-on-end `(quote ,(cdr option)) result))
-    result))
+;;; Lispworks 4.2 and before requires special processing of extra slot and class options
 
-#+lispworks
-(defconstant +extra-class-options+ '(:base-table :version :schemas))
-
-#+lispworks 
-(defmethod clos::canonicalize-class-options :around
-    ((prototype standard-db-class) class-options)
-  "\\lw\\ signals an error on unknown class options; so this method
-removes any extra allowed options before calling the default method
-and returns the canonicalized extra options concatenated to the result
-of the default method.  The extra allowed options are the value of the
-\\fcite{+extra-class-options+}."
-  (let ((extra-class-options nil)
-       (rest-options ())
-       (result ()))
-    (dolist (o class-options)
-      (let ((option (car o)))
-        (cond
-         ((find option +extra-class-options+)
-          ;;(push (cons option (cadr o)) extra-class-options))
-          (setf (assoc option extra-class-options) (cadr o)))
-         (t
-         (push o rest-options)))))
-    (setf result (call-next-method prototype rest-options))
-    (dolist (option extra-class-options)
-      (push-on-end (car option) result)
-      (push-on-end `(quote ,(cdr option)) result))
-    result))
+(defvar +extra-slot-options+ '(:column :db-kind :db-reader :void-value :db-constraints
+                              :db-writer :db-info))
+(defvar +extra-class-options+ '(:base-table))
+
+(dolist (slot-option +extra-slot-options+)
+  (process-slot-option standard-db-class slot-option))
 
+(dolist (class-option +extra-class-options+)
+  (process-class-option standard-db-class class-option))
 
 (defmethod validate-superclass ((class standard-db-class)
                                (superclass standard-class))
@@ -155,7 +76,7 @@ of the default method.  The extra allowed options are the value of the
        ((typep arg 'sql-ident)
         (slot-value arg 'name))
        ((stringp arg)
-        (intern (string-upcase arg)))))
+        (intern (symbol-name-default-case arg)))))
 
 (defun column-name-from-arg (arg)
   (cond ((symbolp arg)
@@ -163,7 +84,7 @@ of the default method.  The extra allowed options are the value of the
        ((typep arg 'sql-ident)
         (slot-value arg 'name))
        ((stringp arg)
-        (intern (string-upcase arg)))))
+        (intern (symbol-name-default-case arg)))))
 
 
 (defun remove-keyword-arg (arglist akey)
@@ -181,7 +102,7 @@ of the default method.  The extra allowed options are the value of the
 (defmethod initialize-instance :around ((class standard-db-class)
                                         &rest all-keys
                                        &key direct-superclasses base-table
-                                        schemas version qualifier
+                                        qualifier
                                        &allow-other-keys)
   (let ((root-class (find-class 'standard-db-object nil))
        (vmc (find-class 'standard-db-class)))
@@ -203,16 +124,12 @@ of the default method.  The extra allowed options are the value of the
                                                         (car base-table)
                                                         base-table))
                                                (class-name class)))))
-    (setf (object-version class) version)
-    (mapc (lambda (schema)
-            (pushnew (class-name class) (gethash schema *object-schemas*)))
-          (if (listp schemas) schemas (list schemas)))
     (register-metaclass class (nth (1+ (position :direct-slots all-keys))
                                    all-keys))))
 
 (defmethod reinitialize-instance :around ((class standard-db-class)
                                           &rest all-keys
-                                          &key base-table schemas version
+                                          &key base-table 
                                           direct-superclasses qualifier
                                           &allow-other-keys)
   (let ((root-class (find-class 'standard-db-object nil))
@@ -235,10 +152,6 @@ of the default method.  The extra allowed options are the value of the
                                                 direct-superclasses)
                   (remove-keyword-arg all-keys :direct-superclasses)))
         (call-next-method)))
-  (setf (object-version class) version)
-  (mapc (lambda (schema)
-          (pushnew (class-name class) (gethash schema *object-schemas*)))
-        (if (listp schemas) schemas (list schemas)))
   (register-metaclass class (nth (1+ (position :direct-slots all-keys))
                                  all-keys)))
 
@@ -374,13 +287,12 @@ column definition in the database.")
     :initform nil
     :documentation
     "A single constraint or list of constraints for this column")
-   (nulls-ok
-    :accessor view-class-slot-nulls-ok
-    :initarg :nulls-ok
+   (void-value
+    :accessor view-class-slot-void-value
+    :initarg :void-value
     :initform nil
     :documentation
-    "If t, all sql NULL values retrieved from the database become nil; if nil,
-all NULL values retrieved are converted by DATABASE-NULL-VALUE")
+    "Value to store is the SQL value is NULL. Default is NIL.")
    (db-info
     :accessor view-class-slot-db-info
     :initarg :db-info
@@ -461,19 +373,16 @@ implementations."
   (let ((slots (call-next-method))
        desired-sequence
        output-slots)
-
     (dolist (c (compute-class-precedence-list class))
       (dolist (s (class-direct-slots c))
        (let ((name (slot-definition-name s)))
          (unless (find name desired-sequence)
-           (setq desired-sequence (append desired-sequence (list name)))))))
-    ;; desired-sequence is reversed at this time
+           (push name desired-sequence)))))
     (dolist (desired desired-sequence)
       (let ((slot (find desired slots :key #'slot-definition-name)))
        (assert slot)
        (push slot output-slots)))
-
-    (nreverse output-slots)))
+    output-slots))
 
 (defun compute-lisp-type-from-slot-specification (slotd specified-type)
   "Computes the Lisp type for a user-specified type. Needed for OpenMCL
@@ -533,8 +442,8 @@ which does type checking before storing a value in a slot."
              (when (slot-boundp sd 'db-type)
                (view-class-slot-db-type sd)))
        
-       (setf (slot-value slotd 'nulls-ok)
-             (view-class-slot-nulls-ok sd))
+       (setf (slot-value slotd 'void-value)
+             (view-class-slot-void-value sd))
        
        ;; :db-kind slot value defaults to :base (store slot value in
        ;; database)
@@ -592,7 +501,7 @@ which does type checking before storing a value in a slot."
 
 (defun slotdef-for-slot-with-class (slot class)
   (find-if #'(lambda (d) (eql slot (slot-definition-name d)))
-          (ordered-class-slots class)))
+          (class-slots class)))
 
 #+ignore
 (eval-when (:compile-toplevel :load-toplevel :execute)