diff options
-rw-r--r-- | server/src/entitylist.cc | 111 | ||||
-rw-r--r-- | server/src/inotify.cc | 5 | ||||
-rw-r--r-- | server/src/inotify.h | 10 |
3 files changed, 118 insertions, 8 deletions
diff --git a/server/src/entitylist.cc b/server/src/entitylist.cc index b84df61..141345d 100644 --- a/server/src/entitylist.cc +++ b/server/src/entitylist.cc @@ -102,7 +102,8 @@ void EntityList::rescan(std::string entitypath) inotify.addDirectory(entitypath, WATCH_DEEP_FOLLOW, IN_CLOSE_WRITE | IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF | - IN_DELETE | IN_DELETE_SELF); + IN_DELETE | IN_DELETE_SELF | + IN_CREATE); @@ -168,6 +169,17 @@ void EntityList::updateList() if(event.isMoveSelfEvent()) {/* TODO: what to do here? */} if(event.isDeleteSelfEvent()) {/* TODO: what to do here? */} + + if(event.isCreateEvent()) { + if(event.isDir()) { // A new directory was ceated. Scan it for files. + std::vector<std::string> entitys = listdir(event.name()+"/"+event.file()); + std::vector<std::string>::iterator i = entitys.begin(); + while(i != entitys.end()) { + updateFile(*i); + i++; + } + } + } } } @@ -189,17 +201,100 @@ std::string EntityList::getLatestVersion(std::string entity) throw(Exception) } #ifdef TEST_ENTITYLIST -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: +//deps: inotify.cc debug.cc mutex.cc exception.cc versionstr.cc log.cc +//cflags: -I.. +//libs: -lpthread #include "test.h" +class TestList : public EntityList { +public: + TestList(std::string path) : EntityList("test") { rescan(path); } + + void setNext(std::string v, std::string e) + { + this->v = v; + this->e = e; + } + +private: + void addFile(std::string file) + { + fprintf(stderr, "Inserting: %s %s\n", e.c_str(), v.c_str()); + std::pair<VersionStr, std::string> p(VersionStr(v), file); + (*this)[e].insert(p); + } + + std::string v; + std::string e; +}; + +#define _DIR "/tmp/entitylist_test_dir" + +bool createfile(TestList &lst, std::string filename, + std::string name, std::string version) +{ + lst.setNext(version, name); + + FILE *fp = fopen(filename.c_str(), "w"); + if(!fp) return false; + fprintf(fp, "something"); + fclose(fp); + return true; +} + TEST_BEGIN; -// TODO: Put some testcode here (see test.h for usable macros). +if(mkdir(_DIR, 0777) == -1) TEST_FATAL("Could not create test dir."); + +TestList lst(_DIR); + +if(!createfile(lst, _DIR"/file1.xml", "test", "1.0")) + TEST_FATAL("Unable to write to the file"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file1.xml", "Test"); + +if(!createfile(lst, _DIR"/file2.xml", "test", "2.0")) + TEST_FATAL("Unable to write to the file"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file2.xml", "Test"); + +unlink(_DIR"/file2.xml"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file1.xml", "Test"); + +if(mkdir(_DIR"/more", 0777) == -1) TEST_FATAL("Could not create test dir."); + +if(!createfile(lst, _DIR"/more/file1.xml", "test", "3.0")) + TEST_FATAL("Unable to write to the file"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/more/file1.xml", "Test"); + +if(!createfile(lst, _DIR"/more/file2.xml", "test", "4.0")) + TEST_FATAL("Unable to write to the file"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/more/file2.xml", "Test"); + +unlink(_DIR"/more/file2.xml"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/more/file1.xml", "Test"); + +rename(_DIR"/more/file1.xml", _DIR"/more/file2.xml"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/more/file2.xml", "Test"); + +rename(_DIR"/more/file2.xml", _DIR"/file3.xml"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file3.xml", "Test"); + +unlink(_DIR"/file3.xml"); + +rmdir(_DIR"/more"); + +TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file1.xml", "Test"); + +unlink(_DIR"/file1.xml"); + +rmdir(_DIR); TEST_END; diff --git a/server/src/inotify.cc b/server/src/inotify.cc index c94f809..dba3bfd 100644 --- a/server/src/inotify.cc +++ b/server/src/inotify.cc @@ -173,6 +173,11 @@ bool INotify::Event::isMovedToEvent() return TEST(_mask, IN_MOVED_TO); } +bool INotify::Event::isDir() +{ + return TEST(_mask, IN_ISDIR); +} + std::string INotify::Event::name() { return _name; diff --git a/server/src/inotify.h b/server/src/inotify.h index 5199055..cbf75b2 100644 --- a/server/src/inotify.h +++ b/server/src/inotify.h @@ -64,6 +64,8 @@ public: bool isMovedFromEvent(); bool isMovedToEvent(); + bool isDir(); + std::string name(); std::string file(); uint32_t mask(); @@ -78,6 +80,14 @@ public: ~INotify(); void addFile(std::string name, uint32_t mask = IN_ALL_EVENTS); + + /** + * WARNING: If a directory is added with WATCH_DEEP_FOLLOW, newly + * created folders will not be added to the watch before the next call + * to hasEvents or getNextEvent. thie means that any files created in + * that folder prior to htese calls will not be caught. This will need + * to be done mnually by a recursive scan. + */ void addDirectory(std::string name, depth_t depth = WATCH_SINGLE, uint32_t mask = IN_ALL_EVENTS); |