This commit is contained in:
Alan Kligman 2013-05-31 03:52:04 -04:00
parent 63980ad1d2
commit 580dad5315
15 changed files with 504 additions and 187 deletions

View File

@ -1,5 +1,5 @@
var IDBFS = require( "src/fs" );
var IDBFS = require( "src/file-system" );
return IDBFS;

300
dist/idbfs.js vendored
View File

@ -5617,76 +5617,6 @@ define('src/constants',['require'],function(require) {
FS_ERROR: 'ERROR',
};
});
define('src/object-store',['require'],function(require) {
function read_object(objectStore, id, callback) {
var getRequest = objectStore.get(id);
getRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
getRequest.onerror = function onerror(error) {
callback(error);
};
};
function write_object(objectStore, object, id, callback) {
var putRequest = objectStore.put(object, id);
putRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
putRequest.onerror = function onerror(error) {
callback(error);
};
};
function delete_object(objectStore, id, callback) {
var deleteRequest = objectStore.delete(id);
deleteRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
deleteRequest.onerror = function(error) {
callback(error);
};
};
return {
read_object: read_object,
write_object: write_object,
delete_object: delete_object,
};
});
define('src/file',['require','src/constants','src/shared','src/shared'],function(require) {
var MODE_FILE = require('src/constants').MODE_FILE;
var guid = require('src/shared').guid;
var hash = require('src/shared').hash;
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, links, version) {
var now = Date.now();
this.id = id || hash(guid()),
this.mode = mode || MODE_FILE; // node type (file, directory, etc)
this.size = size || 0; // size (bytes for files, entries for directories)
this.atime = atime || now; // access time
this.ctime = ctime || now; // creation time
this.mtime = mtime || now; // modified time
this.flags = flags || ''; // file flags
this.xattrs = xattrs || {}; // extended attributes
this.links = links || 0; // links count
this.version = version || 0; // node version
this.data = hash(id) // id for data object
};
return {
Node: Node,
};
});
// Copyright Joyent, Inc. and other Node contributors.
//
@ -5815,31 +5745,20 @@ define('src/path',['require'],function(require) {
}
});
define('src/directory',['require','src/object-store','src/object-store','src/object-store','src/error','src/error','src/error','src/constants','src/constants','src/constants','src/constants','src/file','src/path','src/path','src/path'],function(require) {
var read_object = require('src/object-store').read_object;
var write_object = require('src/object-store').write_object;
var delete_object = require('src/object-store').delete_object;
define('src/object-store',['require','src/error','src/error','src/error','src/path','src/path','src/path','src/constants','src/constants','src/constants'],function(require) {
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
var EPathExists = require('src/error').EPathExists;
var MODE_FILE = require('src/constants').MODE_FILE;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME;
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID;
var Node = require('src/file').Node;
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
function DirectoryEntry(id, type) {
this.id = id;
this.type = type || MODE_FILE;
};
var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME;
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
// in: file or directory path
// out: node structure, or error
@ -5892,6 +5811,189 @@ define('src/directory',['require','src/object-store','src/object-store','src/obj
}
};
function read_object(objectStore, id, callback) {
var getRequest = objectStore.get(id);
getRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
getRequest.onerror = function onerror(error) {
callback(error);
};
};
function write_object(objectStore, object, id, callback) {
var putRequest = objectStore.put(object, id);
putRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
putRequest.onerror = function onerror(error) {
callback(error);
};
};
function delete_object(objectStore, id, callback) {
var deleteRequest = objectStore.delete(id);
deleteRequest.onsuccess = function onsuccess(event) {
var result = event.target.result;
callback(undefined, result);
};
deleteRequest.onerror = function(error) {
callback(error);
};
};
return {
read_object: read_object,
write_object: write_object,
delete_object: delete_object,
find_node: find_node
};
});
define('src/file',['require','lodash','src/path','src/path','src/path','src/constants','src/shared','src/shared','src/object-store','src/object-store','src/object-store','src/object-store','src/constants'],function(require) {
var _ = require('lodash');
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
var MODE_FILE = require('src/constants').MODE_FILE;
var guid = require('src/shared').guid;
var hash = require('src/shared').hash;
var read_object = require('src/object-store').read_object;
var write_object = require('src/object-store').write_object;
var delete_object = require('src/object-store').delete_object;
var find_node = require('src/object-store').find_node;
var O_CREATE = require('src/constants').O_CREATE;
function DirectoryEntry(id, type) {
this.id = id;
this.type = type || MODE_FILE;
};
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, links, version) {
var now = Date.now();
this.id = id || hash(guid()),
this.mode = mode || MODE_FILE; // node type (file, directory, etc)
this.size = size || 0; // size (bytes for files, entries for directories)
this.atime = atime || now; // access time
this.ctime = ctime || now; // creation time
this.mtime = mtime || now; // modified time
this.flags = flags || []; // file flags
this.xattrs = xattrs || {}; // extended attributes
this.links = links || 0; // links count
this.version = version || 0; // node version
this.data = hash(this.id) // id for data object
};
function open_file(objectStore, path, flags, mode, callback) {
path = normalize(path);
var name = basename(path);
var directoryNode;
var directoryData;
var fileNode;
var fileData;
function read_directory_data(error, result) {
if(error) {
callback(error);
} else {
directoryNode = result;
read_object(objectStore, directoryNode.data, check_if_file_exists);
}
};
function check_if_file_exists(error, result) {
if(error) {
callback(error);
} else {
directoryData = result;
if(_(directoryData).has(name)) {
// file exists
} else {
if(_(flags).contains(O_CREATE)) {
write_file_node();
} else {
callback(error);
}
}
}
};
function write_file_node() {
fileNode = new Node(undefined, MODE_FILE);
fileNode.links += 1;
write_object(objectStore, fileNode, fileNode.id, write_file_data);
};
function write_file_data(error) {
if(error) {
callback(error);
} else {
fileData = {};
write_object(objectStore, fileData, fileNode.data, update_directory_data);
}
};
function update_directory_data(error) {
if(error) {
callback(error);
} else {
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_FILE);
write_object(objectStore, directoryData, directoryNode.data, create_file_descriptor);
}
};
function create_file_descriptor(error) {
if(error) {
console.log(error);
} else {
callback(undefined, '!');
}
};
var parentPath = dirname(path);
find_node(objectStore, parentPath, read_directory_data);
};
return {
Node: Node,
open_file: open_file,
DirectoryEntry: DirectoryEntry,
};
});
define('src/directory',['require','src/object-store','src/object-store','src/object-store','src/object-store','src/error','src/error','src/error','src/constants','src/constants','src/constants','src/constants','src/file','src/file','src/path','src/path','src/path'],function(require) {
var read_object = require('src/object-store').read_object;
var write_object = require('src/object-store').write_object;
var delete_object = require('src/object-store').delete_object;
var find_node = require('src/object-store').find_node;
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
var EPathExists = require('src/error').EPathExists;
var MODE_FILE = require('src/constants').MODE_FILE;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME;
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID;
var Node = require('src/file').Node;
var DirectoryEntry = require('src/file').DirectoryEntry;
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
// Note: this should only be invoked when formatting a new file system
function make_root_directory(objectStore, callback) {
var directoryNode;
@ -6058,11 +6160,10 @@ define('src/directory',['require','src/object-store','src/object-store','src/obj
make_directory: make_directory,
make_root_directory: make_root_directory,
remove_directory: remove_directory,
find_node: find_node,
};
});
define('src/file-system',['require','lodash','when','src/shared','src/shared','src/shared','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/constants','src/constants','src/constants','src/constants','src/constants','src/constants','src/constants','src/directory','src/directory','src/directory'],function(require) {
define('src/file-system',['require','lodash','when','src/shared','src/shared','src/shared','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/error','src/constants','src/constants','src/constants','src/constants','src/constants','src/constants','src/constants','src/directory','src/directory','src/directory','src/file'],function(require) {
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
@ -6097,6 +6198,8 @@ define('src/file-system',['require','lodash','when','src/shared','src/shared','s
var make_directory = require('src/directory').make_directory;
var remove_directory = require('src/directory').remove_directory;
var open_file = require('src/file').open_file;
/*
* FileSystem
*/
@ -6162,7 +6265,22 @@ define('src/file-system',['require','lodash','when','src/shared','src/shared','s
this.db = null;
};
FileSystem.prototype.open = function open(path, flags, mode) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
function check_result(error, fd) {
if(error) {
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
}
};
open_file(files, path, flags, mode, check_result);
return deferred.promise;
};
FileSystem.prototype.opendir = function opendir(path) {
@ -6174,7 +6292,7 @@ define('src/file-system',['require','lodash','when','src/shared','src/shared','s
function check_result(error) {
if(error) {
transaction.abort();
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
@ -6191,7 +6309,7 @@ define('src/file-system',['require','lodash','when','src/shared','src/shared','s
function check_result(error) {
if(error) {
transaction.abort();
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
@ -6222,7 +6340,7 @@ define('src/file-system',['require','lodash','when','src/shared','src/shared','s
};
});
var IDBFS = require( "src/fs" );
var IDBFS = require( "src/file-system" );
return IDBFS;

View File

@ -93,11 +93,11 @@ var enableLogging = false;
if (enableDebugging) {
returnObject.viewer = viewer(dbConfig);
linq2indexedDB.prototype.utilities.log(linq2indexedDB.prototype.utilities.severity.warning, "Debugging enabled: be carefull when using in production enviroment. Complex objects get written to the log and may cause memory leaks.")
} else {
returnObject.viewer = null;
}
return returnObject;
};
@ -507,7 +507,7 @@ var enableLogging = false;
});
});
}
function executeWhere(queryBuilder, pw, transaction) {
linq2indexedDB.prototype.core.objectStore(transaction, queryBuilder.from).then(function (objArgs) {
try {
@ -1187,7 +1187,7 @@ var enableLogging = false;
for (var i = 1; i < arguments.length; i++) {
args.push(arguments[i]);
}
switch (severity) {
case linq2indexedDB.prototype.utilities.severity.exception:
if (window.console.exception) {
@ -1333,7 +1333,7 @@ var enableLogging = false;
})(typeof Windows !== "undefined");
if (typeof window !== "undefined") {
// UI Thread
// UI Thread
// Namespace linq2indexedDB.prototype.core
(function (window, isMetroApp) {
@ -1568,16 +1568,16 @@ if (typeof window !== "undefined") {
function (args /*error, e*/) {
// Database connection error or abort
var err = internal.wrapError(args[1], "db");
// Fix for firefox & chrome
if (args[1].target && args[1].target.errorCode == 12) {
err.type = "VersionError";
}
if (err.type == "VersionError") {
err.message = "You are trying to open the database in a lower version (" + version + ") than the current version of the database";
}
// Fix for firefox & chrome
if (args[1].target && args[1].target.errorCode == 8) {
err.type = "AbortError";
@ -1618,7 +1618,7 @@ if (typeof window !== "undefined") {
transactionType = transactionType || linq2indexedDB.prototype.core.transactionTypes.READ_ONLY;
var nonExistingObjectStores = [];
try {
// Check for non-existing object stores
for (var i = 0; i < objectStoreNames.length; i++) {
@ -1694,7 +1694,7 @@ if (typeof window !== "undefined") {
err.severity = "abort";
err.message = "Transaction was aborted";
}
// Fix for firefox & chrome
if (args[1].target && args[1].target.errorCode == 4) {
err.type = "ConstraintError";
@ -1702,7 +1702,7 @@ if (typeof window !== "undefined") {
if (err.type == "ConstraintError") {
err.message = "A mutation operation in the transaction failed. For more details look at the error on the instert, update, remove or clear statement.";
}
}
// txn error or abort
linq2indexedDB.prototype.utilities.logError(err);
pw.error(this, err);
@ -1982,7 +1982,7 @@ if (typeof window !== "undefined") {
if (propertyName.indexOf(linq2indexedDB.prototype.core.indexSuffix) == -1) {
indexName = indexName + linq2indexedDB.prototype.core.indexSuffix;
}
try {
objectStore.deleteIndex(indexName);
linq2indexedDB.prototype.core.dbStructureChanged.fire({ type: dbEvents.indexRemoved, data: indexName });
@ -2011,9 +2011,9 @@ if (typeof window !== "undefined") {
var keyRange;
var returnData = [];
var request;
try {
keyRange = range;
if (!keyRange) {
@ -2166,7 +2166,7 @@ if (typeof window !== "undefined") {
error.type = "TransactionInactiveError";
error.message = "You are trying to retrieve data on an inactieve transaction. (The transaction was already aborted or committed)";
}
if (ex.name == "TypeError") {
error.type = "TypeError";
error.message = "The provided directory parameter is invalid";
@ -2391,7 +2391,7 @@ if (typeof window !== "undefined") {
try {
var req;
if (key) {
req = source.count(key);
}
@ -2500,7 +2500,7 @@ if (typeof window !== "undefined") {
if (args[1].target && args[1].target.errorCode == 4) {
err.type = "ConstraintError";
}
if (err.type == "ConstraintError") {
var duplicateKey = key;
if (!duplicateKey && objectStore.keyPath) {
@ -2532,22 +2532,22 @@ if (typeof window !== "undefined") {
error.message = "The provided key isn't a valid key (must be an array, string, date or number).";
}
}
if ((ex.READ_ONLY_ERR && ex.code == ex.READ_ONLY_ERR) || ex.name == "ReadOnlyError") {
error.type = "ReadOnlyError";
error.message = "You are trying to insert data in a readonly transaction.";
}
if (ex.name == "TransactionInactiveError") {
error.type = "TransactionInactiveError";
error.message = "You are trying to insert data on an inactieve transaction. (The transaction was already aborted or committed)";
}
if ((ex.DATA_CLONE_ERR && ex.code == ex.DATA_CLONE_ERR) || ex.name == "DataCloneError") {
error.type = "DataCloneError";
error.message = "The data you are trying to insert could not be cloned. Your data probably contains a function which can not be cloned by default. Try using the serialize method to insert the data.";
}
if ((ex.INVALID_STATE_ERR && ex.code == ex.INVALID_STATE_ERR) || (ex.NOT_ALLOWED_ERR && ex.code == ex.NOT_ALLOWED_ERR) || ex.name == "InvalidStateError") {
error.type = "InvalidStateError";
error.message = "You are trying to insert data on a removed object store.";
@ -2610,12 +2610,12 @@ if (typeof window !== "undefined") {
error.type = "ReadOnlyError";
error.message = "You are trying to update data in a readonly transaction.";
}
if (ex.name == "TransactionInactiveError") {
error.type = "TransactionInactiveError";
error.message = "You are trying to update data on an inactieve transaction. (The transaction was already aborted or committed)";
}
if ((ex.DATA_CLONE_ERR && ex.code == ex.DATA_CLONE_ERR) || ex.name == "DataCloneError") {
error.type = "DataCloneError";
error.message = "The data you are trying to update could not be cloned. Your data probably contains a function which can not be cloned by default. Try using the serialize method to update the data.";
@ -2625,7 +2625,7 @@ if (typeof window !== "undefined") {
error.type = "InvalidStateError";
error.message = "You are trying to update data on a removed object store.";
}
linq2indexedDB.prototype.utilities.logError(error);
linq2indexedDB.prototype.core.abortTransaction(objectStore.transaction);
pw.error(this, error);
@ -3080,7 +3080,7 @@ if (typeof window !== "undefined") {
db = target.transaction.db;
} else if (target instanceof IDBIndex) {
db = target.objectStore.transaction.db;
}
}
linq2indexedDB.prototype.utilities.log(linq2indexedDB.prototype.utilities.severity.information, "Close database Connection: ", db);
db.close();
@ -3172,7 +3172,7 @@ if (typeof window !== "undefined") {
linq2indexedDB.prototype.utilities.log(linq2indexedDB.prototype.utilities.severity.information, "IE10+ Initialized", window.indexedDB);
return implementations.MICROSOFT;
}
// Initialising the window.indexedDB Object for IE 8 & 9
else if (navigator.appName == 'Microsoft Internet Explorer') {
try {
@ -3372,6 +3372,6 @@ if (typeof window !== "undefined") {
}
// Extend array for Opera
Array.prototype.contains = function (obj) {
return this.indexOf(obj) > -1;
};
//Array.prototype.contains = function (obj) {
// return this.indexOf(obj) > -1;
//};

View File

@ -35,10 +35,14 @@ function remove_tmp_directory() {
return fs.rmdir('/tmp');
};
function create_tmp_file() {
return fs.open('/tmp/1', 'CREATE');
};
fs.promise.then(make_tmp_directory)
.then(remove_tmp_directory)
.then(create_tmp_file)
.then(function() { console.log('done'); })
.otherwise(function(error) { console.error(error.stack); });
.otherwise(function(error) { console.error(error, error.stack); });
});
</script>

10
src/descriptor.js Normal file
View File

@ -0,0 +1,10 @@
define(function(require) {
function Descriptor() {
};
return {
Descriptor: Descriptor,
};
});

View File

@ -3,6 +3,7 @@ define(function(require) {
var read_object = require('src/object-store').read_object;
var write_object = require('src/object-store').write_object;
var delete_object = require('src/object-store').delete_object;
var find_node = require('src/object-store').find_node;
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
@ -14,67 +15,12 @@ define(function(require) {
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID;
var Node = require('src/file').Node;
var DirectoryEntry = require('src/file').DirectoryEntry;
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
function DirectoryEntry(id, type) {
this.id = id;
this.type = type || MODE_FILE;
};
// in: file or directory path
// out: node structure, or error
function find_node(objectStore, path, callback) {
path = normalize(path);
var name = basename(path);
if(ROOT_DIRECTORY_NAME == name) {
function check_root_directory_node(error, rootDirectoryNode) {
if(error) {
callback(error);
} else if(!rootDirectoryNode) {
callback(new ENoEntry());
} else {
callback(undefined, rootDirectoryNode);
}
};
read_object(objectStore, ROOT_NODE_ID, check_root_directory_node);
} else {
// in: parent directory node
// out: parent directory data
function read_parent_directory_data(error, parentDirectoryNode) {
if(error) {
callback(error);
} else if(!_(parentDirectoryNode).has('data') || !parentDirectoryNode.type == MODE_DIRECTORY) {
callback(new ENotDirectory());
} else {
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
}
};
// in: parent directory data
// out: searched node id
function get_node_id_from_parent_directory_data(error, parentDirectoryData) {
if(error) {
callback(error);
} else {
if(!_(parentDirectoryData).has(name)) {
callback(new ENoEntry());
} else {
var nodeId = parentDirectoryData[name].id;
read_object(objectStore, nodeId, callback);
}
}
};
var parentPath = dirname(path);
find_node(objectStore, parentPath, read_parent_directory_data);
}
};
// Note: this should only be invoked when formatting a new file system
function make_root_directory(objectStore, callback) {
var directoryNode;
@ -241,7 +187,6 @@ define(function(require) {
make_directory: make_directory,
make_root_directory: make_root_directory,
remove_directory: remove_directory,
find_node: find_node,
};
});

View File

@ -33,6 +33,8 @@ define(function(require) {
var make_directory = require('src/directory').make_directory;
var remove_directory = require('src/directory').remove_directory;
var open_file = require('src/file').open_file;
/*
* FileSystem
*/
@ -98,7 +100,22 @@ define(function(require) {
this.db = null;
};
FileSystem.prototype.open = function open(path, flags, mode) {
var deferred = when.defer();
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
var files = transaction.objectStore(FILE_STORE_NAME);
function check_result(error, fd) {
if(error) {
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
}
};
open_file(files, path, flags, mode, check_result);
return deferred.promise;
};
FileSystem.prototype.opendir = function opendir(path) {
@ -110,7 +127,7 @@ define(function(require) {
function check_result(error) {
if(error) {
transaction.abort();
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();
@ -127,7 +144,7 @@ define(function(require) {
function check_result(error) {
if(error) {
transaction.abort();
if(transaction.error) transaction.abort();
deferred.reject(error);
} else {
deferred.resolve();

View File

@ -1,10 +1,28 @@
define(function(require) {
var _ = require('lodash');
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
var MODE_FILE = require('src/constants').MODE_FILE;
var guid = require('src/shared').guid;
var hash = require('src/shared').hash;
var read_object = require('src/object-store').read_object;
var write_object = require('src/object-store').write_object;
var delete_object = require('src/object-store').delete_object;
var find_node = require('src/object-store').find_node;
var O_CREATE = require('src/constants').O_CREATE;
function DirectoryEntry(id, type) {
this.id = id;
this.type = type || MODE_FILE;
};
function Node(id, mode, size, atime, ctime, mtime, flags, xattrs, links, version) {
var now = Date.now();
@ -14,15 +32,88 @@ define(function(require) {
this.atime = atime || now; // access time
this.ctime = ctime || now; // creation time
this.mtime = mtime || now; // modified time
this.flags = flags || ''; // file flags
this.flags = flags || []; // file flags
this.xattrs = xattrs || {}; // extended attributes
this.links = links || 0; // links count
this.version = version || 0; // node version
this.data = hash(id) // id for data object
this.data = hash(this.id) // id for data object
};
function open_file(objectStore, path, flags, mode, callback) {
path = normalize(path);
var name = basename(path);
var directoryNode;
var directoryData;
var fileNode;
var fileData;
function read_directory_data(error, result) {
if(error) {
callback(error);
} else {
directoryNode = result;
read_object(objectStore, directoryNode.data, check_if_file_exists);
}
};
function check_if_file_exists(error, result) {
if(error) {
callback(error);
} else {
directoryData = result;
if(_(directoryData).has(name)) {
// file exists
} else {
if(_(flags).contains(O_CREATE)) {
write_file_node();
} else {
callback(error);
}
}
}
};
function write_file_node() {
fileNode = new Node(undefined, MODE_FILE);
fileNode.links += 1;
write_object(objectStore, fileNode, fileNode.id, write_file_data);
};
function write_file_data(error) {
if(error) {
callback(error);
} else {
fileData = {};
write_object(objectStore, fileData, fileNode.data, update_directory_data);
}
};
function update_directory_data(error) {
if(error) {
callback(error);
} else {
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_FILE);
write_object(objectStore, directoryData, directoryNode.data, create_file_descriptor);
}
};
function create_file_descriptor(error) {
if(error) {
console.log(error);
} else {
callback(undefined, '!');
}
};
var parentPath = dirname(path);
find_node(objectStore, parentPath, read_directory_data);
};
return {
Node: Node,
open_file: open_file,
DirectoryEntry: DirectoryEntry,
};
});

View File

@ -1,5 +1,69 @@
define(function(require) {
var ENoEntry = require('src/error').ENoEntry;
var ENotDirectory = require('src/error').ENotDirectory;
var EPathExists = require('src/error').EPathExists;
var normalize = require('src/path').normalize;
var dirname = require('src/path').dirname;
var basename = require('src/path').basename;
var ROOT_DIRECTORY_NAME = require('src/constants').ROOT_DIRECTORY_NAME;
var ROOT_NODE_ID = require('src/constants').ROOT_NODE_ID;
var MODE_DIRECTORY = require('src/constants').MODE_DIRECTORY;
// in: file or directory path
// out: node structure, or error
function find_node(objectStore, path, callback) {
path = normalize(path);
var name = basename(path);
if(ROOT_DIRECTORY_NAME == name) {
function check_root_directory_node(error, rootDirectoryNode) {
if(error) {
callback(error);
} else if(!rootDirectoryNode) {
callback(new ENoEntry());
} else {
callback(undefined, rootDirectoryNode);
}
};
read_object(objectStore, ROOT_NODE_ID, check_root_directory_node);
} else {
// in: parent directory node
// out: parent directory data
function read_parent_directory_data(error, parentDirectoryNode) {
if(error) {
callback(error);
} else if(!_(parentDirectoryNode).has('data') || !parentDirectoryNode.type == MODE_DIRECTORY) {
callback(new ENotDirectory());
} else {
read_object(objectStore, parentDirectoryNode.data, get_node_id_from_parent_directory_data);
}
};
// in: parent directory data
// out: searched node id
function get_node_id_from_parent_directory_data(error, parentDirectoryData) {
if(error) {
callback(error);
} else {
if(!_(parentDirectoryData).has(name)) {
callback(new ENoEntry());
} else {
var nodeId = parentDirectoryData[name].id;
read_object(objectStore, nodeId, callback);
}
}
};
var parentPath = dirname(path);
find_node(objectStore, parentPath, read_parent_directory_data);
}
};
function read_object(objectStore, id, callback) {
var getRequest = objectStore.get(id);
getRequest.onsuccess = function onsuccess(event) {
@ -37,6 +101,7 @@ define(function(require) {
read_object: read_object,
write_object: write_object,
delete_object: delete_object,
find_node: find_node
};
});

52
tests/index.html Normal file
View File

@ -0,0 +1,52 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="../tools/jasmine-1.3.1/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="../tools/jasmine-1.3.1/jasmine.css">
<script type="text/javascript" src="../tools/jasmine-1.3.1/jasmine.js"></script>
<script type="text/javascript" src="../tools/jasmine-1.3.1/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../dist/idbfs.js"></script>
<!-- include spec files here... -->
<!--script type="text/javascript" src="spec/SpecHelper.js"></script-->
<script type="text/javascript" src="spec/idbfs.spec.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body>
</body>
</html>

15
tests/spec/idbfs.spec.js Normal file
View File

@ -0,0 +1,15 @@
var TEST_DATABASE_NAME = 'test';
describe("file system", function() {
beforeEach(function() {
this.fs = new IDBFS.FileSystem(TEST_DATABASE_NAME, 'FORMAT');
});
afterEach(function() {
indexedDB.deleteDatabase(TEST_DATABASE_NAME);
});
it("is created", function() {
expect(typeof this.fs).toEqual('object');
});
});

View File

@ -154,7 +154,7 @@ jasmine.HtmlReporter = function(_doc) {
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
dom.alert = self.createDom('div', {className: 'alert'},
self.createDom('span', { className: 'exceptions' },
self.createDom('label', { className: 'label', for: 'no_try_catch' }, 'No try/catch'),
self.createDom('label', { className: 'label', 'for': 'no_try_catch' }, 'No try/catch'),
self.createDom('input', { id: 'no_try_catch', type: 'checkbox' }))),
dom.results = self.createDom('div', {className: 'results'},
dom.summary = self.createDom('div', { className: 'summary' }),

View File

@ -2595,6 +2595,6 @@ jasmine.WaitsForBlock.prototype.execute = function(onComplete) {
jasmine.version_= {
"major": 1,
"minor": 3,
"build": 0,
"revision": 1354052693
"build": 1,
"revision": 1354556913
};