From e690ed5292e485f2599cd82e1291f5588dc47ad3 Mon Sep 17 00:00:00 2001 From: Alan Kligman Date: Fri, 26 Jul 2013 00:15:48 -0400 Subject: [PATCH] Unlink implementation and tests. --- dist/idbfs.js | 69 ++++++++++++++++++++++++++++++---- examples/refactoring-test.html | 4 +- src/file-system.js | 69 ++++++++++++++++++++++++++++++---- tests/spec/idbfs.spec.js | 48 ++++++++++++++++++++++- 4 files changed, 173 insertions(+), 17 deletions(-) diff --git a/dist/idbfs.js b/dist/idbfs.js index 9e7184d..5ad51c3 100644 --- a/dist/idbfs.js +++ b/dist/idbfs.js @@ -6388,7 +6388,6 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p var oldDirectoryData; var newDirectoryNode; var newDirectoryData; - var directoryEntry; var fileNode; find_node(objectStore, oldParentPath, read_old_directory_data); @@ -6442,16 +6441,51 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p if(error) { callback(error); } else { - read_object(objectStore, newDirectoryData[newname].id, read_file_node); + read_object(objectStore, newDirectoryData[newname].id, update_file_node); } } - function read_file_node(error, result) { + function update_file_node(error, result) { if(error) { callback(error); } else { - directoryEntry = result; - read_object(objectStore, directoryEntry.id, update_file_node); + fileNode = result; + fileNode.nlinks += 1 + write_object(objectStore, fileNode, fileNode.id, callback); + } + }; + }; + + function unlink_node(objectStore, path, callback) { + path = normalize(path); + name = basename(path); + parentPath = dirname(path); + + var directoryNode; + var directoryData; + var fileNode; + + find_node(objectStore, parentPath, read_directory_data); + + function read_directory_data(error, result) { + if(error) { + callback(error); + } else { + directoryNode = result; + read_object(objectStore, directoryNode.data, check_if_file_exists); + } + }; + + function check_if_file_exists(error, result) { + if(error) { + callback(error); + } else { + directoryData = result; + if(!_(directoryData).has(name)) { + callback(new ENoEntry('a component of the path does not name an existing file')); + } else { + read_object(objectStore, directoryData[name].id, update_file_node); + } } }; @@ -6460,10 +6494,31 @@ define('src/file-system',['require','lodash','when','src/path','src/path','src/p callback(error); } else { fileNode = result; - fileNode.nlinks += 1 - write_object(objectStore, fileNode, directoryEntry.id, callback); + fileNode.nlinks -= 1; + if(fileNode.nlinks < 1) { + delete_object(objectStore, fileNode.id, delete_file_data); + } else { + write_object(objectStore, fileNode, fileNode.id, update_directory_data); + } } }; + + function delete_file_data(error) { + if(error) { + callback(error); + } else { + delete_object(objectStore, fileNode.data, update_directory_data); + } + }; + + function update_directory_data(error) { + if(error) { + callback(error); + } else { + delete directoryData[name]; + write_object(objectStore, directoryData, directoryNode.data, callback); + } + } }; /* diff --git a/examples/refactoring-test.html b/examples/refactoring-test.html index 880a7c3..fa5bcc3 100644 --- a/examples/refactoring-test.html +++ b/examples/refactoring-test.html @@ -37,9 +37,9 @@ fs.open('/myfile', 'w+', function(error, fd) { fs.link('/myfile', '/myotherfile', function(error) { if(error) throw error; console.log('linked'); - fs.stat('/myfile', function(error, stats) { + fs.unlink('/myfile', function(error) { if(error) throw error; - console.log(stats); + console.log('unlinked'); }); }); }); diff --git a/src/file-system.js b/src/file-system.js index 060821e..72eac26 100644 --- a/src/file-system.js +++ b/src/file-system.js @@ -588,7 +588,6 @@ define(function(require) { var oldDirectoryData; var newDirectoryNode; var newDirectoryData; - var directoryEntry; var fileNode; find_node(objectStore, oldParentPath, read_old_directory_data); @@ -642,16 +641,51 @@ define(function(require) { if(error) { callback(error); } else { - read_object(objectStore, newDirectoryData[newname].id, read_file_node); + read_object(objectStore, newDirectoryData[newname].id, update_file_node); } } - function read_file_node(error, result) { + function update_file_node(error, result) { if(error) { callback(error); } else { - directoryEntry = result; - read_object(objectStore, directoryEntry.id, update_file_node); + fileNode = result; + fileNode.nlinks += 1 + write_object(objectStore, fileNode, fileNode.id, callback); + } + }; + }; + + function unlink_node(objectStore, path, callback) { + path = normalize(path); + name = basename(path); + parentPath = dirname(path); + + var directoryNode; + var directoryData; + var fileNode; + + find_node(objectStore, parentPath, read_directory_data); + + function read_directory_data(error, result) { + if(error) { + callback(error); + } else { + directoryNode = result; + read_object(objectStore, directoryNode.data, check_if_file_exists); + } + }; + + function check_if_file_exists(error, result) { + if(error) { + callback(error); + } else { + directoryData = result; + if(!_(directoryData).has(name)) { + callback(new ENoEntry('a component of the path does not name an existing file')); + } else { + read_object(objectStore, directoryData[name].id, update_file_node); + } } }; @@ -660,10 +694,31 @@ define(function(require) { callback(error); } else { fileNode = result; - fileNode.nlinks += 1 - write_object(objectStore, fileNode, directoryEntry.id, callback); + fileNode.nlinks -= 1; + if(fileNode.nlinks < 1) { + delete_object(objectStore, fileNode.id, delete_file_data); + } else { + write_object(objectStore, fileNode, fileNode.id, update_directory_data); + } } }; + + function delete_file_data(error) { + if(error) { + callback(error); + } else { + delete_object(objectStore, fileNode.data, update_directory_data); + } + }; + + function update_directory_data(error) { + if(error) { + callback(error); + } else { + delete directoryData[name]; + write_object(objectStore, directoryData, directoryNode.data, callback); + } + } }; /* diff --git a/tests/spec/idbfs.spec.js b/tests/spec/idbfs.spec.js index 438fd1b..638049c 100644 --- a/tests/spec/idbfs.spec.js +++ b/tests/spec/idbfs.spec.js @@ -810,4 +810,50 @@ describe('fs.unlink', function() { it('should be a function', function() { expect(typeof this.fs.unlink).toEqual('function'); }); -}); \ No newline at end of file + + it('should remove a link to an existing file', function() { + var complete1 = false; + var complete2 = false; + var _error, _stats; + var that = this; + + that.fs.open('/myfile', 'w+', function(error, result) { + if(error) throw error; + + var fd = result; + that.fs.close(fd, function(error) { + if(error) throw error; + + that.fs.link('/myfile', '/myotherfile', function(error) { + if(error) throw error; + + that.fs.unlink('/myfile', function(error) { + if(error) throw error; + + that.fs.stat('/myfile', function(error, result) { + _error = error; + complete1 = true; + }); + + that.fs.stat('/myotherfile', function(error, result) { + if(error) throw error; + + _stats = result; + complete2 = true; + }); + }); + }); + }); + }); + + waitsFor(function() { + return complete1 && complete2; + }, 'test to complete', DEFAULT_TIMEOUT); + + runs(function() { + expect(_error).toBeDefined(); + expect(_error).toBeDefined(); + expect(_stats.nlinks).toEqual(1); + }); + }); +});