Initial work on #227 - improve storage efficiency of provider API
This commit is contained in:
parent
2d653d474e
commit
d55bf23f1b
|
@ -31,7 +31,8 @@
|
|||
"bower": "~1.3.8",
|
||||
"request": "^2.36.0",
|
||||
"browser-request": "git://github.com/humphd/browser-request.git#959ea95bf200d64939ed76897d3b06bb684f3a0d",
|
||||
"jszip": "git://github.com/humphd/jszip.git#ad3f356bb165aba1cafeabe1bb3e49293803f975"
|
||||
"jszip": "git://github.com/humphd/jszip.git#ad3f356bb165aba1cafeabe1bb3e49293803f975",
|
||||
"base64-arraybuffer": "^0.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"chai": "~1.9.1",
|
||||
|
|
|
@ -37,6 +37,7 @@ var OpenFileDescription = require('../open-file-description.js');
|
|||
var SuperNode = require('../super-node.js');
|
||||
var Node = require('../node.js');
|
||||
var Stats = require('../stats.js');
|
||||
var Buffer = require('../buffer.js');
|
||||
|
||||
/**
|
||||
* Many functions below use this callback pattern. If it's not
|
||||
|
@ -124,7 +125,7 @@ function update_node_times(context, path, node, times, callback) {
|
|||
}
|
||||
|
||||
if(update) {
|
||||
context.put(node.id, node, complete);
|
||||
context.putObject(node.id, node, complete);
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
|
@ -167,7 +168,7 @@ function make_node(context, path, mode, callback) {
|
|||
} else if(error && !(error instanceof Errors.ENOENT)) {
|
||||
callback(error);
|
||||
} else {
|
||||
context.get(parentNode.data, create_node);
|
||||
context.getObject(parentNode.data, create_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -184,7 +185,7 @@ function make_node(context, path, mode, callback) {
|
|||
}
|
||||
node = result;
|
||||
node.nlinks += 1;
|
||||
context.put(node.id, node, update_parent_node_data);
|
||||
context.putObject(node.id, node, update_parent_node_data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -205,7 +206,7 @@ function make_node(context, path, mode, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
parentNodeData[name] = new DirectoryEntry(node.id, mode);
|
||||
context.put(parentNode.data, parentNodeData, update_time);
|
||||
context.putObject(parentNode.data, parentNodeData, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,7 +234,7 @@ function find_node(context, path, callback) {
|
|||
} else if(!superNode || superNode.mode !== MODE_META || !superNode.rnode) {
|
||||
callback(new Errors.EFILESYSTEMERROR());
|
||||
} else {
|
||||
context.get(superNode.rnode, check_root_directory_node);
|
||||
context.getObject(superNode.rnode, check_root_directory_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,7 +256,7 @@ function find_node(context, path, callback) {
|
|||
} else if(parentDirectoryNode.mode !== MODE_DIRECTORY || !parentDirectoryNode.data) {
|
||||
callback(new Errors.ENOTDIR('a component of the path prefix is not a directory'));
|
||||
} else {
|
||||
context.get(parentDirectoryNode.data, get_node_from_parent_directory_data);
|
||||
context.getObject(parentDirectoryNode.data, get_node_from_parent_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,7 +270,7 @@ function find_node(context, path, callback) {
|
|||
callback(new Errors.ENOENT());
|
||||
} else {
|
||||
var nodeId = parentDirectoryData[name].id;
|
||||
context.get(nodeId, is_symbolic_link);
|
||||
context.getObject(nodeId, is_symbolic_link);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -296,14 +297,14 @@ function find_node(context, path, callback) {
|
|||
parentPath = dirname(data);
|
||||
name = basename(data);
|
||||
if(ROOT_DIRECTORY_NAME == name) {
|
||||
context.get(SUPER_NODE_ID, read_root_directory_node);
|
||||
context.getObject(SUPER_NODE_ID, read_root_directory_node);
|
||||
} else {
|
||||
find_node(context, parentPath, read_parent_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
if(ROOT_DIRECTORY_NAME == name) {
|
||||
context.get(SUPER_NODE_ID, read_root_directory_node);
|
||||
context.getObject(SUPER_NODE_ID, read_root_directory_node);
|
||||
} else {
|
||||
find_node(context, parentPath, read_parent_directory_data);
|
||||
}
|
||||
|
@ -338,7 +339,7 @@ function set_extended_attribute (context, path_or_fd, name, value, flag, callbac
|
|||
}
|
||||
else {
|
||||
node.xattrs[name] = value;
|
||||
context.put(node.id, node, update_time);
|
||||
context.putObject(node.id, node, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -348,7 +349,7 @@ function set_extended_attribute (context, path_or_fd, name, value, flag, callbac
|
|||
}
|
||||
else if (typeof path_or_fd == 'object' && typeof path_or_fd.id == 'string') {
|
||||
path = path_or_fd.path;
|
||||
context.get(path_or_fd.id, set_xattr);
|
||||
context.getObject(path_or_fd.id, set_xattr);
|
||||
}
|
||||
else {
|
||||
callback(new Errors.EINVAL('path or file descriptor of wrong type'));
|
||||
|
@ -380,7 +381,7 @@ function ensure_root_directory(context, callback) {
|
|||
return;
|
||||
}
|
||||
superNode = result;
|
||||
context.put(superNode.id, superNode, write_directory_node);
|
||||
context.putObject(superNode.id, superNode, write_directory_node);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -396,7 +397,7 @@ function ensure_root_directory(context, callback) {
|
|||
}
|
||||
directoryNode = result;
|
||||
directoryNode.nlinks += 1;
|
||||
context.put(directoryNode.id, directoryNode, write_directory_data);
|
||||
context.putObject(directoryNode.id, directoryNode, write_directory_data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -406,11 +407,11 @@ function ensure_root_directory(context, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
context.put(directoryNode.data, directoryData, callback);
|
||||
context.putObject(directoryNode.data, directoryData, callback);
|
||||
}
|
||||
}
|
||||
|
||||
context.get(SUPER_NODE_ID, ensure_super_node);
|
||||
context.getObject(SUPER_NODE_ID, ensure_super_node);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -441,7 +442,7 @@ function make_directory(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
context.get(parentDirectoryNode.data, write_directory_node);
|
||||
context.getObject(parentDirectoryNode.data, write_directory_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -457,7 +458,7 @@ function make_directory(context, path, callback) {
|
|||
}
|
||||
directoryNode = result;
|
||||
directoryNode.nlinks += 1;
|
||||
context.put(directoryNode.id, directoryNode, write_directory_data);
|
||||
context.putObject(directoryNode.id, directoryNode, write_directory_data);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -467,7 +468,7 @@ function make_directory(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
context.put(directoryNode.data, directoryData, update_parent_directory_data);
|
||||
context.putObject(directoryNode.data, directoryData, update_parent_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -485,7 +486,7 @@ function make_directory(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData[name] = new DirectoryEntry(directoryNode.id, MODE_DIRECTORY);
|
||||
context.put(parentDirectoryNode.data, parentDirectoryData, update_time);
|
||||
context.putObject(parentDirectoryNode.data, parentDirectoryData, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +511,7 @@ function remove_directory(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
context.get(parentDirectoryNode.data, check_if_node_exists);
|
||||
context.getObject(parentDirectoryNode.data, check_if_node_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,7 +525,7 @@ function remove_directory(context, path, callback) {
|
|||
} else {
|
||||
parentDirectoryData = result;
|
||||
directoryNode = parentDirectoryData[name].id;
|
||||
context.get(directoryNode, check_if_node_is_directory);
|
||||
context.getObject(directoryNode, check_if_node_is_directory);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,7 +536,7 @@ function remove_directory(context, path, callback) {
|
|||
callback(new Errors.ENOTDIR());
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_directory_is_empty);
|
||||
context.getObject(directoryNode.data, check_if_directory_is_empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,7 +564,7 @@ function remove_directory(context, path, callback) {
|
|||
|
||||
function remove_directory_entry_from_parent_directory_node() {
|
||||
delete parentDirectoryData[name];
|
||||
context.put(parentDirectoryNode.data, parentDirectoryData, update_time);
|
||||
context.putObject(parentDirectoryNode.data, parentDirectoryData, update_time);
|
||||
}
|
||||
|
||||
function remove_directory_node(error) {
|
||||
|
@ -615,7 +616,7 @@ function open_file(context, path, flags, callback) {
|
|||
callback(new Errors.ENOENT());
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_file_exists);
|
||||
context.getObject(directoryNode.data, check_if_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -632,7 +633,7 @@ function open_file(context, path, flags, callback) {
|
|||
if(directoryEntry.type == MODE_DIRECTORY && _(flags).contains(O_WRITE)) {
|
||||
callback(new Errors.EISDIR('the named file is a directory and O_WRITE is set'));
|
||||
} else {
|
||||
context.get(directoryEntry.id, check_if_symbolic_link);
|
||||
context.getObject(directoryEntry.id, check_if_symbolic_link);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -694,7 +695,7 @@ function open_file(context, path, flags, callback) {
|
|||
}
|
||||
fileNode = result;
|
||||
fileNode.nlinks += 1;
|
||||
context.put(fileNode.id, fileNode, write_file_data);
|
||||
context.putObject(fileNode.id, fileNode, write_file_data);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -704,7 +705,7 @@ function open_file(context, path, flags, callback) {
|
|||
} else {
|
||||
fileData = new Buffer(0);
|
||||
fileData.fill(0);
|
||||
context.put(fileNode.data, fileData, update_directory_data);
|
||||
context.putBuffer(fileNode.data, fileData, update_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,7 +723,7 @@ function open_file(context, path, flags, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_FILE);
|
||||
context.put(directoryNode.data, directoryData, update_time);
|
||||
context.putObject(directoryNode.data, directoryData, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -759,7 +760,7 @@ function replace_data(context, ofd, buffer, offset, length, callback) {
|
|||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
context.put(fileNode.id, fileNode, update_time);
|
||||
context.putObject(fileNode.id, fileNode, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -776,11 +777,11 @@ function replace_data(context, ofd, buffer, offset, length, callback) {
|
|||
fileNode.size = length;
|
||||
fileNode.version += 1;
|
||||
|
||||
context.put(fileNode.data, newData, update_file_node);
|
||||
context.putBuffer(fileNode.data, newData, update_file_node);
|
||||
}
|
||||
}
|
||||
|
||||
context.get(ofd.id, write_file_data);
|
||||
context.getObject(ofd.id, write_file_data);
|
||||
}
|
||||
|
||||
function write_data(context, ofd, buffer, offset, length, position, callback) {
|
||||
|
@ -808,7 +809,7 @@ function write_data(context, ofd, buffer, offset, length, position, callback) {
|
|||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
context.put(fileNode.id, fileNode, update_time);
|
||||
context.putObject(fileNode.id, fileNode, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -835,7 +836,7 @@ function write_data(context, ofd, buffer, offset, length, position, callback) {
|
|||
fileNode.size = newSize;
|
||||
fileNode.version += 1;
|
||||
|
||||
context.put(fileNode.data, newData, update_file_node);
|
||||
context.putBuffer(fileNode.data, newData, update_file_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -844,11 +845,11 @@ function write_data(context, ofd, buffer, offset, length, position, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
fileNode = result;
|
||||
context.get(fileNode.data, update_file_data);
|
||||
context.getBuffer(fileNode.data, update_file_data);
|
||||
}
|
||||
}
|
||||
|
||||
context.get(ofd.id, read_file_data);
|
||||
context.getObject(ofd.id, read_file_data);
|
||||
}
|
||||
|
||||
function read_data(context, ofd, buffer, offset, length, position, callback) {
|
||||
|
@ -878,11 +879,11 @@ function read_data(context, ofd, buffer, offset, length, position, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
fileNode = result;
|
||||
context.get(fileNode.data, handle_file_data);
|
||||
context.getBuffer(fileNode.data, handle_file_data);
|
||||
}
|
||||
}
|
||||
|
||||
context.get(ofd.id, read_file_data);
|
||||
context.getObject(ofd.id, read_file_data);
|
||||
}
|
||||
|
||||
function stat_file(context, path, callback) {
|
||||
|
@ -892,7 +893,7 @@ function stat_file(context, path, callback) {
|
|||
}
|
||||
|
||||
function fstat_file(context, ofd, callback) {
|
||||
context.get(ofd.id, standard_check_result_cb(callback));
|
||||
context.getObject(ofd.id, standard_check_result_cb(callback));
|
||||
}
|
||||
|
||||
function lstat_file(context, path, callback) {
|
||||
|
@ -914,7 +915,7 @@ function lstat_file(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_file_exists);
|
||||
context.getObject(directoryNode.data, check_if_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -926,7 +927,7 @@ function lstat_file(context, path, callback) {
|
|||
if(!_(directoryData).has(name)) {
|
||||
callback(new Errors.ENOENT('a component of the path does not name an existing file'));
|
||||
} else {
|
||||
context.get(directoryData[name].id, standard_check_result_cb(callback));
|
||||
context.getObject(directoryData[name].id, standard_check_result_cb(callback));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -961,7 +962,7 @@ function link_node(context, oldpath, newpath, callback) {
|
|||
} else {
|
||||
fileNode = result;
|
||||
fileNode.nlinks += 1;
|
||||
context.put(fileNode.id, fileNode, update_time);
|
||||
context.putObject(fileNode.id, fileNode, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,7 +970,7 @@ function link_node(context, oldpath, newpath, callback) {
|
|||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
context.get(newDirectoryData[newname].id, update_file_node);
|
||||
context.getObject(newDirectoryData[newname].id, update_file_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -982,7 +983,7 @@ function link_node(context, oldpath, newpath, callback) {
|
|||
callback(new Errors.EEXIST('newpath resolves to an existing file'));
|
||||
} else {
|
||||
newDirectoryData[newname] = oldDirectoryData[oldname];
|
||||
context.put(newDirectoryNode.data, newDirectoryData, read_directory_entry);
|
||||
context.putObject(newDirectoryNode.data, newDirectoryData, read_directory_entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -992,7 +993,7 @@ function link_node(context, oldpath, newpath, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
newDirectoryNode = result;
|
||||
context.get(newDirectoryNode.data, check_if_new_file_exists);
|
||||
context.getObject(newDirectoryNode.data, check_if_new_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1015,7 @@ function link_node(context, oldpath, newpath, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
oldDirectoryNode = result;
|
||||
context.get(oldDirectoryNode.data, check_if_old_file_exists);
|
||||
context.getObject(oldDirectoryNode.data, check_if_old_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1035,7 +1036,7 @@ function unlink_node(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
delete directoryData[name];
|
||||
context.put(directoryNode.data, directoryData, function(error) {
|
||||
context.putObject(directoryNode.data, directoryData, function(error) {
|
||||
var now = Date.now();
|
||||
update_node_times(context, parentPath, directoryNode, { mtime: now, ctime: now }, callback);
|
||||
});
|
||||
|
@ -1059,7 +1060,7 @@ function unlink_node(context, path, callback) {
|
|||
if(fileNode.nlinks < 1) {
|
||||
context.delete(fileNode.id, delete_file_data);
|
||||
} else {
|
||||
context.put(fileNode.id, fileNode, function(error) {
|
||||
context.putObject(fileNode.id, fileNode, function(error) {
|
||||
update_node_times(context, path, fileNode, { ctime: Date.now() }, update_directory_data);
|
||||
});
|
||||
}
|
||||
|
@ -1074,7 +1075,7 @@ function unlink_node(context, path, callback) {
|
|||
if(!_(directoryData).has(name)) {
|
||||
callback(new Errors.ENOENT('a component of the path does not name an existing file'));
|
||||
} else {
|
||||
context.get(directoryData[name].id, update_file_node);
|
||||
context.getObject(directoryData[name].id, update_file_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1084,7 +1085,7 @@ function unlink_node(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_file_exists);
|
||||
context.getObject(directoryNode.data, check_if_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1113,7 +1114,7 @@ function read_directory(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, handle_directory_data);
|
||||
context.getObject(directoryNode.data, handle_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1140,7 +1141,7 @@ function make_symbolic_link(context, srcpath, dstpath, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_file_exists);
|
||||
context.getObject(directoryNode.data, check_if_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1167,7 +1168,7 @@ function make_symbolic_link(context, srcpath, dstpath, callback) {
|
|||
fileNode.nlinks += 1;
|
||||
fileNode.size = srcpath.length;
|
||||
fileNode.data = srcpath;
|
||||
context.put(fileNode.id, fileNode, update_directory_data);
|
||||
context.putObject(fileNode.id, fileNode, update_directory_data);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1185,7 +1186,7 @@ function make_symbolic_link(context, srcpath, dstpath, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryData[name] = new DirectoryEntry(fileNode.id, MODE_SYMBOLIC_LINK);
|
||||
context.put(directoryNode.data, directoryData, update_time);
|
||||
context.putObject(directoryNode.data, directoryData, update_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1205,7 +1206,7 @@ function read_link(context, path, callback) {
|
|||
callback(error);
|
||||
} else {
|
||||
directoryNode = result;
|
||||
context.get(directoryNode.data, check_if_file_exists);
|
||||
context.getObject(directoryNode.data, check_if_file_exists);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1217,7 +1218,7 @@ function read_link(context, path, callback) {
|
|||
if(!_(directoryData).has(name)) {
|
||||
callback(new Errors.ENOENT('a component of the path does not name an existing file'));
|
||||
} else {
|
||||
context.get(directoryData[name].id, check_if_symbolic);
|
||||
context.getObject(directoryData[name].id, check_if_symbolic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1247,7 +1248,7 @@ function truncate_file(context, path, length, callback) {
|
|||
callback(new Errors.EISDIR());
|
||||
} else{
|
||||
fileNode = node;
|
||||
context.get(fileNode.data, truncate_file_data);
|
||||
context.getObject(fileNode.data, truncate_file_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1264,7 +1265,7 @@ function truncate_file(context, path, length, callback) {
|
|||
if(fileData) {
|
||||
fileData.copy(data);
|
||||
}
|
||||
context.put(fileNode.data, data, update_file_node);
|
||||
context.putBuffer(fileNode.data, data, update_file_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1283,7 +1284,7 @@ function truncate_file(context, path, length, callback) {
|
|||
} else {
|
||||
fileNode.size = length;
|
||||
fileNode.version += 1;
|
||||
context.put(fileNode.id, fileNode, update_time);
|
||||
context.putObject(fileNode.id, fileNode, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1304,7 +1305,7 @@ function ftruncate_file(context, ofd, length, callback) {
|
|||
callback(new Errors.EISDIR());
|
||||
} else{
|
||||
fileNode = node;
|
||||
context.get(fileNode.data, truncate_file_data);
|
||||
context.getObject(fileNode.data, truncate_file_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1323,7 +1324,7 @@ function ftruncate_file(context, ofd, length, callback) {
|
|||
data = new Buffer(length);
|
||||
data.fill(0);
|
||||
}
|
||||
context.put(fileNode.data, data, update_file_node);
|
||||
context.putBuffer(fileNode.data, data, update_file_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1342,14 +1343,14 @@ function ftruncate_file(context, ofd, length, callback) {
|
|||
} else {
|
||||
fileNode.size = length;
|
||||
fileNode.version += 1;
|
||||
context.put(fileNode.id, fileNode, update_time);
|
||||
context.putObject(fileNode.id, fileNode, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
if(length < 0) {
|
||||
callback(new Errors.EINVAL('length cannot be negative'));
|
||||
} else {
|
||||
context.get(ofd.id, read_file_data);
|
||||
context.getObject(ofd.id, read_file_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1392,7 +1393,7 @@ function futimes_file(context, ofd, atime, mtime, callback) {
|
|||
callback(new Errors.EINVAL('atime and mtime must be positive integers'));
|
||||
}
|
||||
else {
|
||||
context.get(ofd.id, update_times);
|
||||
context.getObject(ofd.id, update_times);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1481,7 +1482,7 @@ function fgetxattr_file (context, ofd, name, callback) {
|
|||
callback(new Errors.EINVAL('attribute name cannot be an empty string'));
|
||||
}
|
||||
else {
|
||||
context.get(ofd.id, get_xattr);
|
||||
context.getObject(ofd.id, get_xattr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1507,7 +1508,7 @@ function removexattr_file (context, path, name, callback) {
|
|||
}
|
||||
else {
|
||||
delete node.xattrs[name];
|
||||
context.put(node.id, node, update_time);
|
||||
context.putObject(node.id, node, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1541,7 +1542,7 @@ function fremovexattr_file (context, ofd, name, callback) {
|
|||
}
|
||||
else {
|
||||
delete node.xattrs[name];
|
||||
context.put(node.id, node, update_time);
|
||||
context.putObject(node.id, node, update_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1552,7 +1553,7 @@ function fremovexattr_file (context, ofd, name, callback) {
|
|||
callback(new Errors.EINVAL('attribute name cannot be an empty string'));
|
||||
}
|
||||
else {
|
||||
context.get(ofd.id, remove_xattr);
|
||||
context.getObject(ofd.id, remove_xattr);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,7 +156,7 @@ function FileSystem(options, callback) {
|
|||
// Otherwise (default) make sure this id is unused first
|
||||
function guidWithCheck(callback) {
|
||||
var id = guid();
|
||||
context.get(id, function(err, value) {
|
||||
context.getObject(id, function(err, value) {
|
||||
if(err) {
|
||||
callback(err);
|
||||
return;
|
||||
|
|
|
@ -3,6 +3,7 @@ var FILE_STORE_NAME = require('../constants.js').FILE_STORE_NAME;
|
|||
var IDB_RW = require('../constants.js').IDB_RW;
|
||||
var IDB_RO = require('../constants.js').IDB_RO;
|
||||
var Errors = require('../errors.js');
|
||||
var FilerBuffer = require('../buffer.js');
|
||||
|
||||
var indexedDB = global.indexedDB ||
|
||||
global.mozIndexedDB ||
|
||||
|
@ -13,6 +14,7 @@ function IndexedDBContext(db, mode) {
|
|||
var transaction = db.transaction(FILE_STORE_NAME, mode);
|
||||
this.objectStore = transaction.objectStore(FILE_STORE_NAME);
|
||||
}
|
||||
|
||||
IndexedDBContext.prototype.clear = function(callback) {
|
||||
try {
|
||||
var request = this.objectStore.clear();
|
||||
|
@ -26,9 +28,10 @@ IndexedDBContext.prototype.clear = function(callback) {
|
|||
callback(e);
|
||||
}
|
||||
};
|
||||
IndexedDBContext.prototype.get = function(key, callback) {
|
||||
|
||||
function _get(objectStore, key, callback) {
|
||||
try {
|
||||
var request = this.objectStore.get(key);
|
||||
var request = objectStore.get(key);
|
||||
request.onsuccess = function onsuccess(event) {
|
||||
var result = event.target.result;
|
||||
callback(null, result);
|
||||
|
@ -39,10 +42,22 @@ IndexedDBContext.prototype.get = function(key, callback) {
|
|||
} catch(e) {
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
IndexedDBContext.prototype.getObject = function(key, callback) {
|
||||
_get(this.objectStore, key, callback);
|
||||
};
|
||||
IndexedDBContext.prototype.put = function(key, value, callback) {
|
||||
IndexedDBContext.prototype.getBuffer = function(key, callback) {
|
||||
_get(this.objectStore, key, function(err, arrayBuffer) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
callback(null, new FilerBuffer(arrayBuffer));
|
||||
});
|
||||
};
|
||||
|
||||
function _put(objectStore, key, value, callback) {
|
||||
try {
|
||||
var request = this.objectStore.put(value, key);
|
||||
var request = objectStore.put(value, key);
|
||||
request.onsuccess = function onsuccess(event) {
|
||||
var result = event.target.result;
|
||||
callback(null, result);
|
||||
|
@ -53,7 +68,14 @@ IndexedDBContext.prototype.put = function(key, value, callback) {
|
|||
} catch(e) {
|
||||
callback(e);
|
||||
}
|
||||
}
|
||||
IndexedDBContext.prototype.putObject = function(key, value, callback) {
|
||||
_put(this.objectStore, key, value, callback);
|
||||
};
|
||||
IndexedDBContext.prototype.putBuffer = function(key, uint8BackedBuffer, callback) {
|
||||
_put(this.objectStore, key, uint8BackedBuffer.buffer, callback);
|
||||
};
|
||||
|
||||
IndexedDBContext.prototype.delete = function(key, callback) {
|
||||
try {
|
||||
var request = this.objectStore.delete(key);
|
||||
|
|
|
@ -24,6 +24,7 @@ function MemoryContext(db, readOnly) {
|
|||
this.readOnly = readOnly;
|
||||
this.objectStore = db;
|
||||
}
|
||||
|
||||
MemoryContext.prototype.clear = function(callback) {
|
||||
if(this.readOnly) {
|
||||
asyncCallback(function() {
|
||||
|
@ -37,13 +38,19 @@ MemoryContext.prototype.clear = function(callback) {
|
|||
});
|
||||
asyncCallback(callback);
|
||||
};
|
||||
MemoryContext.prototype.get = function(key, callback) {
|
||||
|
||||
// Memory context doesn't care about differences between Object and Buffer
|
||||
MemoryContext.prototype.getObject =
|
||||
MemoryContext.prototype.getBuffer =
|
||||
function(key, callback) {
|
||||
var that = this;
|
||||
asyncCallback(function() {
|
||||
callback(null, that.objectStore[key]);
|
||||
});
|
||||
};
|
||||
MemoryContext.prototype.put = function(key, value, callback) {
|
||||
MemoryContext.prototype.putObject =
|
||||
MemoryContext.prototype.putBuffer =
|
||||
function(key, value, callback) {
|
||||
if(this.readOnly) {
|
||||
asyncCallback(function() {
|
||||
callback("[MemoryContext] Error: write operation on read only context");
|
||||
|
@ -53,6 +60,7 @@ MemoryContext.prototype.put = function(key, value, callback) {
|
|||
this.objectStore[key] = value;
|
||||
asyncCallback(callback);
|
||||
};
|
||||
|
||||
MemoryContext.prototype.delete = function(key, callback) {
|
||||
if(this.readOnly) {
|
||||
asyncCallback(function() {
|
||||
|
|
|
@ -3,8 +3,9 @@ var FILE_STORE_NAME = require('../constants.js').FILE_STORE_NAME;
|
|||
var WSQL_VERSION = require('../constants.js').WSQL_VERSION;
|
||||
var WSQL_SIZE = require('../constants.js').WSQL_SIZE;
|
||||
var WSQL_DESC = require('../constants.js').WSQL_DESC;
|
||||
var u8toArray = require('../shared.js').u8toArray;
|
||||
var Errors = require('../errors.js');
|
||||
var FilerBuffer = require('../buffer.js');
|
||||
var base64ArrayBuffer = require('base64-arraybuffer');
|
||||
|
||||
function WebSQLContext(db, isReadOnly) {
|
||||
var that = this;
|
||||
|
@ -20,6 +21,7 @@ function WebSQLContext(db, isReadOnly) {
|
|||
});
|
||||
};
|
||||
}
|
||||
|
||||
WebSQLContext.prototype.clear = function(callback) {
|
||||
function onError(transaction, error) {
|
||||
callback(error);
|
||||
|
@ -32,52 +34,74 @@ WebSQLContext.prototype.clear = function(callback) {
|
|||
[], onSuccess, onError);
|
||||
});
|
||||
};
|
||||
WebSQLContext.prototype.get = function(key, callback) {
|
||||
|
||||
function _get(getTransaction, key, callback) {
|
||||
function onSuccess(transaction, result) {
|
||||
// If the key isn't found, return null
|
||||
var value = result.rows.length === 0 ? null : result.rows.item(0).data;
|
||||
try {
|
||||
if(value) {
|
||||
value = JSON.parse(value);
|
||||
// Deal with special-cased flattened typed arrays in WebSQL (see put() below)
|
||||
if(value.__isUint8Array) {
|
||||
value = new Uint8Array(value.__array);
|
||||
}
|
||||
}
|
||||
callback(null, value);
|
||||
} catch(e) {
|
||||
callback(e);
|
||||
}
|
||||
callback(null, value);
|
||||
}
|
||||
function onError(transaction, error) {
|
||||
callback(error);
|
||||
}
|
||||
this.getTransaction(function(transaction) {
|
||||
transaction.executeSql("SELECT data FROM " + FILE_STORE_NAME + " WHERE id = ?;",
|
||||
getTransaction(function(transaction) {
|
||||
transaction.executeSql("SELECT data FROM " + FILE_STORE_NAME + " WHERE id = ? LIMIT 1;",
|
||||
[key], onSuccess, onError);
|
||||
});
|
||||
}
|
||||
WebSQLContext.prototype.getObject = function(key, callback) {
|
||||
_get(this.getTransaction, key, function(err, result) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
try {
|
||||
if(result) {
|
||||
result = JSON.parse(result);
|
||||
}
|
||||
} catch(e) {
|
||||
return callback(e);
|
||||
}
|
||||
|
||||
callback(null, result);
|
||||
});
|
||||
};
|
||||
WebSQLContext.prototype.put = function(key, value, callback) {
|
||||
// We do extra work to make sure typed arrays survive
|
||||
// being stored in the db and still get the right prototype later.
|
||||
if(Object.prototype.toString.call(value) === "[object Uint8Array]") {
|
||||
value = {
|
||||
__isUint8Array: true,
|
||||
__array: u8toArray(value)
|
||||
};
|
||||
}
|
||||
value = JSON.stringify(value);
|
||||
WebSQLContext.prototype.getBuffer = function(key, callback) {
|
||||
_get(this.getTransaction, key, function(err, result) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
if(result) {
|
||||
var arrayBuffer = base64ArrayBuffer.decode(result);
|
||||
result = new FilerBuffer(arrayBuffer);
|
||||
}
|
||||
|
||||
callback(null, result);
|
||||
});
|
||||
};
|
||||
|
||||
function _put(getTransaction, key, value, callback) {
|
||||
function onSuccess(transaction, result) {
|
||||
callback(null);
|
||||
}
|
||||
function onError(transaction, error) {
|
||||
callback(error);
|
||||
}
|
||||
this.getTransaction(function(transaction) {
|
||||
getTransaction(function(transaction) {
|
||||
transaction.executeSql("INSERT OR REPLACE INTO " + FILE_STORE_NAME + " (id, data) VALUES (?, ?);",
|
||||
[key, value], onSuccess, onError);
|
||||
});
|
||||
}
|
||||
WebSQLContext.prototype.putObject = function(key, value, callback) {
|
||||
var json = JSON.stringify(value);
|
||||
_put(this.getTransaction, key, json, callback);
|
||||
};
|
||||
WebSQLContext.prototype.putBuffer = function(key, uint8BackedBuffer, callback) {
|
||||
var base64 = base64ArrayBuffer.encode(uint8BackedBuffer.buffer);
|
||||
_put(this.getTransaction, key, base64, callback);
|
||||
};
|
||||
|
||||
WebSQLContext.prototype.delete = function(key, callback) {
|
||||
function onSuccess(transaction, result) {
|
||||
callback(null);
|
||||
|
|
|
@ -18,7 +18,7 @@ function IndexedDBTestProvider(name) {
|
|||
|
||||
function cleanup(callback) {
|
||||
if(!that.provider || _done) {
|
||||
return;
|
||||
return callback();
|
||||
}
|
||||
|
||||
// We have to force any other connections to close
|
||||
|
@ -49,5 +49,8 @@ function IndexedDBTestProvider(name) {
|
|||
this.init = init;
|
||||
this.cleanup = cleanup;
|
||||
}
|
||||
IndexedDBTestProvider.isSupported = function() {
|
||||
return Filer.FileSystem.providers.IndexedDB.isSupported();
|
||||
};
|
||||
|
||||
module.exports = IndexedDBTestProvider;
|
||||
|
|
|
@ -18,5 +18,8 @@ function MemoryTestProvider(name) {
|
|||
this.init = init;
|
||||
this.cleanup = cleanup;
|
||||
}
|
||||
MemoryTestProvider.isSupported = function() {
|
||||
return Filer.FileSystem.providers.Memory.isSupported();
|
||||
};
|
||||
|
||||
module.exports = MemoryTestProvider;
|
||||
|
|
|
@ -13,11 +13,11 @@ function WebSQLTestProvider(name) {
|
|||
|
||||
function cleanup(callback) {
|
||||
if(!that.provider || _done) {
|
||||
return;
|
||||
return callback();
|
||||
}
|
||||
// Provider is there, but db was never touched
|
||||
if(!that.provider.db) {
|
||||
return;
|
||||
return callback();
|
||||
}
|
||||
|
||||
var context = that.provider.getReadWriteContext();
|
||||
|
@ -39,5 +39,8 @@ function WebSQLTestProvider(name) {
|
|||
this.init = init;
|
||||
this.cleanup = cleanup;
|
||||
}
|
||||
WebSQLTestProvider.isSupported = function() {
|
||||
return Filer.FileSystem.providers.WebSQL.isSupported();
|
||||
};
|
||||
|
||||
module.exports = WebSQLTestProvider;
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
var Buffer = require('../../..').Buffer;
|
||||
var util = require('../../lib/test-utils.js');
|
||||
var expect = require('chai').expect;
|
||||
|
||||
/**
|
||||
* Due to the different setup/cleanup needs of the built-in providers,
|
||||
* we use the test provider wrappers instead of the raw providers themselves.
|
||||
*/
|
||||
module.exports = function createProviderTestsFor(providerName, testProvider) {
|
||||
if(!testProvider.isSupported()) {
|
||||
console.log("Skipping provider tests for `" + providerName +"'--not supported in current environment.");
|
||||
return;
|
||||
}
|
||||
|
||||
describe("Filer Provider Tests for " + providerName, function() {
|
||||
var _provider;
|
||||
var provider;
|
||||
|
||||
beforeEach(function() {
|
||||
_provider = new testProvider(util.uniqueName());
|
||||
_provider.init();
|
||||
provider = _provider.provider;
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
_provider.cleanup(done);
|
||||
_provider = null;
|
||||
provider = null;
|
||||
});
|
||||
|
||||
|
||||
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
||||
expect(provider.open).to.be.a('function');
|
||||
expect(provider.getReadOnlyContext).to.be.a('function');
|
||||
expect(provider.getReadWriteContext).to.be.a('function');
|
||||
});
|
||||
|
||||
it("should open a new IndexedDB database", function(done) {
|
||||
provider.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow putObject() and getObject()", function(done) {
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
// Simple JS Object
|
||||
var value = {
|
||||
a: "a",
|
||||
b: 1,
|
||||
c: true,
|
||||
d: [1,2,3],
|
||||
e: {
|
||||
e1: ['a', 'b', 'c']
|
||||
}
|
||||
};
|
||||
context.putObject("key", value, function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.getObject("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).to.be.an('object');
|
||||
expect(result).to.deep.equal(value);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow putBuffer() and getBuffer()", function(done) {
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
// Filer Buffer
|
||||
var buf = new Buffer([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
|
||||
context.putBuffer("key", buf, function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.getBuffer("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(Buffer.isBuffer(result)).to.be.true;
|
||||
expect(result).to.deep.equal(buf);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow delete()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.putObject("key", "value", function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.delete("key", function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.getObject("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow clear()", function(done) {
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.putObject("key1", "value1", function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.putObject("key2", "value2", function(error) {
|
||||
if(error) throw error;
|
||||
|
||||
context.clear(function(err) {
|
||||
if(error) throw error;
|
||||
|
||||
context.getObject("key1", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
|
||||
context.getObject("key2", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
|
@ -1,148 +1,4 @@
|
|||
var Filer = require('../../..');
|
||||
var util = require('../../lib/test-utils.js');
|
||||
var expect = require('chai').expect;
|
||||
var providerBase = require('./providers.base.js');
|
||||
|
||||
if(!Filer.FileSystem.providers.IndexedDB.isSupported()) {
|
||||
console.log("Skipping Filer.FileSystem.providers.IndexedDB tests, since IndexedDB isn't supported.");
|
||||
} else {
|
||||
describe("Filer.FileSystem.providers.IndexedDB", function() {
|
||||
it("is supported -- if it isn't, none of these tests can run.", function() {
|
||||
expect(Filer.FileSystem.providers.IndexedDB.isSupported()).to.be.true;
|
||||
});
|
||||
|
||||
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
||||
var indexedDBProvider = new Filer.FileSystem.providers.IndexedDB();
|
||||
expect(indexedDBProvider.open).to.be.a('function');
|
||||
expect(indexedDBProvider.getReadOnlyContext).to.be.a('function');
|
||||
expect(indexedDBProvider.getReadWriteContext).to.be.a('function');
|
||||
});
|
||||
|
||||
describe("open an IndexedDB provider", function() {
|
||||
var _provider;
|
||||
|
||||
beforeEach(function() {
|
||||
_provider = new util.providers.IndexedDB(util.uniqueName());
|
||||
_provider.init();
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
_provider.cleanup(done);
|
||||
_provider = null;
|
||||
});
|
||||
|
||||
it("should open a new IndexedDB database", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Read/Write operations on an IndexedDB provider", function() {
|
||||
var _provider;
|
||||
|
||||
beforeEach(function() {
|
||||
_provider = new util.providers.IndexedDB(util.uniqueName());
|
||||
_provider.init();
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
_provider.cleanup(done);
|
||||
_provider = null;
|
||||
});
|
||||
|
||||
it("should allow put() and get()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).to.equal('value');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow delete()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.delete("key", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow clear()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.put("key2", "value2", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.clear(function(err) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key1", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
|
||||
context.get("key2", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* With issue 123 (see https://github.com/js-platform/filer/issues/128) we had to
|
||||
* start using readwrite contexts everywhere with IndexedDB. Skipping for now.
|
||||
*/
|
||||
it.skip("should fail when trying to write on ReadOnlyContext", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadOnlyContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
expect(error).to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
providerBase('IndexedDB', util.providers.IndexedDB);
|
||||
|
|
|
@ -1,145 +1,4 @@
|
|||
var Filer = require('../../..');
|
||||
var expect = require('chai').expect;
|
||||
var util = require('../../lib/test-utils.js');
|
||||
var providerBase = require('./providers.base.js');
|
||||
|
||||
describe("Filer.FileSystem.providers.Memory", function() {
|
||||
it("is supported -- if it isn't, none of these tests can run.", function() {
|
||||
expect(Filer.FileSystem.providers.Memory.isSupported()).to.be.true;
|
||||
});
|
||||
|
||||
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
||||
var memoryProvider = new Filer.FileSystem.providers.Memory();
|
||||
expect(memoryProvider.open).to.be.a('function');
|
||||
expect(memoryProvider.getReadOnlyContext).to.be.a('function');
|
||||
expect(memoryProvider.getReadWriteContext).to.be.a('function');
|
||||
});
|
||||
|
||||
describe("Memory provider DBs are sharable", function() {
|
||||
it("should share a single memory db when name is the same", function(done) {
|
||||
var provider1;
|
||||
var provider2;
|
||||
var provider3;
|
||||
var name1 = 'memory-db';
|
||||
var name2 = 'memory-db2';
|
||||
|
||||
provider1 = new Filer.FileSystem.providers.Memory(name1);
|
||||
provider1.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
|
||||
provider2 = new Filer.FileSystem.providers.Memory(name1);
|
||||
provider2.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.false;
|
||||
expect(provider1.db).to.equal(provider2.db);
|
||||
|
||||
provider3 = new Filer.FileSystem.providers.Memory(name2);
|
||||
provider3.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
expect(provider3.db).not.to.equal(provider2.db);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("open an Memory provider", function() {
|
||||
it("should open a new Memory database", function(done) {
|
||||
var provider = new Filer.FileSystem.providers.Memory();
|
||||
provider.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Read/Write operations on an Memory provider", function() {
|
||||
it("should allow put() and get()", function(done) {
|
||||
var provider = new Filer.FileSystem.providers.Memory();
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).to.equal("value");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow delete()", function(done) {
|
||||
var provider = new Filer.FileSystem.providers.Memory();
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.delete("key", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow clear()", function(done) {
|
||||
var provider = new Filer.FileSystem.providers.Memory();
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.put("key2", "value2", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.clear(function(err) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key1", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
|
||||
context.get("key2", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail when trying to write on ReadOnlyContext", function(done) {
|
||||
var provider = new Filer.FileSystem.providers.Memory();
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadOnlyContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
expect(error).to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
providerBase('Memory', util.providers.Memory);
|
||||
|
|
|
@ -1,143 +1,4 @@
|
|||
var Filer = require('../../..');
|
||||
var util = require('../../lib/test-utils.js');
|
||||
var expect = require('chai').expect;
|
||||
var providerBase = require('./providers.base.js');
|
||||
|
||||
if(!Filer.FileSystem.providers.WebSQL.isSupported()) {
|
||||
console.log("Skipping Filer.FileSystem.providers.WebSQL tests, since WebSQL isn't supported.");
|
||||
} else {
|
||||
describe("Filer.FileSystem.providers.WebSQL", function() {
|
||||
it("is supported -- if it isn't, none of these tests can run.", function() {
|
||||
expect(Filer.FileSystem.providers.WebSQL.isSupported()).to.be.true;
|
||||
});
|
||||
|
||||
it("has open, getReadOnlyContext, and getReadWriteContext instance methods", function() {
|
||||
var webSQLProvider = new Filer.FileSystem.providers.WebSQL();
|
||||
expect(webSQLProvider.open).to.be.a('function');
|
||||
expect(webSQLProvider.getReadOnlyContext).to.be.a('function');
|
||||
expect(webSQLProvider.getReadWriteContext).to.be.a('function');
|
||||
});
|
||||
|
||||
describe("open an WebSQL provider", function() {
|
||||
var _provider;
|
||||
|
||||
beforeEach(function() {
|
||||
_provider = new util.providers.WebSQL(util.uniqueName());
|
||||
_provider.init();
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
_provider.cleanup(done);
|
||||
_provider = null;
|
||||
});
|
||||
|
||||
it("should open a new WebSQL database", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
expect(error).not.to.exist;
|
||||
expect(firstAccess).to.be.true;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("Read/Write operations on an WebSQL provider", function() {
|
||||
var _provider;
|
||||
|
||||
beforeEach(function() {
|
||||
_provider = new util.providers.WebSQL(util.uniqueName());
|
||||
_provider.init();
|
||||
});
|
||||
|
||||
afterEach(function(done) {
|
||||
_provider.cleanup(done);
|
||||
_provider = null;
|
||||
});
|
||||
|
||||
it("should allow put() and get()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).to.equal("value");
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow delete()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key", "value", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.delete("key", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should allow clear()", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadWriteContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.put("key2", "value2", function(error, result) {
|
||||
if(error) throw error;
|
||||
|
||||
context.clear(function(err) {
|
||||
if(error) throw error;
|
||||
|
||||
context.get("key1", function(error, result) {
|
||||
if(error) throw error;
|
||||
expect(result).not.to.exist;
|
||||
|
||||
context.get("key2", function(error, result) {
|
||||
expect(error).not.to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("should fail when trying to write on ReadOnlyContext", function(done) {
|
||||
var provider = _provider.provider;
|
||||
provider.open(function(error, firstAccess) {
|
||||
if(error) throw error;
|
||||
|
||||
var context = provider.getReadOnlyContext();
|
||||
context.put("key1", "value1", function(error, result) {
|
||||
expect(error).to.exist;
|
||||
expect(result).not.to.exist;
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
providerBase('WebSQL', util.providers.WebSQL);
|
||||
|
|
|
@ -358,12 +358,12 @@ describe('node times (atime, mtime, ctime)', function() {
|
|||
var buffer = new Filer.Buffer([1, 2, 3, 4, 5, 6, 7, 8]);
|
||||
|
||||
createTree(function() {
|
||||
fs.open('/myfile', 'w', function(err, fd) {
|
||||
if(err) throw error;
|
||||
fs.open('/myfile', 'w', function(error, fd) {
|
||||
if(error) throw error;
|
||||
|
||||
stat('/myfile', function(stats1) {
|
||||
fs.write(fd, buffer, 0, buffer.length, 0, function(err, nbytes) {
|
||||
if(err) throw error;
|
||||
fs.write(fd, buffer, 0, buffer.length, 0, function(error, nbytes) {
|
||||
if(error) throw error;
|
||||
|
||||
fs.close(fd, function(error) {
|
||||
if(error) throw error;
|
||||
|
|
Loading…
Reference in New Issue