Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 397 lines (313 sloc) 15.017 kB
cd6c915 Simple prefetching works.
zef authored
1 persistence.js
2 ==============
14f8aac Working on the readme
Zef Hemel authored
3 `persistence.js` is a simple asynchronous Javascript object-relational
1b2c013 @zefhemel Documentation tweaks to accomodate for server environments.
zefhemel authored
4 mapper library. In the browser it works with the HTML5 SQLite database as
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
5 well as Google Gears' local data store. It may be used to develop
6 offline-capable web applications.
7
1b2c013 @zefhemel Documentation tweaks to accomodate for server environments.
zefhemel authored
8 `persistence.js` may also be used on the server, in particular in
9 [node.js](http://nodejs.org) environments. The support for this is
10 currently under heavy development. There is currently a MySQL back-end
11 available. The API to be used in node.js is slightly different than
12 described in this README, be sure to check out the
13 `docs/backend.mysql.md` document to see how it differs.
14
15 For browser use, `persistence.js` has no dependencies on any other
16 frameworks, other than the Google Gears [initialization
17 script](http://code.google.com/apis/gears/gears_init.js), in case you
18 want to enable Gears support.
cd6c915 Simple prefetching works.
zef authored
19
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
20 About asynchronous programming
12acce8 Added an initial basic implementation of full-text search. See
Zef Hemel authored
21 ------------------------------
bf2edb5 More info on asynchronous programming
Zef Hemel authored
22
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
23 In browsers, Javascript and the web page's rendering engine share
24 a single thread. The result of this is that only one thing can happen
25 at a time. If a database query would be performed _synchronously_,
26 like in many other programming environments like Java and PHP the
27 browser would freeze from the moment the query was issued until the
28 results came back. Therefore, many APIs in Javascript are defined as
29 _asynchronous_ APIs, which mean that they do not block when an
30 "expensive" computation is performed, but instead provide the call
31 with a function that will be invoked once the result is known. In the
32 meantime, the browser can perform other duties.
bf2edb5 More info on asynchronous programming
Zef Hemel authored
33
34 For instance, a synchronous database call call would look as follows:
35
36 var results = db.query("SELECT * FROM Table");
37 for(...) { ... }
38
39 The execution of the first statement could take half a second, during
40 which the browser doesn't do anything else. By contrast, the
41 asynchronous version looks as follows:
42
43 db.query("SELECT * FROM Table", function(results) {
44 for(...) { ... }
45 });
46
47 Note that there will be a delay between the `db.query` call and the
48 result being available and that while the database is processing the
49 query, the execution of the Javascript continues. To make this clear,
50 consider the following program:
51
52 db.query("SELECT * FROM Table", function(results) {
53 console.log("hello");
54 });
55 console.log("world");
56
57 Although one could assume this would print "hello", followed by
58 "world", the result will likely be that "world" is printed before
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
59 "hello", because "hello" is only printed when the results from the
bf2edb5 More info on asynchronous programming
Zef Hemel authored
60 query are available. This is a tricky thing about asynchronous
61 programming that a Javascript developer will have to get used to.
62
14f8aac Working on the readme
Zef Hemel authored
63 Browser support
64 ---------------
65
66 * Modern webkit browsers (Google Chrome and Safari)
67 * Firefox (through Google Gears)
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
68 * Android browser (tested on 1.6 and 2.1)
69 * iPhone browser (iPhone OS 3+)
06e6304 Added WebOS to supported platforms.
Zef Hemel authored
70 * Palm WebOS (tested on 1.4.0)
cd6c915 Simple prefetching works.
zef authored
71
c65213f Added Fabio's Date type to documentation.
Zef Hemel authored
72 There is also an experimental support for [Qt 4.7 Declarative UI framework (QML)](http://doc.trolltech.org/4.7-snapshot/declarativeui.html) which is an extension to JavaScript.
42ec4a7 @fgrehm Experimental QML support with HTML5 Synchronous DB API and fixing som…
fgrehm authored
73
14f8aac Working on the readme
Zef Hemel authored
74 Internet Explorer is likely not supported (untested) because it
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
75 lacks `__defineGetter__` and `__defineSetter__` support, which
76 `persistence.js` uses heavily. This may change in IE 8.
14f8aac Working on the readme
Zef Hemel authored
77
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
78 Connecting to a database
14f8aac Working on the readme
Zef Hemel authored
79 -------------------------
80
d61084e persistence.sync.js now keeps track of changes to all entities in
Zef Hemel authored
81 There is one global database connection, which is
14f8aac Working on the readme
Zef Hemel authored
82 initialized with a `persistence.connect` call. Its first argument is
83 the database name, the second a database description and third the
84 maximum database size (in bytes):
cd6c915 Simple prefetching works.
zef authored
85
86 persistence.connect('testdb', 'My test db', 5 * 1024 * 1024);
14f8aac Working on the readme
Zef Hemel authored
87
88 Schema definition
89 -----------------
90
91 A data model is declared using `persistence.define`. The following two
92 definitions define a `Task` and `Category` entity with a few simple
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
93 properties. The property types are based on [SQLite
94 types](http://www.sqlite.org/datatype3.html), currently supported
95 types are:
96
97 * `TEXT`: for textual data
98 * `INT`: for numeric values
99 * `BOOL`: for boolean values (`true` or `false`)
c65213f Added Fabio's Date type to documentation.
Zef Hemel authored
100 * `DATE`: for date/time value (with precision of 1 second)
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
101 * `JSON`: a special type that can be used to store arbitrary
102 [JSON](http://www.json.org) data. Note that this data can not be used
1e94adf Some more JSON property examples + minified version.
Zef Hemel authored
103 to filter or sort in any sensible way. If internal changes are made to a `JSON`
104 property, `persistence.js` may not register them. Therefore, a manual
105 call to `anObj.markDirty('jsonPropertyName')` is required before calling
106 `persistence.flush`.
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
107
108 Example use:
cd6c915 Simple prefetching works.
zef authored
109
73724ff Added .add and .remove methods to QueryCollections.
zef authored
110 var Task = persistence.define('Task', {
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
111 name: "TEXT",
112 description: "TEXT",
113 done: "BOOL"
cd6c915 Simple prefetching works.
zef authored
114 });
115
73724ff Added .add and .remove methods to QueryCollections.
zef authored
116 var Category = persistence.define('Category', {
1e94adf Some more JSON property examples + minified version.
Zef Hemel authored
117 name: "TEXT",
118 metaData: "JSON"
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
119 });
120
121 var Tag = persistence.define('Task', {
122 name: "TEXT"
cd6c915 Simple prefetching works.
zef authored
123 });
124
14f8aac Working on the readme
Zef Hemel authored
125 The returned values are constructor functions and can be used to
126 create new instances of these entities later:
cd6c915 Simple prefetching works.
zef authored
127
128
14f8aac Working on the readme
Zef Hemel authored
129 Relationships between entities are defined using the constructor
130 function's `hasMany` call:
cd6c915 Simple prefetching works.
zef authored
131
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
132 // This defines a one-to-many relationship:
73724ff Added .add and .remove methods to QueryCollections.
zef authored
133 Category.hasMany('tasks', Task, 'category');
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
134 // These two definitions define a many-to-many relationship
135 Task.hasMany('tags', Tag, 'tasks');
136 Tag.hasMany('tasks', Task, 'tags');
cd6c915 Simple prefetching works.
zef authored
137
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
138 The first statement defines a `tasks` relationship on category objects
139 containing a `QueryCollection` (see the section on query collections
140 later) of `Task`s, it also defines an inverse relationship on `Task`
141 objects with the name `category`. The last two statements define a
142 many-to-many relationships between `Task` and `Tag`. `Task` gets a
143 `tags` property (a `QueryCollection`) containing all its tags and vice
144 versa, `Tag` gets a `tasks` property containing all of its tasks.
cd6c915 Simple prefetching works.
zef authored
145
14f8aac Working on the readme
Zef Hemel authored
146 The defined entity definitions are synchronized (activated) with the
147 database using a `persistence.schemaSync` call, which takes a callback
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
148 function (with a newly created transaction as an argument), that is called
14f8aac Working on the readme
Zef Hemel authored
149 when the schema synchronization has completed, the callback is
150 optional.
cd6c915 Simple prefetching works.
zef authored
151
152 persistence.schemaSync();
73724ff Added .add and .remove methods to QueryCollections.
zef authored
153 // or
14f8aac Working on the readme
Zef Hemel authored
154 persistence.schemaSync(function(tx) {
155 // tx is the transaction object of the transaction that was
156 // automatically started
157 });
cd6c915 Simple prefetching works.
zef authored
158
eae6f59 @fgrehm Finishing up documentation
fgrehm authored
159 There is also a migrations plugin you can check out, documentation can be found
58183c9 @fgrehm Fixing link to migrations documentation
fgrehm authored
160 in [persistence.migrations.docs.md](migrations/persistence.migrations.docs.md) file.
eae6f59 @fgrehm Finishing up documentation
fgrehm authored
161
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
162 Creating and manipulating objects
163 ---------------------------------
164
165 New objects can be instantiated with the constructor functions.
166 Optionally, an object with initial property values can be passed as
167 well, or the properties may be set later:
168
169 var task = new Task();
170 var category = new Category({name: "My category"});
1e94adf Some more JSON property examples + minified version.
Zef Hemel authored
171 category.metaData = {rating: 5};
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
172 var tag = new Tag();
173 tag.name = "work";
174
175 Many-to-one relationships are accessed using their specified name, e.g.:
176 task.category = category;
177
178 One-to-many and many-to-many relationships are access and manipulated
179 through the `QueryCollection` API that will be discussed later:
180
181 task.tags.add(tag);
182 tasks.tags.remove(tag)l
183 tasks.tags.list(tx, function(allTags) { console.log(allTags); });
184
4941cd3 Added support for object removal (via `persistence.remove`).
Zef Hemel authored
185 Persisting/removing objects
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
186 ---------------------------
cd6c915 Simple prefetching works.
zef authored
187
14f8aac Working on the readme
Zef Hemel authored
188 Similar to [hibernate](http://www.hibernate.org), `persistence.js`
189 uses a tracking mechanism to determine which objects' changes have to
190 be persisted to the datase. All objects retrieved from the database
191 are automatically tracked for changes. New entities can be tracked to
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
192 be persisted using the `persistence.add` function:
cd6c915 Simple prefetching works.
zef authored
193
c37c40d Formatted readme slightly
Zef Hemel authored
194 var c = new Category({name: "Main category"});
195 persistence.add(c);
196 for ( var i = 0; i < 5; i++) {
197 var t = new Task();
198 t.name = 'Task ' + i;
199 t.done = i % 2 == 0;
200 t.category = c;
201 persistence.add(t);
202 }
cd6c915 Simple prefetching works.
zef authored
203
4941cd3 Added support for object removal (via `persistence.remove`).
Zef Hemel authored
204 Objects can also be removed from the database:
205
206 persistence.remove(c);
207
14f8aac Working on the readme
Zef Hemel authored
208 All changes made to tracked objects can be flushed to the database by
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
209 using `persistence.flush`, which takes a transaction object and
210 callback function as arguments. A new transaction can be started using
e38fbe0 Got rid of redundancy in readme.
Zef Hemel authored
211 `persistence.transaction`:
cd6c915 Simple prefetching works.
zef authored
212
213 persistence.transaction(function(tx) {
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
214 persistence.flush(tx, function() {
215 alert('Done flushing!');
216 });
217 });
14f8aac Working on the readme
Zef Hemel authored
218
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
219 For convenience, it is also possible to not specify a transaction or
220 callback, in that case a new transaction will be started
221 automatically. For instance:
14f8aac Working on the readme
Zef Hemel authored
222
223 persistence.flush();
224 // or, with callback
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
225 persistence.flush(function() {
14f8aac Working on the readme
Zef Hemel authored
226 alert('Done flushing');
227 });
228
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
229 Note that when no callback is defined, the flushing still happens
230 asynchronously.
14f8aac Working on the readme
Zef Hemel authored
231
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
232 __Important__: Changes and new objects will not be persisted until you
233 explicitly call `persistence.flush()`. The exception to this rule is
e38fbe0 Got rid of redundancy in readme.
Zef Hemel authored
234 using the `list(...)` method on a database `QueryCollection`, which also
235 flushes first, although this behavior may change in the future.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
236
d61084e persistence.sync.js now keeps track of changes to all entities in
Zef Hemel authored
237 Dumping and restoring data
ef3606a A simple database dump function. Restore will come soon.
Zef Hemel authored
238 --------------------------------
239
240 `persistence.dump` can be used to create an object containing a full
241 dump of a database. Naturally, it is adviced to only do this with
242 smaller databases. Example:
243
244 persistence.dump(tx, [Task, Category], function(dump) {
245 console.log(dump);
246 });
247
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
248 The `tx` is left out, a new transaction will be started for the
249 operation. If the second argument is left out, `dump` defaults
250 to dumping _all_ defined entities.
ef3606a A simple database dump function. Restore will come soon.
Zef Hemel authored
251
252 The dump format is:
253
254 {"entity-name": [list of instances],
255 ...}
256
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
257 `persistence.load` is used to restore the dump produced by
258 `persistence.dump`. Usage:
259
260 persistence.load(tx, dumpObj, function() {
261 alert('Dump restored!');
262 });
263
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
264 The `tx` argument can be left out to automatically start a new
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
265 transaction. Note that `persistence.load` does not empty the database
266 first, it simply attempts to add all objects to the database. If
267 objects with, e.g. the same ID already exist, this will fail.
ef3606a A simple database dump function. Restore will come soon.
Zef Hemel authored
268
d61084e persistence.sync.js now keeps track of changes to all entities in
Zef Hemel authored
269 Similarly, `persistence.loadFromJson` and `persistence.dumpToJson`
270 respectively load and dump all the database's data as JSON strings.
271
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
272 Entity constructor functions
273 ----------------------------
274
275 The constructor function returned by a `persistence.define` call
276 cannot only be used to instantiate new objects, it also has some
277 useful methods of its own:
278
279 * `EntityName.all([session])` returns a query collection containing
280 all
281 persisted instances of that object. The `session` argument is
282 optional and only required when `persistence.js` is used in
283 multi-session mode.
284 * `EntityName.load([session], [tx], id, callback)` loads an particular
285 object from the database by id or returns `null` if it has not been
286 found.
287 * `EntityName.findBy([session], [tx], property, value, callback)` searches
288 for a particular object based on a property value (this is assumed to
289 be unique), the callback function is called with the found object or
290 `null` if it has not been found.
291
292 And of course the methods to define relationships to other entities:
293
294 * `EntityName.hasMany(property, Entity, inverseProperty)` defines a
295 1:N or N:M relationship (depending on the inverse property)
296 * `EntityName.hasOne(property, Entity)` defines a 1:1 or N:1
297 relationship
298
14f8aac Working on the readme
Zef Hemel authored
299 Query collections
300 -----------------
301
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
302 A core concept of `persistence.js` is the `QueryCollection`. A
14f8aac Working on the readme
Zef Hemel authored
303 `QueryCollection` represents a (sometimes) virtual collection that can
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
304 be filtered, ordered or paginated. `QueryCollection`s are somewhate
305 inspired by [Google AppEngine's Query
306 class](http://code.google.com/appengine/docs/python/datastore/queryclass.html).
14f8aac Working on the readme
Zef Hemel authored
307 A `QueryCollection` has the following methods:
308
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
309 * `filter(property, operator, value)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
310 Returns a new `QueryCollection` that adds a filter, filtering a
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
311 certain property based on an operator and value. Supported operators
312 are '=', '!=', '<', '<=', '>' and '>='. Example: `.filter('done',
313 '=', true)`
314 * `order(property, ascending)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
315 Returns a new `QueryCollection` that will order its results by the
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
316 property specified in either an ascending (ascending === true) or
317 descending (ascending === false) order.
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
318 * `limit(n)`
319 Returns a new `QueryCollection` that limits the size of the result
320 set to `n` items. Useful for pagination.
321 * `skip(n)`
322 Returns a new `QueryCollection` that skips the first `n` results.
323 Useful for pagination.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
324 * `prefetch(rel)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
325 Returns a new `QueryCollection` that prefetches entities linked
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
326 through relationship `rel`, note that this only works for one-to-one
327 and many-to-one relationships.
a9fa189 @zefhemel Added `count` call to query collections. Fixed a little bug in
zefhemel authored
328 * `add(obj)`
329 Adds object `obj` to the collection.
330 * `remove(obj)`
331 Removes object `obj` from the collection.
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
332 * `list([tx], callback)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
333 Asynchronously fetches the results matching the formulated query.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
334 Once retrieved, the callback function is invoked with an array of
335 entity objects as argument.
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
336 * `each([tx], eachCallback)`
9520607 Basic implementation of LocalQueryCollection, only supports filtering
Zef Hemel authored
337 Asynchronously fetches the results matching the formulated query.
338 Once retrieved, the `eachCallback` function is invoked on each
339 element of the result objects.
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
340 * `forEach([tx], eachCallback)`
341 Alias for `each`
342 * `one([tx], callback)`
a2c07b5 @zefhemel Added `destroyAll` method to DbQueryCollections to remove all the items
zefhemel authored
343 Asynchronously fetches the first element of the collection, or `null` if none.
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
344 * `destroyAll([tx], callback)`
a2c07b5 @zefhemel Added `destroyAll` method to DbQueryCollections to remove all the items
zefhemel authored
345 Asynchronously removes all the items in the collection. __Important__: this does
346 not only remove the items from the collection, but removes the items themselves!
e2d2c10 @zefhemel IMPORTANT: Minor breaking changes!
zefhemel authored
347 * `count([tx], callback)`
a9fa189 @zefhemel Added `count` call to query collections. Fixed a little bug in
zefhemel authored
348 Asynchronously counts the number of items in the collection. The arguments passed
349 to the `callback` function is the number of items.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
350
351 Query collections are returned by:
352
353 * `EntityName.all()`, e.g. `Task.all()`
354 * one-to-many and many-to-many relationships, e.g. `task.tags`
355
356 Example:
cd6c915 Simple prefetching works.
zef authored
357
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
358 var allTasks = Task.all().filter("done", '=', true).prefetch("category").order("name", false).limit(10);
cd6c915 Simple prefetching works.
zef authored
359
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
360 allTasks.list(null, function (results) {
361 results.forEach(function (r) {
362 console.log(r.name)
363 window.task = r;
cd6c915 Simple prefetching works.
zef authored
364 });
365 });
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
366
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
367 Bugs and Contributions
b07a858 Moved issues to the issue tracker.
Zef Hemel authored
368 -----------------
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
369
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
370 If you find a bug, please [report it](http://yellowgrass.org/project/persistence.js).
c65213f Added Fabio's Date type to documentation.
Zef Hemel authored
371 or fork the project, fix the problem and send me a pull request. For
b07a858 Moved issues to the issue tracker.
Zef Hemel authored
372 a list of planned features and open issues, have a look at the [issue
b5cd840 Changed location of issue tracker.
Zef Hemel authored
373 tracker](http://yellowgrass.org/project/persistence.js).
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
374
0302c86 Added link to Google Group
Zef Hemel authored
375 For support and discussion, please join the [persistence.js Google
376 Group](http://groups.google.com/group/persistencejs).
377
c65213f Added Fabio's Date type to documentation.
Zef Hemel authored
378 Thanks goes to [Fabio Rehm](http://github.com/fgrehm) and [Lukas
379 Berns](http://github.com/lukasberns) for their contributions.
380
cda1de2 @zefhemel Added link to the persistence.js GWT wrapper.
zefhemel authored
381 If you use [GWT](http://code.google.com/webtoolkit/) (the Google Web
382 Toolkit), be sure to have a look at [Dennis Z. Jiang's GWT persistence.js
383 wrapper](http://github.com/dennisjzh/gwt-persistence).
384
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
385 License
386 -------
387
388 This work is licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
cb16171 Added flattr link
Zef Hemel authored
389
390 Support this work
391 -----------------
392
393 You can support this project by flattering it:
394
395 <a href="http://flattr.com/thing/2510/persistence-js" target="_blank">
396 <img src="http://api.flattr.com/button/button-static-50x60.png" title="Flattr this" border="0" /></a>
Something went wrong with that request. Please try again.