Reorganize files.
This commit is contained in:
parent
a2ff2823dc
commit
4f5ff333fb
|
@ -15,7 +15,7 @@ require.config({
|
|||
}
|
||||
});
|
||||
|
||||
require(["src/fs2"], function(IDBFS) {
|
||||
require(["src/file-system"], function(IDBFS) {
|
||||
|
||||
var flags = 'FORMAT';
|
||||
//var flags = undefined;
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
define(function(require) {
|
||||
|
||||
return {
|
||||
METADATA_STORE_NAME: 'metadata',
|
||||
FILE_STORE_NAME: 'files',
|
||||
|
||||
IDB_RO: 'readonly',
|
||||
IDB_RW: 'readwrite',
|
||||
|
||||
MODE_FILE: 'FILE',
|
||||
MODE_DIRECTORY: 'DIRECTORY',
|
||||
MODE_SYMBOLIC_LINK: 'SYMLINK',
|
||||
|
||||
BINARY_MIME_TYPE: 'application/octet-stream',
|
||||
JSON_MIME_TYPE: 'application/json',
|
||||
|
||||
ROOT_DIRECTORY_NAME: '/', // basename(normalize(path))
|
||||
ROOT_NODE_ID: '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1', // sha256(ROOT_DIRECTORY_NAME)
|
||||
|
||||
// FileSystem flags
|
||||
FS_FORMAT: 'FORMAT',
|
||||
|
||||
// Open flags
|
||||
O_READONLY: 'READONLY',
|
||||
O_READWRITE: 'READWRITE',
|
||||
O_APPEND: 'APPEND',
|
||||
O_CREATE: 'CREATE',
|
||||
O_TRUNCATE: 'TRUNCATE',
|
||||
|
||||
// FileSystem readyState
|
||||
FS_READY: 'READY',
|
||||
FS_PENDING: 'PENDING',
|
||||
FS_ERROR: 'ERROR',
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,247 @@
|
|||
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 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;
|
||||
};
|
||||
|
||||
// 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;
|
||||
var directoryData;
|
||||
|
||||
function write_directory_node(error, existingNode) {
|
||||
if(!error && existingNode) {
|
||||
callback(new EPathExists());
|
||||
} else if(error && !error instanceof ENoEntry) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryNode = new Node(ROOT_NODE_ID, MODE_DIRECTORY);
|
||||
directoryNode.links += 1;
|
||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
write_object(objectStore, directoryData, directoryNode.data, callback);
|
||||
}
|
||||
};
|
||||
|
||||
find_node(objectStore, ROOT_DIRECTORY_NAME, write_directory_node);
|
||||
}
|
||||
|
||||
function make_directory(objectStore, path, callback) {
|
||||
path = normalize(path);
|
||||
var name = basename(path);
|
||||
var parentPath = dirname(path);
|
||||
|
||||
var directoryNode;
|
||||
var directoryData;
|
||||
var parentDirectoryNode;
|
||||
var parentDirectoryData;
|
||||
|
||||
function check_if_directory_exists(error, result) {
|
||||
if(!error && result) {
|
||||
callback(new EPathExists());
|
||||
} else if(error && !error instanceof ENoEntry) {
|
||||
callback(error);
|
||||
} else {
|
||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
function read_parent_directory_data(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
read_object(objectStore, parentDirectoryNode.data, write_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_node(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData = result;
|
||||
directoryNode = new Node(undefined, MODE_DIRECTORY);
|
||||
directoryNode.links += 1;
|
||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
write_object(objectStore, directoryData, directoryNode.data, update_parent_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function update_parent_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData[name] = new DirectoryEntry(directoryNode.id, MODE_DIRECTORY);
|
||||
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, callback);
|
||||
}
|
||||
}
|
||||
|
||||
find_node(objectStore, path, check_if_directory_exists);
|
||||
};
|
||||
|
||||
function remove_directory(objectStore, path, callback) {
|
||||
path = normalize(path);
|
||||
var name = basename(path);
|
||||
var parentPath = dirname(path);
|
||||
|
||||
var directoryNode;
|
||||
var directoryData;
|
||||
var parentDirectoryNode;
|
||||
var parentDirectoryData;
|
||||
|
||||
function check_if_directory_exists(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else if(!result) {
|
||||
callback(new ENoEntry());
|
||||
} else {
|
||||
directoryNode = result;
|
||||
read_object(objectStore, directoryNode.data, check_if_directory_is_empty);
|
||||
}
|
||||
}
|
||||
|
||||
function check_if_directory_is_empty(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = result;
|
||||
if(_(directoryData).size() > 0) {
|
||||
callback(new ENotEmpty());
|
||||
} else {
|
||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function read_parent_directory_data(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
read_object(objectStore, parentDirectoryNode.data, remove_directory_entry_from_parent_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_entry_from_parent_directory_node(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData = result;
|
||||
delete parentDirectoryData[name];
|
||||
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, remove_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_node(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
delete_object(objectStore, directoryNode.id, remove_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
delete_object(objectStore, directoryNode.data, callback);
|
||||
}
|
||||
};
|
||||
|
||||
find_node(objectStore, path, check_if_directory_exists);
|
||||
};
|
||||
|
||||
return {
|
||||
make_directory: make_directory,
|
||||
make_root_directory: make_root_directory,
|
||||
remove_directory: remove_directory,
|
||||
find_node: find_node,
|
||||
};
|
||||
|
||||
});
|
48
src/event.js
48
src/event.js
|
@ -1,48 +0,0 @@
|
|||
define function(require) {
|
||||
|
||||
var _ = require('lodash');
|
||||
|
||||
function Event(type, data) {
|
||||
this.type = type;
|
||||
this.data = data;
|
||||
};
|
||||
|
||||
function EventSource(types) {
|
||||
var events = this.events = {};
|
||||
_(types).forEach(function(type) {
|
||||
events[type] = [];
|
||||
});
|
||||
|
||||
this.on = function on(type, callback) {
|
||||
if(!_(events).has(type)) {
|
||||
throw new Error('unsupported event: ' + type);
|
||||
}
|
||||
|
||||
events[type].push(callback);
|
||||
};
|
||||
|
||||
this.off = function off(type, callback) {
|
||||
if(!_(events).has(type)) {
|
||||
throw new Error('unsupported event: ' + type);
|
||||
}
|
||||
|
||||
events[type] = _(events[type]).without(callback);
|
||||
};
|
||||
|
||||
this.emit = function emit(event) {
|
||||
if(!_(events).has(type)) {
|
||||
throw new Error('unsupported event: ' + type);
|
||||
}
|
||||
|
||||
_(events[type]).forEach(function(callack) {
|
||||
callback.call(this, event);
|
||||
});
|
||||
};
|
||||
};
|
||||
|
||||
return {
|
||||
Event: Event,
|
||||
EventSource: EventSource
|
||||
};
|
||||
|
||||
};
|
|
@ -0,0 +1,160 @@
|
|||
define(function(require) {
|
||||
|
||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
|
||||
var _ = require('lodash');
|
||||
var when = require('when');
|
||||
|
||||
var guid = require('src/shared').guid;
|
||||
var hash = require('src/shared').hash;
|
||||
var nop = require('src/shared').nop;
|
||||
|
||||
var EPathExists = require('src/error').EPathExists;
|
||||
var EIsDirectory = require('src/error').EIsDirectory;
|
||||
var ENoEntry = require('src/error').ENoEntry;
|
||||
var EBusy = require('src/error').EBusy;
|
||||
var ENotEmpty = require('src/error').ENotEmpty;
|
||||
var ENotDirectory = require('src/error').ENotDirectory;
|
||||
var EBadFileDescriptor = require('src/error').EBadFileDescriptor;
|
||||
var ENotImplemented = require('src/error').ENotImplemented;
|
||||
var ENotMounted = require('src/error').ENotMounted;
|
||||
var EFileExists = require('src/error').EFileExists;
|
||||
|
||||
var FS_FORMAT = require('src/constants').FS_FORMAT;
|
||||
|
||||
var IDB_RW = require('src/constants').IDB_RW;
|
||||
var IDB_RO = require('src/constants').IDB_RO;
|
||||
var FILE_STORE_NAME = require('src/constants').FILE_STORE_NAME;
|
||||
var FS_READY = require('src/constants').READY;
|
||||
var FS_PENDING = require('src/constants').FS_PENDING;
|
||||
var FS_ERROR = require('src/constants').FS_ERROR;
|
||||
|
||||
var make_root_directory = require('src/directory').make_root_directory;
|
||||
var make_directory = require('src/directory').make_directory;
|
||||
var remove_directory = require('src/directory').remove_directory;
|
||||
|
||||
/*
|
||||
* FileSystem
|
||||
*/
|
||||
|
||||
function FileSystem(name, flags) {
|
||||
var format = _(flags).contains(FS_FORMAT);
|
||||
var that = this;
|
||||
|
||||
var deferred = when.defer();
|
||||
this.promise = deferred.promise;
|
||||
|
||||
var openRequest = indexedDB.open(name);
|
||||
openRequest.onupgradeneeded = function onupgradeneeded(event) {
|
||||
var db = event.target.result;
|
||||
|
||||
if(db.objectStoreNames.contains(FILE_STORE_NAME)) {
|
||||
db.deleteObjectStore(FILE_STORE_NAME);
|
||||
}
|
||||
var files = db.createObjectStore(FILE_STORE_NAME);
|
||||
|
||||
if(db.objectStoreNames.contains(METADATA_STORE_NAME)) {
|
||||
db.deleteObjectStore(METADATA_STORE_NAME);
|
||||
}
|
||||
var metadata = db.createObjectStore(METADATA_STORE_NAME);
|
||||
|
||||
format = true;
|
||||
};
|
||||
openRequest.onsuccess = function onsuccess(event) {
|
||||
var db = event.target.result;
|
||||
|
||||
function complete(error) {
|
||||
if(error) {
|
||||
that.readyState = FS_ERROR;
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
that.readyState = FS_READY;
|
||||
that.db = db;
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
if(format) {
|
||||
var transaction = db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||
|
||||
var clearRequest = files.clear();
|
||||
clearRequest.onsuccess = function onsuccess(event) {
|
||||
make_root_directory(files, complete);
|
||||
};
|
||||
clearRequest.onerror = function onerror(error) {
|
||||
complete(error);
|
||||
};
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
};
|
||||
openRequest.onerror = function onerror(error) {
|
||||
this.readyState = FS_ERROR;
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
this.readyState = FS_PENDING;
|
||||
this.db = null;
|
||||
};
|
||||
FileSystem.prototype.open = function open(path, flags, mode) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.opendir = function opendir(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.mkdir = function mkdir(path) {
|
||||
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) {
|
||||
if(error) {
|
||||
transaction.abort();
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
make_directory(files, path, check_result);
|
||||
return deferred.promise;
|
||||
};
|
||||
FileSystem.prototype.rmdir = function rmdir(path) {
|
||||
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) {
|
||||
if(error) {
|
||||
transaction.abort();
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
remove_directory(files, path, check_result);
|
||||
return deferred.promise;
|
||||
};
|
||||
FileSystem.prototype.stat = function stat(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.link = function link(oldpath, newpath) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.unlink = function unlink(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.getxattr = function getxattr(path, name) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.setxattr = function setxattr(path, name, value) {
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
FileSystem: FileSystem,
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,28 @@
|
|||
define(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,
|
||||
};
|
||||
|
||||
});
|
482
src/fs2.js
482
src/fs2.js
|
@ -1,482 +0,0 @@
|
|||
define(function(require) {
|
||||
|
||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
|
||||
var _ = require('lodash');
|
||||
var when = require('when');
|
||||
var Path = require('src/path');
|
||||
var guid = require('src/guid');
|
||||
require("crypto-js/rollups/sha256"); var Crypto = CryptoJS;
|
||||
|
||||
function EPathExists(){ Error.apply(this, arguments); }
|
||||
EPathExists.prototype = new Error();
|
||||
EPathExists.prototype.name = "EPathExists";
|
||||
EPathExists.prototype.constructor = EPathExists;
|
||||
|
||||
function EIsDirectory(){ Error.apply(this, arguments); }
|
||||
EIsDirectory.prototype = new Error();
|
||||
EIsDirectory.prototype.name = "EIsDirectory";
|
||||
EIsDirectory.prototype.constructor = EIsDirectory;
|
||||
|
||||
function ENoEntry(){ Error.apply(this, arguments); }
|
||||
ENoEntry.prototype = new Error();
|
||||
ENoEntry.prototype.name = "ENoEntry";
|
||||
ENoEntry.prototype.constructor = ENoEntry;
|
||||
|
||||
function EBusy(){ Error.apply(this, arguments); }
|
||||
EBusy.prototype = new Error();
|
||||
EBusy.prototype.name = "EBusy";
|
||||
EBusy.prototype.constructor = EBusy;
|
||||
|
||||
function ENotEmpty(){ Error.apply(this, arguments); }
|
||||
ENotEmpty.prototype = new Error();
|
||||
ENotEmpty.prototype.name = "ENotEmpty";
|
||||
ENotEmpty.prototype.constructor = ENotEmpty;
|
||||
|
||||
function ENotDirectory(){ Error.apply(this, arguments); }
|
||||
ENotDirectory.prototype = new Error();
|
||||
ENotDirectory.prototype.name = "NotADirectoryError";
|
||||
ENotDirectory.prototype.constructor = ENotDirectory;
|
||||
|
||||
function EBadFileDescriptor(){ Error.apply(this, arguments); }
|
||||
EBadFileDescriptor.prototype = new Error();
|
||||
EBadFileDescriptor.prototype.name = "EBadFileDescriptor";
|
||||
EBadFileDescriptor.prototype.constructor = EBadFileDescriptor;
|
||||
|
||||
function ENotImplemented(){ Error.apply(this, arguments); }
|
||||
ENotImplemented.prototype = new Error();
|
||||
ENotImplemented.prototype.name = "ENotImplemented";
|
||||
ENotImplemented.prototype.constructor = ENotImplemented;
|
||||
|
||||
function ENotMounted(){ Error.apply(this, arguments); }
|
||||
ENotMounted.prototype = new Error();
|
||||
ENotMounted.prototype.name = "ENotMounted";
|
||||
ENotMounted.prototype.constructor = ENotMounted;
|
||||
|
||||
function EFileExists(){ Error.apply(this, arguments); }
|
||||
EFileExists.prototype = new Error();
|
||||
EFileExists.prototype.name = "EFileExists";
|
||||
EFileExists.prototype.constructor = EFileExists;
|
||||
|
||||
var METADATA_STORE_NAME = 'metadata';
|
||||
var FILE_STORE_NAME = 'files';
|
||||
|
||||
var IDB_RO = 'readonly';
|
||||
var IDB_RW = 'readwrite';
|
||||
|
||||
var MODE_FILE = 'FILE';
|
||||
var MODE_DIRECTORY = 'DIRECTORY';
|
||||
var MODE_SYMBOLIC_LINK = 'SYMLINK';
|
||||
|
||||
var BINARY_MIME_TYPE = 'application/octet-stream';
|
||||
var JSON_MIME_TYPE = 'application/json';
|
||||
|
||||
var ROOT_DIRECTORY_NAME = '/'; // basename(normalize(path))
|
||||
var ROOT_NODE_ID = '8a5edab282632443219e051e4ade2d1d5bbc671c781051bf1437897cbdfea0f1'; // sha256(ROOT_DIRECTORY_NAME)
|
||||
|
||||
// FileSystem flags
|
||||
var FS_FORMAT = 'FORMAT';
|
||||
|
||||
// FileSystem readyState
|
||||
var FS_READY = 'READY';
|
||||
var FS_PENDING = 'PENDING';
|
||||
var FS_ERROR = 'ERROR';
|
||||
|
||||
function nop() {};
|
||||
|
||||
function hash(string) {
|
||||
return Crypto.SHA256(string).toString(Crypto.enc.hex);
|
||||
};
|
||||
|
||||
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
|
||||
};
|
||||
|
||||
function DirectoryEntry(id, type) {
|
||||
this.id = id;
|
||||
this.type = type || MODE_FILE;
|
||||
};
|
||||
|
||||
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);
|
||||
};
|
||||
};
|
||||
|
||||
// in: file or directory path
|
||||
// out: node structure, or error
|
||||
function find_node(objectStore, path, callback) {
|
||||
path = Path.normalize(path);
|
||||
var name = Path.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 = Path.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;
|
||||
var directoryData;
|
||||
|
||||
function write_directory_node(error, existingNode) {
|
||||
if(!error && existingNode) {
|
||||
callback(new EPathExists());
|
||||
} else if(error && !error instanceof ENoEntry) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryNode = new Node(ROOT_NODE_ID, MODE_DIRECTORY);
|
||||
directoryNode.links += 1;
|
||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
write_object(objectStore, directoryData, directoryNode.data, callback);
|
||||
}
|
||||
};
|
||||
|
||||
find_node(objectStore, ROOT_DIRECTORY_NAME, write_directory_node);
|
||||
}
|
||||
|
||||
function make_directory(objectStore, path, callback) {
|
||||
path = Path.normalize(path);
|
||||
var name = Path.basename(path);
|
||||
var parentPath = Path.dirname(path);
|
||||
|
||||
var directoryNode;
|
||||
var directoryData;
|
||||
var parentDirectoryNode;
|
||||
var parentDirectoryData;
|
||||
|
||||
function check_if_directory_exists(error, result) {
|
||||
if(!error && result) {
|
||||
callback(new EPathExists());
|
||||
} else if(error && !error instanceof ENoEntry) {
|
||||
callback(error);
|
||||
} else {
|
||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||
}
|
||||
}
|
||||
|
||||
function read_parent_directory_data(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
read_object(objectStore, parentDirectoryNode.data, write_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_node(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData = result;
|
||||
directoryNode = new Node(undefined, MODE_DIRECTORY);
|
||||
directoryNode.links += 1;
|
||||
write_object(objectStore, directoryNode, directoryNode.id, write_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function write_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = {};
|
||||
write_object(objectStore, directoryData, directoryNode.data, update_parent_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function update_parent_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData[name] = new DirectoryEntry(directoryNode.id, MODE_DIRECTORY);
|
||||
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, callback);
|
||||
}
|
||||
}
|
||||
|
||||
find_node(objectStore, path, check_if_directory_exists);
|
||||
};
|
||||
|
||||
function remove_directory(objectStore, path, callback) {
|
||||
path = Path.normalize(path);
|
||||
var name = Path.basename(path);
|
||||
var parentPath = Path.dirname(path);
|
||||
|
||||
var directoryNode;
|
||||
var directoryData;
|
||||
var parentDirectoryNode;
|
||||
var parentDirectoryData;
|
||||
|
||||
function check_if_directory_exists(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else if(!result) {
|
||||
callback(new ENoEntry());
|
||||
} else {
|
||||
directoryNode = result;
|
||||
read_object(objectStore, directoryNode.data, check_if_directory_is_empty);
|
||||
}
|
||||
}
|
||||
|
||||
function check_if_directory_is_empty(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
directoryData = result;
|
||||
if(_(directoryData).size() > 0) {
|
||||
callback(new ENotEmpty());
|
||||
} else {
|
||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function read_parent_directory_data(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryNode = result;
|
||||
read_object(objectStore, parentDirectoryNode.data, remove_directory_entry_from_parent_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_entry_from_parent_directory_node(error, result) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
parentDirectoryData = result;
|
||||
delete parentDirectoryData[name];
|
||||
write_object(objectStore, parentDirectoryData, parentDirectoryNode.data, remove_directory_node);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_node(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
delete_object(objectStore, directoryNode.id, remove_directory_data);
|
||||
}
|
||||
};
|
||||
|
||||
function remove_directory_data(error) {
|
||||
if(error) {
|
||||
callback(error);
|
||||
} else {
|
||||
delete_object(objectStore, directoryNode.data, callback);
|
||||
}
|
||||
};
|
||||
|
||||
find_node(objectStore, path, check_if_directory_exists);
|
||||
};
|
||||
|
||||
/*
|
||||
* FileSystem
|
||||
*/
|
||||
|
||||
function FileSystem(name, flags) {
|
||||
var format = _(flags).contains(FS_FORMAT);
|
||||
var that = this;
|
||||
|
||||
var deferred = when.defer();
|
||||
this.promise = deferred.promise;
|
||||
|
||||
var openRequest = indexedDB.open(name);
|
||||
openRequest.onupgradeneeded = function onupgradeneeded(event) {
|
||||
var db = event.target.result;
|
||||
|
||||
if(db.objectStoreNames.contains(FILE_STORE_NAME)) {
|
||||
db.deleteObjectStore(FILE_STORE_NAME);
|
||||
}
|
||||
var files = db.createObjectStore(FILE_STORE_NAME);
|
||||
|
||||
if(db.objectStoreNames.contains(METADATA_STORE_NAME)) {
|
||||
db.deleteObjectStore(METADATA_STORE_NAME);
|
||||
}
|
||||
var metadata = db.createObjectStore(METADATA_STORE_NAME);
|
||||
|
||||
format = true;
|
||||
};
|
||||
openRequest.onsuccess = function onsuccess(event) {
|
||||
var db = event.target.result;
|
||||
|
||||
function complete(error) {
|
||||
if(error) {
|
||||
that.readyState = FS_ERROR;
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
that.readyState = FS_READY;
|
||||
that.db = db;
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
if(format) {
|
||||
var transaction = db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||
|
||||
var clearRequest = files.clear();
|
||||
clearRequest.onsuccess = function onsuccess(event) {
|
||||
make_root_directory(files, complete);
|
||||
};
|
||||
clearRequest.onerror = function onerror(error) {
|
||||
complete(error);
|
||||
};
|
||||
} else {
|
||||
complete();
|
||||
}
|
||||
};
|
||||
openRequest.onerror = function onerror(error) {
|
||||
this.readyState = FS_ERROR;
|
||||
deferred.reject(error);
|
||||
};
|
||||
|
||||
this.readyState = FS_PENDING;
|
||||
this.db = null;
|
||||
};
|
||||
FileSystem.prototype.open = function open(path, flags, mode) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.opendir = function opendir(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.mkdir = function mkdir(path) {
|
||||
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) {
|
||||
if(error) {
|
||||
transaction.abort();
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
make_directory(files, path, check_result);
|
||||
return deferred.promise;
|
||||
};
|
||||
FileSystem.prototype.rmdir = function rmdir(path) {
|
||||
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) {
|
||||
if(error) {
|
||||
transaction.abort();
|
||||
deferred.reject(error);
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
};
|
||||
|
||||
remove_directory(files, path, check_result);
|
||||
return deferred.promise;
|
||||
};
|
||||
FileSystem.prototype.stat = function stat(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.link = function link(oldpath, newpath) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.unlink = function unlink(path) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.getxattr = function getxattr(path, name) {
|
||||
|
||||
};
|
||||
FileSystem.prototype.setxattr = function setxattr(path, name, value) {
|
||||
|
||||
};
|
||||
|
||||
return {
|
||||
FileSystem: FileSystem,
|
||||
};
|
||||
|
||||
});
|
17
src/guid.js
17
src/guid.js
|
@ -1,17 +0,0 @@
|
|||
if ( typeof define !== "function" ) {
|
||||
var define = require( "amdefine" )( module );
|
||||
}
|
||||
|
||||
define( function ( require ) {
|
||||
"use strict";
|
||||
|
||||
function guid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
||||
return v.toString(16);
|
||||
}).toUpperCase();
|
||||
}
|
||||
|
||||
return guid;
|
||||
|
||||
});
|
320
src/indexeddb.js
320
src/indexeddb.js
|
@ -1,320 +0,0 @@
|
|||
define(function(require) {
|
||||
|
||||
var when = require('when');
|
||||
|
||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
|
||||
function Event(idbEvent, target) {
|
||||
this._event = idbEvent;
|
||||
this.type = idbEvent.type;
|
||||
this.timeStamp = idbEvent.timeStamp;
|
||||
this.target = target || idbEvent.target;
|
||||
};
|
||||
|
||||
function Target(idbTarget, result) {
|
||||
this.idbTarget = idbTarget;
|
||||
this.result = result || idbTarget.result;
|
||||
};
|
||||
|
||||
/*
|
||||
* Cursor
|
||||
*/
|
||||
|
||||
function Cursor(idbCursor) {
|
||||
this.idbCursor = idbCursor;
|
||||
|
||||
Object.defineProperty(this, 'source', {
|
||||
get: function() {
|
||||
return idbCursor.source;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'direction', {
|
||||
get: function() {
|
||||
return idbCursor.direction;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'key', {
|
||||
get: function() {
|
||||
return idbCursor.key;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'primaryKey', {
|
||||
get: function() {
|
||||
return idbCursor.primaryKey;
|
||||
}
|
||||
});
|
||||
};
|
||||
Cursor.prototype.update = function update(value) {
|
||||
var idbCursor = this.idbCursor;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbCursor.update(value);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
Cursor.prototype.advance = function advance(count) {
|
||||
var idbCursor = this.idbCursor;
|
||||
return idbCursor.advance(count);
|
||||
};
|
||||
Cursor.prototype.continue = function continue(key) {
|
||||
var idbCursor = this.idbCursor;
|
||||
return idbCursor.continue(key);
|
||||
};
|
||||
Cursor.prototype.delete = function delete() {
|
||||
var idbCursor = this.idbCursor;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbCursor.delete();
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/*
|
||||
* ObjectStore
|
||||
*/
|
||||
|
||||
function ObjectStore(idbTransaction, name) {
|
||||
this.idbObjectStore = idbTransaction.objectStore(name);
|
||||
};
|
||||
ObjectStore.prototype.add = function add(value, key) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.add(value, key);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.clear = function clear() {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.clear();
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.count = function count(key) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.count(key);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.createIndex = function createIndex(name, keyPath, optionalParameters) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
return idbObjectStore.createIndex(name, keyPath, optionalParameters);
|
||||
};
|
||||
ObjectStore.prototype.delete = function delete(key) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.delete(key);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.deleteIndex = function deleteIndex(name) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
return idbObjectStore.deleteIndex(name);
|
||||
};
|
||||
ObjectStore.prototype.get = function get(key) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.get(key);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.index = function index(name) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
return idbObjectStore.index(name);
|
||||
};
|
||||
ObjectStore.prototype.openCursor = function openCursor(range, direction) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = (!(range || direction)) ? idbObjectStore.openCursor() : idbObjectStore.openCursor(range, direction);
|
||||
request.onsuccess = function(event) {
|
||||
var wrappedEvent = new Event(event);
|
||||
wrappedEvent.result = event.result;
|
||||
if(!event.result) {
|
||||
deferred.resolve(wrappedEvent);
|
||||
} else {
|
||||
deferred.notify(wrappedEvent);
|
||||
}
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
ObjectStore.prototype.put = function put(value, key) {
|
||||
var idbObjectStore = this.idbObjectStore;
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = idbObjectStore.put(value, key);
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
/*
|
||||
* Transaction
|
||||
*/
|
||||
|
||||
function Transaction(idbDatabase, storeNames, mode) {
|
||||
this.idbTransaction = idbDatabase.transaction(storeNames, mode);
|
||||
};
|
||||
Transaction.prototype.objectStore = function objectStore(name) {
|
||||
var idbTransaction = this.idbTransaction;
|
||||
return new ObjectStore(idbTransaction, name);
|
||||
};
|
||||
Transaction.prototype.abort = function abort() {
|
||||
var idbTransaction = this.idbTransaction;
|
||||
return idbTransaction.abort();
|
||||
};
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
|
||||
function Database(idbDatabase) {
|
||||
this.idbDatabase = idbDatabase;
|
||||
|
||||
Object.defineProperty(this, 'name', {
|
||||
get: function() {
|
||||
return idbDatabase.name;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'version', {
|
||||
get: function() {
|
||||
return idbDatabase.version;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'objectStoreNames', {
|
||||
get: function() {
|
||||
return idbDatabase.objectStoreNames;
|
||||
}
|
||||
});
|
||||
};
|
||||
Database.prototype.createObjectStore = function createObjectStore(name, optionalParameters) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.createObjectStore(name, optionalParameters);
|
||||
};
|
||||
Database.prototype.deleteObjectStore = function deleteObjectStore(name) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.deleteObjectStore(name);
|
||||
};
|
||||
Database.prototype.transaction = function transaction(storeNames, mode) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return new Transaction(idbDatabase, storeNames, mode);
|
||||
};
|
||||
Database.prototype.close = function close() {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.close();
|
||||
};
|
||||
Database.prototype.objectStoreNames = function objectStoreNames() {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.objectStoreNames;
|
||||
};
|
||||
|
||||
/*
|
||||
* Factory
|
||||
*/
|
||||
|
||||
function open(name, version) {
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = indexedDB.open(name);
|
||||
request.onupgradeneeded = function(event) {
|
||||
var wrappedEvent = new Event(event, new Target(event.target, new Database(event.target.result)));
|
||||
deferred.notify(wrappedEvent);
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
var wrappedEvent = new Event(event, new Target(event.target, new Database(event.target.result)));
|
||||
deferred.resolve(wrappedEvent);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
function deleteDatabase(name) {
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = indexedDB.deleteDatabase(name);
|
||||
request.onupgradeneeded = function(event) {
|
||||
deferred.notify(event);
|
||||
};
|
||||
request.onsuccess = function(event) {
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(event) {
|
||||
deferred.reject(event);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
return {
|
||||
open: open,
|
||||
deleteDatabase: deleteDatabase,
|
||||
KeyRange: indexedDB.KeyRange,
|
||||
when: when,
|
||||
};
|
||||
|
||||
});
|
|
@ -1,108 +0,0 @@
|
|||
define(function(require) {
|
||||
|
||||
var when = require('when');
|
||||
|
||||
var indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
||||
|
||||
/*
|
||||
* Transaction
|
||||
*/
|
||||
|
||||
function Transaction(idbDatabase, storeNames, mode) {
|
||||
this.idbTransaction = idbDatabase.transaction(storeNames, mode);
|
||||
};
|
||||
Transaction.prototype.objectStore = function objectStore(name) {
|
||||
var idbTransaction = this.idbTransaction;
|
||||
return new ObjectStore(idbTransaction, name);
|
||||
};
|
||||
Transaction.prototype.abort = function abort() {
|
||||
var idbTransaction = this.idbTransaction;
|
||||
return idbTransaction.abort();
|
||||
};
|
||||
|
||||
/*
|
||||
* Database
|
||||
*/
|
||||
|
||||
function Database(idbDatabase) {
|
||||
this.idbDatabase = idbDatabase;
|
||||
|
||||
Object.defineProperty(this, 'name', {
|
||||
get: function() {
|
||||
return idbDatabase.name;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'version', {
|
||||
get: function() {
|
||||
return idbDatabase.version;
|
||||
}
|
||||
});
|
||||
|
||||
Object.defineProperty(this, 'objectStoreNames', {
|
||||
get: function() {
|
||||
return idbDatabase.objectStoreNames;
|
||||
}
|
||||
});
|
||||
};
|
||||
Database.prototype.createObjectStore = function createObjectStore(name, optionalParameters) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.createObjectStore(name, optionalParameters);
|
||||
};
|
||||
Database.prototype.deleteObjectStore = function deleteObjectStore(name) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.deleteObjectStore(name);
|
||||
};
|
||||
Database.prototype.transaction = function transaction(storeNames, mode) {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return new Transaction(idbDatabase, storeNames, mode);
|
||||
};
|
||||
Database.prototype.close = function close() {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.close();
|
||||
};
|
||||
Database.prototype.objectStoreNames = function objectStoreNames() {
|
||||
var idbDatabase = this.idbDatabase;
|
||||
return idbDatabase.objectStoreNames;
|
||||
};
|
||||
|
||||
/*
|
||||
* Factory
|
||||
*/
|
||||
|
||||
function Factory() {
|
||||
this.when = when;
|
||||
};
|
||||
Factory.prototype.open = function open(name, version) {
|
||||
var deferred = when.defer();
|
||||
|
||||
var request = indexedDB.open(name);
|
||||
request.onupgradeneeded = function(idbEvent) {
|
||||
var db = new Database(idbEvent.target.result);
|
||||
var event = {
|
||||
type: 'upgradeneeded',
|
||||
db: db
|
||||
};
|
||||
deferred.notify(event);
|
||||
};
|
||||
request.onsuccess = function(idbEvent) {
|
||||
var db = new Database(idbEvent.target.result);
|
||||
var event = {
|
||||
type: 'success',
|
||||
db: db
|
||||
};
|
||||
deferred.resolve(event);
|
||||
};
|
||||
request.onerror = function(idbError) {
|
||||
deferred.reject(idbError);
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
Factory.prototype.deleteDatabase = function deleteDatabase(name) {
|
||||
|
||||
};
|
||||
|
||||
return new Factory();
|
||||
|
||||
});
|
|
@ -0,0 +1,42 @@
|
|||
define(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,
|
||||
};
|
||||
|
||||
});
|
|
@ -0,0 +1,24 @@
|
|||
define(function(require) {
|
||||
|
||||
require("crypto-js/rollups/sha256"); var Crypto = CryptoJS;
|
||||
|
||||
function guid() {
|
||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
||||
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
|
||||
return v.toString(16);
|
||||
}).toUpperCase();
|
||||
};
|
||||
|
||||
function hash(string) {
|
||||
return Crypto.SHA256(string).toString(Crypto.enc.hex);
|
||||
};
|
||||
|
||||
function nop() {};
|
||||
|
||||
return {
|
||||
guid: guid,
|
||||
hash: hash,
|
||||
nop: nop,
|
||||
};
|
||||
|
||||
});
|
Loading…
Reference in New Issue