Stat implementation, updated tests.
This commit is contained in:
parent
19b21e10de
commit
c3c9751ff4
File diff suppressed because it is too large
Load Diff
|
@ -18,15 +18,25 @@ require.config({
|
||||||
require(["src/file-system"], function(IDBFS) {
|
require(["src/file-system"], function(IDBFS) {
|
||||||
|
|
||||||
var flags = 'FORMAT';
|
var flags = 'FORMAT';
|
||||||
//var flags = undefined;
|
//var flags;
|
||||||
|
|
||||||
var fs = new IDBFS.FileSystem('local', flags);
|
var fs = new IDBFS.FileSystem('local', flags);
|
||||||
fs.promise.otherwise(
|
fs.stat('/', function(error, result) {
|
||||||
function(error) {
|
console.log('stat /', error, result);
|
||||||
console.error(error);
|
});
|
||||||
}
|
fs.stat('/tmp', function(error, result) {
|
||||||
);
|
console.log('stat /tmp', error, result);
|
||||||
|
});
|
||||||
|
/*
|
||||||
|
fs.mkdir('/tmp', function(error) {
|
||||||
|
if(error) throw error;
|
||||||
|
fs.stat('/tmp', function(error, result) {
|
||||||
|
console.log('stat /tmp', error, result);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
function make_tmp_directory() {
|
function make_tmp_directory() {
|
||||||
return fs.mkdir('/tmp');
|
return fs.mkdir('/tmp');
|
||||||
};
|
};
|
||||||
|
@ -69,7 +79,7 @@ fs.promise.then(make_tmp_directory)
|
||||||
.then(write_data)
|
.then(write_data)
|
||||||
.then(function() { console.log('done'); })
|
.then(function() { console.log('done'); })
|
||||||
.otherwise(function(error) { console.error(error, error.message, error.stack); });
|
.otherwise(function(error) { console.error(error, error.message, error.stack); });
|
||||||
|
*/
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -91,6 +91,13 @@ define(function(require) {
|
||||||
EIO.prototype.name = "EIO";
|
EIO.prototype.name = "EIO";
|
||||||
EIO.prototype.constructor = EIO;
|
EIO.prototype.constructor = EIO;
|
||||||
|
|
||||||
|
function EFileSystemError(message){
|
||||||
|
this.message = message || '';
|
||||||
|
};
|
||||||
|
EFileSystemError.prototype = new Error();
|
||||||
|
EFileSystemError.prototype.name = "EFileSystemError";
|
||||||
|
EFileSystemError.prototype.constructor = EFileSystemError;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
EExists: EExists,
|
EExists: EExists,
|
||||||
EIsDirectory: EIsDirectory,
|
EIsDirectory: EIsDirectory,
|
||||||
|
|
|
@ -24,6 +24,7 @@ define(function(require) {
|
||||||
var ENotMounted = require('src/error').ENotMounted;
|
var ENotMounted = require('src/error').ENotMounted;
|
||||||
var EInvalid = require('src/error').EInvalid;
|
var EInvalid = require('src/error').EInvalid;
|
||||||
var EIO = require('src/error').EIO;
|
var EIO = require('src/error').EIO;
|
||||||
|
var EFileSystemError = require('src/error').EFileSystemError;
|
||||||
|
|
||||||
var FS_FORMAT = require('src/constants').FS_FORMAT;
|
var FS_FORMAT = require('src/constants').FS_FORMAT;
|
||||||
var MODE_FILE = require('src/constants').MODE_FILE;
|
var MODE_FILE = require('src/constants').MODE_FILE;
|
||||||
|
@ -34,7 +35,7 @@ define(function(require) {
|
||||||
var IDB_RO = require('src/constants').IDB_RO;
|
var IDB_RO = require('src/constants').IDB_RO;
|
||||||
var FILE_STORE_NAME = require('src/constants').FILE_STORE_NAME;
|
var FILE_STORE_NAME = require('src/constants').FILE_STORE_NAME;
|
||||||
var METADATA_STORE_NAME = require('src/constants').METADATA_STORE_NAME;
|
var METADATA_STORE_NAME = require('src/constants').METADATA_STORE_NAME;
|
||||||
var FS_READY = require('src/constants').READY;
|
var FS_READY = require('src/constants').FS_READY;
|
||||||
var FS_PENDING = require('src/constants').FS_PENDING;
|
var FS_PENDING = require('src/constants').FS_PENDING;
|
||||||
var FS_ERROR = require('src/constants').FS_ERROR;
|
var FS_ERROR = require('src/constants').FS_ERROR;
|
||||||
var O_READ = require('src/constants').O_READ;
|
var O_READ = require('src/constants').O_READ;
|
||||||
|
@ -81,7 +82,9 @@ define(function(require) {
|
||||||
this.xattrs = xattrs || {}; // extended attributes
|
this.xattrs = xattrs || {}; // extended attributes
|
||||||
this.nlinks = nlinks || 0; // links count
|
this.nlinks = nlinks || 0; // links count
|
||||||
this.version = version || 0; // node version
|
this.version = version || 0; // node version
|
||||||
this.data = hash(guid()) // id for data object
|
this.blksize = undefined; // block size
|
||||||
|
this.nblocks = 1; // blocks count
|
||||||
|
this.data = hash(guid()); // id for data object
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -96,6 +99,7 @@ define(function(require) {
|
||||||
return callback(new ENoEntry('path is an empty string'));
|
return callback(new ENoEntry('path is an empty string'));
|
||||||
}
|
}
|
||||||
var name = basename(path);
|
var name = basename(path);
|
||||||
|
var parentPath = dirname(path);
|
||||||
|
|
||||||
if(ROOT_DIRECTORY_NAME == name) {
|
if(ROOT_DIRECTORY_NAME == name) {
|
||||||
function check_root_directory_node(error, rootDirectoryNode) {
|
function check_root_directory_node(error, rootDirectoryNode) {
|
||||||
|
@ -137,7 +141,6 @@ define(function(require) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var parentPath = dirname(path);
|
|
||||||
find_node(objectStore, parentPath, read_parent_directory_data);
|
find_node(objectStore, parentPath, read_parent_directory_data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -538,6 +541,22 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function stat_file(objectStore, path, callback) {
|
||||||
|
path = normalize(path);
|
||||||
|
var name = basename(path);
|
||||||
|
var parentPath = dirname(path);
|
||||||
|
|
||||||
|
find_node(objectStore, path, check_file);
|
||||||
|
|
||||||
|
function check_file(error, result) {
|
||||||
|
if(error) {
|
||||||
|
callback(error);
|
||||||
|
} else {
|
||||||
|
callback(undefined, result);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FileSystem
|
* FileSystem
|
||||||
*/
|
*/
|
||||||
|
@ -606,6 +625,7 @@ define(function(require) {
|
||||||
this.db = null;
|
this.db = null;
|
||||||
this.nextDescriptor = nextDescriptor;
|
this.nextDescriptor = nextDescriptor;
|
||||||
this.openFiles = openFiles;
|
this.openFiles = openFiles;
|
||||||
|
this.name = name;
|
||||||
};
|
};
|
||||||
FileSystem.prototype._allocate_descriptor = function _allocate_descriptor(openFileDescription) {
|
FileSystem.prototype._allocate_descriptor = function _allocate_descriptor(openFileDescription) {
|
||||||
var fd = this.nextDescriptor ++;
|
var fd = this.nextDescriptor ++;
|
||||||
|
@ -615,7 +635,7 @@ define(function(require) {
|
||||||
FileSystem.prototype._release_descriptor = function _release_descriptor(fd) {
|
FileSystem.prototype._release_descriptor = function _release_descriptor(fd) {
|
||||||
delete this.openFiles[fd];
|
delete this.openFiles[fd];
|
||||||
};
|
};
|
||||||
FileSystem.prototype.open = function open(path, flags) {
|
FileSystem.prototype.open = function open(path, flags, callback) {
|
||||||
var that = this;
|
var that = this;
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
|
@ -644,11 +664,11 @@ define(function(require) {
|
||||||
flags = O_FLAGS[flags];
|
flags = O_FLAGS[flags];
|
||||||
}
|
}
|
||||||
|
|
||||||
open_file(this, files, path, flags, check_result);
|
|
||||||
|
|
||||||
return deferred.promise;
|
open_file(this, files, path, flags, check_result);
|
||||||
|
deferred.then(callback);
|
||||||
};
|
};
|
||||||
FileSystem.prototype.close = function close(fd) {
|
FileSystem.prototype.close = function close(fd, callback) {
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
|
|
||||||
if(!_(this.openFiles).has(fd)) {
|
if(!_(this.openFiles).has(fd)) {
|
||||||
|
@ -658,26 +678,41 @@ define(function(require) {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
return deferred.promise;
|
deferred.then(callback);
|
||||||
};
|
};
|
||||||
FileSystem.prototype.mkdir = function mkdir(path) {
|
FileSystem.prototype.mkdir = function mkdir(path, callback) {
|
||||||
var deferred = when.defer();
|
var that = this;
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
this.promise.then(
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
function() {
|
||||||
|
var deferred = when.defer();
|
||||||
|
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
function check_result(error) {
|
function check_result(error) {
|
||||||
if(error) {
|
if(error) {
|
||||||
// if(transaction.error) transaction.abort();
|
// if(transaction.error) transaction.abort();
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve();
|
deferred.resolve();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
make_directory(files, path, check_result);
|
||||||
|
deferred.promise.then(
|
||||||
|
function() {
|
||||||
|
callback();
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
callback(new EFileSystemError('unknown error'));
|
||||||
}
|
}
|
||||||
};
|
);
|
||||||
|
|
||||||
make_directory(files, path, check_result);
|
|
||||||
return deferred.promise;
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.rmdir = function rmdir(path) {
|
FileSystem.prototype.rmdir = function rmdir(path, callback) {
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
@ -692,27 +727,66 @@ define(function(require) {
|
||||||
};
|
};
|
||||||
|
|
||||||
remove_directory(files, path, check_result);
|
remove_directory(files, path, check_result);
|
||||||
return deferred.promise;
|
deferred.then(callback);
|
||||||
};
|
};
|
||||||
FileSystem.prototype.stat = function stat(path) {
|
FileSystem.prototype.readdir = function readdir(path, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.fstat = function fstat(fd) {
|
FileSystem.prototype.stat = function stat(path, callback) {
|
||||||
|
var that = this;
|
||||||
|
this.promise.then(
|
||||||
|
function() {
|
||||||
|
var deferred = when.defer();
|
||||||
|
var transaction = that.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
||||||
|
function check_result(error, result) {
|
||||||
|
if(error) {
|
||||||
|
// if(transaction.error) transaction.abort();
|
||||||
|
deferred.reject(error);
|
||||||
|
} else {
|
||||||
|
var stats = {
|
||||||
|
dev: that.name,
|
||||||
|
nlinks: result.nlinks,
|
||||||
|
atime: result.atime,
|
||||||
|
mtime: result.mtime,
|
||||||
|
ctime: result.ctime
|
||||||
|
};
|
||||||
|
deferred.resolve(stats);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
stat_file(files, path, check_result);
|
||||||
|
deferred.promise.then(
|
||||||
|
function(result) {
|
||||||
|
callback(undefined, result);
|
||||||
|
},
|
||||||
|
function(error) {
|
||||||
|
callback(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
function() {
|
||||||
|
callback(new EFileSystemError('unknown error'));
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
FileSystem.prototype.fstat = function fstat(fd, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.link = function link(oldpath, newpath) {
|
FileSystem.prototype.link = function link(oldpath, newpath, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.unlink = function unlink(path) {
|
FileSystem.prototype.unlink = function unlink(path, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.getxattr = function getxattr(path, name) {
|
FileSystem.prototype.getxattr = function getxattr(path, name, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.setxattr = function setxattr(path, name, value) {
|
FileSystem.prototype.setxattr = function setxattr(path, name, value, callback) {
|
||||||
|
|
||||||
};
|
};
|
||||||
FileSystem.prototype.read = function read(fd, buffer, offset, length, position) {
|
FileSystem.prototype.read = function read(fd, buffer, offset, length, position, callback) {
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
@ -722,6 +796,7 @@ define(function(require) {
|
||||||
|
|
||||||
function check_result(error, nbytes) {
|
function check_result(error, nbytes) {
|
||||||
if(error) {
|
if(error) {
|
||||||
|
// if(transaction.error) transaction.abort();
|
||||||
deferred.reject(error);
|
deferred.reject(error);
|
||||||
} else {
|
} else {
|
||||||
deferred.resolve(nbytes);
|
deferred.resolve(nbytes);
|
||||||
|
@ -742,7 +817,7 @@ define(function(require) {
|
||||||
|
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
FileSystem.prototype.write = function write(fd, buffer, offset, length, position) {
|
FileSystem.prototype.write = function write(fd, buffer, offset, length, position, callback) {
|
||||||
var deferred = when.defer();
|
var deferred = when.defer();
|
||||||
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
var transaction = this.db.transaction([FILE_STORE_NAME], IDB_RW);
|
||||||
var files = transaction.objectStore(FILE_STORE_NAME);
|
var files = transaction.objectStore(FILE_STORE_NAME);
|
||||||
|
|
|
@ -1,15 +1,130 @@
|
||||||
var TEST_DATABASE_NAME = 'test';
|
var TEST_DATABASE_NAME = 'test';
|
||||||
|
var DEFAULT_TIMEOUT = 5000;
|
||||||
|
|
||||||
describe("file system", function() {
|
var next_id = 1;
|
||||||
beforeEach(function() {
|
function mk_db_name() {
|
||||||
this.fs = new IDBFS.FileSystem(TEST_DATABASE_NAME, 'FORMAT');
|
return TEST_DATABASE_NAME + next_id++;
|
||||||
});
|
};
|
||||||
|
|
||||||
afterEach(function() {
|
describe("IDBFS", function() {
|
||||||
indexedDB.deleteDatabase(TEST_DATABASE_NAME);
|
it("is defined", function() {
|
||||||
});
|
expect(typeof IDBFS).not.toEqual(undefined);
|
||||||
|
});
|
||||||
|
|
||||||
it("is created", function() {
|
it("has FileSystem constructor", function() {
|
||||||
expect(typeof this.fs).toEqual('object');
|
expect(typeof IDBFS.FileSystem).toEqual('function');
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("new fs", function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.db_name = mk_db_name();
|
||||||
|
this.fs = new IDBFS.FileSystem(this.db_name, 'FORMAT');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
indexedDB.deleteDatabase(this.db_name);
|
||||||
|
delete this.fs;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("is an object", function() {
|
||||||
|
expect(typeof this.fs).toEqual('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
var api_methods = [
|
||||||
|
"mkdir",
|
||||||
|
"rmdir",
|
||||||
|
"readdir",
|
||||||
|
"link",
|
||||||
|
"unlink",
|
||||||
|
"open",
|
||||||
|
"close",
|
||||||
|
"read",
|
||||||
|
"write",
|
||||||
|
"setxattr",
|
||||||
|
"getxattr",
|
||||||
|
"stat",
|
||||||
|
"fstat",
|
||||||
|
];
|
||||||
|
|
||||||
|
api_methods.forEach(function(method) {
|
||||||
|
it("has method " + method, function() {
|
||||||
|
expect(typeof this.fs[method]).toEqual('function');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have a root directory', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
|
||||||
|
this.fs.stat('/', function(error, result) {
|
||||||
|
_error = error;
|
||||||
|
_result = result;
|
||||||
|
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'stat to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_result).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('stat', function() {
|
||||||
|
beforeEach(function() {
|
||||||
|
this.db_name = mk_db_name();
|
||||||
|
this.fs = new IDBFS.FileSystem(this.db_name, 'FORMAT');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(function() {
|
||||||
|
indexedDB.deleteDatabase(this.db_name);
|
||||||
|
delete this.fs;
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('on path that does not exist', function() {
|
||||||
|
it('should return an error', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
|
||||||
|
this.fs.stat('/tmp', function(error, result) {
|
||||||
|
_error = error;
|
||||||
|
_result = result;
|
||||||
|
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'stat to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_error).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not return a result', function() {
|
||||||
|
var complete = false;
|
||||||
|
var _error, _result;
|
||||||
|
|
||||||
|
this.fs.stat('/tmp', function(error, result) {
|
||||||
|
jasmine.log(error, result);
|
||||||
|
_error = error;
|
||||||
|
_result = result;
|
||||||
|
|
||||||
|
complete = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
waitsFor(function() {
|
||||||
|
return complete;
|
||||||
|
}, 'stat to complete', DEFAULT_TIMEOUT);
|
||||||
|
|
||||||
|
runs(function() {
|
||||||
|
expect(_result).not.toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
Loading…
Reference in New Issue