diff options
| author | s-ol <s-ol@users.noreply.github.com> | 2019-11-01 12:47:09 +0000 |
|---|---|---|
| committer | s-ol <s-ol@users.noreply.github.com> | 2019-11-01 12:47:09 +0000 |
| commit | 053e607a49989b2d4491c20ff14c839b7161d713 (patch) | |
| tree | 2397569c518c2de29f6de73d589bb80e84616821 | |
| parent | browsing, adding, removing fileders in inspector (diff) | |
| download | mmm-053e607a49989b2d4491c20ff14c839b7161d713.tar.gz mmm-053e607a49989b2d4491c20ff14c839b7161d713.zip | |
add proper order handling, fsck for stores.fs
| -rw-r--r-- | build/fsck.moon | 37 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/fs.moon | 78 | ||||
| -rw-r--r-- | mmm/mmmfs/stores/init.moon | 3 |
3 files changed, 104 insertions, 14 deletions
diff --git a/build/fsck.moon b/build/fsck.moon new file mode 100644 index 0000000..df882a9 --- /dev/null +++ b/build/fsck.moon @@ -0,0 +1,37 @@ +add = (tmpl) -> + package.path ..= ";#{tmpl}.lua" + package.moonpath ..= ";#{tmpl}.moon" + +add '?' +add '?.server' +add '?/init' +add '?/init.server' + +require 'mmm' + +import get_store from require 'mmm.mmmfs.stores' + +-- usage: +-- moon server.moon [FLAGS] [STORE] [host] [port] +-- * FLAGS - any of the following: +-- --[no-]rw - enable/disable POST?PUT/DELETE operations (default: on if local) +-- --[no-]unsafe - enable/disable server-side code execution when writable is on (default: on if local or --no-rw) +-- * STORE - see mmm/mmmfs/stores/init.moon:get_store +-- * host - interface to bind to (default localhost, set to 0.0.0.0 for public hosting) +-- * port - port to serve from, default 8000 + +flags = {} +arguments = for a in *arg + if flag = a\match '^%-%-no%-(.*)$' + flags[flag] = false + continue + elseif flag = a\match '^%-%-(.*)$' + flags[flag] = true + continue + else + a + +{ store, host, port } = arguments + +store = get_store store, verbose: true +store\fsck! diff --git a/mmm/mmmfs/stores/fs.moon b/mmm/mmmfs/stores/fs.moon index d4d5bd4..edcca3b 100644 --- a/mmm/mmmfs/stores/fs.moon +++ b/mmm/mmmfs/stores/fs.moon @@ -21,38 +21,63 @@ class FSStore extends Store @log "opening '#{opts.root}'..." -- fileders - list_fileders_in: (path='') => + get_order: (path, forgiving=false) => entries = {} - for entry_name in lfs.dir @root .. path - continue if '.' == entry_name\sub 1, 1 - entry_path = @root .. "#{path}/#{entry_name}" + for name in lfs.dir @root .. path + continue if '.' == name\sub 1, 1 + entry_path = @root .. "#{path}/#{name}" if 'directory' ~= lfs.attributes entry_path, 'mode' continue - entries[entry_name] = "#{path}/#{entry_name}" + entries[name] = :name, path: "#{path}/#{name}" sorted = {} - order_file = @root .. "#{path}/$order" if 'file' == lfs.attributes order_file, 'mode' for line in io.lines order_file - path = assert entries[line], "entry in $order but not on disk: #{line}" - table.insert sorted, path + entry = entries[line] + if not entry + if forgiving + @log "removed stale entry '#{line}' from #{path}/$order" + continue + error "entry in $order but not on disk: #{line}" + + table.insert sorted, entry sorted[line] = true - entries = [path for entry, path in pairs entries when not sorted[entry]] - table.sort entries - for path in *entries - table.insert sorted, path + unsorted = [entry for name, entry in pairs entries when not sorted[entry.name]] + if forgiving + for entry in *unsorted + @log "adding new entry '#{entry.name}' in #{path}/$order" + table.insert sorted, entry + else + assert #unsorted == 0, unsorted[1] and "entry on disk but not in $order: #{unsorted[1].path}" + + sorted + + write_order: (path, order=@get_order path, true) => + order_file = @root .. "#{path}/$order" + if #order == 0 + os.remove order_file + return + + file = assert io.open order_file, 'w' + for { :name } in *order + file\write "#{name}\n" + file\close! + + list_fileders_in: (path='') => + sorted = @get_order path coroutine.wrap -> - for path in *sorted + for { :path } in *sorted coroutine.yield path create_fileder: (parent, name) => path = "#{parent}/#{name}" @log "creating fileder #{path}" assert lfs.mkdir @root .. path + @write_order parent path remove_fileder: (path) => @@ -73,6 +98,9 @@ class FSStore extends Store rmdir @root .. path + parent = dir_base path + @write_order parent + rename_fileder: (path, next_name) => @log "renaming fileder #{path} -> '#{next_name}'" parent, name = dir_base path @@ -83,6 +111,22 @@ class FSStore extends Store parent, name = dir_base path assert os.rename @root .. path, @root .. "#{next_parent}/#{name}" + -- swap two childrens' order + swap_fileders: (parent, name_a, name_b) => + @log "swapping #{name_a} and #{name_b} in #{parent}" + order = @get_order parent + local a, b + for i, entry in ipairs order + a = i if entry.name == name_a + b = i if entry.name == name_b + break if a and b + + assert a, "couldn't find #{parent}/#{name_a} in $order" + assert b, "couldn't find #{parent}/#{name_b} in $order" + + order[a], order[b] = order[b], order[a] + @write_order parent, order + -- facets list_facets: (path) => coroutine.wrap -> @@ -161,6 +205,14 @@ class FSStore extends Store file\write blob file\close! + -- fsck + fsck: (path='') => + order = @get_order path, true + @write_order path, order + + for { :path } in *order + @fsck path + { :FSStore } diff --git a/mmm/mmmfs/stores/init.moon b/mmm/mmmfs/stores/init.moon index 905188f..3d8480f 100644 --- a/mmm/mmmfs/stores/init.moon +++ b/mmm/mmmfs/stores/init.moon @@ -42,13 +42,14 @@ class Store @remove_facet path, name, type update_facet: => error "not implemented" close: => + fsck: => log: (...) => print "[#{@@__name}]", ... -- instantiate a store from a CLI arg -- e.g.: sql, fs:/path/to/root, sql:MEMORY, sql:db.sqlite3 -get_store = (args='sql', opts={verbose: true}) -> +get_store = (args='sql', opts={}) -> type, arg = args\match '(%w+):(.*)' type = args unless type |
