Skip to content

Get your joins!

Latest
Compare
Choose a tag to compare
@swlkr swlkr released this 26 Jul 15:58
· 16 commits to master since this release

There were several improvements made to db this release:

  • smarter insert/update/delete
  • join support in from and find-by
  • plural or singular table names work just make sure foreign keys match the table name: accounts_id vs account_id for a plural or singular table name

Smarter insert/update/delete

This works just like before, but the secret sauce is in the metadata (just :db/table that gets returned from every query). You can now do things like this:

(def account (db/insert :accounts {:name "sean"})) ; # => {:name "sean" :db/table :accounts :id 1}

(def account (db/update account {:name "@sean"})) ; # => {:name "@sean" :db/table :accounts :id 1}

(db/delete account) ; # => {:name "@sean" :db/table :accounts :id 1}

Similarly, fetch, fetch-all, find, find-by and from all return the :db/table key and work with the transaction functions too!

(def a (db/find :account 1))

(db/update a {:name "new name"})

You don't have to specify a table if you already have a dictionary with :db/table!

Joins

This is the really cool part, you can not only return joined records with from like so:

(db/from :accounts :join :todos) ; # => [{:name "sean" :id 1 :db/table :accounts :todos/id 1 :todos/name "todo #1"}]

You can also group them into their own array with :join/many

(db/from :accounts :join/many :todos) ; # => [{:name "sean" :id 1 :db/table :accounts :todos [{:id 1 :name "todo #1"}]}]

Similarly you can do a one join where you know the foreign key column is in the queried table:

(db/from :todos :join/one :accounts) ; # => [{:name "todo #1" :id 1 :db/table :todos :account {:id 1 :name "sean"}}]

There are some current gotchas when joining:

  • You can't join more than one table
  • join/one attempts to change the table name to singular if it isn't already: :accounts becomes :account
  • join/many attempts to pluralize the table name in the resulting rows: :account -> :accounts
  • This only works for columns named {{table}}_id, there is no way to specify columns not named after the table yet