Added wrappers for requests and transactions.

This commit is contained in:
Alan Kligman 2012-10-08 01:53:12 -04:00
parent 920bf44cae
commit 129189ea77
2 changed files with 109 additions and 56 deletions

View File

@ -14,11 +14,14 @@ require.config({
require(["../../javascript-debug/debug", "src/filesystem"], function(debug, FileSystem) { require(["../../javascript-debug/debug", "src/filesystem"], function(debug, FileSystem) {
var fs = new FileSystem(undefined, true); var fs = new FileSystem(undefined, true);
debug.log("filesystem state: ", fs.state); // debug.log("filesystem state: ", fs.state);
fs.then(function(fs) { fs.then(function(fs) {
debug.log("filesystem state: ", fs.state); // debug.log("filesystem state: ", fs.state);
var p = fs.mkdir("/tmp");
p.then(function(e) {
fs.mkdir("/tmp"); fs.mkdir("/tmp");
}); });
});
}); });
</script> </script>
</html> </html>

View File

@ -30,6 +30,10 @@ define(function(require) {
}).toUpperCase(); }).toUpperCase();
} }
function dirname(path) {
return path.match( /.*\// );
}
function FileError(code) { function FileError(code) {
this.code = code; this.code = code;
// FIXME: add a message field with the text error // FIXME: add a message field with the text error
@ -58,6 +62,59 @@ define(function(require) {
RW = "readwrite"; RW = "readwrite";
function FileSystem(name, optFormat) { 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; var fs = this;
fs.OBJECT_STORE_NAME = "files"; fs.OBJECT_STORE_NAME = "files";
fs.name = name || "default"; fs.name = name || "default";
@ -88,22 +145,17 @@ define(function(require) {
} }
} }
function queuePending(request) { function queuePending(transaction, id) {
var id = guid(); fs.pending[id] = transaction;
request.id = id;
fs.pending[id] = request;
updateState(); updateState();
return request; return transaction;
} }
function clearPending(request) { function clearPending(id) {
var id = request.id;
if(fs.pending.hasOwnProperty(id)) { if(fs.pending.hasOwnProperty(id)) {
delete fs.pending[id]; delete fs.pending[id];
} }
delete request.id;
updateState(); updateState();
return request;
} }
var format = undefined !== optFormat ? optFormat : false; var format = undefined !== optFormat ? optFormat : false;
@ -111,27 +163,8 @@ define(function(require) {
fs.then = deferred.promise.then; fs.then = deferred.promise.then;
updateState(); updateState();
var openRequest = queuePending(indexedDB.open(name)); var openRequest = new OpenDBRequest(indexedDB.open(name), function(e) {
fs.state = FileSystem.PENDING; var db = fs.db = e.target.result;
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;
if(db.objectStoreNames.contains("files")) { if(db.objectStoreNames.contains("files")) {
db.deleteObjectStore("files"); db.deleteObjectStore("files");
} }
@ -140,40 +173,57 @@ define(function(require) {
store.createIndex("name", "name", {unique: true}); store.createIndex("name", "name", {unique: true});
format = true; format = true;
}; });
openRequest.then(function(e) {
openRequest.onerror = function(e) { fs.db = e.target.result;
clearPending(openRequest); 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 // API
this.mkdir = function mkdir(path) { this.mkdir = function mkdir(name, transaction) {
debug.info("mkdir"); debug.info("mkdir invoked");
var db = fs.db; var deferred = when.defer();
var d = when.defer(); var transaction = transaction || new Transaction(fs.db, [this.OBJECT_STORE_NAME], RW);
var transaction = db.transaction([this.OBJECT_STORE_NAME], RW);
var store = transaction.objectStore(fs.OBJECT_STORE_NAME); var store = transaction.objectStore(fs.OBJECT_STORE_NAME);
var nameIndex = store.index("name"); var nameIndex = store.index("name");
var getRequest = queuePending(nameIndex.get(path)); var getRequest = new Request(nameIndex.get(name));
getRequest.onsuccess = function(e) { getRequest.then(function(e) {
clearPending(getRequest);
var result = e.target.result; var result = e.target.result;
if(result) { if(result) {
debug.info("mkdir PATH_EXISTS_ERR"); debug.info("mkdir error: PATH_EXISTS_ERR");
d.reject(new DirectoryError(DirectoryError.PATH_EXISTS_ERR)); deferred.reject(new DirectoryError(DirectoryError.PATH_EXISTS_ERR));
} else { } else {
var directoryRequest = queuePending(store.put({}, path)); try{
directoryRequest.onsuccess = function(e) { var directoryRequest = new Request(store.put({
"parent": dirname(name),
"name": name
}, name));
directoryRequest.then(function(e) {
debug.info("mkdir complete"); debug.info("mkdir complete");
clearPending(directoryRequest); deferred.resolve();
d.resolve(); });
}; }catch(e){console.log(e);}
} }
});
return deferred.promise;
}; };
return d.promise;
}
} }
FileSystem.READY = 0; FileSystem.READY = 0;
FileSystem.PENDING = 1; FileSystem.PENDING = 1;