diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-10-09 11:06:44 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-10-09 11:06:44 +0000 |
| commit | 86bbe805a7ec49a8b891412713ea43d6e46d0d73 (patch) | |
| tree | d2f86a3934ce257cee5a5295f6c6a61d71ec87eb | |
| parent | add ba_log entry 2019-10-08 (diff) | |
| download | mmm-86bbe805a7ec49a8b891412713ea43d6e46d0d73.tar.gz mmm-86bbe805a7ec49a8b891412713ea43d6e46d0d73.zip | |
add lfs driver, spec
| -rw-r--r-- | mmm/mmmfs/drivers/lfs.moon | 157 | ||||
| -rw-r--r-- | mmm/mmmfs/drivers/sql.moon | 5 | ||||
| -rw-r--r-- | mmm/mmmfs/drivers/zip.moon | 59 | ||||
| -rw-r--r-- | spec/driver_spec.moon | 45 |
4 files changed, 194 insertions, 72 deletions
diff --git a/mmm/mmmfs/drivers/lfs.moon b/mmm/mmmfs/drivers/lfs.moon new file mode 100644 index 0000000..a90b55a --- /dev/null +++ b/mmm/mmmfs/drivers/lfs.moon @@ -0,0 +1,157 @@ +lfs = require 'lfs' + +-- split filename into dirname + basename +dir_base = (path) -> + dir, base = path\match '(.-)([^/]-)$' + if dir and #dir > 0 + dir = dir\sub 1, #dir - 1 + + dir, base + + +class LFSStore + new: (opts = {}) => + opts.root or= 'root' + opts.verbose or= false + + if not opts.verbose + @log = -> + + -- ensure path doesnt end with a slash + @root = opts.root\match '^(.-)/?$' + @log "opening '#{opts.root}'..." + + log: (...) => + print "[DB]", ... + + -- fileders + list_fileders_in: (path='') => + coroutine.wrap -> + for entry_name in lfs.dir @root .. path + continue if '.' == entry_name\sub 1, 1 + entry_path = @root .. "#{path}/#{entry_name}" + if 'directory' == lfs.attributes entry_path, 'mode' + coroutine.yield "#{path}/#{entry_name}" + + list_all_fileders: (path='') => + coroutine.wrap -> + for path in @list_fileders_in path + coroutine.yield path + for p in @list_all_fileders path + coroutine.yield p + + create_fileder: (parent, name) => + @log "creating fileder #{path}" + path = "#{parent}/#{name}" + assert lfs.mkdir @root .. path + path + + remove_fileder: (path) => + @log "removing fileder #{path}" + + rmdir = (path) -> + for file in lfs.dir path + continue if '.' == file\sub 1, 1 + + file_path = "#{path}/#{file}" + switch lfs.attributes file_path, 'mode' + when 'file' + assert os.remove file_path + when 'directory' + assert rmdir file_path + + lfs.rmdir path + + rmdir @root .. path + + rename_fileder: (path, next_name) => + @log "renaming fileder #{path} -> '#{next_name}'" + parent, name = dir_base path + assert os.rename path, @root .. "#{parent}/#{next_name}" + + move_fileder: (path, next_parent) => + @log "moving fileder #{path} -> #{next_parent}/" + parent, name = dir_base path + assert os.rename @root .. path, @root .. "#{next_parent}/#{name}" + + -- facets + list_facets: (path) => + coroutine.wrap -> + for entry_name in lfs.dir @root .. path + entry_path = "#{@root .. path}/#{entry_name}" + if 'file' == lfs.attributes entry_path, 'mode' + entry_name = (entry_name\match '(.*)%.%w+') or entry_name + entry_name = entry_name\gsub '%$', '/' + name, type = entry_name\match '(%w+): *(.+)' + if not name + name = '' + type = entry_name + + coroutine.yield name, type + + tofp: (path, name, type) => + type = "#{name}: #{type}" if #name > 0 + type = type\gsub '%/', '$' + @root .. "#{path}/#{type}" + + locate: (path, name, type) => + return unless lfs.attributes @root .. path, 'mode' + + type = type\gsub '%/', '$' + name = "#{name}: " if #name > 0 + name = name .. type + name = name\gsub '([^%w])', '%%%1' + + local file_name + for entry_name in lfs.dir @root .. path + if (entry_name\match "^#{name}$") or entry_name\match "^#{name}%.%w+$" + if file_name + error "two files match #{name}: #{file_name} and #{entry_name}!" + file_name = entry_name + + + file_name and @root .. "#{path}/#{file_name}" + + load_facet: (path, name, type) => + filepath = @locate path, name, type + return unless filepath + file = assert (io.open filepath, 'rb'), "couldn't open facet file '#{filepath}'" + with file\read '*all' + file\close! + + create_facet: (path, name, type, blob) => + @log "creating facet #{path} | #{name}: #{type}" + assert blob, "cant create facet without value!" + + filepath = @tofp path, name, type + if lfs.attributes filepath, 'mode' + error "facet file already exists!" + + file = assert (io.open filepath, 'wb'), "couldn't open facet file '#{filepath}'" + file\write blob + file\close! + + remove_facet: (path, name, type) => + @log "removing facet #{path} | #{name}: #{type}" + + filepath = @locate path, name, type + assert filepath, "couldn't locate facet!" + assert os.remove filepath + + rename_facet: (path, name, type, next_name) => + @log "renaming facet #{path} | #{name}: #{type} -> #{next_name}" + filepath = @locate path, name, type + assert filepath, "couldn't locate facet!" + assert os.rename filepath, @tofp path, next_name, type + + update_facet: (path, name, type, blob) => + @log "updating facet #{path} | #{name}: #{type}" + filepath = @locate path, name, type + assert filepath, "couldn't locate facet!" + file = assert (io.open filepath, 'wb'), "couldn't open facet file '#{filepath}'" + file\write blob + file\close! + +{ + :LFSStore +} diff --git a/mmm/mmmfs/drivers/sql.moon b/mmm/mmmfs/drivers/sql.moon index 9337dd8..490eade 100644 --- a/mmm/mmmfs/drivers/sql.moon +++ b/mmm/mmmfs/drivers/sql.moon @@ -1,4 +1,5 @@ sqlite = require 'sqlite3' +root = os.tmpname! class SQLStore new: (opts = {}) => @@ -96,6 +97,7 @@ class SQLStore OR path = :path', path rename_fileder: (path, next_name) => + @log "renaming fileder #{path} -> '#{next_name}'" error 'not implemented' @exec 'UPDATE fileder @@ -105,7 +107,8 @@ class SQLStore -- @TODO: rename all children, child-children... - move_fileder: (path, new_parent) => + move_fileder: (path, next_parent) => + @log "moving fileder #{path} -> #{next_parent}/" error 'not implemented' -- @TODO: remove all children, child-children... diff --git a/mmm/mmmfs/drivers/zip.moon b/mmm/mmmfs/drivers/zip.moon deleted file mode 100644 index c6417e2..0000000 --- a/mmm/mmmfs/drivers/zip.moon +++ /dev/null @@ -1,59 +0,0 @@ -require = relative ..., 1 -import Fileder, Key from require '.fileder' -zip = require 'brimworks.zip' - --- split filename into dirname + basename -dir_base = (path) -> - dir, base = path\match '(.-)([^/]-)$' - if dir and #dir > 0 - dir = dir\sub 1, #dir - 1 - - dir, base - --- insert into array unless contained -table_add = (tbl, entry) -> - for _, v in ipairs tbl - if v == entry - return - - table.insert tbl, entry - --- strip facet formatting -load_facet = (filename) -> - key = (filename\match '(.*)%.%w+') or filename - key = Key key\gsub '%$', '/' - key.filename = filename - - key - -load_tree = (file='root.zip') -> - archive = zip.open file - - fileders = setmetatable {}, - __index: (path) => - with val = Fileder {} - .path = path - rawset @, path, val - - fileders['/root'].facets['name: alpha'] = -> 'root' - - for i = 1, #archive - { :name, :size } = archive\stat i - - path, facet = dir_base "/#{name}" - parent, name = dir_base path - - key = load_facet facet - - this = fileders[path] - this.facets['name: alpha'] = -> name - this.facets[key] = -> - file = archive\open i - with file\read size - file\close! - - table_add fileders[parent].children, this - - fileders['/root'] - -{ :load_tree } diff --git a/spec/driver_spec.moon b/spec/driver_spec.moon index 379dcac..918f620 100644 --- a/spec/driver_spec.moon +++ b/spec/driver_spec.moon @@ -1,17 +1,17 @@ -import SQLStore from require 'mmm.mmmfs.drivers.sql' - sort2 = (a, b) -> {ax, ay}, {bx, by} = a, b "#{ax}//#{ay}" < "#{bx}//#{by}" -toseq = (iter) -> with v = [x for x in iter] - table.sort v -toseq2 = (iter) -> with v = [{x, y} for x, y in iter] - table.sort v, sort2 -describe "sql driver", -> - randomize false +toseq = (iter) -> + with v = [x for x in iter] + table.sort v + +toseq2 = (iter) -> + with v = [{x, y} for x, y in iter] + table.sort v, sort2 - ts = SQLStore memory: true +test_driver = (ts) -> + randomize false it "starts out empty", -> assert.are.same {}, toseq ts\list_fileders_in! @@ -44,13 +44,13 @@ describe "sql driver", -> ts\create_facet '/hello/world', 'name', 'alpha', 'world' ts\create_facet '/hello/world', '', 'text/markdown', '# Helau World!' - it "can't create facet for nonexistant fileders", -> + it "but can't create facet for nonexistant fileders", -> assert.has_error -> ts\create_facet '/hello/orldw', 'name', 'alpha', 'foo' - it "can't create facet without value", -> + it "but can't create facet without value", -> assert.has_error -> ts\create_facet '/hello/world', 'other', 'alpha', nil - it "can't create facet for duplicate keys", -> + it "but can't create facet for duplicate keys", -> assert.has_error -> ts\create_facet '/hello/world', 'name', 'alpha', 'foo' assert.are.same {{'name', 'alpha'}}, toseq2 ts\list_facets '/hello' @@ -88,3 +88,24 @@ describe "sql driver", -> ts\remove_fileder '/hello' assert.are.same {}, toseq ts\list_all_fileders! + +describe "SQL driver", -> + import SQLStore from require 'mmm.mmmfs.drivers.sql' + + test_driver SQLStore memory: true + +describe "LFS driver", -> + import LFSStore from require 'mmm.mmmfs.drivers.lfs' + + lfs = require 'lfs' + + root = os.tmpname! + + setup -> + assert os.remove root + assert lfs.mkdir root + + test_driver LFSStore :root + + teardown -> + assert lfs.rmdir root |
