Skip to content
Newer
Older
100644 214 lines (166 sloc) 5.61 KB
66f813c @1602 README.md
authored
1 ## About
2
40b346d @1602 Edited README.md via GitHub
authored
3 JugglingDB is cross-db ORM, providing **common interface** to access most popular database formats.
4 Currently supported are: mysql, mongodb, redis, neo4j and js-memory-storage (yep,
5 self-written engine for test-usage only). You can add your favorite database adapter, checkout one of the
6 existing adapters to learn how, it's super-easy, I guarantee.
66f813c @1602 README.md
authored
7
8 ## Installation
9
10 git clone git://github.com/1602/jugglingdb.git
11
12 ## Usage
13
14 ```javascript
c7ee4b7 @1602 README.md
authored
15 var Schema = require('./jugglingdb').Schema;
66f813c @1602 README.md
authored
16 var s = new Schema('redis');
17 // define models
18 var Post = schema.define('Post', {
19 title: { type: String, length: 255 },
20 content: { type: Schema.Text },
f4642ec @1602 Typo fix
authored
21 date: { type: Date, default: Date.now },
66f813c @1602 README.md
authored
22 published: { type: Boolean, default: false }
23 });
098fa98 Edited README.md via GitHub
Anatoliy Chakkaev authored
24 // simplier way to describe model
66f813c @1602 README.md
authored
25 var User = schema.define('User', {
26 name: String,
098fa98 Edited README.md via GitHub
Anatoliy Chakkaev authored
27 bio: Schema.Text,
66f813c @1602 README.md
authored
28 approved: Boolean,
29 joinedAt: Date,
30 age: Number
31 });
32
33 // setup relationships
34 User.hasMany(Post, {as: 'posts', foreignKey: 'userId'});
35 // creates instance methods:
36 // user.posts(conds)
8e05e59 @1602 Scopes
authored
37 // user.posts.build(data) // like new Post({userId: user.id});
38 // user.posts.create(data) // build and save
66f813c @1602 README.md
authored
39
40 Post.belongsTo(User, {as: 'author', foreignKey: 'userId'});
41 // creates instance methods:
42 // post.author(callback) -- getter when called with function
43 // post.author() -- sync getter when called without params
44 // post.author(user) -- setter when called with object
45
46 s.automigrate(); // required only for mysql NOTE: it will drop User and Post tables
47
48 // work with models:
49 var user = new User;
50 user.save(function (err) {
8e05e59 @1602 Scopes
authored
51 var post = user.posts.build({title: 'Hello world'});
66f813c @1602 README.md
authored
52 post.save(console.log);
53 });
54
55 // Common API methods
56
57 // just instantiate model
58 new Post
59 // save model (of course async)
60 Post.create(cb);
61 // all posts
62 Post.all(cb)
63 // all posts by user
63192ff @1602 Describe object livecycle, update isValid usage
authored
64 Post.all({where: {userId: user.id}});
66f813c @1602 README.md
authored
65 // the same as prev
66 user.posts(cb)
67 // same as new Post({userId: user.id});
8e05e59 @1602 Scopes
authored
68 user.posts.build
66f813c @1602 README.md
authored
69 // save as Post.create({userId: user.id}, cb);
8e05e59 @1602 Scopes
authored
70 user.posts.create(cb)
66f813c @1602 README.md
authored
71 // find instance by id
72 User.find(1, cb)
73 // count instances
74 User.count(cb)
75 // destroy instance
76 user.destroy(cb);
77 // destroy all instances
78 User.destroyAll(cb);
8abce47 @1602 Update validations stuff in README
authored
79
80 // Setup validations
81 User.validatesPresenceOf('name', 'email')
82 User.validatesLengthOf('password', {min: 5, message: {min: 'Password is too short'}});
83 User.validatesInclusionOf('gender', {in: ['male', 'female']});
84 User.validatesExclusionOf('domain', {in: ['www', 'billing', 'admin']});
85 User.validatesNumericalityOf('age', {int: true});
63192ff @1602 Describe object livecycle, update isValid usage
authored
86 User.validatesUniquenessOf('email', {message: 'email is not unique'});
8abce47 @1602 Update validations stuff in README
authored
87
63192ff @1602 Describe object livecycle, update isValid usage
authored
88 user.isValid(function (valid) {
89 if (!valid) {
90 user.errors // hash of errors {attr: [errmessage, errmessage, ...], attr: ...}
91 }
92 })
93
94 ```
95
96 ## Callbacks
97
98 The following callbacks supported:
99
100 - afterInitialize
101 - beforeCreate
102 - afterCreate
103 - beforeSave
104 - afterSave
105 - beforeUpdate
106 - afterUpdate
107 - beforeDestroy
108 - afterDestroy
109 - beforeValidation
110 - afterValidation
111
112 Each callback is class method of the model, it should accept single argument: `next`, this is callback which
113 should be called after end of the hook. Except `afterInitialize` because this method is syncronous (called after `new Model`).
114
115 ## Object lifecycle:
116
117 ```javascript
118 var user = new User;
119 // afterInitialize
120 user.save(callback);
121 // beforeValidation
122 // afterValidation
123 // beforeSave
124 // beforeCreate
125 // afterCreate
126 // afterSave
127 // callback
128 user.updateAttribute('email', 'email@example.com', callback);
129 // beforeValidation
130 // afterValidation
131 // beforeUpdate
132 // afterUpdate
133 // callback
134 user.destroy(callback);
135 // beforeDestroy
136 // afterDestroy
137 // callback
138 User.create(data, callback);
139 // beforeValidate
140 // afterValidate
141 // beforeCreate
142 // afterCreate
143 // callback
66f813c @1602 README.md
authored
144 ```
145
146 Read the tests for usage examples: ./test/common_test.js
8abce47 @1602 Update validations stuff in README
authored
147 Validations: ./test/validations_test.js
66f813c @1602 README.md
authored
148
149 ## Your own database adapter
150
40b346d @1602 Edited README.md via GitHub
authored
151 To use custom adapter, pass it's package name as first argument to `Schema` constructor:
66f813c @1602 README.md
authored
152
153 mySchema = new Schema('couch-db-adapter', {host:.., port:...});
154
155 Make sure, your adapter can be required (just put it into ./node_modules):
156
157 require('couch-db-adapter');
158
159 ## Running tests
160
40b346d @1602 Edited README.md via GitHub
authored
161 All tests are written using nodeunit:
66f813c @1602 README.md
authored
162
163 nodeunit test/common_test.js
164
40b346d @1602 Edited README.md via GitHub
authored
165 If you run this line, of course it will fall, because it requres different databases to be up and running,
166 but you can use js-memory-engine out of box! Specify ONLY env var:
66f813c @1602 README.md
authored
167
168 ONLY=memory nodeunit test/common_test.js
169
170 of course, if you have redis running, you can run
171
172 ONLY=redis nodeunit test/common_test.js
173
174 ## Package structure
175
8abce47 @1602 Update validations stuff in README
authored
176 Now all common logic described in `./lib/*.js`, and database-specific stuff in `./lib/adapters/*.js`. It's super-tiny, right?
66f813c @1602 README.md
authored
177
178 ## Project status
179
40b346d @1602 Edited README.md via GitHub
authored
180 This project was written in one weekend (1,2 oct 2011), and of course does not claim to be production-ready,
181 but I plan to use this project as default ORM for RailwayJS in nearest future.
182 So, if you are familiar with some database engines - please help me to improve adapter for that database.
66f813c @1602 README.md
authored
183
40b346d @1602 Edited README.md via GitHub
authored
184 For example, I know, mysql implementation sucks now, 'cause I'm not digging too deep into SequelizeJS code,
185 and I think it would be better to replace sequelize with something low-level in nearest future, such
186 as `mysql` package from npm.
66f813c @1602 README.md
authored
187
188 ## Contributing
189
190 If you have found a bug please write unit test, and make sure all other tests still pass before pushing code to repo.
191
192 ## Roadmap
193
194 ### Common:
195
098fa98 Edited README.md via GitHub
Anatoliy Chakkaev authored
196 + transparent interface to APIs
66f813c @1602 README.md
authored
197 + -before and -after hooks on save, update, destroy
8e05e59 @1602 Scopes
authored
198 + scopes
66f813c @1602 README.md
authored
199 + default values
200 + more relationships stuff
201 + docs
202
203 ### Databases:
204
205 + riak
206 + couchdb
207 + low-level mysql
208 + postgres
209 + sqlite
210
211 ## License
212
213 MIT
Something went wrong with that request. Please try again.