Skip to content

Commit 3acac4e

Browse files
committed
README.
1 parent 07ee73c commit 3acac4e

File tree

1 file changed

+180
-7
lines changed

1 file changed

+180
-7
lines changed

README.markdown

+180-7
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,36 @@
22

33
[![Build Status](https://travis-ci.org/fukamachi/mito.svg?branch=master)](https://travis-ci.org/fukamachi/mito)
44
[![Coverage Status](https://coveralls.io/repos/fukamachi/mito/badge.svg?branch=master&service=github)](https://coveralls.io/github/fukamachi/mito?branch=master)
5-
6-
Work in progress.
5+
[![Quicklisp dist](http://quickdocs.org/badge/mito.svg)](http://quickdocs.org/mito/)
76

87
Mito is yet another object relational mapper and it aims to be a successor of [Integral](https://github.com/fukamachi/integral).
98

10-
* Support PostgreSQL
11-
* Better abstraction for RDBMS
12-
* Better code structure
9+
* Supports MySQL, PostgreSQL and SQLite3
10+
* Migrations
11+
* DB schema versioning
12+
13+
## Warning
14+
15+
This software is still ALPHA quality. The APIs will be likely to change.
1316

1417
## Usage
1518

1619
```common-lisp
20+
(mito:connect-toplevel :mysql :database-name "myapp" :username "fukamachi" :password "c0mon-1isp")
21+
;=> #<DBD.MYSQL:<DBD-MYSQL-CONNECTION> {100691BFF3}>
22+
1723
(defclass user ()
1824
((name :col-type (:varchar 64)
1925
:initarg :name
2026
:accessor user-name)
2127
(email :col-type (or (:varchar 128) :null)
2228
:initarg :email
2329
:accessor user-email))
24-
(:metaclass dao-table-class))
30+
(:metaclass mito:dao-table-class))
31+
;=> #<MITO.DAO.TABLE:DAO-TABLE-CLASS COMMON-LISP-USER::USER>
32+
33+
(mito:table-definition 'user)
34+
;=> #<SXQL-STATEMENT: CREATE TABLE user (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL, email VARCHAR(128))>
2535
2636
(defclass tweet ()
2737
((status :col-type :text
@@ -30,9 +40,172 @@ Mito is yet another object relational mapper and it aims to be a successor of [I
3040
(user :col-type user
3141
:initarg :user
3242
:accessor tweet-user))
33-
(:metaclass dao-table-class))
43+
(:metaclass mito:dao-table-class))
44+
;=> #<MITO.DAO.TABLE:DAO-TABLE-CLASS COMMON-LISP-USER::TWEET>
45+
46+
(mito:table-definition 'tweet)
47+
;=> #<SXQL-STATEMENT: CREATE TABLE tweet (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, status TEXT NOT NULL, user_id BIGINT UNSIGNED NOT NULL)>
48+
```
49+
50+
### Connecting to DB
51+
52+
Mito provides a function `connect-toplevel` and `disconnect-toplevel` to establish a connection to RDBMS.
53+
54+
`connect-toplevel` takes the same arguments as `dbi:connect`, typically the driver-type, the database name to connect, user name and password.
55+
56+
```common-lisp
57+
(mito:connect-toplevel :mysql :database-name "myapp" :username "fukamachi" :password "c0mon-1isp")
58+
```
59+
60+
`connect-toplevel` sets `*connection*` the new connection and returns it.
61+
62+
If you want to use a connection lexically, just bind it:
63+
64+
```common-lisp
65+
(let ((mito:*connection* (dbi:connect :sqlite3 :database-name #P"/tmp/myapp.db")))
66+
(unwind-protect (progn ...)
67+
;; Ensure that the connection is closed.
68+
(dbi:disconnect mito:*connection*)))
3469
```
3570

71+
### Class Definitions
72+
73+
In Mito, you can define a class which corresponds to a database table by specifying `(:metaclass mito:dao-table-class)`.
74+
75+
```common-lisp
76+
(defclass user ()
77+
((name :col-type (:varchar 64)
78+
:initarg :name
79+
:accessor user-name)
80+
(email :col-type (or (:varchar 128) :null)
81+
:initarg :email
82+
:accessor user-email))
83+
(:metaclass mito:dao-table-class))
84+
```
85+
86+
The above defines a Common Lisp normal class except that it allows additional options.
87+
88+
```
89+
(defclass {class-name} ()
90+
({column-definition}*)
91+
(:metaclass mito:dao-table-class)
92+
[[class-option]])
93+
94+
column-definition ::= (slot-name [[column-option]])
95+
column-option ::= {:col-type col-type} |
96+
{:primary-key boolean} |
97+
{:ghost boolean}
98+
col-type ::= { keyword |
99+
(keyword . args) |
100+
(or keyword :null) |
101+
(or :null keyword) }
102+
class-option ::= {:primary-keys symbol*} |
103+
{:unique-keys {symbol | (symbol*)}*} |
104+
{:keys {symbol | (symbol*)}*} |
105+
{:table-name table-name}
106+
{:auto-pk boolean}
107+
```
108+
109+
Note the class automatically adds a primary key named `id` if there's no primary keys.
110+
111+
```common-lisp
112+
(c2mop:class-direct-slots (find-class 'user))
113+
;=> (#<MITO.DAO.COLUMN:DAO-TABLE-COLUMN-CLASS MITO.DAO.TABLE::%SYNCED>
114+
; #<MITO.DAO.COLUMN:DAO-TABLE-COLUMN-CLASS MITO.DAO.TABLE::ID>
115+
; #<MITO.DAO.COLUMN:DAO-TABLE-COLUMN-CLASS COMMON-LISP-USER::NAME>
116+
; #<MITO.DAO.COLUMN:DAO-TABLE-COLUMN-CLASS COMMON-LISP-USER::EMAIL>)
117+
```
118+
119+
To prevent this behavior, add `:auto-pk nil` to the class options.
120+
121+
The class inherits `mito:dao-class` implicitly.
122+
123+
```common-lisp
124+
(find-class 'user)
125+
;=> #<MITO.DAO.TABLE:DAO-TABLE-CLASS COMMON-LISP-USER::USER>
126+
127+
(c2mop:class-direct-superclasses *)
128+
;=> (#<STANDARD-CLASS MITO.DAO.TABLE:DAO-CLASS>)
129+
```
130+
131+
This may be useful when you define methods which can be applied for all table classes.
132+
133+
### Generating Table Definitions
134+
135+
```common-lisp
136+
(mito:table-definition 'user)
137+
;=> #<SXQL-STATEMENT: CREATE TABLE user (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL, email VARCHAR(128))>
138+
139+
(sxql:yield *)
140+
;=> "CREATE TABLE user (id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(64) NOT NULL, email VARCHAR(128))"
141+
; NIL
142+
```
143+
144+
### Creating DB tables
145+
146+
```common-lisp
147+
(mito:execute-sql (mito:table-definition 'user))
148+
149+
(mito:ensure-table-exists 'user)
150+
```
151+
152+
### CRUD
153+
154+
```common-lisp
155+
(defvar me
156+
(make-instance 'user :name "Eitaro Fukamachi" :email "[email protected]"))
157+
;=> USER
158+
159+
(mito:insert-dao me)
160+
;-> ;; INSERT INTO `user` (`name`, `email`) VALUES (?, ?) ("Eitaro Fukamachi", "[email protected]") [0 rows] | MITO.DAO:INSERT-DAO
161+
;=> #<USER {10053C4453}>
162+
163+
;; Same as above
164+
(mito:create-dao 'user :name "Eitaro Fukamachi" :email "[email protected]")
165+
166+
;; Getting the primary key value
167+
(mito:object-id me)
168+
;=> 1
169+
170+
;; Retrieving from the DB
171+
(mito:find-dao 'user 1)
172+
;-> ;; SELECT * FROM `user` WHERE (`id` = ?) LIMIT 1 (1) [1 row] | MITO.DB:RETRIEVE-BY-SQL
173+
;=> #<USER {10077C6073}>
174+
175+
;; Updating
176+
(setf (slot-value me 'name) "nitro_idiot")
177+
;=> "nitro_idiot"
178+
179+
(mito:save-dao me)
180+
;-> ;; UPDATE `user` SET `id` = ?, `name` = ?, `email` = ? WHERE (`id` = ?) (1, "nitro_idiot", "[email protected]", 2) [0 rows] | MITO.DB:EXECUTE-SQL
181+
182+
;; Deleting
183+
(mito:delete-dao me)
184+
;-> ;; DELETE FROM `user` WHERE (`id` = ?) (1) [0 rows] | MITO.DAO:DELETE-DAO
185+
```
186+
187+
### Relation
188+
189+
### Migrations
190+
191+
## Installation
192+
193+
```
194+
$ mkdir -p ~/common-lisp
195+
$ cd ~/common-lisp
196+
$ git clone https://github.com/fukamachi/mito
197+
$ ros -L ~/common-lisp/mito/mito.asd install mito
198+
```
199+
200+
```common-lisp
201+
(ql:quickload :mito)
202+
```
203+
204+
## See Also
205+
206+
* [CL-DBI](https://github.com/fukamachi/cl-dbi)
207+
* [SxQL](https://github.com/fukamachi/sxql)
208+
36209
## Author
37210

38211
* Eitaro Fukamachi ([email protected])

0 commit comments

Comments
 (0)