X-Git-Url: http://git.kpe.io/?a=blobdiff_plain;f=sql%2Foodml.lisp;h=7bf7d5bf77db5adcb9bed1ca976ca7082a2afebb;hb=95704a836b85f40018186f97b332fd3873168a53;hp=e075b0c0d08535cd2acf50a3a60c287ff2009e11;hpb=730b9c2ed37582c51a1c02fcdaee63686bb80beb;p=clsql.git diff --git a/sql/oodml.lisp b/sql/oodml.lisp index e075b0c..7bf7d5b 100644 --- a/sql/oodml.lisp +++ b/sql/oodml.lisp @@ -1,8 +1,6 @@ ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10 -*- ;;;; ************************************************************************* ;;;; -;;;; $Id$ -;;;; ;;;; The CLSQL Object Oriented Data Manipulation Language (OODML). ;;;; ;;;; This file is part of CLSQL. @@ -208,6 +206,13 @@ (defmethod update-record-from-slots ((obj standard-db-object) slots &key (database *default-database*)) + (when (normalizedp (class-of obj)) + ;; FIXME: Rewrite to bundle slots for same table to be written + ;; as avpairs (like how is done for non-normalized view-classes below) + (dolist (slot slots) + (update-record-from-slot obj slot :database database)) + (return-from update-record-from-slots (values))) + (let* ((database (or (view-database obj) database)) (vct (view-table (class-of obj))) (sds (slotdefs-for-slots-with-class slots (class-of obj))) @@ -260,6 +265,7 @@ (ordered-class-direct-slots view-class) (ordered-class-slots view-class)))) (record-values (mapcar #'slot-value-list slots))) + (cond ((and (not (normalizedp view-class)) (not record-values)) (error "No settable slots.")) @@ -280,16 +286,22 @@ (insert-records :into (sql-expression :table view-class-table) :av-pairs record-values :database database) + (when pk-slot (if (or (and (listp (view-class-slot-db-constraints pk-slot)) (member :auto-increment (view-class-slot-db-constraints pk-slot))) (eql (view-class-slot-db-constraints pk-slot) :auto-increment)) + (unless pk + (let ((db-pk (car (query "SELECT LAST_INSERT_ID();" + :flatp t :field-names nil + :database database)))) + (setf pk db-pk + (slot-value + obj (slot-definition-name pk-slot)) db-pk))) + (setf pk (or pk - (car (query "SELECT LAST_INSERT_ID();" - :flatp t :field-names nil - :database database)))) - (setf pk (or pk - (slot-value obj (slot-definition-name pk-slot)))))) + (slot-value + obj (slot-definition-name pk-slot)))))) (when (eql this-class nil) (setf (slot-value obj 'view-database) database))))))) pk)) @@ -327,6 +339,7 @@ :result-types nil :database vd)))) (when res + (setf (slot-value instance 'view-database) vd) (get-slot-values-from-view instance (mapcar #'car sels) (car res)))) (pres) (t nil))))) @@ -353,6 +366,7 @@ (res (select att-ref :from view-table :where view-qual :result-types nil))) (when res + (setf (slot-value instance 'view-database) vd) (get-slot-values-from-view instance (list slot-def) (car res)))))) (defmethod update-slot-with-null ((object standard-db-object) @@ -575,8 +589,12 @@ (format nil "~F" val)))) (defmethod read-sql-value (val type database db-type) - (declare (ignore type database db-type)) - (read-from-string val)) + (declare (ignore database db-type)) + (cond + ((null type) val) ;;we have no desired type, just give the value + ((typep val type) val) ;;check that it hasn't already been converted. + ((typep val 'string) (read-from-string val)) ;;maybe read will just take care of it? + (T (error "Unable to read-sql-value ~a as type ~a" val type)))) (defmethod read-sql-value (val (type (eql 'string)) database db-type) (declare (ignore database db-type)) @@ -630,10 +648,19 @@ (declare (ignore database db-type)) ;; writing 1.0 writes 1, so we we *really* want a float, must do (float ...) (etypecase val - (string - (float (read-from-string val))) - (float - val))) + (string (float (read-from-string val))) + (float val))) + +(defmethod read-sql-value (val (type (eql 'double-float)) database db-type) + (declare (ignore database db-type)) + ;; writing 1.0 writes 1, so if we *really* want a float, must do (float ...) + (etypecase val + (string (float + (let ((*read-default-float-format* 'double-float)) + (read-from-string val)) + 1.0d0)) + (double-float val) + (float (coerce val 'double-float)))) (defmethod read-sql-value (val (type (eql 'boolean)) database db-type) (declare (ignore database db-type))