From 6dd1d4d83acc3764c1d3f875bbdb303780298031 Mon Sep 17 00:00:00 2001 From: monoid Date: Wed, 6 Jul 2022 16:43:57 +0900 Subject: [PATCH] fix: onchange bug --- src/diff/content_handler.ts | 101 +++++++++++++++++++++--------------- src/diff/content_list.ts | 9 ++-- src/route/contents.ts | 1 + 3 files changed, 67 insertions(+), 44 deletions(-) diff --git a/src/diff/content_handler.ts b/src/diff/content_handler.ts index 75ed383..a3db25b 100644 --- a/src/diff/content_handler.ts +++ b/src/diff/content_handler.ts @@ -1,102 +1,121 @@ -import {basename, dirname, join as pathjoin} from 'path'; -import {Document, DocumentAccessor} from '../model/mod'; +import { basename, dirname, join as pathjoin } from 'path'; +import { Document, DocumentAccessor } from '../model/mod'; import { ContentFile, createContentFile } from '../content/mod'; -import {IDiffWatcher} from './watcher'; -import {ContentList} from './content_list'; +import { IDiffWatcher } from './watcher'; +import { ContentList } from './content_list'; //refactoring needed. -export class ContentDiffHandler{ +export class ContentDiffHandler { /** content file list waiting to add */ - waiting_list:ContentList; + waiting_list: ContentList; /** deleted contents */ - tombstone: Map;//hash, contentfile + tombstone: Map;//hash, contentfile doc_cntr: DocumentAccessor; /** content type of handle */ content_type: string; - constructor(cntr: DocumentAccessor,content_type:string){ + constructor(cntr: DocumentAccessor, content_type: string) { this.waiting_list = new ContentList(); - this.tombstone = new Map(); + this.tombstone = new Map(); this.doc_cntr = cntr; this.content_type = content_type; } - async setup(){ + async setup() { const deleted = await this.doc_cntr.findDeleted(this.content_type); for (const it of deleted) { - this.tombstone.set(it.content_hash,it); + this.tombstone.set(it.content_hash, it); } } - register(diff:IDiffWatcher){ - diff.on('create',(path)=>this.OnCreated(path)) - .on('delete',(path)=>this.OnDeleted(path)) - .on('change',(prev,cur)=>this.OnChanged(prev,cur)); + register(diff: IDiffWatcher) { + diff.on('create', (path) => this.OnCreated(path)) + .on('delete', (path) => this.OnDeleted(path)) + .on('change', (prev, cur) => this.OnChanged(prev, cur)); } - private async OnDeleted(cpath: string){ + private async OnDeleted(cpath: string) { const basepath = dirname(cpath); const filename = basename(cpath); - console.log("deleted ",cpath); + console.log("deleted ", cpath); //if it wait to add, delete it from waiting list. - if(this.waiting_list.hasByPath(cpath)){ + if (this.waiting_list.hasByPath(cpath)) { this.waiting_list.deleteByPath(cpath); return; } - const dbc = await this.doc_cntr.findByPath(basepath,filename); + const dbc = await this.doc_cntr.findByPath(basepath, filename); //when there is no related content in db, ignore. - if(dbc.length === 0) return; + if (dbc.length === 0) { + console.log("its not in waiting_list and db!!!: ", cpath); + return; + } const content_hash = dbc[0].content_hash; // When a path is changed, it takes into account when the // creation event occurs first and the deletion occurs, not // the change event. const cf = this.waiting_list.getByHash(content_hash); - if(cf){ + if (cf) { //if a path is changed, update the changed path. - console.log("update path from", cpath,"to",cf.path); + console.log("update path from", cpath, "to", cf.path); const newFilename = basename(cf.path); const newBasepath = dirname(cf.path); - await this.waiting_list.deleteByHash(content_hash); + this.waiting_list.deleteByHash(content_hash); await this.doc_cntr.update({ - id:dbc[0].id, + id: dbc[0].id, deleted_at: null, - filename:newFilename, - basepath:newBasepath, + filename: newFilename, + basepath: newBasepath, }); return; } //invalidate db and add it to tombstone. await this.doc_cntr.update({ - id:dbc[0].id, + id: dbc[0].id, deleted_at: Date.now(), }); this.tombstone.set(dbc[0].content_hash, dbc[0]); } - private async OnCreated(cpath:string){ + private async OnCreated(cpath: string) { const basepath = dirname(cpath); const filename = basename(cpath); console.log("createContentFile", cpath); - const content = createContentFile(this.content_type,pathjoin(basepath,filename)); + const content = createContentFile(this.content_type, cpath); const hash = await content.getHash(); const c = this.tombstone.get(hash); - if(c !== undefined){ - this.doc_cntr.update({ + if (c !== undefined) { + await this.doc_cntr.update({ id: c.id, deleted_at: null, - filename:filename, - basepath:basepath + filename: filename, + basepath: basepath }); - return; } - if(this.waiting_list.hasByHash(hash)){ - console.log("Conflict!!!"); + if (this.waiting_list.hasByHash(hash)) { + console.log("Hash Conflict!!!"); } this.waiting_list.set(content); + } - private async OnChanged(prev_path:string,cur_path:string){ + private async OnChanged(prev_path: string, cur_path: string) { const prev_basepath = dirname(prev_path); const prev_filename = basename(prev_path); const cur_basepath = dirname(cur_path); const cur_filename = basename(cur_path); - const doc = await this.doc_cntr.findByPath(prev_basepath,prev_filename); - await this.doc_cntr.update({...doc[0], - basepath:cur_basepath, - filename:cur_filename}); + console.log("modify", cur_path, "from", prev_path); + const c = this.waiting_list.getByPath(prev_path); + if(c !== undefined){ + await this.waiting_list.delete(c); + const content = createContentFile(this.content_type, cur_path); + await this.waiting_list.set(content); + return; + } + const doc = await this.doc_cntr.findByPath(prev_basepath, prev_filename); + + if(doc.length === 0){ + await this.OnCreated(cur_path); + return; + } + + await this.doc_cntr.update({ + ...doc[0], + basepath: cur_basepath, + filename: cur_filename + }); } } \ No newline at end of file diff --git a/src/diff/content_list.ts b/src/diff/content_list.ts index fe2eea5..58d4ae2 100644 --- a/src/diff/content_list.ts +++ b/src/diff/content_list.ts @@ -39,12 +39,15 @@ export class ContentList{ async deleteByPath(p:string){ const o = this.getByPath(p); if(o === undefined) return false; - return this.delete(o); + return await this.delete(o); } - async deleteByHash(s:string){ + deleteByHash(s:string){ const o = this.getByHash(s); if(o === undefined) return false; - return this.delete(o); + let r = true; + r = this.cl.delete(o.path) && r; + r = this.hl.delete(s) && r; + return r; } clear(){ this.cl.clear(); diff --git a/src/route/contents.ts b/src/route/contents.ts index 65b064f..f19f378 100644 --- a/src/route/contents.ts +++ b/src/route/contents.ts @@ -73,6 +73,7 @@ const ContentQueryHandler = (controller : DocumentAccessor) => async (ctx: Conte } const UpdateContentHandler = (controller : DocumentAccessor) => async (ctx: Context, next: Next) => { const num = Number.parseInt(ctx.params['num']); + if(ctx.request.type !== 'json'){ return sendError(400,"update fail. invalid document type: it is not json."); }