netizer.relational_mapper

https://github.com/netizer/relational_mapper.git

git clone 'https://github.com/netizer/relational_mapper.git'

(ql:quickload :netizer.relational_mapper)
10

Relational Mapper

A relational mapper in Clojure. If you're using relational database in Clojure then this library is for you.

Leiningen Coordinates

Clojars Project

Project health

Continuous Integration status

Dependencies Status

Usage

Make calls like: clojure (find-all db-state :posts #{:authors :attachments} [:= post.id 1]) and get results like: clojure {:posts {:title "Christmas" :body "Merry Christmas!" :id 1 :authors_id 10 :authors {:name "Rudolf" :id 10} :attachments [{:name "rudolf.png" :id 100 :posts_id 1} {:name "santa.png" :id 101 :posts_id 1}]

to achieve that though you have to first tell ‘relational-mapper’ what's the structure of your data and how to connect to the database, so the full, working example would look like this:

(ns your-project
  (:require [relational-mapper :refer :all]
            [relational-mapper.data-model :as data-model]))

(def associations {:authors {:posts {:type :has-many}
                             :attachments {:type :has-many :through :posts}}
                   :posts {:authors {:type :belongs-to}
                           :attachments {:type :has-many}}
                   :attachments {:authors {:type :belongs-to :through :posts}
                                 :posts {:type :belongs-to}}})

(def db-config {:classname "org.postgresql.Driver"
                :subprotocol "postgresql"
                :subname (str "//" "localhost" ":" 5432 "/" "testdb")
                :user "postgres-user"
                :password "postgres-password"})

(def initial-db-state {:config db-config
                       :data-model {})

(def db-state (data-model/set-associations initial-db-state associations {})

(find-all db-state :posts #{:authors :attachments} [:= post.id 1])

How to define associations

relational-mapper uses the same relations naming as ‘Ruby On Rails`’ ‘ActiveRecord’, which means:

Have in mind that unlike ActiveRecord, here associations are always plural (:posts {:authors :belongs-to} and not :posts {:author :belongs-to). The same applies to key names (users_id, not user_id). This is by design, and it's not likely to change.

Also, unlike ‘ActiveRecord’, here you can define through association referring to belongs-to association (the lack of this feature in ‘ActiveRecord’ is described for example here: https://www.ruby-forum.com/topic/74219)

Different name of an association than a table name

Sometimes you need to set an association that is named differently than the target table name, for example posts may have association authors which refers to table users (or another case: you need associations: created_by and updated_by, both referring to the same users table). In such case you can use inverse-of and model in associations hash, e.g.:

(def associations {:users {:posts {:type :has-many :inverse-of :authors}}
                   :posts {:authors {:type :belongs-to :model :users}}})

Unusual naming for keys/foreign keys

By default keys of tables are assumed to be called id and foreign keys are assumed to match the format association_id (so, for example foreign key for table users is called users_id). If you want to change that, you can define key patterns in last attribute of the function set-associations, e.g.

(def db-state (data-model/set-associations initial-db-state associations {
    :foreign-key-format #(str % "_key")}))

With above settings relational_mapper will expect foreign keys to match the pattern assocation_key.

Dependencies

relational-mapper uses Honey SQL for defining SQL conditions.

TODO

License

Copyright © 2016 Krzysztof Herod

Distributed under the Eclipse Public License, the same as Clojure.