summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordeva <deva>2010-01-15 10:43:59 +0000
committerdeva <deva>2010-01-15 10:43:59 +0000
commite1d4c1224c0e1abce1d8cae49e241b37f1ca3eed (patch)
tree1e6c5fc292b58f640d20bdcd7106158dea5d9a3c
parentc9e19f0f303db3d15f2dcb1185417a4200a29573 (diff)
Add fix to entitylist, for mixing updates on dir rename/moves. Updated MacroList and TemplateList to macth new interface and use new insert method.
-rw-r--r--server/src/entitylist.cc108
-rw-r--r--server/src/entitylist.h6
-rw-r--r--server/src/inotify.cc14
-rw-r--r--server/src/inotify.h3
-rw-r--r--server/src/macrolist.cc9
-rw-r--r--server/src/templatelist.cc9
6 files changed, 96 insertions, 53 deletions
diff --git a/server/src/entitylist.cc b/server/src/entitylist.cc
index 6964df1..6440a11 100644
--- a/server/src/entitylist.cc
+++ b/server/src/entitylist.cc
@@ -62,16 +62,17 @@ static std::vector<std::string> listdir(std::string path)
struct dirent *d;
while((d = readdir(dir)) != 0) {
- if(std::string(d->d_name) == "." || std::string(d->d_name) == "..") continue;
+ std::string name = d->d_name;
- if(isdir(path + "/" + d->d_name)) {
- std::vector<std::string> sub = listdir(path + "/" + d->d_name);
+ if(name == "." || name == "..") continue;
+
+ if(isdir(path + "/" + name)) {
+ std::vector<std::string> sub = listdir(path + "/" + name);
files.insert(files.end(), sub.begin(), sub.end());
continue;
}
- if(isfile(path + "/" + d->d_name)) {
- std::string name = d->d_name;
+ if(isfile(path + "/" + name)) {
if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml")
files.push_back(path + "/" + name);
}
@@ -81,23 +82,22 @@ static std::vector<std::string> listdir(std::string path)
return files;
}
-EntityList::EntityList(std::string entityname)
+EntityList::EntityList(std::string entitypath, std::string entityname)
{
MutexAutolock lock(mutex);
this->entityname = entityname;
+ this->entitypath = entitypath;
}
EntityList::~EntityList()
{
}
-void EntityList::rescan(std::string entitypath)
+void EntityList::rescan()
{
- MutexAutolock lock(mutex);
-
clear();
- // inotify.clear();
+ inotify.clear();
inotify.addDirectory(entitypath, WATCH_DEEP_FOLLOW,
IN_CLOSE_WRITE |
@@ -105,9 +105,6 @@ void EntityList::rescan(std::string entitypath)
IN_DELETE | IN_DELETE_SELF |
IN_CREATE);
-
-
-
std::vector<std::string> entitys = listdir(entitypath);
std::vector<std::string>::iterator i = entitys.begin();
while(i != entitys.end()) {
@@ -162,16 +159,15 @@ void EntityList::updateList()
{
while(inotify.hasEvents()) {
INotify::Event event = inotify.getNextEvent();
- if(event.isCloseWriteEvent()) updateFile(event.name()+"/"+event.file());
- if(event.isMovedFromEvent()) removeFile(event.name()+"/"+event.file());
- if(event.isMovedToEvent()) updateFile(event.name()+"/"+event.file());
- if(event.isDeleteEvent()) removeFile(event.name()+"/"+event.file());
- if(event.isMoveSelfEvent()) {/* TODO: what to do here? */}
- if(event.isDeleteSelfEvent()) {/* TODO: what to do here? */}
+ PRACRO_DEBUG(entitylist, "Handling event %s on %s, with param %s\n",
+ event.maskstr().c_str(),
+ event.name().c_str(),
+ event.file().c_str());
- if(event.isCreateEvent()) {
- if(event.isDir()) { // A new directory was ceated. Scan it for files.
+ if(event.isDir()) {
+ if(event.isCreateEvent()) {
+ // 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()) {
@@ -179,6 +175,18 @@ void EntityList::updateList()
i++;
}
}
+
+ if(event.isMoveSelfEvent()) rescan();
+ if(event.isDeleteSelfEvent()) rescan();
+ if(event.isDeleteEvent()) rescan();
+ if(event.isMovedFromEvent()) rescan();
+ if(event.isMovedToEvent()) rescan();
+
+ } else {
+ if(event.isCloseWriteEvent()) updateFile(event.name()+"/"+event.file());
+ if(event.isMovedFromEvent()) removeFile(event.name()+"/"+event.file());
+ if(event.isMovedToEvent()) updateFile(event.name()+"/"+event.file());
+ if(event.isDeleteEvent()) removeFile(event.name()+"/"+event.file());
}
}
}
@@ -189,9 +197,11 @@ std::string EntityList::getLatestVersion(std::string entity) throw(Exception)
updateList();
- if(find(entity) == end()) throw Exception("Entity ("+entityname+") ["+entity+"] does not exist");
+ if(find(entity) == end())
+ throw Exception("Entity ("+entityname+") ["+entity+"] does not exist");
EntityListItem mli = (*this)[entity];
- if(mli.size() == 0) throw Exception("Entity ("+entityname+") ["+entity+"] does not exist.");
+ if(mli.size() == 0)
+ throw Exception("Entity ("+entityname+") ["+entity+"] does not exist.");
PRACRO_DEBUG(entitylist, "Search for %s - found %s v%s\n",
entity.c_str(),
mli.begin()->second.c_str(),
@@ -200,54 +210,62 @@ std::string EntityList::getLatestVersion(std::string entity) throw(Exception)
return mli.begin()->second;
}
+void EntityList::insertEntity(std::string entity, std::string version, std::string file)
+{
+ std::pair<VersionStr, std::string> p(VersionStr(version), file);
+ (*this)[entity].insert(p);
+}
+
#ifdef TEST_ENTITYLIST
//deps: inotify.cc debug.cc mutex.cc exception.cc versionstr.cc log.cc
//cflags: -I..
//libs: -lpthread
#include "test.h"
+#include <string.h>
+
+#define _DIR "/tmp/entitylist_test_dir"
+
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;
- }
+ TestList(std::string path) : EntityList(path, "test") { rescan(); }
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);
+ char version[32];
+ FILE *fp = fopen(file.c_str(), "r");
+ if(!fp) return;
+ memset(version, 0, sizeof(version));
+ fread(version, sizeof(version), 1, fp);
+ fclose(fp);
+
+ fprintf(stderr, "Inserting: %s\n", version);
+ insertEntity("test", version, file);
}
-
- 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");
+ fprintf(fp, "%s", version.c_str());
fclose(fp);
return true;
}
TEST_BEGIN;
+pracro_debug_parse("-all,+entitylist");
+
if(mkdir(_DIR, 0777) == -1) TEST_FATAL("Could not create test dir.");
TestList lst(_DIR);
+TEST_EXCEPTION(lst.getLatestVersion("test"), Exception,
+ "Test lookup of macro in empty tree.");
+
if(!createfile(lst, _DIR"/file1.xml", "test", "1.0"))
TEST_FATAL("Unable to write to the file");
@@ -282,13 +300,17 @@ 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");
+rename(_DIR"/more", _DIR"/more2");
+
+TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/more2/file2.xml", "Test");
+
+rename(_DIR"/more2/file2.xml", _DIR"/file3.xml");
TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file3.xml", "Test");
unlink(_DIR"/file3.xml");
-rmdir(_DIR"/more");
+rmdir(_DIR"/more2");
TEST_EQUAL_STR(lst.getLatestVersion("test"), _DIR"/file1.xml", "Test");
diff --git a/server/src/entitylist.h b/server/src/entitylist.h
index 9185f67..3bcdfd0 100644
--- a/server/src/entitylist.h
+++ b/server/src/entitylist.h
@@ -58,7 +58,7 @@ public:
* @param entitypath A std::string containing the path in which we should look
* for xml files.
*/
- EntityList(std::string entityname);
+ EntityList(std::string entitypath, std::string entityname);
virtual ~EntityList();
/**
@@ -71,7 +71,8 @@ public:
std::string getLatestVersion(std::string entity) throw(Exception);
protected:
- void rescan(std::string entitypath);
+ void rescan();
+ void insertEntity(std::string entity, std::string version, std::string file);
private:
virtual void addFile(std::string file) = 0;
@@ -84,6 +85,7 @@ private:
INotify inotify;
std::string entityname;
+ std::string entitypath;
};
#endif/*__PRACRO_ENTITYLIST_H__*/
diff --git a/server/src/inotify.cc b/server/src/inotify.cc
index dba3bfd..5fb983e 100644
--- a/server/src/inotify.cc
+++ b/server/src/inotify.cc
@@ -193,6 +193,11 @@ uint32_t INotify::Event::mask()
return _mask;
}
+std::string INotify::Event::maskstr()
+{
+ return mask2asc(_mask);
+}
+
INotify::INotify()
{
ifd = inotify_init1(O_NONBLOCK);
@@ -370,6 +375,15 @@ INotify::Event INotify::getNextEvent()
return e;
}
+void INotify::clear()
+{
+ if(ifd != -1) close(ifd);
+ ifd = inotify_init1(O_NONBLOCK);
+ if(ifd == -1) {
+ perror("Inotify init failed.\n");
+ }
+}
+
#ifdef TEST_INOTIFY
//deps: debug.cc
//cflags: -I..
diff --git a/server/src/inotify.h b/server/src/inotify.h
index cbf75b2..d63e384 100644
--- a/server/src/inotify.h
+++ b/server/src/inotify.h
@@ -69,6 +69,7 @@ public:
std::string name();
std::string file();
uint32_t mask();
+ std::string maskstr();
private:
std::string _name;
@@ -97,6 +98,8 @@ public:
bool hasEvents();
Event getNextEvent();
+ void clear();
+
private:
class Watch {
public:
diff --git a/server/src/macrolist.cc b/server/src/macrolist.cc
index 9dadb12..954149a 100644
--- a/server/src/macrolist.cc
+++ b/server/src/macrolist.cc
@@ -34,9 +34,9 @@
#include "debug.h"
MacroList::MacroList(std::string path)
- : EntityList("macro")
+ : EntityList(path, "macro")
{
- rescan(path);
+ rescan();
}
@@ -47,8 +47,9 @@ void MacroList::addFile(std::string file)
try {
parser.parse();
Macro *macro = parser.getMacro();
- std::pair<VersionStr, std::string> p(VersionStr(macro->attributes["version"]), file);
- (*this)[macro->attributes["name"]].insert(p);
+ insertEntity(macro->attributes["name"],
+ macro->attributes["version"],
+ file);
} catch(Exception &e) {
PRACRO_WARN(macrolist, "Skipping %s: %s\n", file.c_str(), e.what());
}
diff --git a/server/src/templatelist.cc b/server/src/templatelist.cc
index 0fc8ec5..b8e8462 100644
--- a/server/src/templatelist.cc
+++ b/server/src/templatelist.cc
@@ -32,9 +32,9 @@
#include "debug.h"
TemplateList::TemplateList(std::string path)
- : EntityList("template")
+ : EntityList(path, "template")
{
- rescan(path);
+ rescan();
}
void TemplateList::addFile(std::string file)
@@ -44,8 +44,9 @@ void TemplateList::addFile(std::string file)
try {
parser.parse();
Template *templ = parser.getTemplate();
- std::pair<VersionStr, std::string> p(VersionStr(templ->attributes["version"]), file);
- (*this)[templ->attributes["name"]].insert(p);
+ insertEntity(templ->attributes["name"],
+ templ->attributes["version"],
+ file);
} catch(Exception &e) {
PRACRO_WARN(templatelist, "Skipping %s: %s\n", file.c_str(), e.what());
}