Skip to content
A drop-in replacement for korma's scarce entity management.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


A drop-in replacement for korma's scarce entity management and a tool to manage your tables and columns.



Get the game:

[tetrisql "0.1.9-SNAPSHOT"]

Start the game with

(use 'tetrisql.core
(require '[korma.db :as korma])

And choose your options:

(korma/defdb h2 {:classname "org.h2.Driver"
                 :subprotocol "h2"
                 :subname "mem:"
                 :delimiters ["" ""]})
;; Start the game!

Decide wisely where to put your bricks

(create-table! :playfield
               [{:name "brick"
                 :type "INT"}
                {:name "color"
                 :type "VARCHAR"
                 :default (col-value "pink")}])
(create-table! :player
               [{:name "name"
                 :type "VARCHAR"}
                {:name "points"
                 :type "BIGINT"
                 :default 0}])

Personalize them

(dotbl insert player
       (korma/values {:name "zilti"
                      :points 50000}))

And rearrange them later

(if (table-exists? :player)
     :player {:name "anger_level"
              :type "BIGINT"}))

(-> (dotbl* update player
            (korma/set-fields {:anger_level 180})
            (korma/where {:name "zilti"})))

Connect them

(create-relation! :playfield := :player)
;; :> many-to-one - the left-hand table gets a new column "table2_id"
;; :< one-to-many - the right-hand table gets a new column "table1_id"
;; := one-to-one - the right-hand table gets a new column "table1_id"
;; :>< many-to-many - a link-table named "table1_table2" is created, and both tables get a new column.
;; "key :< doors" is the same as "doors :> key

Or just throw them all away

(drop-relation! :playfield := :player)
(drop-column! :player :anger_level)
(drop-table! :player)

Your game will be saved automatically.


TetriSQL has a drop-in replacement for Korma's modification statements. If they're not sufficient at one place, you can still fall back to use the default ones and get your entities like this:

(bootstrap-entity :tblname) ;; This creates an empty entity and inserts it into TetriSQL's config.
		  	    ;; You probably won't need this as entities are implicitly created with
			    ;; create-table! and removed with drop-table!
(relations-select* :tblname) ;; Prepares a korma select* statement to include all relations.


####Reorganize your result sets If you like to work with korma's exec-raw and custom SQL code, TetriSQL has a little present for you: merge-multires. If you use JOIN statements and have to-many or many-to-many relationships (and probably multiple of those), things can get ugly. Consider three tables users, groups and time. users has a has-many relationship to time, and users and groups have a join table users_groups because they're many-to-many. You'll probably end up with something like this:

(korma/exec-raw "SELECT * FROM users
JOIN users_groups ON users_groups.users_id = users.uid
JOIN groups ON groups.gid = users_groups.groups_id
JOIN time ON time.users_id = users.uid" :results)
;; Result set:
[{:users_id_2 1, :time 5, :tid 1, :gname "administrators", :gid 1, :groups_id 1, :users_id 1, :uname "zilti", :uid 1} 
{:users_id_2 1, :time 10, :tid 2, :gname "administrators", :gid 1, :groups_id 1, :users_id 1, :uname "zilti", :uid 1} 
{:users_id_2 1, :time 5, :tid 1, :gname "users", :gid 2, :groups_id 2, :users_id 1, :uname "zilti", :uid 1} 
{:users_id_2 1, :time 10, :tid 2, :gname "users", :gid 2, :groups_id 2, :users_id 1, :uname "zilti", :uid 1} 
{:users_id_2 2, :time 2, :tid 3, :gname "users", :gid 2, :groups_id 2, :users_id 2, :uname "blah", :uid 2}]

Now that's one hell of an ugly result set! :uid is the primary key here, and because of the multiple relationships you see that :uid 1 appears 4 times. Let's sort that stuff! Define which tables contain which columns:

;; Key-mapping
{:groups [:gid :gname], :time [:tid :time]}

Now put both things together:

(merge-multires result-set :uid key-mapping)
;; New result set:
{2 {:uid 2, :uname "blah", :users_id 2, :groups_id 2, :users_id_2 2, :time [{:time 2, :tid 3}], :groups [{:gname "users", :gid 2}]}, 
1 {:uid 1, :uname "zilti", :users_id 1, :groups_id 2, :users_id_2 1, :time [{:time 5, :tid 1} {:time 10, :tid 2}], :groups [{:gname "administrators", :gid 1} {:gname "users", :gid 2}]}}


Copyright © 2013 Daniel Ziltener

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

You can’t perform that action at this time.