X-Git-Url: http://git.kpe.io/?p=clsql.git;a=blobdiff_plain;f=doc%2Fref-ooddl.xml;h=891e213a70dcc09ad053aac05c94f4f8d0699eff;hp=5c51f4b5f35ff3f3c636cea7c2e8e37485a047e8;hb=534849c88501e0ea2ee5dbf78d13d8cb73814d71;hpb=d0695ffb828519fade3aa5166236812e6144975b diff --git a/doc/ref-ooddl.xml b/doc/ref-ooddl.xml index 5c51f4b..891e213 100644 --- a/doc/ref-ooddl.xml +++ b/doc/ref-ooddl.xml @@ -5,9 +5,9 @@ %myents; ]> - - - Object Oriented Data Definition Language (OODDL) + + + Object Oriented Data Definition Language (OODDL) The Object Oriented Data Definition Language (OODDL) provides @@ -15,7 +15,7 @@ (CLOS) objects. SQL tables are mapped to CLOS objects with the SQL columns being mapped to slots of the CLOS object. - + The mapping between SQL tables and CLOS objects is defined with the macro def-view-class. SQL @@ -59,11 +59,11 @@ Slots - + slot VIEW-DATABASE is of type (OR NULL DATABASE) which stores the associated database for the instance. - + @@ -78,14 +78,14 @@ Value Type Fixnum - + Initial Value 255 - Description + Description If a slot of a class defined by def-view-class is of the type @@ -105,9 +105,9 @@ (c :type varchar)))) => #<Standard-Db-Class S80 {480A431D}> -(create-view-from-class 's80) -=> -(table-exists-p [s80]) +(create-view-from-class 's80) +=> +(table-exists-p [s80]) => T @@ -193,7 +193,7 @@ (def-view-class foo () ((a :type (string 80)))) => #<Standard-Db-Class FOO {4807F7CD}> (create-view-from-class 'foo) -=> +=> (list-tables) => ("FOO") @@ -453,7 +453,7 @@ wide. [not supported by all database backends] - bigint - An integer column + bigint - An integer column 64-bits wide. [not supported by all database backends] @@ -469,6 +469,12 @@ provides a number of time manipulation functions to support objects of type wall-time. + + date - a slot which stores the + date (without any time of day resolution) in a + column. &clsql; provides a number of time + manipulation functions that operate on date values. + duration - stores a duration structure. &clsql; provides @@ -489,7 +495,7 @@ keyword - stores a keyword - + symbol - stores a symbol list - stores a list by writing @@ -502,7 +508,7 @@ similarly to list - + @@ -542,6 +548,31 @@ slot value. + + + :db-reader - If a string, then when + reading values from the database, the string will be used + for a format string, with the only value being the value + from the database. The resulting string will be used as + the slot value. If a function then it will take one + argument, the value from the database, and return the + value that should be put into the slot. If a symbol, then + the symbol-function of the symbol will be used. + + + + + :db-writer - If a string, then when + reading values from the slot for the database, the string + will be used for a format string, with the only value + being the value of the slot. The resulting string will be + used as the column value in the database. If a function + then it will take one argument, the value of the slot, and + return the value that should be put into the database. If + a symbol, then the symbol-function of the symbol will be + used. + + @@ -556,6 +587,16 @@ are converted to underscore characters. + + + :normalizedp - specifies whether + this class uses normalized inheritance from parent classes. + Defaults to nil, i.e. non-normalized schemas. When true, + SQL database tables that map to this class and parent + classes are joined on their primary keys to get the full + set of database columns for this class. + + @@ -575,6 +616,127 @@ this class. + + Normalized inheritance schemas + + Specifying that :normalizedp is T + tells &clsql; to normalize the database schema for inheritance. + What this means is shown in the examples below. + + + + With :normalizedp equal to NIL + (the default) the class inheritance would result in the following: + + +(def-view-class node () + ((title :accessor title :initarg :title :type (varchar 240)))) + +SQL table NODE: ++-------+--------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++-------+--------------+------+-----+---------+-------+ +| TITLE | varchar(240) | YES | | NULL | | ++-------+--------------+------+-----+---------+-------+ + +(def-view-class user (node) + ((user-id :accessor user-id :initarg :user-id + :type integer :db-kind :key :db-constraints (:not-null)) + (nick :accessor nick :initarg :nick :type (varchar 64)))) + +SQL table USER: ++---------+--------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++---------+--------------+------+-----+---------+-------+ +| USER_ID | int(11) | NO | PRI | | | +| NICK | varchar(64) | YES | | NULL | | +| TITLE | varchar(240) | YES | | NULL | | ++---------+--------------+------+-----+---------+-------+ + + + + Using :normalizedp T, both + view-classes need a primary key to join them on: + + +(def-view-class node () + ((node-id :accessor node-id :initarg :node-id + :type integer :db-kind :key + :db-constraints (:not-null)) + (title :accessor title :initarg :title :type (varchar 240)))) + +SQL table NODE: ++---------+--------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++---------+--------------+------+-----+---------+-------+ +| NODE_ID | int(11) | NO | PRI | | | +| TITLE | varchar(240) | YES | | NULL | | ++---------+--------------+------+-----+---------+-------+ + +(def-view-class user (node) + ((user-id :accessor user-id :initarg :user-id + :type integer :db-kind :key :db-constraints (:not-null)) + (nick :accessor nick :initarg :nick :type (varchar 64))) + (:normalizedp t)) + +SQL table USER: ++---------+-------------+------+-----+---------+-------+ +| Field | Type | Null | Key | Default | Extra | ++---------+-------------+------+-----+---------+-------+ +| USER_ID | int(11) | NO | PRI | | | +| NICK | varchar(64) | YES | | NULL | | ++---------+-------------+------+-----+---------+-------+ + + + + In this second case, all slots of the view-class 'node + are also available in view-class 'user, and can be used + as one would expect. For example, with the above normalized + view-classes 'node and 'user, and SQL tracing turned on: + + +CLSQL> (setq test-user (make-instance 'user :node-id 1 :nick "test-user" + :title "This is a test user")) +]]> + +CLSQL> (update-records-from-instance test-user :database db) + INSERT INTO NODE (NODE_ID,TITLE) VALUES (1,'This is a test user') +;; .. <= T +;; .. => INSERT INTO USER (USER_ID,NICK) VALUES (1,'test-user') +;; .. <= T +1 +]]> + +CLSQL> (node-id test-user) +1 + +CLSQL> (title test-user) +"This is a test user" + +CLSQL> (nick test-user) +"test-user" + + + Notes from a refactor of this code. + + There are many assumptions that need to be met for normalized classes to work + + * The each of the classes should have its own single key column (of a different name) + that will contain an identical value. EG: node has a node-id, setting which + is a node has a node-id and a setting-id which must be equal. You cannot use + node-id as the primary key on both tables (as I would have expected). The exception + to this seems to be if your class has no slots at all, then you dont need to have a + single key column, because your class is fully represented in the db by its parent(s) + + * more than one parent class per normalized class should be considered experimental + and untested (vaya con Dios) + + * There are a few code paths that just dont pay any attention to normalized classes + eg: delete-records-for-instance + + + Examples @@ -590,7 +752,7 @@ (birthday :type clsql:wall-time :initarg :birthday) (bd-utime :type clsql:universal-time :initarg :bd-utime) (hobby :db-kind :virtual :initarg :hobby :initform nil))) - + (def-view-class employee (person) ((emplid :db-kind :key @@ -822,11 +984,11 @@ Examples (list-tables) -=> ("FOO" "BAR") +=> ("FOO" "BAR") (drop-view-from-class 'foo) -=> +=> (list-tables) -=> ("BAR") +=> ("BAR") @@ -861,7 +1023,7 @@ Notes - None. + None. @@ -934,7 +1096,7 @@ (list-classes) => (#<clsql-sys::standard-db-class big> #<clsql-sys::standard-db-class employee-address> - #<clsql-sys::standard-db-class address> #<clsql-sys::standard-db-class company> + #<clsql-sys::standard-db-class address> #<clsql-sys::standard-db-class company> #<clsql-sys::standard-db-class employee>) (list-classes :test #'(lambda (c) (> (length (symbol-name (class-name c))) 3))) @@ -974,10 +1136,10 @@ Notes - None. + None. - +