Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 337 lines (264 sloc) 12.373 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
bf2edb5 More info on asynchronous programming
Zef Hemel authored
13 -----------------------------------------
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
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
151 Creating and manipulating objects
152 ---------------------------------
153
154 New objects can be instantiated with the constructor functions.
155 Optionally, an object with initial property values can be passed as
156 well, or the properties may be set later:
157
158 var task = new Task();
159 var category = new Category({name: "My category"});
1e94adf Some more JSON property examples + minified version.
Zef Hemel authored
160 category.metaData = {rating: 5};
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
161 var tag = new Tag();
162 tag.name = "work";
163
164 Many-to-one relationships are accessed using their specified name, e.g.:
165 task.category = category;
166
167 One-to-many and many-to-many relationships are access and manipulated
168 through the `QueryCollection` API that will be discussed later:
169
170 task.tags.add(tag);
171 tasks.tags.remove(tag)l
172 tasks.tags.list(tx, function(allTags) { console.log(allTags); });
173
4941cd3 Added support for object removal (via `persistence.remove`).
Zef Hemel authored
174 Persisting/removing objects
cd6c915 Simple prefetching works.
zef authored
175 ------------------
176
14f8aac Working on the readme
Zef Hemel authored
177 Similar to [hibernate](http://www.hibernate.org), `persistence.js`
178 uses a tracking mechanism to determine which objects' changes have to
179 be persisted to the datase. All objects retrieved from the database
180 are automatically tracked for changes. New entities can be tracked to
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
181 be persisted using the `persistence.add` function:
cd6c915 Simple prefetching works.
zef authored
182
c37c40d Formatted readme slightly
Zef Hemel authored
183 var c = new Category({name: "Main category"});
184 persistence.add(c);
185 for ( var i = 0; i < 5; i++) {
186 var t = new Task();
187 t.name = 'Task ' + i;
188 t.done = i % 2 == 0;
189 t.category = c;
190 persistence.add(t);
191 }
cd6c915 Simple prefetching works.
zef authored
192
4941cd3 Added support for object removal (via `persistence.remove`).
Zef Hemel authored
193 Objects can also be removed from the database:
194
195 persistence.remove(c);
196
14f8aac Working on the readme
Zef Hemel authored
197 All changes made to tracked objects can be flushed to the database by
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
198 using `persistence.flush`, which takes a transaction object and
199 callback function as arguments. A new transaction can be started using
e38fbe0 Got rid of redundancy in readme.
Zef Hemel authored
200 `persistence.transaction`:
cd6c915 Simple prefetching works.
zef authored
201
202 persistence.transaction(function(tx) {
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
203 persistence.flush(tx, function() {
204 alert('Done flushing!');
205 });
206 });
14f8aac Working on the readme
Zef Hemel authored
207
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
208 For convenience, it is also possible to not specify a transaction or
209 callback, in that case a new transaction will be started
210 automatically. For instance:
14f8aac Working on the readme
Zef Hemel authored
211
212 persistence.flush();
213 // or, with callback
214 persistence.flush(null, function() {
215 alert('Done flushing');
216 });
217
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
218 Note that when no callback is defined, the flushing still happens
219 asynchronously.
14f8aac Working on the readme
Zef Hemel authored
220
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
221 __Important__: Changes and new objects will not be persisted until you
222 explicitly call `persistence.flush()`. The exception to this rule is
e38fbe0 Got rid of redundancy in readme.
Zef Hemel authored
223 using the `list(...)` method on a database `QueryCollection`, which also
224 flushes first, although this behavior may change in the future.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
225
d61084e persistence.sync.js now keeps track of changes to all entities in
Zef Hemel authored
226 Dumping and restoring data
ef3606a A simple database dump function. Restore will come soon.
Zef Hemel authored
227 --------------------------------
228
229 `persistence.dump` can be used to create an object containing a full
230 dump of a database. Naturally, it is adviced to only do this with
231 smaller databases. Example:
232
233 persistence.dump(tx, [Task, Category], function(dump) {
234 console.log(dump);
235 });
236
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
237 When `null` is provided as a first argument a new transaction will be
238 started for the operation. If `null` is provided as second argument,
239 `dump` defaults to dumping _all_ defined entities.
ef3606a A simple database dump function. Restore will come soon.
Zef Hemel authored
240
241 The dump format is:
242
243 {"entity-name": [list of instances],
244 ...}
245
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
246 `persistence.load` is used to restore the dump produced by
247 `persistence.dump`. Usage:
248
249 persistence.load(tx, dumpObj, function() {
250 alert('Dump restored!');
251 });
252
253 The `tx` argument can be `null` to automatically start a new
254 transaction. Note that `persistence.load` does not empty the database
255 first, it simply attempts to add all objects to the database. If
256 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
257
d61084e persistence.sync.js now keeps track of changes to all entities in
Zef Hemel authored
258 Similarly, `persistence.loadFromJson` and `persistence.dumpToJson`
259 respectively load and dump all the database's data as JSON strings.
260
14f8aac Working on the readme
Zef Hemel authored
261 Query collections
262 -----------------
263
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
264 A core concept of `persistence.js` is the `QueryCollection`. A
14f8aac Working on the readme
Zef Hemel authored
265 `QueryCollection` represents a (sometimes) virtual collection that can
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
266 be filtered, ordered or paginated. `QueryCollection`s are somewhate
267 inspired by [Google AppEngine's Query
268 class](http://code.google.com/appengine/docs/python/datastore/queryclass.html).
14f8aac Working on the readme
Zef Hemel authored
269 A `QueryCollection` has the following methods:
270
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
271 * `filter(property, operator, value)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
272 Returns a new `QueryCollection` that adds a filter, filtering a
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
273 certain property based on an operator and value. Supported operators
274 are '=', '!=', '<', '<=', '>' and '>='. Example: `.filter('done',
275 '=', true)`
276 * `order(property, ascending)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
277 Returns a new `QueryCollection` that will order its results by the
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
278 property specified in either an ascending (ascending === true) or
279 descending (ascending === false) order.
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
280 * `limit(n)`
281 Returns a new `QueryCollection` that limits the size of the result
282 set to `n` items. Useful for pagination.
283 * `skip(n)`
284 Returns a new `QueryCollection` that skips the first `n` results.
285 Useful for pagination.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
286 * `prefetch(rel)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
287 Returns a new `QueryCollection` that prefetches entities linked
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
288 through relationship `rel`, note that this only works for one-to-one
289 and many-to-one relationships.
290 * `list(tx, callback)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
291 Asynchronously fetches the results matching the formulated query.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
292 Once retrieved, the callback function is invoked with an array of
293 entity objects as argument.
9520607 Basic implementation of LocalQueryCollection, only supports filtering
Zef Hemel authored
294 * `each(tx, eachCallback)`
295 Asynchronously fetches the results matching the formulated query.
296 Once retrieved, the `eachCallback` function is invoked on each
297 element of the result objects.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
298 * `add(obj)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
299 Adds object `obj` to the collection.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
300 * `remove(obj)`
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
301 Removes object `obj` from the collection.
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
302
303 Query collections are returned by:
304
305 * `EntityName.all()`, e.g. `Task.all()`
306 * one-to-many and many-to-many relationships, e.g. `task.tags`
307
308 Example:
cd6c915 Simple prefetching works.
zef authored
309
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
310 var allTasks = Task.all().filter("done", '=', true).prefetch("category").order("name", false).limit(10);
cd6c915 Simple prefetching works.
zef authored
311
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
312 allTasks.list(null, function (results) {
313 results.forEach(function (r) {
314 console.log(r.name)
315 window.task = r;
cd6c915 Simple prefetching works.
zef authored
316 });
317 });
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
318
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
319 Bugs and Contributions
b07a858 Moved issues to the issue tracker.
Zef Hemel authored
320 -----------------
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
321
127d79b Rewrote parts of readme. Added documentation for supported property
Zef Hemel authored
322 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
323 or fork the project, fix the problem and send me a pull request. For
b07a858 Moved issues to the issue tracker.
Zef Hemel authored
324 a list of planned features and open issues, have a look at the [issue
b5cd840 Changed location of issue tracker.
Zef Hemel authored
325 tracker](http://yellowgrass.org/project/persistence.js).
033f67a Added .limit(n) and .skip(n) support.
Zef Hemel authored
326
0302c86 Added link to Google Group
Zef Hemel authored
327 For support and discussion, please join the [persistence.js Google
328 Group](http://groups.google.com/group/persistencejs).
329
c65213f Added Fabio's Date type to documentation.
Zef Hemel authored
330 Thanks goes to [Fabio Rehm](http://github.com/fgrehm) and [Lukas
331 Berns](http://github.com/lukasberns) for their contributions.
332
90ea29b Extended README + license. Preparing for initial release.
Zef Hemel authored
333 License
334 -------
335
336 This work is licensed under the [MIT license](http://en.wikipedia.org/wiki/MIT_License).
Something went wrong with that request. Please try again.