From 35c290c4a0a3dd7697a1a2e2907aadba0de5eec4 Mon Sep 17 00:00:00 2001 From: skilion Date: Thu, 17 Sep 2015 16:28:24 +0200 Subject: [PATCH] working monitor --- src/itemdb.d | 54 +++++++++++++++++++++++++++++--- src/main.d | 6 +++- src/sync.d | 88 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 107 insertions(+), 41 deletions(-) diff --git a/src/itemdb.d b/src/itemdb.d index de38f667..6410fbb4 100644 --- a/src/itemdb.d +++ b/src/itemdb.d @@ -24,6 +24,7 @@ final class ItemDatabase { Database db; Statement insertItemStmt; + Statement updateItemStmt; Statement selectItemByIdStmt; Statement selectItemByParentIdStmt; @@ -44,11 +45,8 @@ final class ItemDatabase db.exec("CREATE INDEX IF NOT EXISTS name_idx ON item (name)"); db.exec("PRAGMA foreign_keys = ON"); db.exec("PRAGMA recursive_triggers = ON"); - //insertItemStmt = db.prepare("INSERT OR REPLACE INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); - insertItemStmt = db.prepare(" - INSERT OR IGNORE - INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32) - VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8); + insertItemStmt = db.prepare("INSERT OR REPLACE INTO item (id, name, type, eTag, cTag, mtime, parentId, crc32) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); + updateItemStmt = db.prepare(" UPDATE item SET name = ?2, type = ?3, eTag = ?4, cTag = ?5, mtime = ?6, parentId = ?7, crc32 = ?8 WHERE id = ?1 @@ -77,6 +75,52 @@ final class ItemDatabase } } + void update(const(char)[] id, const(char)[] name, ItemType type, const(char)[] eTag, const(char)[] cTag, const(char)[] mtime, const(char)[] parentId, const(char)[] crc32) + { + with (updateItemStmt) { + bind(1, id); + bind(2, name); + string typeStr = void; + final switch (type) { + case ItemType.file: typeStr = "file"; break; + case ItemType.dir: typeStr = "dir"; break; + } + bind(3, typeStr); + bind(4, eTag); + bind(5, cTag); + bind(6, mtime); + bind(7, parentId); + bind(8, crc32); + exec(); + } + } + + void upsert(const(char)[] id, const(char)[] name, ItemType type, const(char)[] eTag, const(char)[] cTag, const(char)[] mtime, const(char)[] parentId, const(char)[] crc32) + { + auto s = db.prepare("SELECT COUNT(*) FROM item WHERE id = ?"); + s.bind(1, id); + auto r = s.exec(); + Statement* p; + if (r.front[0] == "0") p = &insertItemStmt; + else p = &updateItemStmt; + with (p) { + bind(1, id); + bind(2, name); + string typeStr = void; + final switch (type) { + case ItemType.file: typeStr = "file"; break; + case ItemType.dir: typeStr = "dir"; break; + } + bind(3, typeStr); + bind(4, eTag); + bind(5, cTag); + bind(6, mtime); + bind(7, parentId); + bind(8, crc32); + exec(); + } + } + // returns a range that go trough all items, depth first auto selectAll() { diff --git a/src/main.d b/src/main.d index a1032638..7008d186 100644 --- a/src/main.d +++ b/src/main.d @@ -86,7 +86,11 @@ void main(string[] args) }; m.onFileChanged = delegate(string path) { if (verbose) writeln("[M] File changed: ", path); - sync.uploadDifference(path); + try { + sync.uploadDifference(path); + } catch(SyncException e) { + writeln(e.msg); + } }; m.onDelete = delegate(string path) { if (verbose) writeln("[M] Item deleted: ", path); diff --git a/src/sync.d b/src/sync.d index 2eaa3ae5..e9376fb5 100644 --- a/src/sync.d +++ b/src/sync.d @@ -146,8 +146,12 @@ final class SyncEngine } } + if (cached) { + itemdb.update(id, name, type, eTag, cTag, mtime, parentId, crc32); + } else { + itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32); + } Item newItem; - itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32); itemdb.selectById(id, newItem); // TODO add item in the db only if correctly downloaded @@ -324,7 +328,25 @@ final class SyncEngine final switch (item.type) { case ItemType.file: if (isFile(item.path)) { - uploadItemDifferences(item); + SysTime localModifiedTime = timeLastModified(item.path); + import core.time: Duration; + item.mtime.fracSecs = Duration.zero; // HACK + if (localModifiedTime != item.mtime) { + if (verbose) writeln("The item last modified time has changed"); + string id = item.id; + string eTag = item.eTag; + if (!testCrc32(item.path, item.crc32)) { + if (verbose) writeln("The item content has changed"); + writeln("Uploading: ", item.path); + auto res = onedrive.simpleUpload(item.path, item.path, item.eTag); + saveItem(res); + id = res["id"].str; + eTag = res["eTag"].str; + } + uploadLastModifiedTime(id, eTag, localModifiedTime.toUTC()); + } else { + if (verbose) writeln("The item has not changed"); + } } else { if (verbose) writeln("The item was a file but now is a directory"); uploadDeleteItem(item); @@ -347,38 +369,21 @@ final class SyncEngine } } - // NOTE: this function works only for files - void uploadDifference(string filename) + void uploadDifference(string path) { - Item item; - if (itemdb.selectByPath(filename, item)) { - uploadDifference(item); - } else { - uploadNewFile(filename); - } - } - - // check if the item is changed and upload the differences - private void uploadItemDifferences(Item item) - { - SysTime localModifiedTime = timeLastModified(item.path); - import core.time: Duration; - item.mtime.fracSecs = Duration.zero; // HACK - if (localModifiedTime != item.mtime) { - if (verbose) writeln("The item last modified time has changed"); - string id = item.id; - string eTag = item.eTag; - if (item.type == ItemType.file && !testCrc32(item.path, item.crc32)) { - if (verbose) writeln("The item content has changed"); - writeln("Uploading: ", item.path); - auto res = onedrive.simpleUpload(item.path, item.path, item.eTag); - saveItem(res); - id = res["id"].str; - eTag = res["eTag"].str; + try { + Item item; + if (itemdb.selectByPath(path, item)) { + uploadDifference(item); + } else { + if (isDir(path)) { + uploadCreateDir(path); + } else { + uploadNewFile(path); + } } - uploadLastModifiedTime(id, eTag, localModifiedTime.toUTC()); - } else { - if (verbose) writeln("The item has not changed"); + } catch (FileException e) { + throw new SyncException(e.msg, e); } } @@ -404,7 +409,14 @@ final class SyncEngine saveItem(res); string id = res["id"].str; string eTag = res["eTag"].str; - uploadLastModifiedTime(id, eTag, timeLastModified(path).toUTC()); + SysTime mtime; + try { + mtime = timeLastModified(path).toUTC(); + } catch (FileException e) { + writeln(e.msg); + return; + } + uploadLastModifiedTime(id, eTag, mtime); } private void uploadDeleteItem(Item item) @@ -451,23 +463,29 @@ final class SyncEngine // swallow exception } } - itemdb.insert(id, name, type, eTag, cTag, mtime, parentId, crc32); + itemdb.upsert(id, name, type, eTag, cTag, mtime, parentId, crc32); } void uploadMoveItem(const(char)[] from, string to) { writeln("Moving remote item: ", from, " -> ", to); Item item; - if (!itemdb.selectByPath(from, item)) { + if (!itemdb.selectByPath(from, item) || !isItemSynced(item)) { writeln("Can't move an unsynced item"); return; } + if (itemdb.selectByPath(to, item)) { + uploadDeleteItem(item); + } JSONValue diff = ["name": baseName(to)]; diff["parentReference"] = JSONValue([ "path": "/drive/root:/" ~ dirName(to) ]); auto res = onedrive.updateById(item.id, diff, item.eTag); saveItem(res); + string id = res["id"].str; + string eTag = res["eTag"].str; + uploadLastModifiedTime(id, eTag, timeLastModified(to).toUTC()); } void deleteByPath(const(char)[] path)