Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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