Liking cljdoc? Tell your friends :D

toucan.models

The defmodel macro, used to define Toucan models, and the IModel protocol and default implementations, which implement Toucan model functionality.

The `defmodel` macro, used to define Toucan models, and
the `IModel` protocol and default implementations, which implement Toucan model functionality.
raw docstring

add-property!clj

(add-property! k & {:keys [insert update select]})

Define a new model property and set the functions used to implement its functionality. See documentation for more details.

(add-property! :timestamped? :insert (fn [obj _] (let [now (java.sql.Timestamp. (System/currentTimeMillis))] (assoc obj :created-at now, :updated-at now))) :update (fn [obj _] (assoc obj :updated-at (java.sql.Timestamp. (System/currentTimeMillis)))))

Define a new model property and set the functions used to implement its functionality.
See documentation for more details.

  (add-property! :timestamped?
    :insert (fn [obj _]
              (let [now (java.sql.Timestamp. (System/currentTimeMillis))]
                (assoc obj :created-at now, :updated-at now)))
    :update (fn [obj _]
              (assoc obj :updated-at (java.sql.Timestamp. (System/currentTimeMillis)))))
sourceraw docstring

add-type!clj

(add-type! k & {:keys [in out]})

Add a new type mapping for type named by key K. Supply mappings for the functions that should prepare value when it goes :in to the database, and for when it comes :out.

;; add a :json type (using Cheshire) will serialize objects as JSON ;; going into the DB, and deserialize JSON coming out from the DB (add-type! :json :in json/generate-string :out #(json/parse-string % keyword))

Add a new type mapping for type named by key K. Supply mappings for the functions that should prepare value
when it goes `:in` to the database, and for when it comes `:out`.

  ;; add a :json type (using Cheshire) will serialize objects as JSON
  ;; going into the DB, and deserialize JSON coming out from the DB
  (add-type! :json
    :in  json/generate-string
    :out #(json/parse-string % keyword))
sourceraw docstring

defmodelcljmacro

(defmodel model table-name)
(defmodel model docstr? table-name)

Define a new "model". Models encapsulate information and behaviors related to a specific table in the application DB, and have their own unique record type.

defmodel defines a backing record type following the format <model>Instance. For example, the class associated with User is <root-namespace>.user/UserInstance. (The root namespace defaults to models but can be configured via set-root-namespace!)

This class is used for both the titular model (e.g. User) and for objects that are fetched from the DB. This means they can share the IModel protocol and simplifies the interface somewhat; functions like types work on either the model or instances fetched from the DB.

(defmodel User :user_table) ; creates class UserInstance and DB model User

(db/select User, ...) ; use with toucan.db functions. All results are instances of UserInstance

The record type automatically extends IModel with IModelDefaults, but you can override specific methods, or implement other protocols, by passing them to defmodel, the same way you would with defrecord.

(defmodel User :user_table IModel (hydration-keys [_] [:user]) (properties [_] {:timestamped true}) (pre-insert [user] user))

This is equivalent to:

(extend (class User) ; it's somewhat more readable to write (class User) instead of UserInstance IModel (merge IModelDefaults {...}))

Finally, the model itself is invokable. Calling with no args returns all values of that object; calling with a single arg can be used to fetch a specific instance by its integer ID.

(Database) ; return a seq of all Databases (as instances of DatabaseInstance) (Database 1) ; return Database 1

Define a new "model". Models encapsulate information and behaviors related to a specific table in the application
DB, and have their own unique record type.

`defmodel` defines a backing record type following the format `<model>Instance`. For example, the class associated
with `User` is `<root-namespace>.user/UserInstance`. (The root namespace defaults to `models` but can be configured
via `set-root-namespace!`)

This class is used for both the titular model (e.g. `User`) and for objects that are fetched from the DB. This means
they can share the `IModel` protocol and simplifies the interface somewhat; functions like `types` work on either
the model or instances fetched from the DB.

   (defmodel User :user_table)  ; creates class `UserInstance` and DB model `User`

   (db/select User, ...)  ; use with `toucan.db` functions. All results are instances of `UserInstance`

The record type automatically extends `IModel` with `IModelDefaults`, but you can override specific methods, or
implement other protocols, by passing them to `defmodel`, the same way you would with `defrecord`.

   (defmodel User :user_table
     IModel
     (hydration-keys [_]
       [:user])
     (properties [_]
       {:timestamped true})
     (pre-insert [user]
       user))

 This is equivalent to:

   (extend (class User)             ; it's somewhat more readable to write `(class User)` instead of `UserInstance`
     IModel (merge IModelDefaults
                    {...}))

 Finally, the model itself is invokable. Calling with no args returns *all* values of that object; calling with a
single arg can be used to fetch a specific instance by its integer ID.

   (Database)                       ; return a seq of *all* Databases (as instances of `DatabaseInstance`)
   (Database 1)                     ; return Database 1
sourceraw docstring

do-post-selectclj

(do-post-select model obj)

Don't call this directly! Apply internal functions like post-select when an object is retrieved from the DB.

Don't call this directly! Apply internal functions like `post-select` when an object is retrieved from the DB.
sourceraw docstring

do-pre-insertclj

(do-pre-insert model obj)

Don't call this directly! Apply functions like pre-insert before inserting an object into the DB.

Don't call this directly! Apply functions like `pre-insert` before inserting an object into the DB.
sourceraw docstring

do-pre-updateclj

(do-pre-update model obj)

Don't call this directly! Apply internal functions like pre-update before updating an object in the DB.

Don't call this directly! Apply internal functions like `pre-update` before updating an object in the DB.
sourceraw docstring

do-type-fnclj

(do-type-fn model col v direction)

Don't call this directly! This is automatically applied when doing select.

Don't call this directly! This is automatically applied when doing select.
sourceraw docstring

ICreateFromMapcljprotocol

Used by internal functions like do-post-select.

Used by internal functions like `do-post-select`.
sourceraw docstring

IModelcljprotocol

The IModel protocol defines the various methods that are used to provide custom behavior for various models.

This protocol contains the various methods model classes can optionally implement. All methods have a default implementation provided by IModelDefaults; new models created with the defmodel macro automatically implement this protocol using those default implementations. To override one or more implementations, use extend and merge your custom implementations with IModelDefaults:

(defmodel MyModel)

(extend (class MyModel) IModel (merge IModelDefaults {...}))

The `IModel` protocol defines the various methods that are used to provide custom behavior for various models.

This protocol contains the various methods model classes can optionally implement. All methods have a default
implementation provided by `IModelDefaults`; new models created with the `defmodel` macro automatically implement
this protocol using those default implementations. To override one or more implementations, use `extend` and
`merge` your custom implementations with `IModelDefaults`:

  (defmodel MyModel)

  (extend (class MyModel)
    IModel
    (merge IModelDefaults {...}))

primary-keyclj

(primary-key this)

Defines the primary key. Defaults to :id

(primary-key [_] :id)

NOTE: composite keys are currently not supported

Defines the primary key. Defaults to :id

    (primary-key [_] :id)

NOTE: composite keys are currently not supported

post-insertclj

(post-insert this)

Gets called by insert! with an object that was newly inserted into the database. This provides an opportunity to trigger specific logic that should occur when an object is inserted or modify the object that is returned. The value returned by this method is returned to the caller of insert!. The default implementation is identity.

(post-insert [user] (assoc user :newly-created true))

(post-insert [user] (add-user-to-magic-perm-groups! user) user)

Gets called by `insert!` with an object that was newly inserted into the database.
This provides an opportunity to trigger specific logic that should occur when an object is inserted or modify the
object that is returned. The value returned by this method is returned to the caller of `insert!`. The default
implementation is `identity`.

  (post-insert [user]
    (assoc user :newly-created true))

  (post-insert [user]
    (add-user-to-magic-perm-groups! user)
    user)

propertiesclj

(properties this)

Return a map of properties of this model. Properties can be used to implement advanced behavior across many different models; see the documentation for more details. Declare a model's properties as such:

 (properties [_] {:timestamped? true})

Define functions to handle objects with those properties using add-property!:

(add-property! :timestamped?
  :insert (fn [obj] (assoc obj :created-at (new-timestamp), :updated-at (new-timestamp)))
  :update (fn [obj] (assoc obj :updated-at (new-timestamp))))
Return a map of properties of this model. Properties can be used to implement advanced behavior across many
   different models; see the documentation for more details. Declare a model's properties as such:

     (properties [_] {:timestamped? true})

Define functions to handle objects with those properties using `add-property!`:

    (add-property! :timestamped?
      :insert (fn [obj] (assoc obj :created-at (new-timestamp), :updated-at (new-timestamp)))
      :update (fn [obj] (assoc obj :updated-at (new-timestamp))))

hydration-keysclj

(hydration-keys this)

The hydration-keys method can be overrode to specify the keyword field names that should be hydrated as instances of this model. For example, User might include :creator, which means hydrate will look for :creator_id or :creator-id in other objects to find the User ID, and fetch the Users corresponding to those values.

The `hydration-keys` method can be overrode to specify the keyword field names that should be hydrated
as instances of this model. For example, `User` might include `:creator`, which means `hydrate` will
look for `:creator_id` or `:creator-id` in other objects to find the User ID, and fetch the `Users`
corresponding to those values.

post-updateclj

(post-update this)

Gets called by update! with an object that was successfully updated in the database. This provides an opportunity to trigger specific logic that should occur when an object is updated. The value returned by this method is not returned to the caller of update!. The default implementation is nil (not invoked).

Note: This method is not invoked when calling update! with a honeysql-form form.

(post-update [user] (audit-user-updated! user)

Gets called by `update!` with an object that was successfully updated in the database.
This provides an opportunity to trigger specific logic that should occur when an object is updated.
The value returned by this method is not returned to the caller of `update!`. The default
implementation is `nil` (not invoked).

Note: This method is *not* invoked when calling `update!` with a `honeysql-form` form.

  (post-update [user]
    (audit-user-updated! user)

pre-insertclj

(pre-insert this)

Gets called by insert! immediately before inserting a new object. This provides an opportunity to do things like encode JSON or provide default values for certain fields.

(pre-insert [query]
  (let [defaults {:version 1}]
    (merge defaults query))) ; set some default values
Gets called by `insert!` immediately before inserting a new object.
This provides an opportunity to do things like encode JSON or provide default values for certain fields.

    (pre-insert [query]
      (let [defaults {:version 1}]
        (merge defaults query))) ; set some default values

pre-updateclj

(pre-update this)

Called by update! before DB operations happen. A good place to set updated values for fields like updated-at, or to check preconditions.

Called by `update!` before DB operations happen. A good place to set updated values for fields like `updated-at`,
or to check preconditions.

typesclj

(types this)

Return a map of keyword field names to their types for fields that should be serialized/deserialized in a special way. Values belonging to a type are sent through an input function before being inserted into the DB, and sent through an output function on their way out. :keyword is the only type enabled by default; you can add more by calling add-type!:

(add-type! :json, :in json/generate-string, :out json/parse-string)

Set the types for a model like so:

;; convert `:category` to a keyword when it comes out of the DB; convert back to a string before going in
(types [_] {:category :keyword})
Return a map of keyword field names to their types for fields that should be serialized/deserialized in a special
  way. Values belonging to a type are sent through an input function before being inserted into the DB, and sent
  through an output function on their way out. `:keyword` is the only type enabled by default; you can add more by
  calling `add-type!`:

    (add-type! :json, :in json/generate-string, :out json/parse-string)

Set the types for a model like so:

    ;; convert `:category` to a keyword when it comes out of the DB; convert back to a string before going in
    (types [_] {:category :keyword})

pre-deleteclj

(pre-delete this)

Called by delete! for each matching object that is about to be deleted. Implementations can delete any objects related to this object by recursively calling delete!, or do any other cleanup needed, or check some preconditions that must be fulfilled before deleting an object.

The output of this function is ignored.

  (pre-delete [{database-id :id :as database}]
    (delete! Card :database_id database-id)
    ...)
Called by `delete!` for each matching object that is about to be deleted.
   Implementations can delete any objects related to this object by recursively calling `delete!`, or do
   any other cleanup needed, or check some preconditions that must be fulfilled before deleting an object.

The output of this function is ignored.

      (pre-delete [{database-id :id :as database}]
        (delete! Card :database_id database-id)
        ...)

default-fieldsclj

(default-fields this)

Return a sequence of keyword field names that should be fetched by default when calling select or invoking the model (e.g., (Database 1)).

Return a sequence of keyword field names that should be fetched by default when calling
`select` or invoking the model (e.g., `(Database 1)`).

post-selectclj

(post-select this)

Called on the results from a call to select and similar functions. Default implementation doesn't do anything, but you can provide custom implementations to do things like remove sensitive fields or add dynamic new ones.

For example, let's say we want to add a :name field to Users that combines their :first-name and :last-name:

(defn- post-select [user]
  (assoc user :name (str (:first-name user) " " (:last-name user))))

Then, when we select a User:

(User 1) ; -> {:id 1, :first-name "Cam", :last-name "Saul", :name "Cam Saul"}
Called on the results from a call to `select` and similar functions. Default implementation doesn't do anything,
   but you can provide custom implementations to do things like remove sensitive fields or add dynamic new ones.

For example, let's say we want to add a `:name` field to Users that combines their `:first-name` and `:last-name`:

    (defn- post-select [user]
      (assoc user :name (str (:first-name user) " " (:last-name user))))

Then, when we select a User:

    (User 1) ; -> {:id 1, :first-name "Cam", :last-name "Saul", :name "Cam Saul"}
sourceraw docstring

IModelDefaultsclj

Default implementations for IModel methods.

Default implementations for `IModel` methods.
sourceraw docstring

invoke-model-or-instanceclj

(invoke-model-or-instance obj & args)

Check whether OBJ is an model (e.g. Database) or an object from the DB; if an model, call invoked-model; otherwise call get.

Check whether OBJ is an model (e.g. `Database`) or an object from the DB; if an model,
call `invoked-model`; otherwise call `get`.
sourceraw docstring

model?clj

(model? model)

Is model a valid toucan model?

Is model a valid toucan model?
sourceraw docstring

root-namespaceclj

(root-namespace)

Fetch the parent namespace for all Toucan models.

Fetch the parent namespace for all Toucan models.
sourceraw docstring

set-root-namespace!clj

(set-root-namespace! new-root-namespace)

Set the root namespace where all models are expected to live.

(set-root-namespace! 'my-project.models)

In this example, Toucan would look for a model named UserFollow in the namespace my-project.models.user-follow.

Set the root namespace where all models are expected to live.

   (set-root-namespace! 'my-project.models)

In this example, Toucan would look for a model named `UserFollow` in the namespace `my-project.models.user-follow`.
sourceraw docstring

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close