Refactored error code and added transaction abort on error.
This commit is contained in:
parent
c434385fe4
commit
eb4b1b1aa1
|
@ -64,32 +64,52 @@ define(function(require) {
|
||||||
var IDB_RO = "readonly";
|
var IDB_RO = "readonly";
|
||||||
var IDB_RW = "readwrite";
|
var IDB_RW = "readwrite";
|
||||||
|
|
||||||
function IDBFSError(type, code) {
|
function PathExistsError(){ Error.apply(this, arguments); }
|
||||||
this.type = type;
|
PathExistsError.prototype = new Error();
|
||||||
this.code = code;
|
PathExistsError.prototype.name = "PathExistsError";
|
||||||
}
|
PathExistsError.prototype.constructor = PathExistsError;
|
||||||
// Types
|
|
||||||
var T_NONE = 0x0;
|
|
||||||
var T_OPEN = 0x1;
|
|
||||||
var T_MKDIR = 0x2;
|
|
||||||
var T_STAT = 0x3;
|
|
||||||
var T_RMDIR = 0x4;
|
|
||||||
var T_CLOSE = 0x5;
|
|
||||||
var T_READ = 0x6;
|
|
||||||
var T_UNLINK = 0x7;
|
|
||||||
// Codes
|
|
||||||
var E_EXIST = 0x0;
|
|
||||||
var E_ISDIR = 0x1;
|
|
||||||
var E_NOENT = 0x2;
|
|
||||||
var E_BUSY = 0x3;
|
|
||||||
var E_NOTEMPTY = 0x4;
|
|
||||||
var E_NOTDIR = 0x5;
|
|
||||||
var E_BADF = 0x6;
|
|
||||||
var E_NOT_IMPLEMENTED = 0x7;
|
|
||||||
|
|
||||||
function genericIDBErrorHandler(scope, callback) {
|
function IsDirectoryError(){ Error.apply(this, arguments); }
|
||||||
return function(error) {
|
IsDirectoryError.prototype = new Error();
|
||||||
debug.error("[" + scope + "] error: ", error);
|
IsDirectoryError.prototype.name = "IsDirectoryError";
|
||||||
|
IsDirectoryError.prototype.constructor = IsDirectoryError;
|
||||||
|
|
||||||
|
function NoEntryError(){ Error.apply(this, arguments); }
|
||||||
|
NoEntryError.prototype = new Error();
|
||||||
|
NoEntryError.prototype.name = "NoEntryError";
|
||||||
|
NoEntryError.prototype.constructor = NoEntryError;
|
||||||
|
|
||||||
|
function BusyError(){ Error.apply(this, arguments); }
|
||||||
|
BusyError.prototype = new Error();
|
||||||
|
BusyError.prototype.name = "BusyError";
|
||||||
|
BusyError.prototype.constructor = BusyError;
|
||||||
|
|
||||||
|
function NotEmptyError(){ Error.apply(this, arguments); }
|
||||||
|
NotEmptyError.prototype = new Error();
|
||||||
|
NotEmptyError.prototype.name = "NotEmptyError";
|
||||||
|
NotEmptyError.prototype.constructor = NotEmptyError;
|
||||||
|
|
||||||
|
function NotDirectoryError(){ Error.apply(this, arguments); }
|
||||||
|
NotDirectoryError.prototype = new Error();
|
||||||
|
NotDirectoryError.prototype.name = "NotADirectoryError";
|
||||||
|
NotDirectoryError.prototype.constructor = NotDirectoryError;
|
||||||
|
|
||||||
|
function BadFileDescriptorError(){ Error.apply(this, arguments); }
|
||||||
|
BadFileDescriptorError.prototype = new Error();
|
||||||
|
BadFileDescriptorError.prototype.name = "BadFileDescriptorError";
|
||||||
|
BadFileDescriptorError.prototype.constructor = BadFileDescriptorError;
|
||||||
|
|
||||||
|
function NotImplementedError(){ Error.apply(this, arguments); }
|
||||||
|
NotImplementedError.prototype = new Error();
|
||||||
|
NotImplementedError.prototype.name = "NotImplementedError";
|
||||||
|
NotImplementedError.prototype.constructor = NotImplementedError;
|
||||||
|
|
||||||
|
function genericErrorHandler(callback) {
|
||||||
|
return function(transaction, error) {
|
||||||
|
debug.error("error: ", error);
|
||||||
|
if(transaction) {
|
||||||
|
transaction.abort();
|
||||||
|
}
|
||||||
if(callback && "function" === typeof callback) {
|
if(callback && "function" === typeof callback) {
|
||||||
callback.call(undefined, error);
|
callback.call(undefined, error);
|
||||||
}
|
}
|
||||||
|
@ -136,9 +156,9 @@ define(function(require) {
|
||||||
|
|
||||||
function read(buffer, callback) {
|
function read(buffer, callback) {
|
||||||
debug.info("read -->");
|
debug.info("read -->");
|
||||||
var onerror = genericIDBErrorHandler("read", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
if(!start()) {
|
if(!start()) {
|
||||||
onerror(new IDBFSError(T_READ, E_BADF));
|
onerror(null, new BadFileDescriptorError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
transaction = db.transaction([FILE_STORE_NAME], IDB_RO);
|
transaction = db.transaction([FILE_STORE_NAME], IDB_RO);
|
||||||
|
@ -172,22 +192,22 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
} else if(MIME_DIRECTORY === ofd.entry["contenttype"]) {
|
} else if(MIME_DIRECTORY === ofd.entry["contenttype"]) {
|
||||||
// NOT IMPLEMENTED
|
// NOT IMPLEMENTED
|
||||||
onerror(new IDBFSError(T_READ, E_NOT_IMPLEMENTED))
|
onerror(transaction, new NotImplementedError());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function write(buffer, callback) {
|
function write(buffer, callback) {
|
||||||
debug.info("write -->");
|
debug.info("write -->");
|
||||||
var onerror = genericIDBErrorHandler("write", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
if(OM_RO === ofd.mode) {
|
if(OM_RO === ofd.mode) {
|
||||||
onerror(new IDBFSError(T_READ, E_BADF));
|
onerror(null, new BadFileDescriptorError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!start()) {
|
if(!start()) {
|
||||||
onerror(new IDBFSError(T_READ, E_BADF));
|
onerror(null, new BadFileDescriptorError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
transaction = db.transaction([METADATA_STORE_NAME, FILE_STORE_NAME], IDB_RW);
|
transaction = db.transaction([METADATA_STORE_NAME, FILE_STORE_NAME], IDB_RW);
|
||||||
|
@ -223,13 +243,13 @@ define(function(require) {
|
||||||
callback.call(undefined, undefined, size, buffer);
|
callback.call(undefined, undefined, size, buffer);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
writeMetadataRequest.onerror = onerror;
|
writeMetadataRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
readMetadataRequest.onerror = onerror;
|
readMetadataRequest.onerror = onerror.bind(null, transaction);
|
||||||
};
|
};
|
||||||
putRequest.onerror = onerror;
|
putRequest.onerror = onerror.bind(null, transaction);
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
var SW_SET = "SET";
|
var SW_SET = "SET";
|
||||||
|
@ -274,7 +294,7 @@ define(function(require) {
|
||||||
transaction = db.transaction([METADATA_STORE_NAME], IDB_RW);
|
transaction = db.transaction([METADATA_STORE_NAME], IDB_RW);
|
||||||
var store = transaction.objectStore(METADATA_STORE_NAME);
|
var store = transaction.objectStore(METADATA_STORE_NAME);
|
||||||
var nameIndex = store.index(NAME_INDEX);
|
var nameIndex = store.index(NAME_INDEX);
|
||||||
var onerror = genericIDBErrorHandler("mkdir", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
|
|
||||||
if(undefined === flags) {
|
if(undefined === flags) {
|
||||||
flags = [];
|
flags = [];
|
||||||
|
@ -287,17 +307,17 @@ define(function(require) {
|
||||||
var entry = e.target.result;
|
var entry = e.target.result;
|
||||||
if(!entry) {
|
if(!entry) {
|
||||||
if(!_(flags).contains(OF_CREATE)) {
|
if(!_(flags).contains(OF_CREATE)) {
|
||||||
onerror(new IDBFSError(T_OPEN, E_NOENT));
|
onerror(transaction, new NoEntryError());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
entry = makeFileEntry(pathname);
|
entry = makeFileEntry(pathname);
|
||||||
var createRequest = store.put(entry, pathname);
|
var createRequest = store.put(entry, pathname);
|
||||||
createRequest.onsuccess = complete;
|
createRequest.onsuccess = complete;
|
||||||
createRequest.onerror = onerror;
|
createRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(entry["contenttype"] === MIME_DIRECTORY && mode === OM_RW) {
|
if(entry["contenttype"] === MIME_DIRECTORY && mode === OM_RW) {
|
||||||
onerror(new IDBFSError(T_OPEN, E_ISDIR));
|
onerror(transaction, new IsDirectoryError());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
complete();
|
complete();
|
||||||
|
@ -313,14 +333,14 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function close(fd, callback) {
|
function close(fd, callback) {
|
||||||
debug.info("close -->");
|
debug.info("close -->");
|
||||||
var onerror = genericIDBErrorHandler("close", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
if(!fds.hasOwnProperty(fd.descriptor)) {
|
if(!fds.hasOwnProperty(fd.descriptor)) {
|
||||||
onerror(new IDBFSError(T_CLOSE, E_BADF));
|
onerror(null, new BadFileDescriptorError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var ofd = fds[fd.descriptor];
|
var ofd = fds[fd.descriptor];
|
||||||
|
@ -339,13 +359,13 @@ define(function(require) {
|
||||||
transaction = transaction || db.transaction([METADATA_STORE_NAME], IDB_RW);
|
transaction = transaction || db.transaction([METADATA_STORE_NAME], IDB_RW);
|
||||||
var store = transaction.objectStore(METADATA_STORE_NAME);
|
var store = transaction.objectStore(METADATA_STORE_NAME);
|
||||||
var nameIndex = store.index(NAME_INDEX);
|
var nameIndex = store.index(NAME_INDEX);
|
||||||
var onerror = genericIDBErrorHandler("mkdir", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
|
|
||||||
var getRequest = nameIndex.get(pathname);
|
var getRequest = nameIndex.get(pathname);
|
||||||
getRequest.onsuccess = function(e) {
|
getRequest.onsuccess = function(e) {
|
||||||
var result = e.target.result;
|
var result = e.target.result;
|
||||||
if(result) {
|
if(result) {
|
||||||
onerror(new IDBFSError(T_MKDIR, E_EXIST));
|
onerror(null, new PathExistsError());
|
||||||
} else {
|
} else {
|
||||||
var entry = makeDirectoryEntry(pathname, Date.now());
|
var entry = makeDirectoryEntry(pathname, Date.now());
|
||||||
var directoryRequest = store.put(entry, pathname);
|
var directoryRequest = store.put(entry, pathname);
|
||||||
|
@ -355,10 +375,10 @@ define(function(require) {
|
||||||
callback.call(undefined, undefined);
|
callback.call(undefined, undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
directoryRequest.onerror = onerror;
|
directoryRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function rmdir(pathname, callback) {
|
function rmdir(pathname, callback) {
|
||||||
|
@ -368,20 +388,20 @@ define(function(require) {
|
||||||
var metaStore = transaction.objectStore(METADATA_STORE_NAME);
|
var metaStore = transaction.objectStore(METADATA_STORE_NAME);
|
||||||
var nameIndex = metaStore.index(NAME_INDEX);
|
var nameIndex = metaStore.index(NAME_INDEX);
|
||||||
var parentIndex = metaStore.index(PARENT_INDEX);
|
var parentIndex = metaStore.index(PARENT_INDEX);
|
||||||
var onerror = genericIDBErrorHandler("rmdir", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
|
|
||||||
var getRequest = nameIndex.get(pathname);
|
var getRequest = nameIndex.get(pathname);
|
||||||
getRequest.onsuccess = function(e) {
|
getRequest.onsuccess = function(e) {
|
||||||
var result = e.target.result;
|
var result = e.target.result;
|
||||||
if(!result) {
|
if(!result) {
|
||||||
onerror(new IDBFSError(T_RMDIR, E_NOENT));
|
onerror(transaction, new NoEntryError());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
var contentRequest = parentIndex.get(pathname);
|
var contentRequest = parentIndex.get(pathname);
|
||||||
contentRequest.onsuccess = function(e) {
|
contentRequest.onsuccess = function(e) {
|
||||||
var result = e.target.result;
|
var result = e.target.result;
|
||||||
if(result) {
|
if(result) {
|
||||||
onerror(new IDBFSError(T_RMDIR, E_NOTEMPTY));
|
onerror(transaction, new NotEntry());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
var removeRequest = metaStore.delete(pathname);
|
var removeRequest = metaStore.delete(pathname);
|
||||||
|
@ -391,13 +411,13 @@ define(function(require) {
|
||||||
callback.call(undefined, undefined);
|
callback.call(undefined, undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
removeRequest.onerror = onerror;
|
removeRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
contentRequest.onerror = onerror;
|
contentRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stat(transaction, pathname, callback) {
|
function stat(transaction, pathname, callback) {
|
||||||
|
@ -406,13 +426,13 @@ define(function(require) {
|
||||||
transaction = transaction || db.transaction([METADATA_STORE_NAME], IDB_RO);
|
transaction = transaction || db.transaction([METADATA_STORE_NAME], IDB_RO);
|
||||||
var store = transaction.objectStore(METADATA_STORE_NAME);
|
var store = transaction.objectStore(METADATA_STORE_NAME);
|
||||||
var nameIndex = store.index(NAME_INDEX);
|
var nameIndex = store.index(NAME_INDEX);
|
||||||
var onerror = genericIDBErrorHandler("stat", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
|
|
||||||
var getRequest = nameIndex.get(pathname);
|
var getRequest = nameIndex.get(pathname);
|
||||||
getRequest.onsuccess = function(e) {
|
getRequest.onsuccess = function(e) {
|
||||||
var result = e.target.result;
|
var result = e.target.result;
|
||||||
if(!result) {
|
if(!result) {
|
||||||
onerror(new IDBFSError(T_STAT, E_NOENT));
|
onerror(transaction, new NoEntryError());
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
debug.info("stat <--");
|
debug.info("stat <--");
|
||||||
|
@ -421,7 +441,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
getRequest.onerror = onerror;
|
getRequest.onerror = onerror.bind(null, transaction);
|
||||||
}
|
}
|
||||||
|
|
||||||
function link(oldpath, newpath, callback) {
|
function link(oldpath, newpath, callback) {
|
||||||
|
@ -434,15 +454,15 @@ define(function(require) {
|
||||||
var transaction = db.transaction([METADATA_STORE_NAME], IDB_RW);
|
var transaction = db.transaction([METADATA_STORE_NAME], IDB_RW);
|
||||||
var metaStore = transaction.objectStore(METADATA_STORE_NAME);
|
var metaStore = transaction.objectStore(METADATA_STORE_NAME);
|
||||||
var nameIndex = metaStore.index(NAME_INDEX);
|
var nameIndex = metaStore.index(NAME_INDEX);
|
||||||
var onerror = genericIDBErrorHandler("unlink", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
|
|
||||||
stat(transaction, pathname, function(error, entry) {
|
stat(transaction, pathname, function(error, entry) {
|
||||||
if(error) {
|
if(error) {
|
||||||
onerror(new IDBFSError(T_UNLINK, error));
|
onerror(transaction, error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(MIME_DIRECTORY === entry["contenttype"]) {
|
if(MIME_DIRECTORY === entry["contenttype"]) {
|
||||||
onerror(new IDBFSError(T_UNLINK, E_ISDIR));
|
onerror(transaction, new IsDirectoryError());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var unlinkRequest = metaStore.delete(entry["name"]);
|
var unlinkRequest = metaStore.delete(entry["name"]);
|
||||||
|
@ -457,9 +477,9 @@ define(function(require) {
|
||||||
callback.call(undefined, undefined);
|
callback.call(undefined, undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
deleteRequest.onerror = onerror;
|
deleteRequest.onerror = onerror.bind(null, transaction);
|
||||||
};
|
};
|
||||||
unlinkRequest.onerror = onerror;
|
unlinkRequest.onerror = onerror.bind(null, transaction);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +545,7 @@ define(function(require) {
|
||||||
function mount(name, callback, optFormat) {
|
function mount(name, callback, optFormat) {
|
||||||
debug.info("mount -->");
|
debug.info("mount -->");
|
||||||
optFormat = (IDBFS.FORMAT === optFormat) ? true : false;
|
optFormat = (IDBFS.FORMAT === optFormat) ? true : false;
|
||||||
var onerror = genericIDBErrorHandler("mount", callback);
|
var onerror = genericErrorHandler(callback);
|
||||||
var openRequest = indexedDB.open(name);
|
var openRequest = indexedDB.open(name);
|
||||||
openRequest.onupgradeneeded = function(e) {
|
openRequest.onupgradeneeded = function(e) {
|
||||||
var db = e.target.result;
|
var db = e.target.result;
|
||||||
|
@ -565,7 +585,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
clearRequest.onerror = onerror;
|
clearRequest.onerror = onerror.bind(null, transaction);
|
||||||
} else {
|
} else {
|
||||||
debug.info("mount <--");
|
debug.info("mount <--");
|
||||||
if(callback && "function" === typeof callback) {
|
if(callback && "function" === typeof callback) {
|
||||||
|
@ -573,7 +593,7 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
openRequest.onerror = onerror;
|
openRequest.onerror = onerror.bind(null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
function umount(fs, callback) {
|
function umount(fs, callback) {
|
||||||
|
|
Loading…
Reference in New Issue