-
-
Notifications
You must be signed in to change notification settings - Fork 679
Table.hook('creating')
db.[tableName].hook('creating', function (primKey, obj, transaction) {
// You may do additional database operations using given transaction object.
// You may also modify given obj
// You may set this.onsuccess = function (primKey){}. Called when autoincremented key is known.
// You may set this.onerror = callback if create operation fails.
// If returning any value other than undefined, the returned value will be used as primary key
});
| primKey | The primary key of the object being added, or undefined in case primary key will be created by the system. |
| obj | Object that is about to be created. Modification of obj will affect what will be added to the database. |
| transaction | Transaction instance. |
| <this context> | Possibility to be notified when the create operation succeeds or fails. Done by setting this.onsuccess = function(){} or this.onerror = function(){} |
If return value of given subscriber is other than undefined, the return value will be used as the primary key. Implentors may use this to provide extended methods of auto-generation primary keys other than the built-in autoIncrement (++) method. Return value is only handled in case given primKey was undefined. If primKey was set, any return value will be ignored since it is not allowed.
This event is called whenever an object is being added into the database no matter which method is used. When calling WriteableTable.add(), it will always be called. But when calling WriteableTable.put() it will only be called if the operation results in an object creation. If it would result in replacing an existing object, hook('updating') will be triggered.
A subscriber may use the given transaction object to do additional operations on the database. The chain of operations can be considered atomic since the subscriber can work on the same transaction as being used for creating the object. If any exception or database error event occur, the entire transaction will abort.
If subscriber throws an exception, the create operation will fail and the caller of the create operation will get the failure as a Promise rejection that may be catched/handled or not. If the caller of the create operation does not catch the excetion using Promise.catch(), the transaction will be aborted.
If a database operation initiated by the subscriber, results in a failure, the transaction will be aborted no matter if the origin caller of the delete operation calls catch() or not. However, the origin caller will recieve your error if catching transaction failures, but then the transaction has already aborted. If you as the implementor of the subscriber want to ignore errors resulting from your operations, you may catch() your database operations to prohibit transaction from being aborted. However, it is normally better to let the transaction abort in case a failure of your database operation would impinge database consistancy.
If setting this.onsuccess or this.onerror, those callback functions are responsible of not throwing any exception. Any code within that callback must either be bullet proof or surrounded by try/catch.
Dexie CRUD events can be used to implement several addons to Dexie such as:
- Server Synchronization
- Automatic primary key generation
- Views
- Full-text search or other custom indexes
- etc.
Internally the hook('reading') event is used by the methods Table.defineClass() and Table.mapToClass() in order to make all objects retrieved from database inherit a given class using prototypal inheritance.
This example is a simple implementation of full-text search based on multi-valued indexes and Dexie hooks. NOTE: Multi-valued indexes are only supported in Opera, Firefox and Chrome. Does not work with IE so far. To see an example that works with IE, see FullTextSearch2.js
var db = new Dexie("FullTextSample");
db.version(1).stores({emails: "++id,subject,from,*to,*cc,*bcc,message,*messageWords"});
// To explain the structure of an email, let's declare it as a class (optional!)
var Email = db.emails.defineClass({
id: Number,
subject: String,
from: String,
to: [String],
cc: [String],
bcc: [String],
message: String,
messageWords: [String]
});
// Add hooks that will index "message" for full-text search:
db.emails.hook("creating", function (primKey, obj, trans) {
if (typeof obj.message == 'string') obj.messageWords = getAllWords(obj.message);
});
db.emails.hook("updating", function (mods, primKey, obj, trans) {
if (typeof mods.message == 'string')
return { messageWords: getAllWords(mods.message) };
else
return { messageWords: []};
});
function getAllWords(text) {
/// <param name="text" type="String"></param>
var allWordsIncludingDups = text.split(' ');
var wordSet = allWordsIncludingDups.reduce(function (prev, current) {
prev[current] = true;
return prev;
}, {});
return Object.keys(set);
}
// Open database to allow application code using it.
db.open();
//
// Application code:
//
db.transaction('rw', db.emails, function (emails) {
// Add an email:
emails.add(new Email({
subject: "Testing full-text search",
from: "david@abc.com",
to: ["test@abc.com"],
message: "Here is my very long message that I want to write"
}));
// Search for emails:
emails.where("messageWords").startsWithIgnoreCase("v").distinct().toArray(function (a) {
alert("Found " + a.length + " emails containing a word starting with 'v'");
});
}).catch(function (e) {
alert(e.stack || e);
});
Dexie.js - minimalistic and bullet proof indexedDB library