diff --git a/examples/test.html b/examples/test.html
index b1adf96..cd22b5c 100644
--- a/examples/test.html
+++ b/examples/test.html
@@ -14,10 +14,13 @@ require.config({
require(["../../javascript-debug/debug", "src/filesystem"], function(debug, FileSystem) {
var fs = new FileSystem(undefined, true);
- debug.log("filesystem state: ", fs.state);
+ // debug.log("filesystem state: ", fs.state);
fs.then(function(fs) {
- debug.log("filesystem state: ", fs.state);
- fs.mkdir("/tmp");
+ // debug.log("filesystem state: ", fs.state);
+ var p = fs.mkdir("/tmp");
+ p.then(function(e) {
+ fs.mkdir("/tmp");
+ });
});
});
diff --git a/src/filesystem.js b/src/filesystem.js
index ebb5b93..a562e02 100644
--- a/src/filesystem.js
+++ b/src/filesystem.js
@@ -30,6 +30,10 @@ define(function(require) {
}).toUpperCase();
}
+ function dirname(path) {
+ return path.match( /.*\// );
+ }
+
function FileError(code) {
this.code = code;
// FIXME: add a message field with the text error
@@ -58,6 +62,59 @@ define(function(require) {
RW = "readwrite";
function FileSystem(name, optFormat) {
+ function Transaction(db, scope, mode) {
+ var id = this.id = guid();
+ this._IdbTransaction = db.transaction(scope, mode);
+ var deferred = when.defer();
+ this._IdbTransaction.oncomplete = function(e) {
+ deferred.resolve(e);
+ clearPending(id);
+ };
+ this._IdbTransaction.onerror = function(e) {
+ deferred.reject(e);
+ clearPending(id);
+ };
+ this.then = deferred.promise.then;
+ this.objectStore = this._IdbTransaction.objectStore.bind(this._IdbTransaction);
+ this.abort = this._IdbTransaction.abort.bind(this._IdbTransaction);
+ queuePending(this, id);
+ }
+
+ function Request(request) {
+ var id = this.id = guid();
+ this._IdbRequest = request;
+ var deferred = when.defer();
+ this._IdbRequest.onsuccess = function(e) {
+ deferred.resolve(e);
+ clearPending(id);
+ };
+ this._IdbRequest.onerror = function(e) {
+ deferred.reject(e);
+ clearPending(id);
+ };
+ this.then = deferred.promise.then;
+ queuePending(this, id);
+ }
+
+ function OpenDBRequest(request, upgrade) {
+ var id = this.id = guid();
+ this._IdbRequest = request;
+ var deferred = when.defer();
+ this._IdbRequest.onsuccess = function(e) {
+ deferred.resolve(e);
+ clearPending(id);
+ };
+ this._IdbRequest.onerror = function(e) {
+ deferred.reject(e);
+ clearPending(id);
+ };
+ if(typeof upgrade === "function") {
+ this._IdbRequest.onupgradeneeded = upgrade;
+ }
+ this.then = deferred.promise.then;
+ queuePending(this, id);
+ }
+
var fs = this;
fs.OBJECT_STORE_NAME = "files";
fs.name = name || "default";
@@ -88,22 +145,17 @@ define(function(require) {
}
}
- function queuePending(request) {
- var id = guid();
- request.id = id;
- fs.pending[id] = request;
+ function queuePending(transaction, id) {
+ fs.pending[id] = transaction;
updateState();
- return request;
+ return transaction;
}
- function clearPending(request) {
- var id = request.id;
+ function clearPending(id) {
if(fs.pending.hasOwnProperty(id)) {
delete fs.pending[id];
}
- delete request.id;
updateState();
- return request;
}
var format = undefined !== optFormat ? optFormat : false;
@@ -111,27 +163,8 @@ define(function(require) {
fs.then = deferred.promise.then;
updateState();
- var openRequest = queuePending(indexedDB.open(name));
- fs.state = FileSystem.PENDING;
-
- openRequest.onsuccess = function(e) {
- fs.db = e.target.result;
- var db = fs.db;
- var transaction = db.transaction([fs.OBJECT_STORE_NAME], RW);
- var store = transaction.objectStore(fs.OBJECT_STORE_NAME);
- if(format) {
- debug.info("format required");
- var formatRequest = queuePending(store.put({}, "/"));
- formatRequest.onsuccess = function(e) {
- debug.info("format complete");
- clearPending(formatRequest);
- };
- }
- clearPending(openRequest);
- };
-
- openRequest.onupgradeneeded = function(e) {
- db = e.target.result;
+ var openRequest = new OpenDBRequest(indexedDB.open(name), function(e) {
+ var db = fs.db = e.target.result;
if(db.objectStoreNames.contains("files")) {
db.deleteObjectStore("files");
}
@@ -140,40 +173,57 @@ define(function(require) {
store.createIndex("name", "name", {unique: true});
format = true;
- };
-
- openRequest.onerror = function(e) {
- clearPending(openRequest);
- };
+ });
+ openRequest.then(function(e) {
+ fs.db = e.target.result;
+ var db = fs.db;
+ var transaction = new Transaction(db, [fs.OBJECT_STORE_NAME], RW);
+ var store = transaction.objectStore(fs.OBJECT_STORE_NAME);
+ if(format) {
+ debug.info("format required");
+ var clearRequest = new Request(store.clear());
+ clearRequest.then(function() {
+ var formatRequest = new Request(store.put({
+ "parent": null,
+ "name": "/"
+ }, "/"));
+ formatRequest.then(function(e) {
+ debug.info("format complete");
+ });
+ });
+ }
+ });
// API
- this.mkdir = function mkdir(path) {
- debug.info("mkdir");
- var db = fs.db;
- var d = when.defer();
- var transaction = db.transaction([this.OBJECT_STORE_NAME], RW);
+ this.mkdir = function mkdir(name, transaction) {
+ debug.info("mkdir invoked");
+ var deferred = when.defer();
+ var transaction = transaction || new Transaction(fs.db, [this.OBJECT_STORE_NAME], RW);
var store = transaction.objectStore(fs.OBJECT_STORE_NAME);
var nameIndex = store.index("name");
- var getRequest = queuePending(nameIndex.get(path));
- getRequest.onsuccess = function(e) {
- clearPending(getRequest);
+ var getRequest = new Request(nameIndex.get(name));
+ getRequest.then(function(e) {
var result = e.target.result;
if(result) {
- debug.info("mkdir PATH_EXISTS_ERR");
- d.reject(new DirectoryError(DirectoryError.PATH_EXISTS_ERR));
+ debug.info("mkdir error: PATH_EXISTS_ERR");
+ deferred.reject(new DirectoryError(DirectoryError.PATH_EXISTS_ERR));
} else {
- var directoryRequest = queuePending(store.put({}, path));
- directoryRequest.onsuccess = function(e) {
+ try{
+ var directoryRequest = new Request(store.put({
+ "parent": dirname(name),
+ "name": name
+ }, name));
+ directoryRequest.then(function(e) {
debug.info("mkdir complete");
- clearPending(directoryRequest);
- d.resolve();
- };
+ deferred.resolve();
+ });
+ }catch(e){console.log(e);}
}
- };
- return d.promise;
- }
+ });
+ return deferred.promise;
+ };
}
FileSystem.READY = 0;
FileSystem.PENDING = 1;