mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 18:10:09 +00:00
reworking file store...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
a0a18b52be
commit
e8ea046652
224
pwiki2.js
224
pwiki2.js
@ -712,6 +712,149 @@ module.localStorageNestedStore = {
|
|||||||
var fs = require('fs')
|
var fs = require('fs')
|
||||||
var glob = require('glob')
|
var glob = require('glob')
|
||||||
|
|
||||||
|
// exists(base[, options])
|
||||||
|
// -> true/false
|
||||||
|
//
|
||||||
|
// exists(base, path[, options])
|
||||||
|
// -> true/false
|
||||||
|
//
|
||||||
|
var exists =
|
||||||
|
module.exists =
|
||||||
|
async function(base, sub, options={index: '.index'}){
|
||||||
|
if(typeof(sub) != 'string'){
|
||||||
|
options = sub
|
||||||
|
sub = base
|
||||||
|
base = '' }
|
||||||
|
var {index} = options
|
||||||
|
|
||||||
|
var target = module.path.join(base, sub)
|
||||||
|
if(!fs.existsSync(target)){
|
||||||
|
return false }
|
||||||
|
var stat = await fs.promises.stat(target)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
return fs.existsSync(module.path.join(target, index)) }
|
||||||
|
return true }
|
||||||
|
var read =
|
||||||
|
module.read =
|
||||||
|
async function(base, sub, options={index: '.index'}){
|
||||||
|
if(typeof(sub) != 'string'){
|
||||||
|
options = sub
|
||||||
|
sub = base
|
||||||
|
base = '' }
|
||||||
|
var {index} = options
|
||||||
|
|
||||||
|
var target = module.path.join(base, sub)
|
||||||
|
if(!fs.existsSync(target)){
|
||||||
|
return undefined }
|
||||||
|
// handle dir text...
|
||||||
|
var stat = await fs.promises.stat(target)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
var target = module.path.join(target, index)
|
||||||
|
fs.existsSync(target)
|
||||||
|
|| (target = false) }
|
||||||
|
return target ?
|
||||||
|
fs.promises.readFile(target, {encoding: 'utf-8'})
|
||||||
|
: undefined }
|
||||||
|
var mkdir =
|
||||||
|
module.mkdir =
|
||||||
|
async function(base, sub, options={index: '.index'}){
|
||||||
|
if(typeof(sub) != 'string'){
|
||||||
|
options = sub
|
||||||
|
sub = base
|
||||||
|
base = '' }
|
||||||
|
var {index} = options
|
||||||
|
|
||||||
|
var levels = module.path.split(sub)
|
||||||
|
for(var level of levels){
|
||||||
|
base = module.path.join(base, level)
|
||||||
|
// nothing exists -- create dir and continue...
|
||||||
|
if(!fs.existsSync(base)){
|
||||||
|
await fs.promises.mkdir(base, {recursive: true})
|
||||||
|
continue }
|
||||||
|
// directory -- continue...
|
||||||
|
var stat = await fs.promises.stat(base)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
continue }
|
||||||
|
// file -- convert to dir...
|
||||||
|
await fs.promises.rename(base, base+'.pwiki-bak')
|
||||||
|
await fs.promises.mkdir(base, {recursive: true})
|
||||||
|
await fs.promises.rename(base +'.pwiki-bak', base +'/'+ index) }
|
||||||
|
return base }
|
||||||
|
// XXX error checking???
|
||||||
|
// XXX metadata???
|
||||||
|
// XXX modes???
|
||||||
|
// XXX should this transform <dir>/.index into a file if nothing else exists in it???
|
||||||
|
var update =
|
||||||
|
module.update =
|
||||||
|
async function(base, sub, data, options={index: '.index'}){
|
||||||
|
if(typeof(sub) != 'string'){
|
||||||
|
options = sub
|
||||||
|
sub = base
|
||||||
|
base = '' }
|
||||||
|
var {index} = options
|
||||||
|
|
||||||
|
// path already exists...
|
||||||
|
if(fs.existsSync(module.path.join(base, sub))){
|
||||||
|
var stat = await fs.promises.stat(base)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
sub = module.path.join(sub, index) }
|
||||||
|
// create path / parts of path...
|
||||||
|
} else {
|
||||||
|
var levels = module.path.split(sub)
|
||||||
|
var basename = levels.pop()
|
||||||
|
// ensure the parent dir exists...
|
||||||
|
await module.mkdir(base, levels, index) }
|
||||||
|
// write the data...
|
||||||
|
var target = module.path.join(base, sub)
|
||||||
|
var f = await fs.promises.open(target, 'w')
|
||||||
|
await f.writeFile(data)
|
||||||
|
f.close()
|
||||||
|
return target }
|
||||||
|
var clear =
|
||||||
|
module.clear =
|
||||||
|
async function(base, sub, options={index: '.index'}){
|
||||||
|
if(typeof(sub) != 'string'){
|
||||||
|
options = sub
|
||||||
|
sub = base
|
||||||
|
base = '' }
|
||||||
|
var {index} = options
|
||||||
|
|
||||||
|
// remove leaf...
|
||||||
|
var target = module.path.join(base, sub)
|
||||||
|
// dir...
|
||||||
|
if(fs.existsSync(target)){
|
||||||
|
var stat = await fs.promises.stat(target)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
var files = await fs.promises.readdir(target)
|
||||||
|
// remove index...
|
||||||
|
if(files.includes(index)){
|
||||||
|
await fs.promises.rm(module.path.join(target, index))
|
||||||
|
// NOTE: we do not care what we pop as long as the .length
|
||||||
|
// is correct as we'll not be using the content after
|
||||||
|
// this point...
|
||||||
|
files.pop() }
|
||||||
|
// remove dir if empty...
|
||||||
|
if(files.length == 0){
|
||||||
|
fs.promises.rmdir(target) }
|
||||||
|
// simple file...
|
||||||
|
} else {
|
||||||
|
await fs.promises.rm(target) } }
|
||||||
|
// cleanup path -- remove empty dirs... (XXX ???)
|
||||||
|
var levels = module.path.split(sub)
|
||||||
|
.slice(0, -1)
|
||||||
|
while(levels.length > 0){
|
||||||
|
var cur = module.path.join(base, ...levels)
|
||||||
|
if(fs.existsSync(cur)){
|
||||||
|
var stat = await fs.promises.stat(base)
|
||||||
|
if(stat.isDirectory()){
|
||||||
|
// stop cleanup if non-empty dir...
|
||||||
|
if((await fs.promises.readdir(cur)).length != 0){
|
||||||
|
break }
|
||||||
|
fs.promises.rmdir(cur) } }
|
||||||
|
levels.pop() }
|
||||||
|
return target }
|
||||||
|
|
||||||
|
|
||||||
// XXX add monitor API...
|
// XXX add monitor API...
|
||||||
// XXX backup files on write/delete...
|
// XXX backup files on write/delete...
|
||||||
// XXX do a r/o version...
|
// XXX do a r/o version...
|
||||||
@ -726,6 +869,7 @@ module.FileStore = {
|
|||||||
__directory_text__: '.index',
|
__directory_text__: '.index',
|
||||||
|
|
||||||
// XXX do we remove the extension???
|
// XXX do we remove the extension???
|
||||||
|
// XXX BUG? is this recursive???
|
||||||
// XXX cache???
|
// XXX cache???
|
||||||
__paths__: async function(){
|
__paths__: async function(){
|
||||||
var that = this
|
var that = this
|
||||||
@ -738,85 +882,27 @@ module.FileStore = {
|
|||||||
return path
|
return path
|
||||||
.slice(that.__path__.length) })) }) }) },
|
.slice(that.__path__.length) })) }) }) },
|
||||||
__exists__: async function(path){
|
__exists__: async function(path){
|
||||||
var p = module.path.join(this.__path__, path)
|
return module.exists(this.__path__, path, {index: this.__directory_text__})
|
||||||
try {
|
&& path },
|
||||||
var stat = await fs.promises.stat(p)
|
|
||||||
// NOTE: we consider a directory as "existing" iff we can
|
|
||||||
// produce text for it...
|
|
||||||
return stat.isDirectory() ?
|
|
||||||
(!!fs.existsSync(p +'/'+ this.__directory_text__)
|
|
||||||
&& path)
|
|
||||||
: !!fs.existsSync(p) ?
|
|
||||||
path
|
|
||||||
: false
|
|
||||||
} catch(err){
|
|
||||||
return false } },
|
|
||||||
__get__: async function(path){
|
__get__: async function(path){
|
||||||
var p = module.path.join(this.__path__, path)
|
var p = module.path.join(this.__path__, path)
|
||||||
var stat = await fs.promises.stat(p)
|
var {atimeMs, mtimeMs, ctimeMs, birthtimeMs} = await fs.promises.stat(p)
|
||||||
var {atimeMs, mtimeMs, ctimeMs, birthtimeMs} = stat
|
|
||||||
return {
|
return {
|
||||||
atime: atimeMs,
|
atime: atimeMs,
|
||||||
mtime: mtimeMs,
|
mtime: mtimeMs,
|
||||||
ctime: ctimeMs,
|
ctime: ctimeMs,
|
||||||
text: stat.isDirectory() ?
|
text: module.read(p, {index: this.__directory_text__})
|
||||||
fs.readFileSync(p +'/'+ this.__directory_text__).toString()
|
|
||||||
: fs.readFileSync(p).toString(),
|
|
||||||
} },
|
} },
|
||||||
//
|
|
||||||
// Add data to path...
|
|
||||||
// .__update_path__(<path>, <data>)
|
|
||||||
//
|
|
||||||
// Clear data from path...
|
|
||||||
// .__update_path__(<path>, undefined)
|
|
||||||
//
|
|
||||||
// XXX this is FileStore-specific...
|
|
||||||
// XXX create a file path and set data...
|
|
||||||
// - convert files in path to dirs:
|
|
||||||
// a/b/c -> a/b/c/.text
|
|
||||||
// - move "c" -> "c.bak"
|
|
||||||
// - mkdir "c"
|
|
||||||
// - move "c.bak" -> "c/.text"
|
|
||||||
// - convert last dir to file if directory empty...
|
|
||||||
// a/b/c/.text -> a/b/c
|
|
||||||
// (same as above)
|
|
||||||
// - remove empty dirs from path...
|
|
||||||
// XXX might be a good idea to have a store-specific backup/tmp dir...
|
|
||||||
// XXX might be a good idea to move this functionality to
|
|
||||||
// .__update__(..) and use it from .__delete__(..)...
|
|
||||||
__update_path__: async function(path, data, mode='update'){
|
|
||||||
var p = module.path.join(this.__path__, path)
|
|
||||||
|
|
||||||
// write/update...
|
|
||||||
if(data != null){
|
|
||||||
// XXX create/update basedir...
|
|
||||||
|
|
||||||
// clear/remove...
|
|
||||||
} else {
|
|
||||||
// XXX remove file...
|
|
||||||
// XXX recursively check/remove dirs...
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// XXX handle writing to directories...
|
|
||||||
// i.e. write to "./"+ this.__directory_text__
|
|
||||||
// XXX would need to convert a file to a dir if writing to sub-path...
|
|
||||||
// XXX recursively create all dirs...
|
|
||||||
// XXX do we write all the data or only the .text???
|
// XXX do we write all the data or only the .text???
|
||||||
__update__: async function(path, data, mode='update'){
|
__update__: async function(path, data, mode='update'){
|
||||||
var p = module.path.join(this.__path__, path)
|
return module.update(
|
||||||
|
this.__path__, path,
|
||||||
var f = await fs.promises.open(p, 'w')
|
data.text,
|
||||||
var size = await f.writeFile(data.text)
|
{index: this.__directory_text__}) },
|
||||||
f.close()
|
|
||||||
// XXX check size...
|
|
||||||
// XXX
|
|
||||||
},
|
|
||||||
// XXX remove empty dirs (???)
|
|
||||||
// XXX convert a dir to a file if removing last sub-file/dir...
|
|
||||||
__delete__: async function(path){
|
__delete__: async function(path){
|
||||||
var p = module.path.join(this.__path__, path)
|
return module.clear(
|
||||||
// XXX
|
this.__path__, path,
|
||||||
},
|
{index: this.__directory_text__}) },
|
||||||
load: function(data){
|
load: function(data){
|
||||||
// XXX
|
// XXX
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user