[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4. Customizing

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.1 About Customizing

Each backend in CL-STORE can be customized to store various values in a custom manner. By using the defstore-<backend-name> and defrestore-<backend-name> macros you can define your own methods for storing various objects. This may require a marginal understanding of the backend you wish to extend.


(in-package :cl-user)

(use-package :cl-store)

(setf *default-backend* (find-backend 'cl-store))

;; Create the custom class
(defclass random-obj () ((a :accessor a :initarg :a)))

;; Register random object. This is specific to the
;; cl-store-backend.
(defvar *random-obj-code* (register-code 110 'random-obj))

;; Create a custom storing method for random-obj
;; outputting the code previously registered.
(defstore-cl-store (obj random-obj stream)
  (output-type-code *random-obj-code* stream)
  (store-object (a obj) stream))

;; Define a restoring method.
(defrestore-cl-store (random-obj stream)
  (random (restore-object stream)))

;; Test it out.
(store (make-instance 'random-obj :a 10) "/tmp/random")

(restore "/tmp/random")
=> ; some number from 0 to 9

If you need to get fancier take a look at the macroexpansion of the customizing macros.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2 Customizing API

This API is primarily concerned with the cl-store-backend although other backends will be similar in structure.

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.1 Functions

Function: register-code code name &optional (errorp t)

Registers name under the code code into the cl-store-backend. The backend will use this mapping when restoring values. Will signal an error if code is already registered and errorp is not NIL. Currently codes 1 through 35 are in use.

Function: output-type-code type-code stream

Writes type-code into stream. This must be done when writing out objects so that the type of the object can be identified on deserialization.

Function: store-32-bit integer stream

Outputs the the low 32 bits from integer into stream.

Function: read-32-bit stream

Reads a 32-bit integer from stream.

Generic: store-object object place

Stores object into place. This should be used inside defstore-cl-store to output parts of objects. store should not be used.

Generic: restore-object place

Restore an object, written out using store-object from place.

Generic: get-slot-details slot-definition

Generic function which returns a list of slots details which can be used as an argument to ensure-class. Currently it is only specialized on slot-definition

Generic: serializable-slots object

Method which returns a list of slot-definition objects which will be serialized for object. The default is to call serializable-slots-using-class.

Generic: serializable-slots-using-class object class

Returns a list of slot-definition objects which will be serialized for object and class. Example. When serializing cl-sql objects to disk or to another lisp session the view-database slot should not be serialized. Instead of specializing serializable-slots for each view-class created you can do this.

(defmethod serializable-slots-using-class 
     ((object t) (class clsql-sys::standard-db-class))
  (delete 'clsql-sys::view-database (call-next-method)
          :key 'slot-definition-name))

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

4.2.2 Macros

Macro: defstore-cl-store (var type stream &key qualifier) &body body

Create a custom storing mechanism for type which must be a legal Class Name. Body will be called when an object of class type is stored using store-object with var bound to the object to be stored and stream bound to the stream to output to. If qualifier is given it must be a legal qualifier to defmethod. Example.

(defstore-cl-store (obj ratio stream)
   (output-type-code +ratio-code+ stream)
   (store-object (numerator obj) stream)
   (store-object (denominator obj) stream))

Macro: defrestore-cl-store (type stream) &body body

Create a custom restoring mechanism for the type registered using register-code.Body will be executed with stream being the input stream to restore an object from.


(defrestore-cl-store (ratio stream)
  (/ (restore-object stream)
     (restore-object stream)))

Macro: resolving-object (var create) &body body

Executes body resolving circularities detected in object. Resolving-object works by creating a closure, containing code to set a particular place in object, which is then pushed onto a list. Once the object has been fully restored all functions on this list are called and the circularities are resolved. Example.

(defrestore-cl-store (cons stream)
  (resolving-object (object (cons nil nil))
    (setting (car object) (restore-object stream))
    (setting (cdr object) (restore-object stream))))

Macro: setting place get

This macro can only be used inside resolving-object. It sets the value designated by place to get for the object that is being resolved.


(defrestore-cl-store (simple-vector stream)
  (let* ((size (restore-object stream))
        (res (make-array size)))
    (resolving-object (object res)
     (loop repeat size for i from 0 do
       ;; we need to copy the index so that
       ;; it's value is preserved for after the loop.
       (let ((x i))
         (setting (aref object x) (restore-object stream)))))

Macro: setting-hash getting-key getting-value

setting-hash works identically to setting although it is used exclusively on hash-tables due to the fact that both the key and the value being restored could be a circular reference. Example.

(defrestore-cl-store (hash-table stream)
  (let ((rehash-size (restore-object stream))
        (rehash-threshold (restore-object stream))
        (size (restore-object stream))
        (test (restore-object stream))
        (count (restore-object stream)))
    (let ((hash (make-hash-table :test (symbol-function test)
                                 :rehash-size rehash-size
                                 :rehash-threshold rehash-threshold
                                 :size size)))
      (resolving-object (obj hash)
        (loop repeat count do
              (setting-hash (restore-object stream) 
                            (restore-object stream))))

[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Sean on September, 1 2005 using texi2html 1.76.