diff options
Diffstat (limited to 'project2/json')
| -rw-r--r-- | project2/json/Jamfile.jam | 8 | ||||
| -rw-r--r-- | project2/json/conversion.h | 2 | ||||
| -rw-r--r-- | project2/json/couchSession.cpp | 188 | ||||
| -rw-r--r-- | project2/json/pch.hpp | 4 | ||||
| -rw-r--r-- | project2/json/presenter-p.cpp | 3 | ||||
| -rw-r--r-- | project2/json/presenter.cpp | 26 | ||||
| -rw-r--r-- | project2/json/presenter.h | 2 |
7 files changed, 20 insertions, 213 deletions
diff --git a/project2/json/Jamfile.jam b/project2/json/Jamfile.jam index 0f87d50..3a47ff2 100644 --- a/project2/json/Jamfile.jam +++ b/project2/json/Jamfile.jam @@ -2,12 +2,11 @@ alias glibmm : : : : <cflags>"`pkg-config --cflags glibmm-2.4`" <linkflags>"`pkg-config --libs glibmm-2.4`" ; -lib boost_filesystem : : <name>boost_filesystem ; +lib stdc++fs ; lib boost_date_time : : <name>boost_date_time ; lib jsonpp ; cpp-pch pch : pch.hpp : - <include>../../libmisc <library>glibmm <library>../common//p2common ; @@ -15,13 +14,12 @@ lib p2json : pch [ glob *.cpp ] : <include>. - <include>../libmisc <library>glibmm <library>jsonpp <library>../common//p2common - <library>../lib//p2lib + <library>..//adhocutil <library>../url//p2url - <library>boost_filesystem + <library>stdc++fs <library>boost_date_time : : <include>. diff --git a/project2/json/conversion.h b/project2/json/conversion.h index 0e9d56d..3bc2412 100644 --- a/project2/json/conversion.h +++ b/project2/json/conversion.h @@ -19,7 +19,7 @@ class Project2ToJson : public boost::static_visitor<json::Value> { } }; -class JsonToProject2 : public boost::static_visitor<VariableType> { +class JsonToProject2 { public: VariableType operator()(const json::Object &) const; VariableType operator()(const json::Array &) const; diff --git a/project2/json/couchSession.cpp b/project2/json/couchSession.cpp deleted file mode 100644 index 51d466c..0000000 --- a/project2/json/couchSession.cpp +++ /dev/null @@ -1,188 +0,0 @@ -#include <pch.hpp> -#include "curlHelper.h" -#include "safeMapFind.h" -#include "exceptions.h" -#include "logger.h" -#include "buffer.h" -#include "curlsup.h" -#include <scriptLoader.h> -#include <sessionContainer.h> -#include <boost/bind.hpp> -#include <boost/lexical_cast.hpp> -#include <boost/uuid/uuid_io.hpp> -#include <boost/uuid/uuid_generators.hpp> -#include "jsonpp.h" -#include "safeMapFind.h" -#include "conversion.h" -#include "options.h" - -class CouchDBFailure : public std::exception { }; - -class CouchSessionContainer : public SessionContainer { - public: - CouchSessionContainer() { - } - virtual SessionPtr getSession(const boost::uuids::uuid & uuid) const { - try { - json::Object obj = getSessionFromServer(uuid); - if (boost::get<json::Number>(*safeMapLookup<Session::VariableNotFound>(obj, ExpiryKey)) > time(NULL)) { - SessionPtr s = new Session(uuid); - for (const json::Object::value_type & v : obj) { - s->SetValue(v.first, boost::apply_visitor(JsonToProject2(), *v.second)); - } - return s; - } - } - catch (...) { - } - return NULL; - } - - virtual void SaveSession(SessionPtr s) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_UPLOAD, 1L); - c->setopt(CURLOPT_FAILONERROR, 1); - json::Object obj; - s->ForeachValue(boost::bind(&CouchSessionContainer::addToObject, &obj, _1, _2)); - obj[ExpiryKey] = json::ValuePtr(new json::Value((json::Number)s->ExpiryTime())); - Glib::ustring out = json::serializeObject(obj, "utf-8"); - c->setopt(CURLOPT_INFILESIZE_LARGE, (curl_off_t)out.size()); - unsigned int off = 0; - for (const std::string & b : baseUrls) { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(s->ID())).c_str()); - try { - c->performSend(boost::bind(send, &out, &off, _1, _2)); - return; - } - catch (...) { - } - } - throw CouchDBFailure(); - } - - json::Object getSessionFromServer(const boost::uuids::uuid & uuid) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_FAILONERROR, 1); - Glib::ustring msg; - for (const std::string & b : baseUrls) { - try { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(uuid)).c_str()); - c->performRead(boost::bind(append, &msg, _1, _2)); - json::Object o = json::parseObject(msg); - return o; - } - catch (...) { - } - } - throw CouchDBFailure(); - } - - private: - static void addToObject(json::Object * obj, const Glib::ustring & name, const VariableType & value) { - (*obj)[name] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); - } - - static size_t send(Glib::ustring * buf, unsigned int * off, char * str, size_t l) { - size_t len = std::min(buf->size() - *off, l); - memcpy(str, buf->c_str() + *off, len); - return len; - } - - static size_t append(Glib::ustring * buf, const char * str, size_t l) { - buf->append(str, l); - return l; - } - - void setopt_s(CurlHandle::Ptr c, CURLoption o, const char * v) { - c->setopt(o, v); - } - - void setopt_l(CurlHandle::Ptr c, CURLoption o, int64_t v) { - c->setopt(o, (long)v); - } - - static std::vector<std::string> baseUrls; - static const Glib::ustring ExpiryKey; - friend class CustomCouchSessionLoader; -}; -std::vector<std::string> CouchSessionContainer::baseUrls; -const Glib::ustring CouchSessionContainer::ExpiryKey("project2:expires"); - -class CustomCouchSessionLoader : public SessionContainerLoader::For<CouchSessionContainer> { - public: - void onPeriodic() override { - try { - deleteSessions(); - compactDB(); - } - catch (...) { - Logger()->messagebf(LOG_WARNING, "Failed to purge expired sessions and compact DB"); - } - } - - INITOPTIONS; - private: - static size_t discard(size_t l) { - return l; - } - - void compactDB() { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_POST, 1); - c->appendHeader("Content-Type: application/json"); - for (const std::string & b : CouchSessionContainer::baseUrls) { - c->setopt(CURLOPT_URL, (b + "_compact").c_str()); - c->performRead(boost::bind(discard, _2)); - } - } - void deleteSessions() { - // Create the server side search map - json::Object map; - Buffer mapBuf; - mapBuf.appendf("function(doc) { var exp = doc['%s']; if (exp < %u) { emit(exp, doc._rev); } }", - CouchSessionContainer::ExpiryKey.c_str(), (unsigned int)time(NULL)); - map["map"] = json::ValuePtr(new json::Value(mapBuf.str())); - Glib::ustring mapStr(json::serializeObject(map, "utf-8")); - // Create the CURL handle - CurlPtr c = new Curl(); - c->setopt(CURLOPT_FAILONERROR, 1); - c->appendHeader("Content-Type: application/json"); - c->setopt(CURLOPT_POST, 1); - c->setopt(CURLOPT_POSTFIELDS, mapStr.c_str()); - c->setopt(CURLOPT_POSTFIELDSIZE, mapStr.bytes()); - for (const std::string & b : CouchSessionContainer::baseUrls) { - Glib::ustring msg; - try { - c->setopt(CURLOPT_URL, (b + "_temp_view").c_str()); - c->performRead(boost::bind(CouchSessionContainer::append, &msg, _1, _2)); - json::Object o = json::parseObject(msg); - for (const json::Array::value_type & v : boost::get<json::Array>(*safeMapLookup<ParamNotFound>(o, "rows"))) { - json::Object rec = boost::get<json::Object>(*v); - boost::uuids::uuid u = boost::uuids::string_generator()(boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "id")).raw()); - Glib::ustring & rev = boost::get<json::String>(*safeMapLookup<ParamNotFound>(rec, "value")); - deleteSession(u, rev); - } - return; - } - catch (...) { - } - } - } - - void deleteSession(const boost::uuids::uuid & sid, const Glib::ustring & rev) const { - CurlPtr c = new Curl(); - c->setopt(CURLOPT_CUSTOMREQUEST, "DELETE"); - for (const std::string & b : CouchSessionContainer::baseUrls) { - c->setopt(CURLOPT_URL, (b + boost::lexical_cast<std::string>(sid) + "?rev=" + rev).c_str()); - c->performRead(boost::bind(discard, _2)); - return; - } - } -}; -DECLARE_CUSTOM_COMPONENT_LOADER("couchsession", CouchSessionContainer, CustomCouchSessionLoader, SessionContainerLoader); - -DECLARE_OPTIONS(CustomCouchSessionLoader, "Session CouchDB options") -("session.couchdb.baseUrl", Options::functions([](const VariableType & v) { CouchSessionContainer::baseUrls.push_back(v); }, boost::bind(&std::vector<std::string>::clear, &CouchSessionContainer::baseUrls)), - "Base URL to store sessions in") -END_OPTIONS(CustomCouchSessionLoader); - diff --git a/project2/json/pch.hpp b/project2/json/pch.hpp index 1309317..3aa19d4 100644 --- a/project2/json/pch.hpp +++ b/project2/json/pch.hpp @@ -2,10 +2,8 @@ #ifndef JSON_PCH #define JSON_PCH -#include <boost/variant.hpp> +#include <boost/variant/variant_fwd.hpp> #include <glibmm/ustring.h> -#include <variables.h> -#include <presenter.h> #include <map> #include <stack> diff --git a/project2/json/presenter-p.cpp b/project2/json/presenter-p.cpp index 92ba8c1..29db13c 100644 --- a/project2/json/presenter-p.cpp +++ b/project2/json/presenter-p.cpp @@ -20,4 +20,5 @@ class Json_P_Presenter : public JsonPresenter { Variable Callback; }; -DECLARE_GENERIC_LOADER("json-p", PresenterLoader, Json_P_Presenter) +NAMEDFACTORY("json-p", Json_P_Presenter, PresenterFactory) + diff --git a/project2/json/presenter.cpp b/project2/json/presenter.cpp index 8db182c..4a5713a 100644 --- a/project2/json/presenter.cpp +++ b/project2/json/presenter.cpp @@ -47,21 +47,20 @@ JsonPresenter::addNamedValue(const Glib::ustring & name, const VariableType & va void JsonPresenter::addValueToObject(const Glib::ustring & name, const VariableType & value) const { - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value))); + (*curRowSet.top())[name.collate_key()] = boost::apply_visitor(Project2ToJson(), value); } void JsonPresenter::addValueToArray(const Glib::ustring &, const VariableType & value) const { - curRowArray.top()->push_back(json::ValuePtr(new json::Value(boost::apply_visitor(Project2ToJson(), value)))); + curRowArray.top()->push_back(boost::apply_visitor(Project2ToJson(), value)); } void JsonPresenter::addNewRow(const Glib::ustring &) const { - json::Value * v = new json::Value(json::Object()); - curRowSet.push(boost::get<json::Object>(v)); - curRowArray.top()->push_back(json::ValuePtr(v)); + auto v = &curRowArray.top()->emplace_back(); + curRowSet.push(std::get_if<json::Object>(v)); vaStack.push(&JsonPresenter::addValueToObject); } @@ -75,9 +74,8 @@ JsonPresenter::finishRow() const void JsonPresenter::addNewRowSet(const Glib::ustring & name) const { - json::Value * v = new json::Value(json::Object()); - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(v); - curRowSet.push(boost::get<json::Object>(v)); + auto v = &((*curRowSet.top())[name.collate_key()] = json::Object()); + curRowSet.push(std::get_if<json::Object>(v)); } void @@ -95,9 +93,8 @@ JsonPresenter::finishRowSet() const void JsonPresenter::addNewArray(const Glib::ustring & name, bool) const { - json::Value * v = new json::Value(json::Array()); - curRowArray.push(boost::get<json::Array>(v)); - (*curRowSet.top())[name.collate_key()] = json::ValuePtr(v); + auto v = &((*curRowSet.top())[name.collate_key()] = json::Array()); + curRowArray.push(std::get_if<json::Array>(v)); vaStack.push(&JsonPresenter::addValueToArray); } @@ -134,11 +131,12 @@ void JsonPresenter::writeTo(std::ostream & o, const std::string & encoding, ExecContext * ec) const { if (returnObject(ec).isNull()) { - serializeObject(object, o, encoding); + serializeValue(object, o, encoding); } else { - serializeValue(*object[returnObject(ec).as<Glib::ustring>().collate_key()], o, encoding); + serializeValue(object[returnObject(ec).as<Glib::ustring>().collate_key()], o, encoding); } } -DECLARE_GENERIC_LOADER("json", PresenterLoader, JsonPresenter) +NAMEDFACTORY("json", JsonPresenter, PresenterFactory); + diff --git a/project2/json/presenter.h b/project2/json/presenter.h index 981953c..b18f05f 100644 --- a/project2/json/presenter.h +++ b/project2/json/presenter.h @@ -7,7 +7,7 @@ #include "transform.h" #include <stack> -class JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object>, public WritableContent, public SourceOf<WritableContent> { +class DLL_PUBLIC JsonPresenter : public MultiRowSetPresenter, public ContentPresenter, public SourceOf<json::Object>, public WritableContent, public SourceOf<WritableContent> { public: JsonPresenter(ScriptNodePtr s, ObjectSource, ExecContext *); JsonPresenter(ScriptNodePtr s, ObjectSource, const Glib::ustring &); |
