# Object Oriented Data Manipulation Language (OODML)

Object Oriented Data Manipulation Language (OODML) provides a Common Lisp Object System (CLOS) interface to SQL databases. View classes are defined with the OODDL interface and objects are read and written with the OODML.

The main function for reading data with the OODML is the `select` function. The `select` is also used in the FDML. However, when `select` is given a view class name, it returns a list of instances of view classes.

View class instances can be updated to reflect any changes in the database with the functions `update-slot-from-record` and `update-instance-from-records`.

To update the database to reflect changes made to instances of view classes, use the functions `update-records-from-instance`, `update-record-from-slot`, and `update-record-from-slots`.

The function `delete-instance-records` deletes the records corresponding to an instance of a view class.

*DB-AUTO-SYNC*

Enables SQL storage during Lisp object creation.

Variable

### Value Type

Boolean

### Initial Value

&nil;

### Description

When this variable is &t; an instance is stored in the SQL database when the instance is created by `make-instance`. Furthermore, the appropriate database records are updated whenever the slots of a View Class instance are modified.

When this variable is &nil;, which is the default value, &clsql; behaves like &commonsql;: instances of view classes are stored or updated in the SQL database only when `update-record-from-instance`, `update-record-from-slot` or `update-record-from-slots` are called.

### Examples

    	(let ((instance (make-instance 'foo)))
    	  (update-records-from-instance instance))

    	;; is equivalent to

    	(let ((*db-auto-sync* t))
    	  (make-instance 'foo))

            ;; and

            (progn
              (setf (slot-value instance 'bar) "baz")
              (update-record-from-slot instance 'bar))

            ;; is equivalent to

            (let ((*db-auto-sync* t))
              (setf (slot-value instance 'bar) "baz"))

### Affected By

None.

### See Also

- `update-records-from-instance`
- `update-record-from-slot`
- `update-record-from-slots`

### Notes

This is a CLSQL extension to the CommonSQL API.

*DEFAULT-CACHING*

Controls the default caching behavior.

Variable

### Value Type

Boolean

### Initial Value

&t;

### Description

This variable stores the default value of the `CACHING` keyword for the `select`.

### Examples

    	(let ((*default-caching* nil)))
    	  (select 'foo))

    	;; is equivalent to

    	(select 'foo :caching nil)

### Affected By

None.

### See Also

- `select`

### Notes

This is a CLSQL extension to the &commonsql; API. &commonsql; has caching on at all times.

*DEFAULT-UPDATE-OBJECTS-MAX-LEN*

The default maximum number of objects each query to perform a join

Variable

### Value Type

(or null integer)

### Initial Value

&nil;

### Description

This special variable provides the default value for the `max-len` argument of the function `update-object-joins`.

### Examples

    	(setq *default-update-objects-max-len* 100)

### Affected By

None.

### See Also

- `update-object-joins`

### Notes

None.

INSTANCE-REFRESHED

User hook to call on object refresh.

Generic function

### Syntax

          instance-refreshed object =>

### Arguments and Values

`object`

- The View Class object which is being refreshed.

### Description

Provides a hook which is called within an object oriented call to `select` with a non-nil value of `refresh` when the View Class instance `object` has been updated from the database. A method specialised on `standard-db-object` is provided which has no effects. Methods specialised on particular View Classes can be used to specify any operations that need to be made on View Classes instances which have been updated in calls to `select`.

### Examples

    (slot-value employee1 'email)
    => "lenin@soviet.org"
    (defmethod instance-refreshed ((e employee))
       (format t "~&Details for ~A ~A have been updated from the database."
               (slot-value e 'first-name)
               (slot-value e 'last-name)))
    => #<Standard-Method INSTANCE-REFRESHED (EMPLOYEE) {48174D9D}>
    (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)
    => (#<EMPLOYEE {48149995}>)
    (slot-value (car *) 'email)
    => "lenin@soviet.org"
    (update-records [employee] :av-pairs '(([email] "v.lenin@soviet.org"))
                    :where [= [emplid] 1])
    =>
    (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)
    => (#<EMPLOYEE {48149995}>)
    (slot-value (car *) 'email)
    => "lenin@soviet.org"
    (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t :refresh t)
    Details for Vladimir Lenin have been updated from the database.
    => (#<EMPLOYEE {48149995}>)
    (slot-value (car *) 'email)
    => "v.lenin@soviet.org"

### Side Effects

The user hook function may cause side effects.

### Exceptional Situations

None.

### See Also

- `select`

### Notes

None.

DELETE-INSTANCE-RECORDS

Delete SQL records represented by a View Class object.

Function

### Syntax

          delete-instance-records object =>

### Arguments and Values

`object`

- An instance of a View Class.

### Description

Deletes the records represented by `object` in the appropriate table of the database associated with `object`. If `object` is not yet associated with a database, an error is signalled.

### Examples

    (def-view-class tab ()
      ((a :initarg :a :type integer :db-kind :key)
       (b :initarg :b :type string)))
    => #<Standard-Db-Class TAB {49B01845}>
    (create-view-from-class 'tab)
    =>
    (defvar obj (let ((*db-auto-sync* t))
                  (make-instance 'tab :a 5 :b "the string")))
    => OBJ
    (start-sql-recording :type :both)
    =>
    (delete-instance-records obj)
    ;; 2004-07-17 11:07:19 foo/bar/baz => DELETE FROM tab WHERE tab.a = 5
    ;; 2004-07-17 11:07:19 foo/bar/baz <= T
    =>

### Side Effects

Deletes data from the SQL database.

### Affected by

Permissions granted by the SQL database to the user in the database connection.

### Exceptional Situations

An exception may be signaled if the database connection user does not have sufficient privileges to modify the database. An error of type `sql-database-error` is signalled if `object` is not associated with an active database.

### See Also

- `update-records`
- `delete-records`
- `update-records-from-instance`

### Notes

Instances are referenced in the database by values stored in the key slots. If `delete-records-from-instance` is called with an instance of a class that does not contain any keys, then all records in that table will be deleted.

UPDATE-RECORDS-FROM-INSTANCE

Update database from view class object.

Function

### Syntax

          update-records-from-instance object &key database =>

### Arguments and Values

`object`

- An instance of a View Class.

`database`

- database object. This will default to the value of *default-database*.

### Description

Using an instance of a View Class, `object`, update the table that stores its instance data. `database` specifies the database in which the update is made only if `object` is not associated with a database. In this case, a record is created in the appropriate table of `database` using values from the slot values of `object`, and `object` becomes associated with `database`.

### Examples

    (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t)
    => ("lenin@soviet.org")
    (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))
    => *E1*
    (slot-value *e1* 'email)
    => "lenin@soviet.org"
    (setf (slot-value *e1* 'email) "v.lenin@soviet.org")
    => "v.lenin@soviet.org"
    (update-records-from-instance *e1*)
    =>
    (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t)
    => ("v.lenin@soviet.org")

### Side Effects

Modifies the database.

### Affected by

Nothing.

### Exceptional Situations

Database errors.

### See Also

- `update-record-from-slot`
- `update-record-from-slots`
- `update-records`

### Notes

None.

UPDATE-RECORD-FROM-SLOT

Updates database from slot value.

Function

### Syntax

          update-record-from-slot object slot &key database =>

### Arguments and Values

`object`

- An instance of a View Class.

`slot`

- The name of a slot in `object`.

`database`

- A database object. This will default to the value of *default-database*.

### Description

Updates the value stored in the column represented by the slot, specified by the CLOS slot name `slot`, of View Class instance `object`. `database` specifies the database in which the update is made only if `object` is not associated with a database. In this case, a record is created in `database` and the attribute represented by `slot` is initialised from the value of the supplied slots with other attributes having default values. Furthermore, `object` becomes associated with `database`.

### Examples

    (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t)
    => ("lenin@soviet.org")
    (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))
    => *E1*
    (slot-value *e1* 'email)
    => "lenin@soviet.org"
    (setf (slot-value *e1* 'email) "v.lenin@soviet.org")
    => "v.lenin@soviet.org"
    (update-record-from-slot *e1* 'email)
    =>
    (select [email] :from [employee] :where [= [emplid] 1] :field-names nil :flatp t)
    => ("v.lenin@soviet.org")

### Side Effects

Modifies database.

### Affected By

Nothing.

### Exceptional Situations

Database errors.

### See Also

- `update-record-from-slots`
- `update-records-from-instance`

### Notes

None.

UPDATE-RECORD-FROM-SLOTS

Update database from slots of view class object.

function

### syntax

          update-record-from-slots object slots &key database =>

### Arguments and Values

`object`

- An instance of a View Class.

`slots`

- A list of slot names in `object`.

`database`

- A database object. This will default to the value of *default-database*.

### Description

Updates the values stored in the columns represented by the slots, specified by the clos slot names `slots`, of View Class instance `object`. `database` specifies the database in which the update is made only if `object` is not associated with a database. In this case, a record is created in the appropriate table of `database` and the attributes represented by `slots` are initialised from the values of the supplied slots with other attributes having default values. Furthermore, `object` becomes associated with `database`.

### Examples

    (select [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil)
    => (("Lenin" "lenin@soviet.org"))
    (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))
    => *E1*
    (slot-value *e1* 'last-name)
    => "Lenin"
    (slot-value *e1* 'email)
    => "lenin@soviet.org"
    (setf (slot-value *e1* 'last-name) "Ivanovich")
    => "Ivanovich"
    (setf (slot-value *e1* 'email) "v.ivanovich@soviet.org")
    => "v.ivanovich@soviet.org"
    (update-record-from-slots *e1* '(email last-name))
    =>
    (select [last-name] [email] :from [employee] :where [= [emplid] 1] :field-names nil)
    => (("Ivanovich" "v.ivanovich@soviet.org"))

### Side Effects

Modifies the SQL database.

### Affected by

Nothing.

### Exceptional Situations

Database errors.

### See Also

- `update-record-from-slot`
- `update-records-from-instance`

### Notes

None.

UPDATE-INSTANCE-FROM-RECORDS

Update slot values from database.

Function

### Syntax

          update-instance-from-records object &key database => object

### Arguments and Values

`object`

- An instance of a View Class.

`database`

- A database object. This will default to the value of *default-database*.

### Description

Updates the slot values of the View Class instance `object` using the attribute values of the appropriate table of `database` which defaults to the database associated with `object` or, if `object` is not associated with a database, `*default-database*`. Join slots are updated but instances of the class on which the join is made are not updated.

### Examples

    (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))
    => *E1*
    (slot-value *e1* 'email)
    => "lenin@soviet.org"
    (update-records [employee]
                    :av-pairs '(([email] "v.lenin@soviet.org"))
                    :where [= [emplid] 1])
    =>
    (update-instance-from-records *e1*)
    => #<EMPLOYEE {4806B53D}>
    (slot-value *e1* 'email)
    => "v.lenin@soviet.org"

### Side Effects

Slot values of `object` may be modified.

### Affected by

- Data in SQL database.

### Exceptional Situations

If `database` is not able to be read.

### See Also

- `update-slot-from-record`
- `update-objects-joins`

### Notes

None.

UPDATE-SLOT-FROM-RECORD

Update objects slot from database.

Function

### Syntax

          update-slot-from-record object slot &key database => object

### Arguments and Values

`object`

- An instance of a View Class.

`slot`

- The name of a slot in `object`.

`database`

- A database object. This will default to the value of *default-database*.

### Description

Updates the slot value, specified by the CLOS slot name `slot`, of the View Class instance `object` using the attribute values of the appropriate table of `database` which defaults to the database associated with `object` or, if `object` is not associated with a database, `*default-database*`. Join slots are updated but instances of the class on which the join is made are not updated.

### Examples

    (defvar *e1* (car (select 'employee :where [= [slot-value 'employee 'emplid] 1] :flatp t)))
    => *E1*
    (slot-value *e1* 'email)
    => "lenin@soviet.org"
    (update-records [employee]
                    :av-pairs '(([email] "v.lenin@soviet.org"))
                    :where [= [emplid] 1])
    =>
    (update-slot-from-record *e1* 'email)
    => #<EMPLOYEE {4806B53D}>
    (slot-value *e1* 'email)
    => "v.lenin@soviet.org"

### Side Effects

Modifies the slot value of the object.

### Affected by

- Data in SQL database.

### Exceptional Situations

Database errors.

### See Also

- `update-instance-from-records`
- `update-objects-joins`

### Notes

None.

UPDATE-OBJECTS-JOINS

Updates joined slots of objects.

Function

### Syntax

          update-objects-joins objects &key slots force-p class-name max-len =>

### Arguments and Values

`objects`

- A list of instances of a View Class.

`slots`

- * :immediate (default) - refresh join slots with :retrieval :immediate

  * :deferred - refresh join slots created with :retrieval :deferred

  * :all,t - refresh all join slots regardless of :retrieval

  * list of symbols - which explicit slots to refresh

  * a single symobl - what slot to refresh

`force-p`

- A Boolean, defaulting to &t;.

`class-name`

- A list of instances of a View Class.

`max-len`

- A non-negative integer or &nil; defaulting to *default-update-objects-max-len*. When non-nil this is essentially a batch size for the max number of objects to query from the database at a time. If we need more than max-len we loop till we have all the objects

### Description

Updates from the records of the appropriate database tables the join slots specified by SLOTS in the supplied list of View Class instances OBJECTS. A simpler method of causing a join-slot to be requeried is to set it to unbound, then request it again. This function has efficiency gains where join-objects are shared among the `objects` (querying all join-objects, then attaching them appropriately to each of the `objects`)

### Examples

    (defvar *addresses* (select 'deferred-employee-address :order-by [ea_join aaddressid] :flatp t))
    => *ADDRESSES*
    (slot-boundp (car *addresses*) 'address)
    => NIL
    (update-objects-joins *addresses*)
    =>
    (slot-boundp (car *addresses*) 'address)
    => T
    (slot-value (car *addresses*) 'address)
    => #<ADDRESS {480B0F1D}>

### Side Effects

The slot values of `objects` are modified.

### Affected by

- `*default-update-objects-max-len*`

### Exceptional Situations

Database errors.

### See Also

- `*default-update-objects-max-len*`
- `update-instance-from-records`
- `update-slot-from-record`

### Notes

None.