diff options
Diffstat (limited to 'sca-cpp/trunk/components')
78 files changed, 1156 insertions, 2331 deletions
diff --git a/sca-cpp/trunk/components/cache/Makefile.am b/sca-cpp/trunk/components/cache/Makefile.am index 0240a32bb4..3704a7a3ce 100644 --- a/sca-cpp/trunk/components/cache/Makefile.am +++ b/sca-cpp/trunk/components/cache/Makefile.am @@ -50,7 +50,7 @@ memcache_test_SOURCES = memcache-test.cpp memcache_test_LDFLAGS = -lxml2 client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = memcached-test memcached-ssl-test server-test noinst_PROGRAMS = memcache-test client-test diff --git a/sca-cpp/trunk/components/cache/cache.composite b/sca-cpp/trunk/components/cache/cache.composite index a85f909db9..99fdd8ffc0 100644 --- a/sca-cpp/trunk/components/cache/cache.composite +++ b/sca-cpp/trunk/components/cache/cache.composite @@ -81,7 +81,7 @@ <service name="selector"> <binding.http uri="selector"/> </service> - </component> + </component> <component name="partition1"> <implementation.scheme script="partition1-test.scm"/> diff --git a/sca-cpp/trunk/components/cache/client-test.cpp b/sca-cpp/trunk/components/cache/client-test.cpp index 63d1691f8b..5e9be6c14a 100644 --- a/sca-cpp/trunk/components/cache/client-test.cpp +++ b/sca-cpp/trunk/components/cache/client-test.cpp @@ -42,15 +42,15 @@ const string memocacheuri("http://localhost:8090/memocache"); const string partition1uri("http://localhost:8090/partitioner/a"); const string partition2uri("http://localhost:8090/partitioner/b"); -bool testCache(const string& uri) { - http::CURLSession cs("", "", "", "", 0); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testCache(const string& uri) { + const http::CURLSession cs("", "", "", "", 0); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); const failable<value> id = http::post(a, uri, cs); @@ -63,18 +63,18 @@ bool testCache(const string& uri) { assert(content(val) == a); } - const list<value> j = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$3.55"))); - const list<value> b = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> j = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$3.55"))); + const list<value> b = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + j); { const failable<value> r = http::put(b, uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -84,7 +84,7 @@ bool testCache(const string& uri) { { const failable<value> r = http::del(uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -94,16 +94,16 @@ bool testCache(const string& uri) { return true; } -bool testMemcache() { +const bool testMemcache() { return testCache(memcacheuri); } -bool testDatacache() { +const bool testDatacache() { return testCache(datacacheuri); } -bool testMemocache() { - http::CURLSession cs("", "", "", "", 0); +const bool testMemocache() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> res = http::evalExpr(mklist<value>(string("add"), 33, 22), memocacheuri, cs); assert(hasContent(res)); @@ -116,8 +116,8 @@ bool testMemocache() { return true; } -bool testPartitioner() { - http::CURLSession cs("", "", "", "", 0); +const bool testPartitioner() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> res1 = http::get(partition1uri, cs); assert(hasContent(res1)); @@ -130,35 +130,26 @@ bool testPartitioner() { return true; } -struct getLoop { - const string path; - const value entry; - http::CURLSession& cs; - getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) { - } - const bool operator()() const { - const failable<value> val = http::get(memcacheuri + path, cs); - assert(hasContent(val)); - assert(content(val) == entry); - return true; - } -}; - -bool testGetPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$4.55"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testGetPerf() { + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$4.55"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", "", "", 0); + const http::CURLSession cs("", "", "", "", 0); const failable<value> id = http::post(a, memcacheuri, cs); assert(hasContent(id)); const string p = path(content(id)); - const lambda<bool()> gl = getLoop(p, a, cs); + const blambda gl = [p, a, cs]() -> const bool { + const failable<value> val = http::get(memcacheuri + p, cs); + assert(hasContent(val)); + assert(content(val) == a); + return true; + }; cout << "Cache get test " << time(gl, 5, 200) << " ms" << endl; return true; diff --git a/sca-cpp/trunk/components/cache/datacache.cpp b/sca-cpp/trunk/components/cache/datacache.cpp index c259ec33c6..975ca43dce 100644 --- a/sca-cpp/trunk/components/cache/datacache.cpp +++ b/sca-cpp/trunk/components/cache/datacache.cpp @@ -44,7 +44,7 @@ namespace datacache { /** * Get an item from the cache. */ -const failable<value> get(const value& key, const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, const lambda<value(const list<value>&)>& rcache2, unused const lambda<value(const list<value>&)>& wcache2) { +const failable<value> get(const value& key, const lvvlambda& rcache1, const lvvlambda& wcache1, const lvvlambda& rcache2, unused const lvvlambda& wcache2) { // Lookup level1 cache const value val1 = rcache1(mklist<value>("get", key)); @@ -68,7 +68,7 @@ const failable<value> get(const value& key, const lambda<value(const list<value> /** * Post an item to the cache. */ -const failable<value> post(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) { +const failable<value> post(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { const value id = append<value>(key, mklist(mkuuid())); // Update level1 cache @@ -83,7 +83,7 @@ const failable<value> post(const value& key, const value& val, unused const lamb /** * Put an item into the cache. */ -const failable<value> put(const value& key, const value& val, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) { +const failable<value> put(const value& key, const value& val, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { // Update level1 cache wcache1(mklist<value>("put", key, val)); @@ -91,13 +91,13 @@ const failable<value> put(const value& key, const value& val, unused const lambd // Update level2 cache wcache2(mklist<value>("put", key, val)); - return value(true); + return trueValue; } /** * Delete an item from the cache. */ -const failable<value> del(const value& key, unused const lambda<value(const list<value>&)>& rcache1, const lambda<value(const list<value>&)>& wcache1, unused const lambda<value(const list<value>&)>& rcache2, const lambda<value(const list<value>&)>& wcache2) { +const failable<value> del(const value& key, unused const lvvlambda& rcache1, const lvvlambda& wcache1, unused const lvvlambda& rcache2, const lvvlambda& wcache2) { // Delete from level1 cache wcache1(mklist<value>("delete", key)); @@ -105,7 +105,7 @@ const failable<value> del(const value& key, unused const lambda<value(const list // Delete from level2 cache wcache2(mklist<value>("delete", key)); - return value(true); + return trueValue; } } diff --git a/sca-cpp/trunk/components/cache/memcache-test.cpp b/sca-cpp/trunk/components/cache/memcache-test.cpp index 85fc339f1a..6c6adb0541 100644 --- a/sca-cpp/trunk/components/cache/memcache-test.cpp +++ b/sca-cpp/trunk/components/cache/memcache-test.cpp @@ -33,7 +33,7 @@ namespace tuscany { namespace memcache { bool testMemCached() { - MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213")); + const MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213")); const value k = mklist<value>("a"); assert(hasContent(post(k, string("AAA"), ch))); @@ -46,24 +46,16 @@ bool testMemCached() { return true; } -struct getLoop { - const value k; - MemCached& ch; - getLoop(const value& k, MemCached& ch) : k(k), ch(ch) { - } - const bool operator()() const { - gc_scoped_pool p; - assert(get(k, ch) == value(string("CCC"))); - return true; - } -}; - -bool testGetPerf() { +const bool testGetPerf() { const value k = mklist<value>("c"); - MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213")); + const MemCached ch(mklist<string>("localhost:11211", "localhost:11212", "localhost:11213")); assert(hasContent(post(k, string("CCC"), ch))); - const lambda<bool()> gl = getLoop(k, ch); + const blambda gl = [k, ch]() -> const bool { + const gc_scoped_pool p; + assert(get(k, ch) == value(string("CCC"))); + return true; + }; cout << "Memcached get test " << time(gl, 5, 200) << " ms" << endl; return true; } @@ -72,7 +64,7 @@ bool testGetPerf() { } int main() { - tuscany::gc_scoped_pool p; + const tuscany::gc_scoped_pool p; tuscany::cout << "Testing..." << tuscany::endl; tuscany::memcache::testMemCached(); diff --git a/sca-cpp/trunk/components/cache/memcache.cpp b/sca-cpp/trunk/components/cache/memcache.cpp index 738a6ddd5a..2e4597efd3 100644 --- a/sca-cpp/trunk/components/cache/memcache.cpp +++ b/sca-cpp/trunk/components/cache/memcache.cpp @@ -37,14 +37,14 @@ namespace cache { /** * Get an item from the cache. */ -const failable<value> get(const list<value>& params, memcache::MemCached& ch) { +const failable<value> get(const list<value>& params, const memcache::MemCached& ch) { return memcache::get(car(params), ch); } /** * Post an item to the cache. */ -const failable<value> post(const list<value>& params, memcache::MemCached& ch) { +const failable<value> post(const list<value>& params, const memcache::MemCached& ch) { const value id = append<value>(car(params), mklist(mkuuid())); const failable<bool> val = memcache::post(id, cadr(params), ch); if (!hasContent(val)) @@ -55,7 +55,7 @@ const failable<value> post(const list<value>& params, memcache::MemCached& ch) { /** * Put an item into the cache. */ -const failable<value> put(const list<value>& params, memcache::MemCached& ch) { +const failable<value> put(const list<value>& params, const memcache::MemCached& ch) { const failable<bool> val = memcache::put(car(params), cadr(params), ch); if (!hasContent(val)) return mkfailure<value>(val); @@ -65,7 +65,7 @@ const failable<value> put(const list<value>& params, memcache::MemCached& ch) { /** * Delete an item from the cache. */ -const failable<value> del(const list<value>& params, memcache::MemCached& ch) { +const failable<value> del(const list<value>& params, const memcache::MemCached& ch) { const failable<bool> val = memcache::del(car(params), ch); if (!hasContent(val)) return mkfailure<value>(val); @@ -73,37 +73,12 @@ const failable<value> del(const list<value>& params, memcache::MemCached& ch) { } /** - * Component implementation lambda function. - */ -class applyCache { -public: - applyCache(memcache::MemCached& ch) : ch(ch) { - } - - const value operator()(const list<value>& params) const { - const value func(car(params)); - if (func == "get") - return get(cdr(params), ch); - if (func == "post") - return post(cdr(params), ch); - if (func == "put") - return put(cdr(params), ch); - if (func == "delete") - return del(cdr(params), ch); - return mkfailure<value>(); - } - -private: - memcache::MemCached& ch; -}; - -/** * Convert a list of properties to a list of server addresses. */ const list<string> servers(const list<value>& params) { if (isNil(params)) return list<string>(); - const value s = ((lambda<value(const list<value>&)>)car(params))(list<value>()); + const value s = ((lvvlambda)car(params))(nilListValue); return cons<string>(s, servers(cdr(params))); } @@ -112,10 +87,22 @@ const list<string> servers(const list<value>& params) { */ const failable<value> start(const list<value>& params) { // Connect to memcached - memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(servers(params))); + const memcache::MemCached& ch = *(new (gc_new<memcache::MemCached>()) memcache::MemCached(servers(params))); // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyCache(ch))); + const lvvlambda applyCache = [ch](const list<value>& params) -> const value { + const value func(car(params)); + if (func == "get") + return get(cdr(params), ch); + if (func == "post") + return post(cdr(params), ch); + if (func == "put") + return put(cdr(params), ch); + if (func == "delete") + return del(cdr(params), ch); + return mkfailure<value>(); + }; + return value(applyCache); } } diff --git a/sca-cpp/trunk/components/cache/memcache.hpp b/sca-cpp/trunk/components/cache/memcache.hpp index f18405b2ec..00ee9c6291 100644 --- a/sca-cpp/trunk/components/cache/memcache.hpp +++ b/sca-cpp/trunk/components/cache/memcache.hpp @@ -48,43 +48,28 @@ namespace memcache { */ class MemCached { public: - MemCached() : owner(false) { + MemCached() : owner(false), mc(NULL) { } - MemCached(const string host, const int port) : p(), owner(true) { - debug(host, "memcache::memcached::host"); - debug(port, "memcache::memcached::port"); - apr_memcache_create(pool(p), 1, 0, &mc); - addServer(host, port); + MemCached(const string& host, const int port) : p(), owner(true), mc(mkmc(host, port)) { } - MemCached(const list<string>& servers) : p(), owner(true) { - debug(servers, "memcache::memcached::servers"); - apr_memcache_create(pool(p), (apr_uint16_t)length(servers), 0, &mc); - addServers(servers); + MemCached(const list<string>& servers) : p(), owner(true), mc(mkmc(servers)) { } MemCached(const MemCached& c) : p(c.p), owner(false), mc(c.mc) { debug("memcache::memcached::copy"); } - const MemCached& operator=(const MemCached& c) { - debug("memcache::memcached::operator="); - if(this == &c) - return *this; - p = c.p; - owner = false; - mc = c.mc; - return *this; - } + MemCached& operator=(const MemCached& c) = delete; ~MemCached() { } private: - gc_child_pool p; - bool owner; - apr_memcache_t* mc; + const gc_child_pool p; + const bool owner; + apr_memcache_t* const mc; friend const failable<bool> post(const value& key, const value& val, const MemCached& cache); friend const failable<bool> put(const value& key, const value& val, const MemCached& cache); @@ -94,7 +79,7 @@ private: /** * Add servers to the memcached context. */ - const failable<bool> addServer(const string& host, const int port) { + const failable<bool> addServer(apr_memcache_t* const m, const string& host, const int port) { apr_memcache_server_t *server; const apr_status_t sc = apr_memcache_server_create(pool(p), c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server); if (sc != APR_SUCCESS) { @@ -102,27 +87,48 @@ private: os << "Couldn't connect to memcached server: " << host << ":" << port; return mkfailure<bool>(str(os)); } - const apr_status_t as = apr_memcache_add_server(mc, server); + const apr_status_t as = apr_memcache_add_server(m, server); if (as != APR_SUCCESS) return mkfailure<bool>("Couldn't add memcached server"); return true; } - const failable<bool> addServers(const list<string>& servers) { + const failable<bool> addServers(apr_memcache_t* const m, const list<string>& servers) { if (isNil(servers)) return true; const list<string> toks = tokenize(":", car(servers)); - const failable<bool> r = addServer(car(toks), isNil(cdr(toks))? 11211 : atoi(c_str(cadr(toks)))); + const failable<bool> r = addServer(m, car(toks), isNil(cdr(toks))? 11211 : atoi(c_str(cadr(toks)))); if (!hasContent(r)) return r; - return addServers(cdr(servers)); + return addServers(m, cdr(servers)); + } + + /** + * Create memcached handle. + */ + apr_memcache_t* const mkmc(const string& host, const int port) { + debug(host, "memcache::memcached::host"); + debug(port, "memcache::memcached::port"); + apr_memcache_t* m; + apr_memcache_create(pool(p), 1, 0, &m); + addServer(m, host, port); + return m; } + + apr_memcache_t* const mkmc(const list<string>& servers) { + debug(servers, "memcache::memcached::servers"); + apr_memcache_t* m; + apr_memcache_create(pool(p), (apr_uint16_t)length(servers), 0, &m); + addServers(m, servers); + return m; + } + }; /** * Replace spaces by tabs (as spaces are not allowed in memcached keys). */ -const char* nospaces(const char* s) { +const char* const nospaces(const char* const s) { char* c = const_cast<char*>(s); for (; *c; c++) if (*c == ' ') @@ -137,8 +143,8 @@ const failable<bool> post(const value& key, const value& val, const MemCached& c debug(key, "memcache::post::key"); debug(val, "memcache::post::value"); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); const apr_status_t rc = apr_memcache_add(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27); if (rc != APR_SUCCESS) { ostringstream os; @@ -157,8 +163,8 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca debug(key, "memcache::put::key"); debug(val, "memcache::put::value"); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); const apr_status_t rc = apr_memcache_set(cache.mc, nospaces(c_str(ks)), const_cast<char*>(c_str(vs)), length(vs), 0, 27); if (rc != APR_SUCCESS) { ostringstream os; @@ -176,17 +182,17 @@ const failable<bool> put(const value& key, const value& val, const MemCached& ca const failable<value> get(const value& key, const MemCached& cache) { debug(key, "memcache::get::key"); - const string ks(scheme::writeValue(key)); + const string ks(write(content(scheme::writeValue(key)))); char *data; apr_size_t size; - gc_local_pool lp; + const gc_local_pool lp; const apr_status_t rc = apr_memcache_getp(cache.mc, pool(lp), nospaces(c_str(ks)), &data, &size, NULL); if (rc != APR_SUCCESS) { ostringstream os; os << "Couldn't get memcached entry: " << key; return mkfailure<value>(str(os), 404, false); } - const value val(scheme::readValue(string(data, size))); + const value val(content(scheme::readValue(string(data, size)))); debug(val, "memcache::get::result"); return val; @@ -198,7 +204,7 @@ const failable<value> get(const value& key, const MemCached& cache) { const failable<bool> del(const value& key, const MemCached& cache) { debug(key, "memcache::delete::key"); - const string ks(scheme::writeValue(key)); + const string ks(write(content(scheme::writeValue(key)))); const apr_status_t rc = apr_memcache_delete(cache.mc, nospaces(c_str(ks)), 0); if (rc != APR_SUCCESS) { ostringstream os; diff --git a/sca-cpp/trunk/components/cache/memocache.cpp b/sca-cpp/trunk/components/cache/memocache.cpp index e7e52cdc59..5539ccee2f 100644 --- a/sca-cpp/trunk/components/cache/memocache.cpp +++ b/sca-cpp/trunk/components/cache/memocache.cpp @@ -42,7 +42,7 @@ namespace memocache { /** * Memoize the value of a function application in a cache. */ -const failable<value> memoize(const list<value>& params, const lambda<value(const list<value>&)>& relay, const lambda<value(const list<value>&)>& cache) { +const failable<value> memoize(const list<value>& params, const lvvlambda& relay, const lvvlambda& cache) { debug(params, "memocache::memoize::params"); // Lookup memoized value from cache diff --git a/sca-cpp/trunk/components/cache/partitioner.cpp b/sca-cpp/trunk/components/cache/partitioner.cpp index e3f04ba112..a38c053358 100644 --- a/sca-cpp/trunk/components/cache/partitioner.cpp +++ b/sca-cpp/trunk/components/cache/partitioner.cpp @@ -22,7 +22,7 @@ /** * A partitioner component implementation which forwards data access requests to a * dynamically selected data store component. The selection is externalized, performed - * by a selector component, responsible for selecting the target data store given the + * by a selector component, responsible for selecting the target data stores given the * data access request key and a list of references to available data store components. * This pattern can be used for sharding or load balancing for example. */ @@ -38,54 +38,89 @@ namespace tuscany { namespace partitioner { /** - * Return the target partition for a key. + * Return a list of target partitions for a key. */ -const failable<lambda<value(const list<value>&)> > partition(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) { +const failable<list<value> > partition(const value& key, const lvvlambda& selector, const list<value>& partitions) { - // Call the selector component to convert the given key to a partition number + // Call the selector component to convert the given key to a list of partitions const value p = selector(mklist<value>("get", key, partitions)); if (isNil(p)) { ostringstream os; - os << "Couldn't get partition number: " << key; - return mkfailure<lambda<value(const list<value>&)> >(str(os), -1, false); + os << "Couldn't get partition: " << key; + return mkfailure<list<value> >(str(os), -1, false); } - return (const lambda<value(const list<value>&)>)p; + return (list<value>)p; +} + + +/** + * Get lists of items from a list of partitions. + */ +const failable<list<value> > getlist(const value& key, const list<value>& partitions) { + if (isNil(partitions)) + return nilListValue; + + const lvvlambda l = car(partitions); + const value val = l(mklist<value>("get", key)); + if (isNil(val)) + return getlist(key, cdr(partitions)); + if (!isList(val)) { + ostringstream os; + os << "Couldn't get list of entries from partition: " << key; + return mkfailure<list<value> >(str(os), 500, false); + } + + const failable<list<value> > cdrval = getlist(key, cdr(partitions)); + if (!hasContent(cdrval)) + return cdrval; + + return append<value>((list<value>)val, content(cdrval)); } /** * Get an item from a partition. */ -const failable<value> get(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) { +const failable<value> get(const value& key, const lvvlambda& selector, const list<value>& partitions) { // Select partition - const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions); - if (!hasContent(p)) - return mkfailure<value>(p); - - // Get from selected partition - const value val = content(p)(mklist<value>("get", key)); - if (isNil(val)) { - ostringstream os; - os << "Couldn't get entry from partition: " << key; - return mkfailure<value>(str(os), 404, false); + const failable<list<value> > fp = partition(key, selector, partitions); + if (!hasContent(fp)) + return mkfailure<value>(fp); + const list<value> p = content(fp); + + // Get a single item from the selected partition + if (length(p) == 1) { + const lvvlambda l = car(p); + const value val = l(mklist<value>("get", key)); + if (isNil(val)) { + ostringstream os; + os << "Couldn't get entry from partition: " << key; + return mkfailure<value>(str(os), 404, false); + } + return val; } - return val; + // Get list of items from the list of selected partitions + const failable<list<value> > val = getlist(key, p); + if (!hasContent(val)) + return mkfailure<value>(val); + return (value)content(val); } /** * Post an item to a partition. */ -const failable<value> post(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) { +const failable<value> post(const value& key, const value& val, const lvvlambda& selector, const list<value>& partitions) { const value id = append<value>(key, mklist(mkuuid())); // Select partition - const failable<lambda<value(const list<value>&)> > p = partition(id, selector, partitions); + const failable<list<value> > p = partition(id, selector, partitions); if (!hasContent(p)) return mkfailure<value>(p); // Put into select partition - content(p)(mklist<value>("put", id, val)); + const lvvlambda l = car(content(p)); + l(mklist<value>("post", id, val)); return id; } @@ -93,33 +128,35 @@ const failable<value> post(const value& key, const value& val, const lambda<valu /** * Put an item into a partition. */ -const failable<value> put(const value& key, const value& val, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) { +const failable<value> put(const value& key, const value& val, const lvvlambda& selector, const list<value>& partitions) { // Select partition - const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions); + const failable<list<value> > p = partition(key, selector, partitions); if (!hasContent(p)) return mkfailure<value>(p); // Put into selected partition - content(p)(mklist<value>("put", key, val)); + const lvvlambda l = car(content(p)); + l(mklist<value>("put", key, val)); - return value(true); + return trueValue; } /** * Delete an item from a partition. */ -const failable<value> del(const value& key, const lambda<value(const list<value>&)>& selector, const list<value>& partitions) { +const failable<value> del(const value& key, const lvvlambda& selector, const list<value>& partitions) { // Select partition - const failable<lambda<value(const list<value>&)> > p = partition(key, selector, partitions); + const failable<list<value> > p = partition(key, selector, partitions); if (!hasContent(p)) return mkfailure<value>(p); // Delete from selected partition - content(p)(mklist<value>("delete", key)); + const lvvlambda l = car(content(p)); + l(mklist<value>("delete", key)); - return value(true); + return trueValue; } } diff --git a/sca-cpp/trunk/components/cache/select-test.scm b/sca-cpp/trunk/components/cache/select-test.scm index 9baa82a5da..f788a6104a 100644 --- a/sca-cpp/trunk/components/cache/select-test.scm +++ b/sca-cpp/trunk/components/cache/select-test.scm @@ -17,5 +17,5 @@ ; Partition selector test case -(define (get key partitions) (if (= (car key) "a") (car partitions) (cadr partitions))) +(define (get key partitions) (if (= (car key) "a") (list (car partitions)) (list (cadr partitions)))) diff --git a/sca-cpp/trunk/components/chat/Makefile.am b/sca-cpp/trunk/components/chat/Makefile.am index 5c995ad452..1efbb5b298 100644 --- a/sca-cpp/trunk/components/chat/Makefile.am +++ b/sca-cpp/trunk/components/chat/Makefile.am @@ -58,7 +58,7 @@ xmpp_test_SOURCES = xmpp-test.cpp xmpp_test_LDFLAGS = -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lssl -lresolv client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lssl -lresolv +client_test_LDFLAGS = -lxml2 -lcurl -ljansson -L${LIBSTROPHE_LIB} -R${LIBSTROPHE_LIB} -lstrophe -lssl -lresolv comp_PROGRAMS = chat-send @@ -67,12 +67,18 @@ dist_noinst_SCRIPTS = server-test if WANT_VYSPER +noinst_DATA += test/TestVysperServer.class + AM_JAVACFLAGS = -cp `${top_builddir}/components/chat/vysper-classpath ${VYSPER_PREFIX}`${JAVAROOT} dist_noinst_JAVA = test/*.java +.java.class: + ${JAVAC} ${AM_JAVACFLAGS} test/*.java + CLEANFILES = test/*.class dist_noinst_SCRIPTS += echo-test -TESTS = echo-test server-test +#TESTS = echo-test server-test + endif endif diff --git a/sca-cpp/trunk/components/chat/chat-send.cpp b/sca-cpp/trunk/components/chat/chat-send.cpp index bb3907acfd..b4c21a49ee 100644 --- a/sca-cpp/trunk/components/chat/chat-send.cpp +++ b/sca-cpp/trunk/components/chat/chat-send.cpp @@ -37,7 +37,7 @@ namespace tuscany { namespace chat { -bool sendmsg(const string& jid, const string& pass, const string& to, const string& msg) { +const bool sendmsg(const string& jid, const string& pass, const string& to, const string& msg) { XMPPClient xc(jid, pass); const failable<bool> c = connect(xc); assert(hasContent(c)); @@ -49,7 +49,7 @@ bool sendmsg(const string& jid, const string& pass, const string& to, const stri } } -int main(unused const int argc, const char** argv) { +int main(unused const int argc, const char** const argv) { tuscany::chat::sendmsg(argv[1], argv[2], argv[3], argv[4]); return 0; } diff --git a/sca-cpp/trunk/components/chat/chat-sender.cpp b/sca-cpp/trunk/components/chat/chat-sender.cpp index a4cabef8de..64d0271d43 100644 --- a/sca-cpp/trunk/components/chat/chat-sender.cpp +++ b/sca-cpp/trunk/components/chat/chat-sender.cpp @@ -51,45 +51,38 @@ const failable<value> post(const list<value>& params, XMPPClient& xc) { } /** - * Subscribe and listen to an XMPP session. + * Start the component. */ -class noop { -public: - noop() { - } - - const failable<bool> operator()(unused const value& jid, unused const value& val, unused XMPPClient& xc) const { - return true; - } -}; - -class subscribe { -public: - subscribe(XMPPClient& xc) : xc(xc) { - } - - const failable<bool> operator()() const { - gc_pool pool; +const failable<value> start(const list<value>& params) { + // Extract the the XMPP JID and password + const list<value> props = params; + const value jid = ((lvvlambda)car(props))(nilListValue); + const value pass = ((lvvlambda)cadr(props))(nilListValue); + + // Create an XMPP client session + XMPPClient xc(jid, pass, false); + const failable<bool> r = connect(xc); + if (!hasContent(r)) + return mkfailure<value>(r); + + // Subscribe and listen to XMPP session + const lambda<const failable<bool>()> subscribe = [xc]() -> const failable<bool> { + const gc_pool pool; debug("chat::subscribe::listen"); - const failable<bool> r = listen(noop(), const_cast<XMPPClient&>(xc)); + const lambda<const failable<bool>(const value&, const value&, XMPPClient&)> noop = [](unused const value& jid, unused const value& val, unused XMPPClient& xc) -> const failable<bool> { + return true; + }; + const failable<bool> r = listen(noop, const_cast<XMPPClient&>(xc)); debug("chat::subscribe::stopped"); return r; - } - -private: - const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l; - XMPPClient xc; -}; + }; -/** - * Chatter component lambda function - */ -class chatSender { -public: - chatSender(XMPPClient& xc, worker& w) : xc(xc), w(w) { - } + // Listen and relay messages in a worker thread + worker w(3); + submit<failable<bool> >(w, subscribe); - const value operator()(const list<value>& params) const { + // Return the chat sender component lambda function + const lvvlambda chatSender = [xc, w](const list<value>& params) -> const value { const tuscany::value func(car(params)); if (func == "post") return post(cdr(params), const_cast<XMPPClient&>(xc)); @@ -104,35 +97,9 @@ public: cancel(const_cast<worker&>(w)); debug("chat::sender::stopped"); - return failable<value>(value(lambda<value(const list<value>&)>())); - } - -private: - const XMPPClient xc; - worker w; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Extract the the XMPP JID and password - const list<value> props = params; - const value jid = ((lambda<value(const list<value>&)>)car(props))(list<value>()); - const value pass = ((lambda<value(const list<value>&)>)cadr(props))(list<value>()); - - // Create an XMPP client session - XMPPClient xc(jid, pass, false); - const failable<bool> r = connect(xc); - if (!hasContent(r)) - return mkfailure<value>(r); - - // Listen and relay messages in a worker thread - worker w(3); - submit<failable<bool> >(w, lambda<failable<bool>()>(subscribe(xc))); - - // Return the chat sender component lambda function - return value(lambda<value(const list<value>&)>(chatSender(xc, w))); + return failable<value>(value(lvvlambda())); + }; + return value(chatSender); } } diff --git a/sca-cpp/trunk/components/chat/chat-sender2.cpp b/sca-cpp/trunk/components/chat/chat-sender2.cpp index 0e00728022..2101617899 100644 --- a/sca-cpp/trunk/components/chat/chat-sender2.cpp +++ b/sca-cpp/trunk/components/chat/chat-sender2.cpp @@ -41,7 +41,7 @@ namespace sender { /** * Post an item to an XMPP JID. */ -const failable<value> post(const lambda<value(const list<value>&)>& jid, const lambda<value(const list<value>&)>& pass, const lambda<value(const list<value>&)>& to, const lambda<value(const list<value>&)>& msg, const list<value>& params) { +const failable<value> post(const lvvlambda& jid, const lvvlambda& pass, const lvvlambda& to, const lvvlambda& msg, const list<value>& params) { const value vjid = jid(mklist<value>("get", params)); const value vpass = pass(mklist<value>("get", params)); @@ -65,14 +65,16 @@ const failable<value> post(const lambda<value(const list<value>&)>& jid, const l } /** - * Chat sender component lambda function + * Start the component. */ -class chatSender { -public: - chatSender(const lambda<value(const list<value>&)>& jid, const lambda<value(const list<value>&)>& pass, const lambda<value(const list<value>&)>& to, const lambda<value(const list<value>&)>& msg) : jid(jid), pass(pass), to(to), msg(msg) { - } +const failable<value> start(const list<value>& params) { - const value operator()(const list<value>& params) const { + // Return the chat sender component lambda function + const lvvlambda jid = car(params); + const lvvlambda pass = cadr(params); + const lvvlambda to = caddr(params); + const lvvlambda msg = cadddr(params); + const lvvlambda sender = [jid, pass, to, msg](const list<value>& params) -> const value { const tuscany::value func(car(params)); if (func == "get") return post(jid, pass, to, msg, cdr(params)); @@ -81,23 +83,9 @@ public: if (func != "stop") return mkfailure<value>(); debug("chat::sender::stop"); - return failable<value>(value(lambda<value(const list<value>&)>())); - } - -private: - const lambda<value(const list<value>&)> jid; - const lambda<value(const list<value>&)> pass; - const lambda<value(const list<value>&)> to; - const lambda<value(const list<value>&)> msg; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - - // Return the chat sender component lambda function - return value(lambda<value(const list<value>&)>(chatSender(car(params), cadr(params), caddr(params), cadddr(params)))); + return failable<value>(value(lvvlambda())); + }; + return value(sender); } } diff --git a/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp b/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp index bfbd32b9ae..94577b7551 100644 --- a/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp +++ b/sca-cpp/trunk/components/chat/chat-sendreceiver.cpp @@ -51,56 +51,46 @@ const failable<value> post(const list<value>& params, XMPPClient& xc) { } /** - * A relay function that posts the XMPP messages it receives to a relay component reference. + * Start the component. */ -class relay { -public: - relay(const lambda<value(const list<value>&)>& rel) : rel(rel) { - } +const failable<value> start(const list<value>& params) { + // Extract the relay reference and the XMPP JID and password + const bool hasRelay = !isNil(cddr(params)); + const lvvlambda rel = hasRelay? (lvvlambda)car(params) : lvvlambda(); + const list<value> props = hasRelay? cdr(params) : params; + const value jid = ((lvvlambda)car(props))(nilListValue); + const value pass = ((lvvlambda)cadr(props))(nilListValue); + + // Create an XMPP client session + XMPPClient xc(jid, pass, false); + const failable<bool> r = connect(xc); + if (!hasContent(r)) + return mkfailure<value>(r); - const failable<bool> operator()(const value& jid, const value& val, unused XMPPClient& xc) const { + // Listen and relay messages in a worker thread + worker w(3); + const lambda<const failable<bool>(const value&, const value&, XMPPClient&)> rl = [rel](const value& jid, const value& val, unused XMPPClient& xc) -> const failable<bool> { + // A relay function that posts the XMPP messages it receives to a relay component reference. if (isNil(rel)) return true; debug(jid, "chat::relay::jid"); debug(val, "chat::relay::value"); const value res = rel(mklist<value>("post", mklist<value>(jid), val)); return true; - } - -private: - const lambda<value(const list<value>&)> rel; -}; - -/** - * Subscribe and listen to an XMPP session. - */ -class subscribe { -public: - subscribe(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& l, XMPPClient& xc) : l(l), xc(xc) { - } + }; - const failable<bool> operator()() const { - gc_pool pool; + // Subscribe and listen to the XMPP session. + const lambda<const failable<bool>()> subscribe = [rl, xc]() -> const failable<bool> { + const gc_pool pool; debug("chat::subscribe::listen"); - const failable<bool> r = listen(l, const_cast<XMPPClient&>(xc)); + const failable<bool> r = listen(rl, const_cast<XMPPClient&>(xc)); debug("chat::subscribe::stopped"); return r; - } - -private: - const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l; - XMPPClient xc; -}; - -/** - * Chat sender/receiver component lambda function - */ -class chatSenderReceiver { -public: - chatSenderReceiver(XMPPClient& xc, worker& w) : xc(xc), w(w) { - } + }; + submit<failable<bool> >(w, subscribe); - const value operator()(const list<value>& params) const { + // Return the chat sender/receiver component lambda function + const lvvlambda senderReceiver = [xc, w](const list<value>& params) -> const value { const tuscany::value func(car(params)); if (func == "post") return post(cdr(params), const_cast<XMPPClient&>(xc)); @@ -115,38 +105,9 @@ public: cancel(const_cast<worker&>(w)); debug("chat::sendreceiver::stopped"); - return failable<value>(value(lambda<value(const list<value>&)>())); - } - -private: - const XMPPClient xc; - worker w; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Extract the relay reference and the XMPP JID and password - const bool hasRelay = !isNil(cddr(params)); - const value rel = hasRelay? car(params) : value(lambda<value(const list<value>&)>()); - const list<value> props = hasRelay? cdr(params) : params; - const value jid = ((lambda<value(const list<value>&)>)car(props))(list<value>()); - const value pass = ((lambda<value(const list<value>&)>)cadr(props))(list<value>()); - - // Create an XMPP client session - XMPPClient xc(jid, pass, false); - const failable<bool> r = connect(xc); - if (!hasContent(r)) - return mkfailure<value>(r); - - // Listen and relay messages in a worker thread - worker w(3); - const lambda<failable<bool>(const value&, const value&, XMPPClient&)> rl = relay(rel); - submit<failable<bool> >(w, lambda<failable<bool>()>(subscribe(rl, xc))); - - // Return the chat sender/receiver component lambda function - return value(lambda<value(const list<value>&)>(chatSenderReceiver(xc, w))); + return failable<value>(value(lvvlambda())); + }; + return value(senderReceiver); } } diff --git a/sca-cpp/trunk/components/chat/client-test.cpp b/sca-cpp/trunk/components/chat/client-test.cpp index 220382fa89..11c7bed35e 100644 --- a/sca-cpp/trunk/components/chat/client-test.cpp +++ b/sca-cpp/trunk/components/chat/client-test.cpp @@ -45,12 +45,12 @@ const value pass2("sca2"); const value jid3("sca3@localhost"); const value pass3("sca3"); -const list<value> item = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); -const list<value> entry = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const list<value> item = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); +const list<value> entry = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + item); worker w(2); @@ -63,36 +63,29 @@ const failable<bool> listener(const value& from, const value& val, unused XMPPCl return false; } -struct subscribe { - XMPPClient& xc; - subscribe(XMPPClient& xc) : xc(xc) { - } - const failable<bool> operator()() const { - const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l(listener); - listen(l, xc); - return true; - } -}; - -bool testListen() { +const bool testListen() { received = false; XMPPClient& xc = *(new (gc_new<XMPPClient>()) XMPPClient(jid3, pass3)); const failable<bool> c = connect(xc); assert(hasContent(c)); - const lambda<failable<bool>()> subs = subscribe(xc); + const lambda<const failable<bool>()> subs = [&xc]() -> const failable<bool> { + const lambda<const failable<bool>(const value&, const value&, XMPPClient&)> l(listener); + listen(l, xc); + return true; + }; submit(w, subs); return true; } -bool testPost() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); +const bool testPost() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); const failable<value> id = http::post(entry, "http://localhost:8090/print-sender/sca2@localhost", ch); assert(hasContent(id)); return true; } -bool testReceived() { +const bool testReceived() { shutdown(w); assert(received == true); return true; diff --git a/sca-cpp/trunk/components/chat/xmpp-test.cpp b/sca-cpp/trunk/components/chat/xmpp-test.cpp index 6b7fa3439f..853029a836 100644 --- a/sca-cpp/trunk/components/chat/xmpp-test.cpp +++ b/sca-cpp/trunk/components/chat/xmpp-test.cpp @@ -52,28 +52,21 @@ const failable<bool> listener(const value& from, const value& val, unused XMPPCl return false; } -struct subscribe { - XMPPClient& xc; - subscribe(XMPPClient& xc) : xc(xc) { - } - const failable<bool> operator()() const { - const lambda<failable<bool>(const value&, const value&, XMPPClient&)> l(listener); - listen(l, xc); - return true; - } -}; - -bool testListen() { +const bool testListen() { received = false; XMPPClient& xc = *(new (gc_new<XMPPClient>()) XMPPClient(jid2, pass2)); const failable<bool> c = connect(xc); assert(hasContent(c)); - const lambda<failable<bool>()> subs = subscribe(xc); + const lambda<const failable<bool>()> subs = [&xc]() -> const failable<bool> { + const lambda<const failable<bool>(const value&, const value&, XMPPClient&)> l(listener); + listen(l, xc); + return true; + }; submit(w, subs); return true; } -bool testPost() { +const bool testPost() { XMPPClient xc(jid1, pass1); const failable<bool> c = connect(xc); assert(hasContent(c)); @@ -82,7 +75,7 @@ bool testPost() { return true; } -bool testReceived() { +const bool testReceived() { shutdown(w); assert(received == true); return true; diff --git a/sca-cpp/trunk/components/chat/xmpp.hpp b/sca-cpp/trunk/components/chat/xmpp.hpp index aa006029fa..88174613a0 100644 --- a/sca-cpp/trunk/components/chat/xmpp.hpp +++ b/sca-cpp/trunk/components/chat/xmpp.hpp @@ -66,8 +66,8 @@ private: */ class XMPPClient { public: - XMPPClient(const string& jid, const string& pass, bool owner = true) : owner(owner), ctx(xmpp_ctx_new(NULL, xmppRuntime.log)), conn(xmpp_conn_new(ctx)), connecting(false), connected(false), disconnecting(false) { - xmpp_conn_set_jid(conn, c_str(jid + "/" + mkuuid())); + XMPPClient(const string& jid, const string& pass, const bool owner = true) : owner(owner), ctx(xmpp_ctx_new(NULL, xmppRuntime.log)), conn(xmpp_conn_new(ctx)), connecting(false), connected(false), disconnecting(false) { + xmpp_conn_set_jid(conn, c_str(jid + "/" + (string)mkuuid())); xmpp_conn_set_pass(conn, c_str(pass)); debug(jid, "chat::xmppclient::jid"); } @@ -76,19 +76,7 @@ public: debug("chat::xmppclient::copy"); } - const XMPPClient& operator=(const XMPPClient& xc) { - debug("chat::xmppclient::operator="); - if(this == &xc) - return *this; - owner = false; - ctx = xc.ctx; - conn = xc.conn; - listener = xc.listener; - connecting = xc.connecting; - connected = xc.connected; - disconnecting = xc.disconnecting; - return *this; - } + XMPPClient& operator=(const XMPPClient& xc) = delete; ~XMPPClient() { debug("chat::~xmppclient"); @@ -110,12 +98,12 @@ private: friend const failable<size_t> send(xmpp_stanza_t* const stanza, XMPPClient& xc); friend const failable<bool> post(const value& to, const value& val, XMPPClient& xc); friend const failable<bool> disconnect(XMPPClient& xc); - friend const failable<bool> listen(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc); + friend const failable<bool> listen(const lambda<const failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc); - bool owner; + const bool owner; xmpp_ctx_t* ctx; xmpp_conn_t* conn; - lambda<failable<bool>(const value&, const value&, XMPPClient&)> listener; + gc_mutable_ref<lambda<const failable<bool>(const value&, const value&, XMPPClient&)> > listener; bool connecting; bool connected; bool disconnecting; @@ -124,8 +112,8 @@ private: /** * Make a text stanza. */ -xmpp_stanza_t* textStanza(const char* text, xmpp_ctx_t* ctx) { - xmpp_stanza_t* stanza = xmpp_stanza_new(ctx); +xmpp_stanza_t* const textStanza(const char* const text, xmpp_ctx_t* const ctx) { + xmpp_stanza_t* const stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_text(stanza, text); return stanza; } @@ -133,8 +121,8 @@ xmpp_stanza_t* textStanza(const char* text, xmpp_ctx_t* ctx) { /** * Make a named stanza. */ -xmpp_stanza_t* namedStanza(const char* ns, const char* name, xmpp_ctx_t* ctx) { - xmpp_stanza_t* stanza = xmpp_stanza_new(ctx); +xmpp_stanza_t* const namedStanza(const char* const ns, const char* const name, xmpp_ctx_t* const ctx) { + xmpp_stanza_t* const stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(stanza, name); if (ns != NULL) xmpp_stanza_set_ns(stanza, ns); @@ -144,8 +132,8 @@ xmpp_stanza_t* namedStanza(const char* ns, const char* name, xmpp_ctx_t* ctx) { /** * Make a named stanza using a qualified name. */ -xmpp_stanza_t* namedStanza(const char* name, xmpp_ctx_t* ctx) { - xmpp_stanza_t* stanza = xmpp_stanza_new(ctx); +xmpp_stanza_t* const namedStanza(const char* const name, xmpp_ctx_t* const ctx) { + xmpp_stanza_t* const stanza = xmpp_stanza_new(ctx); xmpp_stanza_set_name(stanza, name); return stanza; } @@ -157,16 +145,16 @@ int versionHandler(xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, void* c XMPPClient& xc = *(XMPPClient*)udata; // Build version reply stanza - xmpp_stanza_t* reply = namedStanza("iq", xc.ctx); + xmpp_stanza_t* const reply = namedStanza("iq", xc.ctx); xmpp_stanza_set_type(reply, "result"); xmpp_stanza_set_id(reply, xmpp_stanza_get_id(stanza)); xmpp_stanza_set_attribute(reply, "to", xmpp_stanza_get_attribute(stanza, "from")); - xmpp_stanza_t* query = namedStanza(xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza)), "query", xc.ctx); + xmpp_stanza_t* const query = namedStanza(xmpp_stanza_get_ns(xmpp_stanza_get_children(stanza)), "query", xc.ctx); xmpp_stanza_add_child(reply, query); - xmpp_stanza_t* name = namedStanza("name", xc.ctx); + xmpp_stanza_t* const name = namedStanza("name", xc.ctx); xmpp_stanza_add_child(query, name); xmpp_stanza_add_child(name, textStanza("Apache Tuscany", xc.ctx)); - xmpp_stanza_t* version = namedStanza("version", xc.ctx); + xmpp_stanza_t* const version = namedStanza("version", xc.ctx); xmpp_stanza_add_child(query, version); xmpp_stanza_add_child(version, textStanza("1.0", xc.ctx)); @@ -188,17 +176,18 @@ int messageHandler(unused xmpp_conn_t* const conn, xmpp_stanza_t* const stanza, // Call the client listener function XMPPClient& xc = *(XMPPClient*)udata; - const char* from = xmpp_stanza_get_attribute(stanza, "from"); - const char* text = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); - if (isNil(xc.listener)) + const char* const from = xmpp_stanza_get_attribute(stanza, "from"); + const char* const text = xmpp_stanza_get_text(xmpp_stanza_get_child_by_name(stanza, "body")); + if (isNil((lambda<const failable<bool>(const value&, const value&, XMPPClient&)>)xc.listener)) return 1; - const value val(scheme::readValue(text)); + const value val(content(scheme::readValue(text))); debug(from, "chat::messageHandler::from"); debug(val, "chat::messageHandler::body"); - const failable<bool> r = xc.listener(value(string(from)), val, xc); + const lambda<const failable<bool>(const value&, const value&, XMPPClient&)> listener = xc.listener; + const failable<bool> r = listener(value(string(from)), val, xc); if (!hasContent(r) || !content(r)) { // Stop listening - xc.listener = lambda<failable<bool>(const value&, const value&, XMPPClient&)>(); + xc.listener = lambda<const failable<bool>(const value&, const value&, XMPPClient&)>(); return 0; } return 1; @@ -216,7 +205,7 @@ void connHandler(xmpp_conn_t * const conn, const xmpp_conn_event_t status, unuse xmpp_handler_add(conn, versionHandler, "jabber:iq:version", "iq", NULL, &xc); // Send a <presence/> stanza so that we appear online to contacts - xmpp_stanza_t* pres = xmpp_stanza_new(xc.ctx); + xmpp_stanza_t* const pres = xmpp_stanza_new(xc.ctx); xmpp_stanza_set_name(pres, "presence"); xmpp_send(conn, pres); xmpp_stanza_release(pres); @@ -246,7 +235,7 @@ const failable<bool> connect(XMPPClient& xc) { /** * Send a buffer on an XMPP session. */ -const failable<size_t> send(const char* data, const size_t len, XMPPClient& xc) { +const failable<size_t> send(const char* const data, const size_t len, XMPPClient& xc) { if (len == 0) return 0; const size_t written = xc.conn->tls? tls_write(xc.conn->tls, data, len) : sock_write(xc.conn->sock, data, len); @@ -268,7 +257,7 @@ const failable<size_t> send(const string& data, XMPPClient& xc) { * Send a stanza on an XMPP session. */ const failable<size_t> send(xmpp_stanza_t* const stanza, XMPPClient& xc) { - char *buf; + char* buf; size_t len; const int rc = xmpp_stanza_to_text(stanza, &buf, &len); if (rc != 0) @@ -291,13 +280,13 @@ const failable<bool> post(const value& to, const value& val, XMPPClient& xc) { debug(val, "chat::post::body"); // Convert the value to a string - const string vs(scheme::writeValue(val)); + const string vs(write(content(scheme::writeValue(val)))); // Build message stanza - xmpp_stanza_t* stanza = namedStanza("message", xc.ctx); + xmpp_stanza_t* const stanza = namedStanza("message", xc.ctx); xmpp_stanza_set_type(stanza, "chat"); xmpp_stanza_set_attribute(stanza, "to", c_str(string(to))); - xmpp_stanza_t* body = namedStanza("body", xc.ctx); + xmpp_stanza_t* const body = namedStanza("body", xc.ctx); xmpp_stanza_add_child(stanza, body); xmpp_stanza_add_child(body, textStanza(c_str(vs), xc.ctx)); @@ -323,12 +312,12 @@ const failable<bool> disconnect(XMPPClient& xc) { /** * Listen to messages received by an XMPP client. */ -const failable<bool> listen(const lambda<failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc) { +const failable<bool> listen(const lambda<const failable<bool>(const value&, const value&, XMPPClient&)>& listener, XMPPClient& xc) { debug("chat::listen"); xc.listener = listener; xmpp_handler_add(xc.conn, messageHandler, NULL, "message", NULL, &xc); xc.ctx->loop_status = XMPP_LOOP_RUNNING; - while(xc.connected && !isNil(xc.listener) && xc.ctx->loop_status == XMPP_LOOP_RUNNING) + while(xc.connected && !isNil((lambda<const failable<bool>(const value&, const value&, XMPPClient&)>)xc.listener) && xc.ctx->loop_status == XMPP_LOOP_RUNNING) xmpp_run_once(xc.ctx, 1000L); return true; } diff --git a/sca-cpp/trunk/components/constdb/Makefile.am b/sca-cpp/trunk/components/constdb/Makefile.am index e4504a53e7..a64d13da1c 100644 --- a/sca-cpp/trunk/components/constdb/Makefile.am +++ b/sca-cpp/trunk/components/constdb/Makefile.am @@ -41,7 +41,7 @@ tinycdb_test_SOURCES = tinycdb-test.cpp tinycdb_test_LDFLAGS = -L${TINYCDB_LIB} -R${TINYCDB_LIB} -lcdb client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = constdb-test server-test noinst_PROGRAMS = tinycdb-test client-test diff --git a/sca-cpp/trunk/components/constdb/client-test.cpp b/sca-cpp/trunk/components/constdb/client-test.cpp index ea45762cd6..b796ef01dd 100644 --- a/sca-cpp/trunk/components/constdb/client-test.cpp +++ b/sca-cpp/trunk/components/constdb/client-test.cpp @@ -38,15 +38,15 @@ namespace constdb { const string uri("http://localhost:8090/constdb"); -bool testConstDb() { - http::CURLSession cs("", "", "", "", 0); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testConstDb() { + const http::CURLSession cs("", "", "", "", 0); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); const failable<value> id = http::post(a, uri, cs); @@ -59,18 +59,18 @@ bool testConstDb() { assert(content(val) == a); } - const list<value> j = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$3.55"))); - const list<value> b = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> j = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$3.55"))); + const list<value> b = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + j); { const failable<value> r = http::put(b, uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -80,7 +80,7 @@ bool testConstDb() { { const failable<value> r = http::del(uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -90,35 +90,26 @@ bool testConstDb() { return true; } -struct getLoop { - const string path; - const value entry; - http::CURLSession& cs; - getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) { - } - const bool operator()() const { - const failable<value> val = http::get(uri + path, cs); - assert(hasContent(val)); - assert(content(val) == entry); - return true; - } -}; - -bool testGetPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$4.55"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testGetPerf() { + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$4.55"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", "", "", 0); + const http::CURLSession cs("", "", "", "", 0); const failable<value> id = http::post(a, uri, cs); assert(hasContent(id)); const string p = path(content(id)); - const lambda<bool()> gl = getLoop(p, a, cs); + const blambda gl = [p, a, cs]() -> const bool { + const failable<value> val = http::get(uri + p, cs); + assert(hasContent(val)); + assert(content(val) == a); + return true; + }; cout << "ConstDb get test " << time(gl, 5, 200) << " ms" << endl; return true; diff --git a/sca-cpp/trunk/components/constdb/constdb.cpp b/sca-cpp/trunk/components/constdb/constdb.cpp index 6d1cb15baf..a9a5bc5817 100644 --- a/sca-cpp/trunk/components/constdb/constdb.cpp +++ b/sca-cpp/trunk/components/constdb/constdb.cpp @@ -37,14 +37,14 @@ namespace constdb { /** * Get an item from the database. */ -const failable<value> get(const list<value>& params, tinycdb::TinyCDB& cdb) { +const failable<value> get(const list<value>& params, const tinycdb::TinyCDB& cdb) { return tinycdb::get(car(params), cdb); } /** * Post an item to the database. */ -const failable<value> post(const list<value>& params, tinycdb::TinyCDB& cdb) { +const failable<value> post(const list<value>& params, const tinycdb::TinyCDB& cdb) { const value id = append<value>(car(params), mklist(mkuuid())); const failable<bool> val = tinycdb::post(id, cadr(params), cdb); if (!hasContent(val)) @@ -55,7 +55,7 @@ const failable<value> post(const list<value>& params, tinycdb::TinyCDB& cdb) { /** * Put an item into the database. */ -const failable<value> put(const list<value>& params, tinycdb::TinyCDB& cdb) { +const failable<value> put(const list<value>& params, const tinycdb::TinyCDB& cdb) { const failable<bool> val = tinycdb::put(car(params), cadr(params), cdb); if (!hasContent(val)) return mkfailure<value>(val); @@ -65,7 +65,7 @@ const failable<value> put(const list<value>& params, tinycdb::TinyCDB& cdb) { /** * Delete an item from the database. */ -const failable<value> del(const list<value>& params, tinycdb::TinyCDB& cdb) { +const failable<value> del(const list<value>& params, const tinycdb::TinyCDB& cdb) { const failable<bool> val = tinycdb::del(car(params), cdb); if (!hasContent(val)) return mkfailure<value>(val); @@ -73,14 +73,15 @@ const failable<value> del(const list<value>& params, tinycdb::TinyCDB& cdb) { } /** - * Component implementation lambda function. + * Start the component. */ -class applyConstDb { -public: - applyConstDb(tinycdb::TinyCDB& cdb) : cdb(cdb) { - } +const failable<value> start(unused const list<value>& params) { + // Connect to the configured database and table + const value dbname = ((lvvlambda)car(params))(nilListValue); + const tinycdb::TinyCDB& cdb = *(new (gc_new<tinycdb::TinyCDB>()) tinycdb::TinyCDB(dbname)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda applyConstDb = [cdb](const list<value>& params) -> const value { const value func(car(params)); if (func == "get") return get(cdr(params), cdb); @@ -91,22 +92,8 @@ public: if (func == "delete") return del(cdr(params), cdb); return mkfailure<value>(); - } - -private: - tinycdb::TinyCDB& cdb; -}; - -/** - * Start the component. - */ -const failable<value> start(unused const list<value>& params) { - // Connect to the configured database and table - const value dbname = ((lambda<value(const list<value>&)>)car(params))(list<value>()); - tinycdb::TinyCDB& cdb = *(new (gc_new<tinycdb::TinyCDB>()) tinycdb::TinyCDB(dbname)); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyConstDb(cdb))); + }; + return value(applyConstDb); } } diff --git a/sca-cpp/trunk/components/constdb/tinycdb-test.cpp b/sca-cpp/trunk/components/constdb/tinycdb-test.cpp index b3b4ea7fd7..6cc9e9eabb 100644 --- a/sca-cpp/trunk/components/constdb/tinycdb-test.cpp +++ b/sca-cpp/trunk/components/constdb/tinycdb-test.cpp @@ -32,8 +32,8 @@ namespace tuscany { namespace tinycdb { -bool testTinyCDB() { - TinyCDB cdb("tmp/test.cdb"); +const bool testTinyCDB() { + const TinyCDB cdb("tmp/test.cdb"); const value k = mklist<value>("a"); assert(hasContent(post(k, string("AAA"), cdb))); @@ -46,23 +46,15 @@ bool testTinyCDB() { return true; } -struct getLoop { - const value k; - TinyCDB& cdb; - getLoop(const value& k, TinyCDB& cdb) : k(k), cdb(cdb) { - } - const bool operator()() const { - assert((get(k, cdb)) == value(string("CCC"))); - return true; - } -}; - -bool testGetPerf() { +const bool testGetPerf() { const value k = mklist<value>("c"); - TinyCDB cdb("tmp/test.cdb"); + const TinyCDB cdb("tmp/test.cdb"); assert(hasContent(post(k, string("CCC"), cdb))); - const lambda<bool()> gl = getLoop(k, cdb); + const blambda gl = [k, cdb]() -> const bool { + assert((get(k, cdb)) == value(string("CCC"))); + return true; + }; cout << "TinyCDB get test " << time(gl, 5, 100000) << " ms" << endl; return true; } diff --git a/sca-cpp/trunk/components/constdb/tinycdb.hpp b/sca-cpp/trunk/components/constdb/tinycdb.hpp index 68be0a09dc..ce1dcbb011 100644 --- a/sca-cpp/trunk/components/constdb/tinycdb.hpp +++ b/sca-cpp/trunk/components/constdb/tinycdb.hpp @@ -41,20 +41,20 @@ namespace tinycdb { */ class buffer { public: - operator void*() const throw() { + operator void* const () const throw() { return buf; } - operator unsigned char*() const throw() { - return (unsigned char*)buf; + operator unsigned char* const () const throw() { + return (unsigned char* const)buf; } - operator char*() const throw() { - return (char*)buf; + operator char* const () const throw() { + return (char* const)buf; } private: - buffer(const unsigned int size, void* buf) : size(size), buf(buf) { + buffer(const unsigned int size, void* const buf) : size(size), buf(buf) { } unsigned int size; @@ -106,48 +106,53 @@ const string absdbname(const string& name) { */ class TinyCDB { public: - TinyCDB() : owner(false), fd(-1) { - st.st_ino = 0; + TinyCDB() : owner(false), h(*(new (gc_new<handles>()) handles())) { } - TinyCDB(const string& name) : owner(true), name(absdbname(name)), fd(-1) { + TinyCDB(const string& name) : owner(true), name(absdbname(name)), h(*(new (gc_new<handles>()) handles())) { debug(name, "tinycdb::tinycdb::name"); - st.st_ino = 0; } - TinyCDB(const TinyCDB& c) : owner(false), name(c.name), fd(c.fd) { + TinyCDB(const TinyCDB& c) : owner(false), name(c.name), h(c.h) { debug("tinycdb::tinycdb::copy"); - st.st_ino = c.st.st_ino; } - const TinyCDB& operator=(const TinyCDB& c) { - debug("tinycdb::tinycdb::operator="); - if(this == &c) - return *this; - owner = false; - name = c.name; - fd = c.fd; - st.st_ino = c.st.st_ino; - return *this; - } + TinyCDB& operator=(const TinyCDB& c) = delete; ~TinyCDB() { if (!owner) return; - if (fd == -1) + if (h.fd == -1) return; - close(fd); + close(h.fd); } private: + class handles { + public: + handles() : fd(-1) { + st.st_ino = 0; + } + + handles(const handles& c) : fd(c.fd), st(c.st) { + } + + private: + int fd; + struct stat st; + + friend class TinyCDB; + friend const failable<int> cdbopen(const TinyCDB& cdb); + friend const failable<bool> cdbclose(const TinyCDB& cdb); + }; + bool owner; string name; - int fd; - struct stat st; + handles& h; friend const string dbname(const TinyCDB& cdb); - friend const failable<int> cdbopen(TinyCDB& cdb); - friend const failable<bool> cdbclose(TinyCDB& cdb); + friend const failable<int> cdbopen(const TinyCDB& cdb); + friend const failable<bool> cdbclose(const TinyCDB& cdb); }; /** @@ -160,7 +165,7 @@ const string dbname(const TinyCDB& cdb) { /** * Open a database. */ -const failable<int> cdbopen(TinyCDB& cdb) { +const failable<int> cdbopen(const TinyCDB& cdb) { // Get database file serial number struct stat st; @@ -169,51 +174,51 @@ const failable<int> cdbopen(TinyCDB& cdb) { return mkfailure<int>(string("Couldn't tinycdb read database stat: ") + cdb.name); // Open database for the first time - if (cdb.fd == -1) { - cdb.fd = open(c_str(cdb.name), O_RDONLY); - if (cdb.fd == -1) + if (cdb.h.fd == -1) { + cdb.h.fd = open(c_str(cdb.name), O_RDONLY); + if (cdb.h.fd == -1) return mkfailure<int>(string("Couldn't open tinycdb database file: ") + cdb.name); - debug(cdb.fd, "tinycdb::open::fd"); - cdb.st = st; - return cdb.fd; + debug(cdb.h.fd, "tinycdb::open::fd"); + cdb.h.st = st; + return cdb.h.fd; } // Close and reopen database after a change - if (st.st_ino != cdb.st.st_ino) { + if (st.st_ino != cdb.h.st.st_ino) { // Close current fd - close(cdb.fd); + close(cdb.h.fd); // Reopen database const int newfd = open(c_str(cdb.name), O_RDONLY); if (newfd == -1) return mkfailure<int>(string("Couldn't open tinycdb database file: ") + cdb.name); - if (newfd == cdb.fd) { - debug(cdb.fd, "tinycdb::open::fd"); - cdb.st = st; - return cdb.fd; + if (newfd == cdb.h.fd) { + debug(cdb.h.fd, "tinycdb::open::fd"); + cdb.h.st = st; + return cdb.h.fd; } // We got a different fd, dup it to the current fd then close it - if (fcntl(newfd, F_DUPFD, cdb.fd) == -1) + if (fcntl(newfd, F_DUPFD, cdb.h.fd) == -1) return mkfailure<int>(string("Couldn't dup tinycdb database file handle: ") + cdb.name); close(newfd); - debug(cdb.fd, "tinycdb::open::fd"); - cdb.st = st; - return cdb.fd; + debug(cdb.h.fd, "tinycdb::open::fd"); + cdb.h.st = st; + return cdb.h.fd; } // No change, just return the current fd - return cdb.fd; + return cdb.h.fd; } /** * Close a database. */ -const failable<bool> cdbclose(TinyCDB& cdb) { - close(cdb.fd); - cdb.fd = -1; +const failable<bool> cdbclose(const TinyCDB& cdb) { + close(cdb.h.fd); + cdb.h.fd = -1; return true; } @@ -222,7 +227,7 @@ const failable<bool> cdbclose(TinyCDB& cdb) { * can return true to let the entry added to the new db, false to skip the * entry, or a failure. */ -const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)>& update, const lambda<failable<bool>(struct cdb_make&)>& finish, buffer& buf, const int tmpfd, TinyCDB& cdb) { +const failable<bool> rewrite(const lambda<const failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)>& update, const lambda<const failable<bool>(struct cdb_make&)>& finish, buffer& buf, const int tmpfd, const TinyCDB& cdb) { // Initialize new db structure struct cdb_make cdbm; @@ -241,7 +246,7 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi if (::read(fd, buf, 2048) != 2048) return mkfailure<bool>("Couldn't read tinycdb database header"); pos += 2048; - unsigned int eod = cdb_unpack(buf); + const unsigned int eod = cdb_unpack(buf); debug(pos, "tinycdb::rewrite::eod"); // Read and add the existing entries @@ -251,9 +256,9 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi if (::read(fd, buf, 8) != 8) return mkfailure<bool>("Couldn't read tinycdb entry header"); pos += 8; - unsigned int klen = cdb_unpack(buf); - unsigned int vlen = cdb_unpack(((unsigned char*)buf) + 4); - unsigned int elen = klen + vlen; + const unsigned int klen = cdb_unpack(buf); + const unsigned int vlen = cdb_unpack(((unsigned char*)buf) + 4); + const unsigned int elen = klen + vlen; // Read existing entry buf = mkbuffer(buf, elen); @@ -264,8 +269,8 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi pos += elen; // Apply the update function to the entry - debug(string((char*)buf, klen), "tinycdb::rewrite::existing key"); - debug(string(((char*)buf) + klen, vlen), "tinycdb::rewrite::existing value"); + debug(string((const char* const)buf, klen), "tinycdb::rewrite::existing key"); + debug(string(((const char* const)buf) + klen, vlen), "tinycdb::rewrite::existing value"); const failable<bool> u = update(buf, klen, vlen); if (!hasContent(u)) return u; @@ -293,11 +298,11 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi return true; } -const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)>& update, const lambda<failable<bool>(struct cdb_make&)>& finish, TinyCDB& cdb) { +const failable<bool> rewrite(const lambda<const failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)>& update, const lambda<const failable<bool>(struct cdb_make&)>& finish, const TinyCDB& cdb) { // Create a new temporary db file - string tmpname = dbname(cdb) + ".XXXXXX"; - int tmpfd = mkstemp(const_cast<char*>(c_str(tmpname))); + const string tmpname = dbname(cdb) + ".XXXXXX"; + const int tmpfd = mkstemp(const_cast<char*>(c_str(tmpname))); if (tmpfd == -1) return mkfailure<bool>("Couldn't create temporary tinycdb database"); @@ -314,7 +319,7 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi if (rename(c_str(tmpname), c_str(dbname(cdb))) == -1) return mkfailure<bool>("Couldn't rename temporary tinycdb database"); cdbclose(cdb); - failable<int> ffd = cdbopen(cdb); + const failable<int> ffd = cdbopen(cdb); if (!hasContent(ffd)) return mkfailure<bool>(ffd); @@ -324,42 +329,27 @@ const failable<bool> rewrite(const lambda<failable<bool>(buffer& buf, const unsi /** * Post a new item to the database. */ -struct postUpdate { - const string ks; - postUpdate(const string& ks) : ks(ks) { - } - const failable<bool> operator()(buffer& buf, const unsigned int klen, unused const unsigned int vlen) const { - if (ks == string((char*)buf, klen)) - return mkfailure<bool>("Key already exists in tinycdb database"); - return true; - } -}; - -struct postFinish { - const string ks; - const string vs; - postFinish(const string& ks, const string& vs) : ks(ks), vs(vs) { - } - const failable<bool> operator()(struct cdb_make& cdbm) const { - if (cdb_make_add(&cdbm, c_str(ks), (unsigned int)length(ks), c_str(vs), (unsigned int)length(vs)) == -1) - return mkfailure<bool>(string("Couldn't add tinycdb entry: ") + ks); - return true; - } -}; - -const failable<bool> post(const value& key, const value& val, TinyCDB& cdb) { +const failable<bool> post(const value& key, const value& val, const TinyCDB& cdb) { debug(key, "tinycdb::post::key"); debug(val, "tinycdb::post::value"); debug(dbname(cdb), "tinycdb::post::dbname"); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); // Process each entry and detect existing key - const lambda<failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)> update = postUpdate(ks); + const lambda<const failable<bool>(buffer&, const unsigned int, const unsigned int)> update = [ks](buffer& buf, const unsigned int klen, unused const unsigned int vlen) -> const failable<bool> { + if (ks == string((char*)buf, klen)) + return mkfailure<bool>("Key already exists in tinycdb database"); + return true; + }; // Add the new entry to the db - const lambda<failable<bool>(struct cdb_make& cdbm)> finish = postFinish(ks, vs); + const lambda<const failable<bool>(struct cdb_make&)> finish = [ks, vs](struct cdb_make& cdbm) -> const failable<bool> { + if (cdb_make_add(&cdbm, c_str(ks), (unsigned int)length(ks), c_str(vs), (unsigned int)length(vs)) == -1) + return mkfailure<bool>(string("Couldn't add tinycdb entry: ") + ks); + return true; + }; // Rewrite the db const failable<bool> r = rewrite(update, finish, cdb); @@ -370,42 +360,27 @@ const failable<bool> post(const value& key, const value& val, TinyCDB& cdb) { /** * Update an item in the database. If the item doesn't exist it is added. */ -struct putUpdate { - const string ks; - putUpdate(const string& ks) : ks(ks) { - } - const failable<bool> operator()(buffer& buf, const unsigned int klen, unused const unsigned int vlen) const { - if (ks == string((char*)buf, klen)) - return false; - return true; - } -}; - -struct putFinish { - const string ks; - const string vs; - putFinish(const string& ks, const string& vs) : ks(ks), vs(vs) { - } - const failable<bool> operator()(struct cdb_make& cdbm) const { - if (cdb_make_add(&cdbm, c_str(ks), (unsigned int)length(ks), c_str(vs), (unsigned int)length(vs)) == -1) - return mkfailure<bool>(string("Couldn't add tinycdb entry: ") + ks); - return true; - } -}; - -const failable<bool> put(const value& key, const value& val, TinyCDB& cdb) { +const failable<bool> put(const value& key, const value& val, const TinyCDB& cdb) { debug(key, "tinycdb::put::key"); debug(val, "tinycdb::put::value"); debug(dbname(cdb), "tinycdb::put::dbname"); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); // Process each entry and skip existing key - const lambda<failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)> update = putUpdate(ks); + const lambda<const failable<bool>(buffer&, const unsigned int, const unsigned int)> update = [ks](buffer& buf, const unsigned int klen, unused const unsigned int vlen) -> const failable<bool> { + if (ks == string((char*)buf, klen)) + return false; + return true; + }; // Add the new entry to the db - const lambda<failable<bool>(struct cdb_make& cdbm)> finish = putFinish(ks, vs); + const lambda<const failable<bool>(struct cdb_make&)> finish = [ks, vs](struct cdb_make& cdbm) -> const failable<bool> { + if (cdb_make_add(&cdbm, c_str(ks), (unsigned int)length(ks), c_str(vs), (unsigned int)length(vs)) == -1) + return mkfailure<bool>(string("Couldn't add tinycdb entry: ") + ks); + return true; + }; // Rewrite the db const failable<bool> r = rewrite(update, finish, cdb); @@ -416,7 +391,7 @@ const failable<bool> put(const value& key, const value& val, TinyCDB& cdb) { /** * Get an item from the database. */ -const failable<value> get(const value& key, TinyCDB& cdb) { +const failable<value> get(const value& key, const TinyCDB& cdb) { debug(key, "tinycdb::get::key"); debug(dbname(cdb), "tinycdb::get::dbname"); @@ -425,7 +400,7 @@ const failable<value> get(const value& key, TinyCDB& cdb) { return mkfailure<value>(ffd); const int fd = content(ffd); - const string ks(scheme::writeValue(key)); + const string ks(write(content(scheme::writeValue(key)))); cdbi_t vlen; if (cdb_seek(fd, c_str(ks), (unsigned int)length(ks), &vlen) <= 0) { @@ -433,10 +408,10 @@ const failable<value> get(const value& key, TinyCDB& cdb) { os << "Couldn't get tinycdb entry: " << key; return mkfailure<value>(str(os), 404, false); } - char* data = gc_cnew(vlen + 1); + char* const data = gc_cnew(vlen + 1); cdb_bread(fd, data, vlen); data[vlen] = '\0'; - const value val(scheme::readValue(string(data))); + const value val(content(scheme::readValue(string(data)))); debug(val, "tinycdb::get::result"); return val; @@ -445,36 +420,23 @@ const failable<value> get(const value& key, TinyCDB& cdb) { /** * Delete an item from the database */ -struct delUpdate { - const string ks; - delUpdate(const string& ks) : ks(ks) { - } - const failable<bool> operator()(buffer& buf, const unsigned int klen, unused const unsigned int vlen) const { - if (ks == string((char*)buf, klen)) - return false; - return true; - } -}; - -struct delFinish { - delFinish() { - } - const failable<bool> operator()(unused struct cdb_make& cdbm) const { - return true; - } -}; - -const failable<bool> del(const value& key, TinyCDB& cdb) { +const failable<bool> del(const value& key, const TinyCDB& cdb) { debug(key, "tinycdb::delete::key"); debug(dbname(cdb), "tinycdb::delete::dbname"); - const string ks(scheme::writeValue(key)); + const string ks(write(content(scheme::writeValue(key)))); // Process each entry and skip existing key - const lambda<failable<bool>(buffer& buf, const unsigned int klen, const unsigned int vlen)> update = delUpdate(ks); + const lambda<const failable<bool>(buffer&, const unsigned int, const unsigned int)> update = [ks](buffer& buf, const unsigned int klen, unused const unsigned int vlen) -> const failable<bool> { + if (ks == string((char*)buf, klen)) + return false; + return true; + }; // Nothing to do to finish - const lambda<failable<bool>(struct cdb_make& cdbm)> finish = delFinish(); + const lambda<const failable<bool>(struct cdb_make&)> finish = [](unused struct cdb_make& cdbm) -> const failable<bool> { + return true; + }; // Rewrite the db const failable<bool> r = rewrite(update, finish, cdb); diff --git a/sca-cpp/trunk/components/filedb/Makefile.am b/sca-cpp/trunk/components/filedb/Makefile.am index c6589a1b7b..e15eb2002e 100644 --- a/sca-cpp/trunk/components/filedb/Makefile.am +++ b/sca-cpp/trunk/components/filedb/Makefile.am @@ -26,15 +26,15 @@ comp_LTLIBRARIES = libfiledb.la noinst_DATA = libfiledb${libsuffix} libfiledb_la_SOURCES = filedb.cpp -libfiledb_la_LDFLAGS = -lxml2 -lmozjs +libfiledb_la_LDFLAGS = -lxml2 -ljansson libfiledb${libsuffix}: ln -s .libs/libfiledb${libsuffix} file_test_SOURCES = file-test.cpp -file_test_LDFLAGS = -lxml2 -lmozjs +file_test_LDFLAGS = -lxml2 -ljansson client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = filedb-test server-test noinst_PROGRAMS = file-test client-test diff --git a/sca-cpp/trunk/components/filedb/client-test.cpp b/sca-cpp/trunk/components/filedb/client-test.cpp index e0f98d8c3b..5694d97522 100644 --- a/sca-cpp/trunk/components/filedb/client-test.cpp +++ b/sca-cpp/trunk/components/filedb/client-test.cpp @@ -38,15 +38,15 @@ namespace filedb { const string uri("http://localhost:8090/filedb"); -bool testFileDB() { - http::CURLSession cs("", "", "", "", 0); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testFileDB() { + const http::CURLSession cs("", "", "", "", 0); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); const failable<value> id = http::post(a, uri, cs); @@ -59,18 +59,18 @@ bool testFileDB() { assert(content(val) == a); } - const list<value> j = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$3.55"))); - const list<value> b = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> j = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$3.55"))); + const list<value> b = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + j); { const failable<value> r = http::put(b, uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -80,7 +80,7 @@ bool testFileDB() { { const failable<value> r = http::del(uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -90,35 +90,26 @@ bool testFileDB() { return true; } -struct getLoop { - const string path; - const value entry; - http::CURLSession& cs; - getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) { - } - const bool operator()() const { - const failable<value> val = http::get(uri + path, cs); - assert(hasContent(val)); - assert(content(val) == entry); - return true; - } -}; - -bool testGetPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$4.55"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testGetPerf() { + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$4.55"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", "", "", 0); + const http::CURLSession cs("", "", "", "", 0); const failable<value> id = http::post(a, uri, cs); assert(hasContent(id)); const string p = path(content(id)); - const lambda<bool()> gl = getLoop(p, a, cs); + const blambda gl = [p, a, cs]() -> const bool { + const failable<value> val = http::get(uri + p, cs); + assert(hasContent(val)); + assert(content(val) == a); + return true; + }; cout << "FileDB get test " << time(gl, 5, 200) << " ms" << endl; return true; diff --git a/sca-cpp/trunk/components/filedb/file-test.cpp b/sca-cpp/trunk/components/filedb/file-test.cpp index ff57bd79ce..5270967ccb 100644 --- a/sca-cpp/trunk/components/filedb/file-test.cpp +++ b/sca-cpp/trunk/components/filedb/file-test.cpp @@ -32,12 +32,12 @@ namespace tuscany { namespace filedb { -bool testFileDB(const string& dbname, const string& format) { - FileDB db(dbname, format); +const bool testFileDB(const string& dbname, const string& format) { + const FileDB db(dbname, format); const value k = mklist<value>("a", "b"); - const list<value> a = mklist<value>(list<value>() + "ns1:a" + (list<value>() + "@xmlns:ns1" + string("http://aaa")) + (list<value>() + "text" + string("Hey!"))); - const list<value> b = mklist<value>(list<value>() + "ns1:b" + (list<value>() + "@xmlns:ns1" + string("http://bbb")) + (list<value>() + "text" + string("Hey!"))); + const list<value> a = mklist<value>(nilListValue + "ns1:a" + (nilListValue + "@xmlns:ns1" + string("http://aaa")) + (nilListValue + "text" + string("Hey!"))); + const list<value> b = mklist<value>(nilListValue + "ns1:b" + (nilListValue + "@xmlns:ns1" + string("http://bbb")) + (nilListValue + "text" + string("Hey!"))); assert(hasContent(post(k, a, db))); assert((get(k, db)) == value(a)); @@ -50,27 +50,17 @@ bool testFileDB(const string& dbname, const string& format) { return true; } -struct getLoop { - const value k; - FileDB& db; - const list<value> c; - getLoop(const value& k, FileDB& db) : k(k), db(db), - c(mklist<value>(list<value>() + "ns1:c" + (list<value>() + "@xmlns:ns1" + string("http://ccc")) + (list<value>() + "text" + string("Hey!")))) { - } - const bool operator()() const { - assert((get(k, db)) == value(c)); - return true; - } -}; - -bool testGetPerf(const string& dbname, const string& format) { - FileDB db(dbname, format); +const bool testGetPerf(const string& dbname, const string& format) { + const FileDB db(dbname, format); const value k = mklist<value>("c"); - const list<value> c = mklist<value>(list<value>() + "ns1:c" + (list<value>() + "@xmlns:ns1" + string("http://ccc")) + (list<value>() + "text" + string("Hey!"))); + const list<value> c = mklist<value>(nilListValue + "ns1:c" + (nilListValue + "@xmlns:ns1" + string("http://ccc")) + (nilListValue + "text" + string("Hey!"))); assert(hasContent(post(k, c, db))); - const lambda<bool()> gl = getLoop(k, db); + const blambda gl = [k, c, db]() -> const bool { + assert((get(k, db)) == value(c)); + return true; + }; cout << "FileDB get test " << time(gl, 5, 5000) << " ms" << endl; return true; } diff --git a/sca-cpp/trunk/components/filedb/filedb.cpp b/sca-cpp/trunk/components/filedb/filedb.cpp index 8644a78574..37cb6c5260 100644 --- a/sca-cpp/trunk/components/filedb/filedb.cpp +++ b/sca-cpp/trunk/components/filedb/filedb.cpp @@ -37,14 +37,14 @@ namespace filedb { /** * Get an item from the database. */ -const failable<value> get(const list<value>& params, filedb::FileDB& db) { +const failable<value> get(const list<value>& params, const filedb::FileDB& db) { return filedb::get(car(params), db); } /** * Post an item to the database. */ -const failable<value> post(const list<value>& params, filedb::FileDB& db) { +const failable<value> post(const list<value>& params, const filedb::FileDB& db) { const value id = append<value>(car(params), mklist(mkuuid())); const failable<bool> val = filedb::post(id, cadr(params), db); if (!hasContent(val)) @@ -55,7 +55,7 @@ const failable<value> post(const list<value>& params, filedb::FileDB& db) { /** * Put an item into the database. */ -const failable<value> put(const list<value>& params, filedb::FileDB& db) { +const failable<value> put(const list<value>& params, const filedb::FileDB& db) { const failable<bool> val = filedb::put(car(params), cadr(params), db); if (!hasContent(val)) return mkfailure<value>(val); @@ -65,7 +65,7 @@ const failable<value> put(const list<value>& params, filedb::FileDB& db) { /** * Delete an item from the database. */ -const failable<value> del(const list<value>& params, filedb::FileDB& db) { +const failable<value> del(const list<value>& params, const filedb::FileDB& db) { const failable<bool> val = filedb::del(car(params), db); if (!hasContent(val)) return mkfailure<value>(val); @@ -73,14 +73,17 @@ const failable<value> del(const list<value>& params, filedb::FileDB& db) { } /** - * Component implementation lambda function. + * Start the component. */ -class applyfiledb { -public: - applyfiledb(filedb::FileDB& db) : db(db) { - } +const failable<value> start(const list<value>& params) { + // Connect to the configured database and table + const value dbname = ((lvvlambda)car(params))(nilListValue); + const value format = ((lvvlambda)cadr(params))(nilListValue); + + const filedb::FileDB& db = *(new (gc_new<filedb::FileDB>()) filedb::FileDB(absdbname(dbname), format)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda applyfiledb = [db](const list<value>& params) -> const value { const value func(car(params)); if (func == "get") return get(cdr(params), db); @@ -91,24 +94,8 @@ public: if (func == "delete") return del(cdr(params), db); return mkfailure<value>(); - } - -private: - filedb::FileDB& db; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Connect to the configured database and table - const value dbname = ((lambda<value(const list<value>&)>)car(params))(list<value>()); - const value format = ((lambda<value(const list<value>&)>)cadr(params))(list<value>()); - - filedb::FileDB& db = *(new (gc_new<filedb::FileDB>()) filedb::FileDB(absdbname(dbname), format)); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyfiledb(db))); + }; + return value(applyfiledb); } } diff --git a/sca-cpp/trunk/components/filedb/filedb.hpp b/sca-cpp/trunk/components/filedb/filedb.hpp index 9c3017d0d8..2855cebfc6 100644 --- a/sca-cpp/trunk/components/filedb/filedb.hpp +++ b/sca-cpp/trunk/components/filedb/filedb.hpp @@ -32,8 +32,8 @@ #include "monad.hpp" #include "fstream.hpp" #include "element.hpp" -#include "xml.hpp" #include "../../modules/scheme/eval.hpp" +#include "../../modules/xml/xml.hpp" #include "../../modules/json/json.hpp" namespace tuscany { @@ -68,30 +68,22 @@ public: debug("filedb::filedb::copy"); } - const FileDB& operator=(const FileDB& c) { - debug("filedb::filedb::operator="); - if(this == &c) - return *this; - owner = false; - name = c.name; - format = c.format; - return *this; - } + FileDB& operator=(const FileDB& c) = delete; ~FileDB() { } private: - bool owner; - string name; - string format; + const bool owner; + const string name; + const string format; friend const failable<bool> write(const value& v, ostream& os, const string& format); friend const failable<value> read(istream& is, const string& format); - friend const failable<bool> post(const value& key, const value& val, FileDB& db); - friend const failable<bool> put(const value& key, const value& val, FileDB& db); - friend const failable<value> get(const value& key, FileDB& db); - friend const failable<bool> del(const value& key, FileDB& db); + friend const failable<bool> post(const value& key, const value& val, const FileDB& db); + friend const failable<bool> put(const value& key, const value& val, const FileDB& db); + friend const failable<value> get(const value& key, const FileDB& db); + friend const failable<bool> del(const value& key, const FileDB& db); }; /** @@ -100,7 +92,7 @@ private: const string filename(const list<value>& path, const string& root) { if (isNil(path)) return root; - const string name = root + "/" + (isString(car(path))? (string)car(path) : scheme::writeValue(car(path))); + const string name = root + "/" + (isString(car(path))? (string)car(path) : write(content(scheme::writeValue(car(path))))); return filename(cdr(path), name); } @@ -116,7 +108,7 @@ const string filename(const value& key, const string& root) { const failable<bool> mkdirs(const list<value>& path, const string& root) { if (isNil(cdr(path))) return true; - const string dir = root + "/" + (isString(car(path))? (string)car(path) : scheme::writeValue(car(path))); + const string dir = root + "/" + (isString(car(path))? (string)car(path) : write(content(scheme::writeValue(car(path))))); mkdir(c_str(dir), S_IRWXU); return mkdirs(cdr(path), dir); } @@ -126,20 +118,19 @@ const failable<bool> mkdirs(const list<value>& path, const string& root) { */ const failable<bool> write(const value& v, ostream& os, const string& format) { if (format == "scheme") { - const string vs(scheme::writeValue(v)); + const string vs(write(content(scheme::writeValue(v)))); os << vs; return true; } if (format == "xml") { - failable<list<string> > s = writeXML(valuesToElements(v)); + failable<list<string> > s = xml::writeElements(valuesToElements(v)); if (!hasContent(s)) return mkfailure<bool>(s); write(content(s), os); return true; } if (format == "json") { - js::JSContext jscx; - failable<list<string> > s = json::writeJSON(valuesToElements(v), jscx); + failable<list<string> > s = json::writeValue(v); if (!hasContent(s)) return mkfailure<bool>(s); write(content(s), os); @@ -153,27 +144,25 @@ const failable<bool> write(const value& v, ostream& os, const string& format) { */ const failable<value> read(istream& is, const string& format) { if (format == "scheme") { - return scheme::readValue(is); + return scheme::readValue(streamList(is)); } if (format == "xml") { - const value v = elementsToValues(readXML(streamList(is))); - return v; - } - if (format == "json") { - js::JSContext jscx; - const failable<list<value> > fv = json::readJSON(streamList(is), jscx); + const failable<list<value> > fv = xml::readElements(streamList(is)); if (!hasContent(fv)) return mkfailure<value>(fv); const value v = elementsToValues(content(fv)); return v; } + if (format == "json") { + return json::readValue(streamList(is)); + } return mkfailure<value>(string("Unsupported database format: ") + format); } /** * Post a new item to the database. */ -const failable<bool> post(const value& key, const value& val, FileDB& db) { +const failable<bool> post(const value& key, const value& val, const FileDB& db) { debug(key, "filedb::post::key"); debug(val, "filedb::post::value"); debug(db.name, "filedb::post::dbname"); @@ -197,7 +186,7 @@ const failable<bool> post(const value& key, const value& val, FileDB& db) { /** * Update an item in the database. If the item doesn't exist it is added. */ -const failable<bool> put(const value& key, const value& val, FileDB& db) { +const failable<bool> put(const value& key, const value& val, const FileDB& db) { debug(key, "filedb::put::key"); debug(val, "filedb::put::value"); debug(db.name, "filedb::put::dbname"); @@ -221,7 +210,7 @@ const failable<bool> put(const value& key, const value& val, FileDB& db) { /** * Get an item from the database. */ -const failable<value> get(const value& key, FileDB& db) { +const failable<value> get(const value& key, const FileDB& db) { debug(key, "filedb::get::key"); debug(db.name, "filedb::get::dbname"); @@ -242,7 +231,7 @@ const failable<value> get(const value& key, FileDB& db) { /** * Delete an item from the database */ -const failable<bool> del(const value& key, FileDB& db) { +const failable<bool> del(const value& key, const FileDB& db) { debug(key, "filedb::delete::key"); debug(db.name, "filedb::delete::dbname"); diff --git a/sca-cpp/trunk/components/http/Makefile.am b/sca-cpp/trunk/components/http/Makefile.am index 623be12298..078a7eeae6 100644 --- a/sca-cpp/trunk/components/http/Makefile.am +++ b/sca-cpp/trunk/components/http/Makefile.am @@ -23,32 +23,32 @@ comp_LTLIBRARIES = libhttpget.la libhttpdelete.la libhttppost.la libhttpput.la l noinst_DATA = libhttpget${libsuffix} libhttpdelete${libsuffix} libhttppost${libsuffix} libhttpput${libsuffix} libhttppatch${libsuffix} libhttpget_la_SOURCES = httpget.cpp -libhttpget_la_LDFLAGS = -lxml2 -lmozjs -curl +libhttpget_la_LDFLAGS = -lxml2 -ljansson -curl libhttpget${libsuffix}: ln -s .libs/libhttpget${libsuffix} libhttpdelete_la_SOURCES = httpdelete.cpp -libhttpdelete_la_LDFLAGS = -lxml2 -lmozjs -curl +libhttpdelete_la_LDFLAGS = -lxml2 -ljansson -curl libhttpdelete${libsuffix}: ln -s .libs/libhttpdelete${libsuffix} libhttppost_la_SOURCES = httppost.cpp -libhttppost_la_LDFLAGS = -lxml2 -lmozjs -curl +libhttppost_la_LDFLAGS = -lxml2 -ljansson -curl libhttppost${libsuffix}: ln -s .libs/libhttppost${libsuffix} libhttpput_la_SOURCES = httpput.cpp -libhttpput_la_LDFLAGS = -lxml2 -lmozjs -curl +libhttpput_la_LDFLAGS = -lxml2 -ljansson -curl libhttpput${libsuffix}: ln -s .libs/libhttpput${libsuffix} libhttppatch_la_SOURCES = httppatch.cpp -libhttppatch_la_LDFLAGS = -lxml2 -lmozjs -curl +libhttppatch_la_LDFLAGS = -lxml2 -ljansson -curl libhttppatch${libsuffix}: ln -s .libs/libhttppatch${libsuffix} client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = server-test noinst_PROGRAMS = client-test diff --git a/sca-cpp/trunk/components/http/client-test.cpp b/sca-cpp/trunk/components/http/client-test.cpp index bb1918f1f8..42d7cd76c0 100644 --- a/sca-cpp/trunk/components/http/client-test.cpp +++ b/sca-cpp/trunk/components/http/client-test.cpp @@ -41,52 +41,45 @@ const string postURI("http://localhost:8090/httppost"); const string putURI("http://localhost:8090/httpput"); const string deleteURI("http://localhost:8090/httpdelete"); -bool testGet() { - http::CURLSession cs("", "", "", "", 0); +const bool testGet() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> val = http::get(getURI, cs); assert(hasContent(val)); return true; } -struct getLoop { - http::CURLSession& cs; - getLoop(http::CURLSession& cs) : cs(cs) { - } - const bool operator()() const { +const bool testGetPerf() { + const http::CURLSession cs("", "", "", "", 0); + + const blambda gl = [cs]() -> const bool { const failable<value> val = http::get(getURI, cs); assert(hasContent(val)); return true; - } -}; - -bool testGetPerf() { - http::CURLSession cs("", "", "", "", 0); - - const lambda<bool()> gl = getLoop(cs); + }; cout << "HTTP get test " << time(gl, 5, 200) << " ms" << endl; return true; } -bool testPost() { - http::CURLSession cs("", "", "", "", 0); +const bool testPost() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> val = http::get(postURI, cs); assert(hasContent(val)); return true; } -bool testPut() { - http::CURLSession cs("", "", "", "", 0); +const bool testPut() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> val = http::get(putURI, cs); assert(hasContent(val)); return true; } -bool testDelete() { - http::CURLSession cs("", "", "", "", 0); +const bool testDelete() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> val = http::get(deleteURI, cs); assert(hasContent(val)); diff --git a/sca-cpp/trunk/components/http/httpdelete.cpp b/sca-cpp/trunk/components/http/httpdelete.cpp index c725461ec2..a23d2a411d 100644 --- a/sca-cpp/trunk/components/http/httpdelete.cpp +++ b/sca-cpp/trunk/components/http/httpdelete.cpp @@ -37,58 +37,37 @@ namespace httpdelete { /** * Evaluate an HTTP delete. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, const http::CURLSession& ch) { debug("httpdelete::get"); - const value u = url(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); debug(u, "httpdelete::get::url"); return http::del(u, ch); } /** - * Component implementation lambda function. + * Start the component. */ -class applyhttp { -public: - applyhttp(const lambda<value(const list<value>&)>& url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const lvvlambda timeout = cadr(params); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [timeout, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + const int t = atoi(c_str((string)timeout(nilListValue))); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, t); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda applyhttp = [url, ch](const list<value>& params) -> const value { debug(params, "httpdelete::applyhttp::params"); const value func(car(params)); if (func == "get") return get(url, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - perthread_ptr<http::CURLSession> ch; -}; - -/** - * Create a new CURL session. - */ -class newsession { -public: - newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) { - } - const gc_ptr<http::CURLSession> operator()() const { - const int t = atoi(c_str((string)timeout(list<value>()))); - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t); - } -private: - const lambda<value(const list<value>&)> timeout; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(cadr(params)))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch))); + }; + return value(applyhttp); } } diff --git a/sca-cpp/trunk/components/http/httpget.cpp b/sca-cpp/trunk/components/http/httpget.cpp index 884dc1a6ff..b4504d939a 100644 --- a/sca-cpp/trunk/components/http/httpget.cpp +++ b/sca-cpp/trunk/components/http/httpget.cpp @@ -38,59 +38,37 @@ namespace httpget { /** * Evaluate an HTTP get. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, const http::CURLSession& ch) { debug("httpget::get"); - const value u = url(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); debug(u, "httpget::get::url"); return http::get(u, ch); } /** - * Component implementation lambda function. + * Start the component. */ -class applyhttp { -public: - applyhttp(const lambda<value(const list<value>&)>& url, const perthread_ptr<http::CURLSession>& ch) : url(url), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const lvvlambda timeout = cadr(params); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [timeout, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + const int t = atoi(c_str((string)timeout(nilListValue))); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, t); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda applyhttp = [url, ch](const list<value>& params) -> const value { debug(params, "httpget::applyhttp::params"); const value func(car(params)); if (func == "get") return get(url, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - perthread_ptr<http::CURLSession> ch; -}; - - -/** - * Create a new CURL session. - */ -class newsession { -public: - newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) { - } - const gc_ptr<http::CURLSession> operator()() const { - const int t = atoi(c_str((string)timeout(list<value>()))); - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t); - } -private: - const lambda<value(const list<value>&)> timeout; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(cadr(params)))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyhttp(car(params), ch))); + }; + return value(applyhttp); } } diff --git a/sca-cpp/trunk/components/http/httppatch.cpp b/sca-cpp/trunk/components/http/httppatch.cpp index 051b1e09ac..4d93249fad 100644 --- a/sca-cpp/trunk/components/http/httppatch.cpp +++ b/sca-cpp/trunk/components/http/httppatch.cpp @@ -38,61 +38,40 @@ namespace httppatch { /** * Evaluate an HTTP patch. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, const lvvlambda& val, const http::CURLSession& ch) { debug("httppatch::get"); - const value u = url(mklist<value>("get", list<value>())); - const value v = val(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); + const value v = val(mklist<value>("get", nilListValue)); debug(u, "httppatch::get::url"); debug(v, "httppatch::get::val"); return http::patch(v, u, ch); } /** - * Component implementation lambda function. + * Start the component. */ -class applyhttp { -public: - applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const lvvlambda timeout = caddr(params); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [timeout, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + const int t = atoi(c_str((string)timeout(nilListValue))); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, t); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda val = cadr(params); + const lvvlambda applyhttp = [url, val, ch](const list<value>& params) -> const value { debug(params, "httppatch::applyhttp::params"); const value func(car(params)); if (func == "get") return get(url, val, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - const lambda<value(const list<value>&)> val; - perthread_ptr<http::CURLSession> ch; -}; - -/** - * Create a new CURL session. - */ -class newsession { -public: - newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) { - } - const gc_ptr<http::CURLSession> operator()() const { - const int t = atoi(c_str((string)timeout(list<value>()))); - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t); - } -private: - const lambda<value(const list<value>&)> timeout; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params)))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch))); + }; + return value(applyhttp); } } diff --git a/sca-cpp/trunk/components/http/httppost.cpp b/sca-cpp/trunk/components/http/httppost.cpp index 84fd984e19..99928a2687 100644 --- a/sca-cpp/trunk/components/http/httppost.cpp +++ b/sca-cpp/trunk/components/http/httppost.cpp @@ -38,61 +38,40 @@ namespace httppost { /** * Evaluate an HTTP post. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, const lvvlambda& val, const http::CURLSession& ch) { debug("httppost::get"); - const value u = url(mklist<value>("get", list<value>())); - const value v = val(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); + const value v = val(mklist<value>("get", nilListValue)); debug(u, "httppost::get::url"); debug(v, "httppost::get::val"); return http::post(v, u, ch); } /** - * Component implementation lambda function. + * Start the component. */ -class applyhttp { -public: - applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const lvvlambda timeout = caddr(params); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [timeout, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + const int t = atoi(c_str((string)timeout(nilListValue))); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, t); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda val = cadr(params); + const lvvlambda applyhttp = [url, val, ch](const list<value>& params) -> const value { debug(params, "httppost::applyhttp::params"); const value func(car(params)); if (func == "get") return get(url, val, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - const lambda<value(const list<value>&)> val; - perthread_ptr<http::CURLSession> ch; -}; - -/** - * Create a new CURL session. - */ -class newsession { -public: - newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) { - } - const gc_ptr<http::CURLSession> operator()() const { - const int t = atoi(c_str((string)timeout(list<value>()))); - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t); - } -private: - const lambda<const value(const list<value>&)> timeout; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params)))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch))); + }; + return value(applyhttp); } } diff --git a/sca-cpp/trunk/components/http/httpput.cpp b/sca-cpp/trunk/components/http/httpput.cpp index 2ae5da396e..8f8e2bc168 100644 --- a/sca-cpp/trunk/components/http/httpput.cpp +++ b/sca-cpp/trunk/components/http/httpput.cpp @@ -38,61 +38,40 @@ namespace httpput { /** * Evaluate an HTTP put. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, const lvvlambda& val, const http::CURLSession& ch) { debug("httpput::get"); - const value u = url(mklist<value>("get", list<value>())); - const value v = val(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); + const value v = val(mklist<value>("get", nilListValue)); debug(u, "httpput::get::url"); debug(v, "httpput::get::val"); return http::put(v, u, ch); } /** - * Component implementation lambda function. + * Start the component. */ -class applyhttp { -public: - applyhttp(const lambda<value(const list<value>&)>& url, const lambda<value(const list<value>&)>& val, const perthread_ptr<http::CURLSession>& ch) : url(url), val(val), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const lvvlambda timeout = caddr(params); + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [timeout, cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + const int t = atoi(c_str((string)timeout(nilListValue))); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, t); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda val = cadr(params); + const lvvlambda applyhttp = [url, val, ch](const list<value>& params) -> const value { debug(params, "httpput::applyhttp::params"); const value func(car(params)); if (func == "get") return get(url, val, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - const lambda<value(const list<value>&)> val; - perthread_ptr<http::CURLSession> ch; -}; - -/** - * Create a new CURL session. - */ -class newsession { -public: - newsession(const lambda<value(const list<value>&)>& timeout) : timeout(timeout) { - } - const gc_ptr<http::CURLSession> operator()() const { - const int t = atoi(c_str((string)timeout(list<value>()))); - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", t); - } -private: - const lambda<value(const list<value>&)> timeout; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - const perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession(caddr(params)))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyhttp(car(params), cadr(params), ch))); + }; + return value(applyhttp); } } diff --git a/sca-cpp/trunk/components/kvdb/Makefile.am b/sca-cpp/trunk/components/kvdb/Makefile.am deleted file mode 100644 index 3212f3f5c8..0000000000 --- a/sca-cpp/trunk/components/kvdb/Makefile.am +++ /dev/null @@ -1,49 +0,0 @@ -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -INCLUDES = -I${LEVELDB_INCLUDE} - -incl_HEADERS = *.hpp -incldir = $(prefix)/include/components/kvdb - -dist_comp_SCRIPTS = leveldb -compdir=$(prefix)/components/kvdb - -comp_DATA = leveldb.prefix -leveldb.prefix: $(top_builddir)/config.status - echo ${LEVELDB_PREFIX} >leveldb.prefix - -EXTRA_DIST = kvdb.composite kvdb.componentType - -comp_LTLIBRARIES = libkvdb.la -noinst_DATA = libkvdb${libsuffix} - -libkvdb_la_SOURCES = kvdb.cpp -libkvdb_la_LDFLAGS = -L${LEVELDB_LIB} -R${LEVELDB_LIB} -lleveldb -libkvdb${libsuffix}: - ln -s .libs/libkvdb${libsuffix} - -leveldb_test_SOURCES = leveldb-test.cpp -leveldb_test_LDFLAGS = -L${LEVELDB_LIB} -R${LEVELDB_LIB} -lleveldb - -client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs - -dist_noinst_SCRIPTS = kvdb-test server-test -noinst_PROGRAMS = leveldb-test client-test -TESTS = kvdb-test server-test - diff --git a/sca-cpp/trunk/components/kvdb/client-test.cpp b/sca-cpp/trunk/components/kvdb/client-test.cpp deleted file mode 100644 index 5f0ef21d00..0000000000 --- a/sca-cpp/trunk/components/kvdb/client-test.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * Test KV (Key-Value) database component. - */ - -#include <assert.h> -#include "stream.hpp" -#include "string.hpp" - -#include "list.hpp" -#include "value.hpp" -#include "monad.hpp" -#include "perf.hpp" -#include "../../modules/http/http.hpp" - -namespace tuscany { -namespace nosqldb { - -const string uri("http://localhost:8090/nosqldb"); - -bool testNoSqlDb() { - http::CURLSession cs("", "", "", ""); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) - + i); - - const failable<value> id = http::post(a, uri, cs); - assert(hasContent(id)); - - const string p = path(content(id)); - { - const failable<value> val = http::get(uri + p, cs); - assert(hasContent(val)); - assert(content(val) == a); - } - - const list<value> j = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$3.55"))); - const list<value> b = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) - + j); - - { - const failable<value> r = http::put(b, uri + p, cs); - assert(hasContent(r)); - assert(content(r) == value(true)); - } - { - const failable<value> val = http::get(uri + p, cs); - assert(hasContent(val)); - assert(content(val) == b); - } - { - const failable<value> r = http::del(uri + p, cs); - assert(hasContent(r)); - assert(content(r) == value(true)); - } - { - const failable<value> val = http::get(uri + p, cs); - assert(!hasContent(val)); - } - - return true; -} - -struct getLoop { - const string path; - const value entry; - http::CURLSession& cs; - getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) { - } - const bool operator()() const { - const failable<value> val = http::get(uri + path, cs); - assert(hasContent(val)); - assert(content(val) == entry); - return true; - } -}; - -bool testGetPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$4.55"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) - + i); - - http::CURLSession cs("", "", "", ""); - const failable<value> id = http::post(a, uri, cs); - assert(hasContent(id)); - const string p = path(content(id)); - - const lambda<bool()> gl = getLoop(p, a, cs); - cout << "NoSqldb get test " << time(gl, 5, 200) << " ms" << endl; - - return true; -} - -} -} - -int main() { - tuscany::cout << "Testing..." << tuscany::endl; - - tuscany::nosqldb::testNoSqlDb(); - tuscany::nosqldb::testGetPerf(); - - tuscany::cout << "OK" << tuscany::endl; - - return 0; -} diff --git a/sca-cpp/trunk/components/kvdb/kvdb-test b/sca-cpp/trunk/components/kvdb/kvdb-test deleted file mode 100755 index 420b98559c..0000000000 --- a/sca-cpp/trunk/components/kvdb/kvdb-test +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Setup -rm -rf tmp -mkdir -p tmp -./tinycdb -c -m tmp/test.cdb </dev/null - -# Test -./tinycdb-test 2>/dev/null -rc=$? - -# Cleanup -exit $rc diff --git a/sca-cpp/trunk/components/kvdb/kvdb.componentType b/sca-cpp/trunk/components/kvdb/kvdb.componentType deleted file mode 100644 index 1c56ab6807..0000000000 --- a/sca-cpp/trunk/components/kvdb/kvdb.componentType +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. ---> -<componentType xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns:t="http://tuscany.apache.org/xmlns/sca/1.1" - targetNamespace="http://tuscany.apache.org/xmlns/sca/components"> - - <service name="nvdb"/> - <property name="dbname" type="xsd:string"/> - -</componentType> diff --git a/sca-cpp/trunk/components/kvdb/kvdb.composite b/sca-cpp/trunk/components/kvdb/kvdb.composite deleted file mode 100644 index 378f418cfc..0000000000 --- a/sca-cpp/trunk/components/kvdb/kvdb.composite +++ /dev/null @@ -1,32 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!-- - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. ---> -<composite xmlns="http://docs.oasis-open.org/ns/opencsa/sca/200912" - targetNamespace="http://tuscany.apache.org/xmlns/sca/components" - name="nvdb"> - - <component name="nvdb"> - <implementation.cpp path="." library="libnvdb"/> - <property name="dbname">tmp/test.cdb</property> - <service name="nvdb"> - <binding.http uri="nvdb"/> - </service> - </component> - -</composite> diff --git a/sca-cpp/trunk/components/kvdb/kvdb.cpp b/sca-cpp/trunk/components/kvdb/kvdb.cpp deleted file mode 100644 index 0df8f13882..0000000000 --- a/sca-cpp/trunk/components/kvdb/kvdb.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * LevelDB-based database component implementation. - */ - -#define WANT_HTTPD_LOG 1 -#include "string.hpp" -#include "function.hpp" -#include "list.hpp" -#include "value.hpp" -#include "monad.hpp" -#include "leveldb.hpp" - -namespace tuscany { -namespace nvdb { - -/** - * Get an item from the database. - */ -const failable<value> get(const list<value>& params, leveldb::LevelDB& cdb) { - return leveldb::get(car(params), cdb); -} - -/** - * Post an item to the database. - */ -const failable<value> post(const list<value>& params, leveldb::LevelDB& cdb) { - const value id = append<value>(car(params), mklist(mkuuid())); - const failable<bool> val = leveldb::post(id, cadr(params), cdb); - if (!hasContent(val)) - return mkfailure<value>(val); - return id; -} - -/** - * Put an item into the database. - */ -const failable<value> put(const list<value>& params, leveldb::LevelDB& cdb) { - const failable<bool> val = leveldb::put(car(params), cadr(params), cdb); - if (!hasContent(val)) - return mkfailure<value>(val); - return value(content(val)); -} - -/** - * Delete an item from the database. - */ -const failable<value> del(const list<value>& params, leveldb::LevelDB& cdb) { - const failable<bool> val = leveldb::del(car(params), cdb); - if (!hasContent(val)) - return mkfailure<value>(val); - return value(content(val)); -} - -/** - * Component implementation lambda function. - */ -class applyNoSqldb { -public: - applyNoSqldb(leveldb::LevelDB& cdb) : cdb(cdb) { - } - - const value operator()(const list<value>& params) const { - const value func(car(params)); - if (func == "get") - return get(cdr(params), cdb); - if (func == "post") - return post(cdr(params), cdb); - if (func == "put") - return put(cdr(params), cdb); - if (func == "delete") - return del(cdr(params), cdb); - return mkfailure<value>(); - } - -private: - leveldb::LevelDB& cdb; -}; - -/** - * Start the component. - */ -const failable<value> start(unused const list<value>& params) { - // Connect to the configured database and table - const value dbname = ((lambda<const value(list<value>&)>)car(params))(list<value>()); - leveldb::LevelDB& cdb = *(new (gc_new<leveldb::LevelDB>()) leveldb::LevelDB(dbname)); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyNoSqldb(cdb))); -} - -} -} - -extern "C" { - -const tuscany::value apply(const tuscany::list<tuscany::value>& params) { - const tuscany::value func(car(params)); - if (func == "start") - return tuscany::nosqldb::start(cdr(params)); - return tuscany::mkfailure<tuscany::value>(); -} - -} diff --git a/sca-cpp/trunk/components/kvdb/leveldb b/sca-cpp/trunk/components/kvdb/leveldb deleted file mode 100755 index f9c54465f6..0000000000 --- a/sca-cpp/trunk/components/kvdb/leveldb +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -here=`echo "import os; print os.path.realpath('$0')" | python`; here=`dirname $here` -leveldb_prefix=`cat $here/leveldb.prefix` - -$leveldb_prefix/bin/cdb $* - diff --git a/sca-cpp/trunk/components/kvdb/leveldb-test.cpp b/sca-cpp/trunk/components/kvdb/leveldb-test.cpp deleted file mode 100644 index b3b4ea7fd7..0000000000 --- a/sca-cpp/trunk/components/kvdb/leveldb-test.cpp +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -/** - * Test TinyCDB access functions. - */ - -#include <assert.h> -#include "stream.hpp" -#include "string.hpp" -#include "perf.hpp" -#include "tinycdb.hpp" - -namespace tuscany { -namespace tinycdb { - -bool testTinyCDB() { - TinyCDB cdb("tmp/test.cdb"); - const value k = mklist<value>("a"); - - assert(hasContent(post(k, string("AAA"), cdb))); - assert((get(k, cdb)) == value(string("AAA"))); - assert(hasContent(put(k, string("aaa"), cdb))); - assert((get(k, cdb)) == value(string("aaa"))); - assert(hasContent(del(k, cdb))); - assert(!hasContent(get(k, cdb))); - - return true; -} - -struct getLoop { - const value k; - TinyCDB& cdb; - getLoop(const value& k, TinyCDB& cdb) : k(k), cdb(cdb) { - } - const bool operator()() const { - assert((get(k, cdb)) == value(string("CCC"))); - return true; - } -}; - -bool testGetPerf() { - const value k = mklist<value>("c"); - TinyCDB cdb("tmp/test.cdb"); - assert(hasContent(post(k, string("CCC"), cdb))); - - const lambda<bool()> gl = getLoop(k, cdb); - cout << "TinyCDB get test " << time(gl, 5, 100000) << " ms" << endl; - return true; -} - -} -} - -int main() { - tuscany::cout << "Testing..." << tuscany::endl; - - tuscany::tinycdb::testTinyCDB(); - tuscany::tinycdb::testGetPerf(); - - tuscany::cout << "OK" << tuscany::endl; - - return 0; -} diff --git a/sca-cpp/trunk/components/kvdb/leveldb.hpp b/sca-cpp/trunk/components/kvdb/leveldb.hpp deleted file mode 100644 index 05a89a76f7..0000000000 --- a/sca-cpp/trunk/components/kvdb/leveldb.hpp +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -/* $Rev$ $Date$ */ - -#ifndef tuscany_leveldb_hpp -#define tuscany_leveldb_hpp - -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> -#include <leveldb/db.h> - -#include "string.hpp" -#include "list.hpp" -#include "value.hpp" -#include "monad.hpp" -#include "../../modules/scheme/eval.hpp" - -namespace tuscany { -namespace leveldb { - -/** - * A reallocatable buffer. - */ -class buffer { -public: - operator void*() const throw() { - return buf; - } - - operator unsigned char*() const throw() { - return (unsigned char*)buf; - } - - operator char*() const throw() { - return (char*)buf; - } - -private: - buffer(const unsigned int size, void* buf) : size(size), buf(buf) { - } - - unsigned int size; - void* buf; - - friend const buffer mkbuffer(const unsigned int sz); - friend const buffer mkbuffer(const buffer& b, const unsigned int newsz); - friend const bool free(const buffer& b); -}; - -/** - * Make a new buffer. - */ -const buffer mkbuffer(const unsigned int sz) { - return buffer(sz, malloc(sz)); -} - -/** - * Make a new buffer by reallocating an existing one. - */ -const buffer mkbuffer(const buffer& b, const unsigned int sz) { - if (sz <= b.size) - return b; - return buffer(sz, realloc(b.buf, sz)); -} - -/** - * Free a buffer. - */ -const bool free(const buffer&b) { - ::free(b.buf); - return true; -} - -/** - * Convert a database name to an absolute path. - */ -const string absdbname(const string& name) { - if (length(name) == 0 || c_str(name)[0] == '/') - return name; - char cwd[512]; - if (getcwd(cwd, sizeof(cwd)) == NULL) - return name; - return string(cwd) + "/" + name; -} - -/** - * Represents a LevelDB connection. - */ -class LevelDB { -public: - LevelDB() : owner(false), fd(-1) { - debug("leveldb::leveldb"); - st.st_ino = 0; - } - - LevelDB(const string& name) : owner(true), name(absdbname(name)), fd(-1) { - debug(name, "leveldb::leveldb::name"); - st.st_ino = 0; - } - - LevelDB(const LevelDB& c) : owner(false), name(c.name), fd(c.fd) { - debug("leveldb::leveldb::copy"); - st.st_ino = c.st.st_ino; - } - - const LevelDB& operator=(const LevelDB& c) { - debug("leveldb::leveldb::operator="); - if(this == &c) - return *this; - owner = false; - name = c.name; - fd = c.fd; - st.st_ino = c.st.st_ino; - return *this; - } - - ~LevelDB() { - debug("leveldb::~leveldb"); - if (!owner) - return; - if (fd == -1) - return; - close(fd); - } - -private: - bool owner; - string name; - leveldb::DB* db; - struct stat st; - - friend const string dbname(const LevelDB& db); - friend const failable<int> dbopen(LevelDB& db); - friend const failable<bool> dbclose(LevelDB& db); -}; - -/** - * Return the name of the database. - */ -const string dbname(const LevelDB& db) { - return db.name; -} - -/** - * Open a database. - */ -const failable<int> dbopen(LevelDB& db) { - - // Get database file serial number - struct stat st; - const int s = stat(c_str(db.name), &st); - if (s == -1) - return mkfailure<int>(string("Couldn't leveldb read database stat: ") + db.name); - - leveldb::DB* ldb; - leveldb::Options options; - options.create_if_missing = true; - leveldb::Status status = leveldb::DB::Open(options, s, &ldb); - db.db = ldb; -} - -/** - * Close a database. - */ -const failable<bool> dbclose(LevelDB& db) { - delete db.db; - db.db = NULL; - return true; -} - - -const failable<bool> post(const value& key, const value& val, LevelDB& db) { - debug(key, "leveldb::post::key"); - debug(val, "leveldb::post::value"); - debug(dbname(db), "leveldb::post::dbname"); - - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); - - put(ks, vs, db); - - debug(r, "leveldb::post::result"); - return r; -} - - -const failable<bool> put(const value& key, const value& val, LevelDB& db) { - debug(key, "leveldb::put::key"); - debug(val, "leveldb::put::value"); - debug(dbname(db), "leveldb::put::dbname"); - - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); - - debug(r, "leveldb::put::result"); - return r; -} - -/** - * Get an item from the database. - */ -const failable<value> get(const value& key, LevelDB& db) { - debug(key, "leveldb::get::key"); - debug(dbname(db), "leveldb::get::dbname"); - - const string ks(scheme::writeValue(key)); - - std::string data; - db.db->Get(leveldb::ReadOptions(), key, &data); - const value val(scheme::readValue(string(data))); - - debug(val, "leveldb::get::result"); - return val; -} - -/** - * Delete an item from the database - */ -struct delUpdate { - const string ks; - delUpdate(const string& ks) : ks(ks) { - } - const failable<bool> operator()(buffer& buf, const unsigned int klen, unused const unsigned int vlen) const { - if (ks == string((char*)buf, klen)) - return false; - return true; - } -}; - -struct delFinish { - delFinish() { - } - const failable<bool> operator()(unused struct db_make& dbm) const { - return true; - } -}; - -const failable<bool> del(const value& key, LevelDB& db) { - debug(key, "leveldb::delete::key"); - debug(dbname(db), "leveldb::delete::dbname"); - - const string ks(scheme::writeValue(key)); - - leveldb::Status s = db.db->Delete(leveldb::WriteOptions(), key); - - debug(r, "leveldb::delete::result"); - return s.ok(); -} - -} -} - -#endif /* tuscany_leveldb_hpp */ diff --git a/sca-cpp/trunk/components/kvdb/server-test b/sca-cpp/trunk/components/kvdb/server-test deleted file mode 100755 index ebf01b9b4b..0000000000 --- a/sca-cpp/trunk/components/kvdb/server-test +++ /dev/null @@ -1,41 +0,0 @@ -#!/bin/sh - -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. - -# Setup -rm -rf tmp -../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs -../../modules/server/server-conf tmp -../../modules/server/scheme-conf tmp -cat >>tmp/conf/httpd.conf <<EOF -SCAContribution `pwd`/ -SCAComposite nosqldb.composite -EOF - -./leveldb -c -m tmp/test.cdb </dev/null -../../modules/http/httpd-start tmp -sleep 2 - -# Test -./client-test #2>/dev/null -rc=$? - -# Cleanup -../../modules/http/httpd-stop tmp -sleep 2 -exit $rc diff --git a/sca-cpp/trunk/components/log/Makefile.am b/sca-cpp/trunk/components/log/Makefile.am index 0e96be5697..45074b11a4 100644 --- a/sca-cpp/trunk/components/log/Makefile.am +++ b/sca-cpp/trunk/components/log/Makefile.am @@ -70,7 +70,7 @@ scribe_status_SOURCES = scribe-status.cpp scribe_status_LDFLAGS = -L${THRIFT_LIB} -R${THRIFT_LIB} -lthrift -L${FB303_LIB} -R${FB303_LIB} -lfb303 -L${SCRIBE_LIB} -R${SCRIBE_LIB} -lscribe client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = scribe-test server-test noinst_PROGRAMS = client-test diff --git a/sca-cpp/trunk/components/log/client-test.cpp b/sca-cpp/trunk/components/log/client-test.cpp index d8cac5ee81..6e0ecaf89e 100644 --- a/sca-cpp/trunk/components/log/client-test.cpp +++ b/sca-cpp/trunk/components/log/client-test.cpp @@ -38,15 +38,15 @@ namespace log { const string uri("http://localhost:8090/log"); -bool testLog() { - http::CURLSession cs("", "", "", "", 0); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testLog() { + const http::CURLSession cs("", "", "", "", 0); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); const failable<value> id = http::post(a, uri, cs); @@ -55,40 +55,31 @@ bool testLog() { return true; } -struct logLoop { - const value a; - const string uri; - http::CURLSession& cs; - logLoop(const value& a, const string& uri, http::CURLSession& cs) : a(a), uri(uri), cs(cs) { - } - const bool operator()() const { - const failable<value> id = http::post(a, uri, cs); - assert(hasContent(id)); - return true; - } -}; - -bool testLogPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testLogPerf() { + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", "", "", 0); + const http::CURLSession cs("", "", "", "", 0); const failable<value> id = http::post(a, uri, cs); assert(hasContent(id)); - const lambda<bool()> ll = logLoop(a, uri, cs); + const blambda ll = [a, uri, cs]() -> const bool { + const failable<value> id = http::post(a, uri, cs); + assert(hasContent(id)); + return true; + }; cout << "Log test " << time(ll, 5, 200) << " ms" << endl; return true; } -bool testLogger() { - http::CURLSession cs("", "", "", "", 0); +const bool testLogger() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> res = http::evalExpr(mklist<value>(string("sum"), 33, 22), string("http://localhost:8090/client"), cs); assert(hasContent(res)); diff --git a/sca-cpp/trunk/components/log/log.cpp b/sca-cpp/trunk/components/log/log.cpp index f7f7086192..11d24c8da5 100644 --- a/sca-cpp/trunk/components/log/log.cpp +++ b/sca-cpp/trunk/components/log/log.cpp @@ -38,7 +38,7 @@ namespace log { /** * Post an item to the Scribe log. */ -const failable<value> post(const list<value>& params, const value& host, const value& category, scribe::Scribe& sc) { +const failable<value> post(const list<value>& params, const value& host, const value& category, const scribe::Scribe& sc) { debug(cadr(params), "log::post::value"); const failable<bool> val = scribe::log(cadr(params), host, category, sc); if (!hasContent(val)) @@ -47,41 +47,26 @@ const failable<value> post(const list<value>& params, const value& host, const v } /** - * Component implementation lambda function. - */ -class applyLog { -public: - applyLog(const value& host, const value& category, scribe::Scribe& sc) : host(host), category(category), sc(sc) { - } - - const value operator()(const list<value>& params) const { - const value func(car(params)); - if (func == "post") - return post(cdr(params), host, category, sc); - return mkfailure<value>(); - } - -private: - const value host; - const value category; - scribe::Scribe& sc; -}; - -/** * Start the component. */ const failable<value> start(const list<value>& params) { // Connect to Scribe - scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464)); + const scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464)); // Extract the configured category - const value host = ((lambda<value(const list<value>&)>)car(params))(list<value>()); - const value category = ((lambda<value(const list<value>&)>)cadr(params))(list<value>()); + const value host = ((lvvlambda)car(params))(nilListValue); + const value category = ((lvvlambda)cadr(params))(nilListValue); debug(host, "log::start::host"); debug(category, "log::start::category"); // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyLog(host, category, sc))); + const lvvlambda applyLog = [host, category, sc](const list<value>& params) -> const value { + const value func(car(params)); + if (func == "post") + return post(cdr(params), host, category, sc); + return mkfailure<value>(); + }; + return value(applyLog); } } diff --git a/sca-cpp/trunk/components/log/logger.cpp b/sca-cpp/trunk/components/log/logger.cpp index d7969036ab..46fd1f7cb4 100644 --- a/sca-cpp/trunk/components/log/logger.cpp +++ b/sca-cpp/trunk/components/log/logger.cpp @@ -37,14 +37,21 @@ namespace tuscany { namespace logger { /** - * Component implementation lambda function. + * Start the component. */ -class applyLog { -public: - applyLog(const lambda<value(const list<value>&)>& relay, const value& host, const value& category, scribe::Scribe& sc) : relay(relay), host(host), category(category), sc(sc) { - } +const failable<value> start(const list<value>& params) { + // Connect to Scribe + const scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464)); - const value operator()(const list<value>& params) const { + // Extract the configured relay service and category + const value relay = car(params); + const value host = ((lvvlambda)cadr(params))(nilListValue); + const value category = ((lvvlambda)caddr(params))(nilListValue); + debug(host, "logger::start::host"); + debug(category, "logger::start::category"); + + // Return the component implementation lambda function + const lvvlambda applyLog = [relay, host, category, sc](const list<value>& params) -> const value { // Log the function params debug(params, "logger::apply::params"); scribe::log(params, host, category, sc); @@ -55,31 +62,8 @@ public: // Log the result scribe::log(res, host, category, sc); return res; - } - -private: - const lambda<value(const list<value>&)> relay; - const value host; - const value category; - scribe::Scribe& sc; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Connect to Scribe - scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe("localhost", 1464)); - - // Extract the configured relay service and category - const value rel = car(params); - const value host = ((lambda<value(const list<value>&)>)cadr(params))(list<value>()); - const value category = ((lambda<value(const list<value>&)>)caddr(params))(list<value>()); - debug(host, "logger::start::host"); - debug(category, "logger::start::category"); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applyLog(rel, host, category, sc))); + }; + return value(applyLog); } } diff --git a/sca-cpp/trunk/components/log/scribe-cat.cpp b/sca-cpp/trunk/components/log/scribe-cat.cpp index 254e2167ae..d9a2e44613 100644 --- a/sca-cpp/trunk/components/log/scribe-cat.cpp +++ b/sca-cpp/trunk/components/log/scribe-cat.cpp @@ -36,14 +36,14 @@ namespace tuscany { namespace scribecat { -int cat(const string& host, const string& category, const string& type) { +const int cat(const string& host, const string& category, const string& type) { // Connect to Scribe scribe::Scribe& sc = *(new (gc_new<scribe::Scribe>()) scribe::Scribe(host, 1464)); // Read lines from stdin and log them char buf[8193]; for (;;) { - gc_scoped_pool p; + const gc_scoped_pool p; // Write line prefix ostringstream os; @@ -54,7 +54,7 @@ int cat(const string& host, const string& category, const string& type) { strcpy(buf, c_str(prefix)); // Read log line - const char* s = fgets(buf + pl, 8192 - pl, stdin); + const char* const s = fgets(buf + pl, 8192 - pl, stdin); if (s == NULL) return 0; @@ -73,7 +73,7 @@ int cat(const string& host, const string& category, const string& type) { } } -int main(const int argc, const char** argv) { +int main(const int argc, const char** const argv) { return tuscany::scribecat::cat(argc < 2? "localhost" : argv[1], argc < 3? "default" : argv[2], argc < 4? "" : argv[3]); } diff --git a/sca-cpp/trunk/components/log/scribe-status.cpp b/sca-cpp/trunk/components/log/scribe-status.cpp index 79f7572947..7dbf94542b 100644 --- a/sca-cpp/trunk/components/log/scribe-status.cpp +++ b/sca-cpp/trunk/components/log/scribe-status.cpp @@ -60,7 +60,7 @@ const int status(const string& host, const int port) { } } -int main(const int argc, const char** argv) { +int main(const int argc, const char** const argv) { return tuscany::scribestatus::status(argc < 2? "localhost" : argv[1], argc < 3? 1463 : atoi(argv[2])); } diff --git a/sca-cpp/trunk/components/log/scribe.hpp b/sca-cpp/trunk/components/log/scribe.hpp index 0f0570be64..fd18f53bb7 100644 --- a/sca-cpp/trunk/components/log/scribe.hpp +++ b/sca-cpp/trunk/components/log/scribe.hpp @@ -74,21 +74,11 @@ public: init(host, port); } - Scribe(const Scribe& c) : owner(false) { + Scribe(const Scribe& c) : owner(false), client(c.client), transport(c.transport) { debug("scribe::scribe::copy"); - client = c.client; - transport = c.transport; } - const Scribe& operator=(const Scribe& c) { - debug("scribe::scribe::operator="); - if(this == &c) - return *this; - owner = false; - client = c.client; - transport = c.transport; - return *this; - } + Scribe& operator=(const Scribe& c) = delete; ~Scribe() { if (!owner) @@ -102,7 +92,7 @@ public: } private: - bool owner; + const bool owner; ::scribe::thrift::scribeClient* client; boost::shared_ptr<apache::thrift::transport::TTransport> transport; @@ -135,8 +125,8 @@ const failable<bool> log(const value& val, const string& host, const value& cate debug(category, "scribe::log::category"); const value cat = isString(category)? value(c_str(category)):category; - const string cs(scheme::writeValue(cat)); - const string vs(scheme::writeValue(val)); + const string cs(write(content(scheme::writeValue(cat)))); + const string vs(write(content(scheme::writeValue(val)))); ostringstream os; os << "[" << host << "] " << vs; @@ -147,8 +137,8 @@ const failable<bool> log(const value& val, const string& host, const value& cate std::vector< ::scribe::thrift::LogEntry> msgs; msgs.push_back(entry); - int result = sc.client->Log(msgs); - if (result != ::scribe::thrift::OK) + const int result = sc.client->Log(msgs); + if (result != ::scribe::thrift::ResultCode::OK) return mkfailure<bool>("Could not log value, retry later"); } catch (const std::exception& e) { return mkfailure<bool>(e.what()); @@ -165,24 +155,24 @@ const failable<string> status(const Scribe& sc) { debug("scribe::status"); try { - ::facebook::fb303::fb_status s = sc.client->getStatus(); + ::facebook::fb303::fb_status::type s = sc.client->getStatus(); switch(s) { - case ::facebook::fb303::DEAD: + case ::facebook::fb303::fb_status::DEAD: debug("DEAD", "scribe::status::result"); return string("DEAD"); - case ::facebook::fb303::STARTING: + case ::facebook::fb303::fb_status::STARTING: debug("STARTING", "scribe::status::result"); return string("STARTING"); - case ::facebook::fb303::ALIVE: + case ::facebook::fb303::fb_status::ALIVE: debug("ALIVE", "scribe::status::result"); return string("ALIVE"); - case ::facebook::fb303::STOPPING: + case ::facebook::fb303::fb_status::STOPPING: debug("STOPPING", "scribe::status::result"); return string("STOPPING"); - case ::facebook::fb303::STOPPED: + case ::facebook::fb303::fb_status::STOPPED: debug("STOPPED", "scribe::status::result"); return string("STOPPED"); - case ::facebook::fb303::WARNING: + case ::facebook::fb303::fb_status::WARNING: debug("WARNING", "scribe::status::result"); return string("WARNING"); } diff --git a/sca-cpp/trunk/components/queue/Makefile.am b/sca-cpp/trunk/components/queue/Makefile.am index c44722a523..81a7128b4a 100644 --- a/sca-cpp/trunk/components/queue/Makefile.am +++ b/sca-cpp/trunk/components/queue/Makefile.am @@ -48,7 +48,7 @@ qpid_test_SOURCES = qpid-test.cpp qpid_test_LDFLAGS = -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon +client_test_LDFLAGS = -lxml2 -lcurl -ljansson -L${QPIDC_LIB} -R${QPIDC_LIB} -lqpidclient -lqpidcommon dist_noinst_SCRIPTS = send-test server-test noinst_PROGRAMS = qpid-test client-test diff --git a/sca-cpp/trunk/components/queue/client-test.cpp b/sca-cpp/trunk/components/queue/client-test.cpp index 30bfe07bf7..f1399bb22c 100644 --- a/sca-cpp/trunk/components/queue/client-test.cpp +++ b/sca-cpp/trunk/components/queue/client-test.cpp @@ -46,15 +46,15 @@ namespace queue { const value key(mklist<value>(string("report"))); const string qname("reportq"); -const list<value> item = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); -const list<value> entry = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const list<value> item = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); +const list<value> entry = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + item); -bool testDeclareQueue() { +const bool testDeclareQueue() { QpidConnection qc; QpidSession qs(qc); const failable<bool> r = declareQueue(key, qname, qs); @@ -69,18 +69,18 @@ const bool listener(const value& k, const value& v) { return false; } -bool testListen() { +const bool testListen() { QpidConnection qc; QpidSession qs(qc); QpidSubscription qsub(qs); - const lambda<bool(const value&, const value&)> l(listener); + const lambda<const bool(const value&, const value&)> l(listener); listen(qname, l, qsub); return true; } -bool testPost() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", ""); +const bool testPost() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); const failable<value> id = http::post(entry, "http://localhost:8090/print-sender", ch); assert(hasContent(id)); return true; diff --git a/sca-cpp/trunk/components/queue/qpid-test.cpp b/sca-cpp/trunk/components/queue/qpid-test.cpp index 27db7734b0..87fc39c8bd 100644 --- a/sca-cpp/trunk/components/queue/qpid-test.cpp +++ b/sca-cpp/trunk/components/queue/qpid-test.cpp @@ -45,7 +45,7 @@ namespace queue { const value key(mklist<value>("test")); const string qname("testq"); -bool testDeclareQueue() { +const bool testDeclareQueue() { QpidConnection qc; QpidSession qs(qc); const failable<bool> r = declareQueue(key, qname, qs); @@ -53,12 +53,12 @@ bool testDeclareQueue() { return true; } -const list<value> item = list<value>() - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99")); +const list<value> item = nilListValue + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99")); const list<value> entry = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), item); -bool testPost() { +const bool testPost() { QpidConnection qc; QpidSession qs(qc); const failable<bool> r = post(key, entry, qs); @@ -72,11 +72,11 @@ const bool listener(const value& k, const value& v) { return false; } -bool testListen() { +const bool testListen() { QpidConnection qc; QpidSession qs(qc); QpidSubscription qsub(qs); - const lambda<bool(const value&, const value&)> l(listener); + const lambda<const bool(const value&, const value&)> l(listener); listen(qname, l, qsub); return true; } diff --git a/sca-cpp/trunk/components/queue/qpid.hpp b/sca-cpp/trunk/components/queue/qpid.hpp index ef53c529e8..77361461c6 100644 --- a/sca-cpp/trunk/components/queue/qpid.hpp +++ b/sca-cpp/trunk/components/queue/qpid.hpp @@ -65,14 +65,7 @@ public: debug("queue::qpidonnection::copy"); } - const QpidConnection& operator=(const QpidConnection& qc) { - debug("queue::qpidonnection::operator="); - if(this == &c) - return *this; - owner = false; - c = qc.c; - return *this; - } + QpidConnection& operator=(const QpidConnection& qc) = delete; ~QpidConnection() { debug("queue::~qpidonnection"); @@ -148,7 +141,7 @@ const failable<bool> close(QpidSession& qs) { * Declare a key / AMQP queue pair. */ const failable<bool> declareQueue(const value& key, const string& name, QpidSession& qs) { - const string ks(scheme::writeValue(key)); + const string ks(write(content(scheme::writeValue(key)))); try { qs.s.queueDeclare(qpid::client::arg::queue=c_str(name)); qs.s.exchangeBind(qpid::client::arg::exchange="amq.direct", qpid::client::arg::queue=c_str(name), qpid::client::arg::bindingKey=c_str(ks)); @@ -164,8 +157,8 @@ const failable<bool> declareQueue(const value& key, const string& name, QpidSess const failable<bool> post(const value& key, const value& val, QpidSession& qs) { // Send in a message with the given key. - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); try { qpid::client::Message message; message.getDeliveryProperties().setRoutingKey(c_str(ks)); @@ -202,7 +195,7 @@ public: } private: - friend const failable<bool> listen(const string& name, const lambda<bool(const value&, const value&)>& l, QpidSubscription& qsub); + friend const failable<bool> listen(const string& name, const lambda<const bool(const value&, const value&)>& l, QpidSubscription& qsub); friend const failable<bool> stop(QpidSubscription& qsub); const bool owner; @@ -214,14 +207,14 @@ private: */ class Listener : public qpid::client::MessageListener { public: - Listener(const lambda<bool(const value&, const value&)> l, qpid::client::SubscriptionManager& subs) : l(l), subs(subs) { + Listener(const lambda<const bool(const value&, const value&)> l, qpid::client::SubscriptionManager& subs) : l(l), subs(subs) { } virtual void received(qpid::client::Message& msg) { // Call the listener function - const value k(scheme::readValue(msg.getDeliveryProperties().getRoutingKey().c_str())); - const value v(scheme::readValue(msg.getData().c_str())); + const value k(content(scheme::readValue(msg.getDeliveryProperties().getRoutingKey().c_str()))); + const value v(content(scheme::readValue(msg.getData().c_str()))); const bool r = l(k, v); if (!r) { try { @@ -233,12 +226,12 @@ public: } private: - const lambda<bool(const value&, const value&)> l; + const lambda<const bool(const value&, const value&)> l; qpid::client::SubscriptionManager& subs; }; -const failable<bool> listen(const string& name, const lambda<bool(const value&, const value&)>& l, QpidSubscription& qsub) { +const failable<bool> listen(const string& name, const lambda<const bool(const value&, const value&)>& l, QpidSubscription& qsub) { debug("queue::listen"); Listener listener(l, qsub.subs); try { diff --git a/sca-cpp/trunk/components/queue/queue-listener.cpp b/sca-cpp/trunk/components/queue/queue-listener.cpp index 483d0de65a..f6793ecae7 100644 --- a/sca-cpp/trunk/components/queue/queue-listener.cpp +++ b/sca-cpp/trunk/components/queue/queue-listener.cpp @@ -42,57 +42,45 @@ namespace tuscany { namespace queue { /** - * A relay function that posts the AMQP messages it receives to a relay component reference. + * Start the component. */ -class relay { -public: - relay(const lambda<value(const list<value>&)>& rel) : rel(rel) { - } +const failable<value> start(const list<value>& params) { + // Extract the relay reference and the AMQP key and queue name + const value rel = car(params); + const value pk = ((lvvlambda)cadr(params))(nilListValue); + const value key = isList(pk)? (list<value>)pk : mklist<value>(pk); + const value qname = ((lvvlambda)caddr(params))(nilListValue); + + // Create an AMQP session + QpidConnection qc(false); + QpidSession qs(qc, false); + + // Declare the configured AMQP key / queue pair + declareQueue(key, qname, qs); - const bool operator()(const value& k, const value& v) const { + // Listen and relay messages in a worker thread + QpidSubscription qsub(qs, false); + const worker w(3); + const lambda<const bool(const value&, const value&)> rl = [rel](const value& k, const value& v) -> const bool { + // A relay function that posts the AMQP messages it receives to a relay component reference. debug(k, "queue::relay::key"); debug(v, "queue::relay::value"); const value res = rel(mklist<value>("post", isList(k)? (list<value>)k : mklist<value>(k), v)); return true; - } + }; -private: - const lambda<value(const list<value>&)> rel; -}; - -/** - * Subscribe and listen to an AMQP queue. - */ -class subscribe { -public: - subscribe(const string& qname, const lambda<bool(const value&, const value&)>& l, const QpidSubscription& qsub) : qname(qname), l(l), qsub(qsub) { - } - - const failable<bool> operator()() const { - gc_pool pool; + // Subscribe and listen to the AMQP queue. + const lambda<const failable<bool>()> subscribe = [qname, rl, qsub]() -> const failable<bool> { + const gc_pool pool; debug(qname, "queue::subscribe::listen"); - const failable<bool> r = listen(qname, l, const_cast<QpidSubscription&>(qsub)); + const failable<bool> r = listen(qname, rl, const_cast<QpidSubscription&>(qsub)); debug(qname, "queue::subscribe::stopped"); return r; - } - -private: - const string qname; - const lambda<bool(const value&, const value&)> l; - const QpidSubscription qsub; -}; - -/** - * Listener lambda function, responsible for starting an AMQP subscription in a worker thread, and - * apply any function calls to the listener component. The only supported function is stop(), - * called to stop the listener component and shutdown the worker thread. - */ -class listener { -public: - listener(QpidConnection& qc, QpidSession& qs, QpidSubscription& qsub, worker& w) : qc(qc), qs(qs), qsub(qsub), w(w) { - } + }; + submit<failable<bool> >(w, subscribe); - const value operator()(const list<value>& params) const { + // Return the listener component lambda function + const lvvlambda listener = [qc, qs, qsub, w](const list<value>& params) -> const value { const tuscany::value func(car(params)); // Stop the component @@ -107,41 +95,9 @@ public: cancel(const_cast<worker&>(w)); debug("queue::listener::stopped"); - return failable<value>(value(lambda<value(const list<value>&)>())); - } - -private: - QpidConnection qc; - QpidSession qs; - QpidSubscription qsub; - worker w; -}; - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Extract the relay reference and the AMQP key and queue name - const value rel = car(params); - const value pk = ((lambda<value(const list<value>&)>)cadr(params))(list<value>()); - const value key = isList(pk)? (list<value>)pk : mklist<value>(pk); - const value qname = ((lambda<value(const list<value>&)>)caddr(params))(list<value>()); - - // Create an AMQP session - QpidConnection qc(false); - QpidSession qs(qc, false); - - // Declare the configured AMQP key / queue pair - declareQueue(key, qname, qs); - - // Listen and relay messages in a worker thread - QpidSubscription qsub(qs, false); - worker w(3); - const lambda<bool(const value&, const value&)> rl = relay(rel); - submit<failable<bool> >(w, lambda<failable<bool>()>(subscribe(qname, rl, qsub))); - - // Return the listener component lambda function - return value(lambda<value(const list<value>&)>(listener(qc, qs, qsub, w))); + return failable<value>(value(lvvlambda())); + }; + return value(listener); } } diff --git a/sca-cpp/trunk/components/queue/queue-sender.cpp b/sca-cpp/trunk/components/queue/queue-sender.cpp index 202a0e4435..a479f255ce 100644 --- a/sca-cpp/trunk/components/queue/queue-sender.cpp +++ b/sca-cpp/trunk/components/queue/queue-sender.cpp @@ -48,7 +48,7 @@ const failable<value> post(const list<value>& params) { QpidSession qs(qc); // Post the item - const value pk = ((lambda<value(const list<value>&)>)caddr(params))(list<value>()); + const value pk = ((lvvlambda)caddr(params))(nilListValue); const value key = isList(pk)? append<value>(pk, (list<value>)car(params)) : cons<value>(pk, (list<value>)car(params)); debug(key, "queue::post::key"); debug(cadr(params), "queue::post::value"); diff --git a/sca-cpp/trunk/components/smtp/Makefile.am b/sca-cpp/trunk/components/smtp/Makefile.am index 41fa686b9a..42c0d3347f 100644 --- a/sca-cpp/trunk/components/smtp/Makefile.am +++ b/sca-cpp/trunk/components/smtp/Makefile.am @@ -23,12 +23,12 @@ comp_LTLIBRARIES = libsmtppost.la noinst_DATA = libsmtppost${libsuffix} libsmtppost_la_SOURCES = smtppost.cpp -libsmtppost_la_LDFLAGS = -lxml2 -lmozjs -curl +libsmtppost_la_LDFLAGS = -lxml2 -ljansson -curl libsmtppost${libsuffix}: ln -s .libs/libsmtppost${libsuffix} client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = server-test noinst_PROGRAMS = client-test diff --git a/sca-cpp/trunk/components/smtp/client-test.cpp b/sca-cpp/trunk/components/smtp/client-test.cpp index 10274a6248..4a60b475fc 100644 --- a/sca-cpp/trunk/components/smtp/client-test.cpp +++ b/sca-cpp/trunk/components/smtp/client-test.cpp @@ -38,8 +38,8 @@ namespace smtp { const string postURI("http://localhost:8090/smtppost"); -bool testPost() { - http::CURLSession cs("", "", "", "", 0); +const bool testPost() { + const http::CURLSession cs("", "", "", "", 0); const failable<value> val = http::get(postURI, cs); assert(hasContent(val)); diff --git a/sca-cpp/trunk/components/smtp/smtppost.cpp b/sca-cpp/trunk/components/smtp/smtppost.cpp index 1030ccc223..396b1a0a38 100644 --- a/sca-cpp/trunk/components/smtp/smtppost.cpp +++ b/sca-cpp/trunk/components/smtp/smtppost.cpp @@ -38,7 +38,7 @@ namespace smtppost { /** * Post/send an email message using SMTP. */ -const failable<value> post(const string& url, const string& user, const string& pass, const string& from, const string& to, const string& subject, const value& val, http::CURLSession& cs) { +const failable<value> post(const string& url, const string& user, const string& pass, const string& from, const string& to, const string& subject, const value& val, const http::CURLSession& cs) { // Convert value to a content request const failable<list<list<string> > > freq = http::contentRequest(val, url); if (!hasContent(freq)) @@ -52,7 +52,7 @@ const failable<value> post(const string& url, const string& user, const string& http::cleanup(cs); return mkfailure<value>(fch); } - CURL* ch = content(fch); + CURL* const ch = content(fch); curl_easy_setopt(ch, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); // Convert message to a string @@ -88,25 +88,25 @@ const failable<value> post(const string& url, const string& user, const string& } http::cleanup(cs); - return value(true); + return trueValue; } /** * Evaluate an SMTP post/send. */ -const failable<value> get(const lambda<value(const list<value>&)>& url, - const lambda<value(const list<value>&)>& user, const lambda<value(const list<value>&)>& pass, - const lambda<value(const list<value>&)>& from, const lambda<value(const list<value>&)>& to, - const lambda<value(const list<value>&)>& subject, const lambda<value(const list<value>&)>& val, - http::CURLSession& ch) { +const failable<value> get(const lvvlambda& url, + const lvvlambda& user, const lvvlambda& pass, + const lvvlambda& from, const lvvlambda& to, + const lvvlambda& subject, const lvvlambda& val, + const http::CURLSession& ch) { debug("smtppost::get"); - const value u = url(mklist<value>("get", list<value>())); - const value i = user(mklist<value>("get", list<value>())); - const value p = pass(mklist<value>("get", list<value>())); - const value f = from(mklist<value>("get", list<value>())); - const value t = to(mklist<value>("get", list<value>())); - const value s = subject(mklist<value>("get", list<value>())); - const value v = val(mklist<value>("get", list<value>())); + const value u = url(mklist<value>("get", nilListValue)); + const value i = user(mklist<value>("get", nilListValue)); + const value p = pass(mklist<value>("get", nilListValue)); + const value f = from(mklist<value>("get", nilListValue)); + const value t = to(mklist<value>("get", nilListValue)); + const value s = subject(mklist<value>("get", nilListValue)); + const value v = val(mklist<value>("get", nilListValue)); debug(u, "smtppost::get::url"); debug(i, "smtppost::get::user"); debug(p, "smtppost::get::pass"); @@ -118,53 +118,33 @@ const failable<value> get(const lambda<value(const list<value>&)>& url, } /** - * Component implementation lambda function. + * Start the component. */ -class applysmtp { -public: - applysmtp(const lambda<value(const list<value>&)>& url, - const lambda<value(const list<value>&)>& user, const lambda<value(const list<value>&)>& pass, - const lambda<value(const list<value>&)>& from, const lambda<value(const list<value>&)>& to, - const lambda<value(const list<value>&)>& subject, const lambda<value(const list<value>&)>& val, - perthread_ptr<http::CURLSession>& ch) : - url(url), user(user), pass(pass), from(from), to(to), subject(subject), val(val), ch(ch) { - } +const failable<value> start(const list<value>& params) { + // Create a CURL session + const gc_pool cp(gc_current_pool()); + const lambda<const gc_ptr<http::CURLSession>()> newsession = [cp]() -> const gc_ptr<http::CURLSession> { + const gc_scoped_pool sp(pool(cp)); + return new (gc_new<http::CURLSession>()) http::CURLSession(emptyString, emptyString, emptyString, emptyString, 0); + }; + const perthread_ptr<http::CURLSession> ch = *(new (gc_new<perthread_ptr<http::CURLSession> >()) perthread_ptr<http::CURLSession>(newsession)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda url = car(params); + const lvvlambda user = cadr(params); + const lvvlambda pass = caddr(params); + const lvvlambda from = cadddr(params); + const lvvlambda to = caddddr(params); + const lvvlambda subject = cadddddr(params); + const lvvlambda val = caddddddr(params); + const lvvlambda applysmtp = [url, user, pass, from, to, subject, val, ch](const list<value>& params) -> const value { debug(params, "smtppost::applysmtp::params"); const value func(car(params)); if (func == "get") return get(url, user, pass, from, to, subject, val, *ch); return mkfailure<value>(); - } - -private: - const lambda<value(const list<value>&)> url; - const lambda<value(const list<value>&)> user; - const lambda<value(const list<value>&)> pass; - const lambda<value(const list<value>&)> from; - const lambda<value(const list<value>&)> to; - const lambda<value(const list<value>&)> subject; - const lambda<value(const list<value>&)> val; - perthread_ptr<http::CURLSession> ch; -}; - -/** - * Create a new CURL session. - */ -const gc_ptr<http::CURLSession> newsession() { - return new (gc_new<http::CURLSession>()) http::CURLSession("", "", "", "", 0); -} - -/** - * Start the component. - */ -const failable<value> start(const list<value>& params) { - // Create a CURL session - perthread_ptr<http::CURLSession> ch = perthread_ptr<http::CURLSession>(lambda<gc_ptr<http::CURLSession>()>(newsession)); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applysmtp(car(params), cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params), ch))); + }; + return value(applysmtp); } } diff --git a/sca-cpp/trunk/components/sqldb/Makefile.am b/sca-cpp/trunk/components/sqldb/Makefile.am index 9ce5f26713..988383b4f1 100644 --- a/sca-cpp/trunk/components/sqldb/Makefile.am +++ b/sca-cpp/trunk/components/sqldb/Makefile.am @@ -48,10 +48,10 @@ pgsql_standby_test_SOURCES = pgsql-standby-test.cpp pgsql_standby_test_LDFLAGS = -L${PGSQL_LIB} -R${PGSQL_LIB} -lpq client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs +client_test_LDFLAGS = -lxml2 -lcurl -ljansson dist_noinst_SCRIPTS = sqldb-test standby-test server-test noinst_PROGRAMS = pgsql-test pgsql-standby-test client-test -TESTS = sqldb-test standby-test server-test +TESTS = sqldb-test server-test endif diff --git a/sca-cpp/trunk/components/sqldb/client-test.cpp b/sca-cpp/trunk/components/sqldb/client-test.cpp index 0cbcb57363..c9fbb7d5bb 100644 --- a/sca-cpp/trunk/components/sqldb/client-test.cpp +++ b/sca-cpp/trunk/components/sqldb/client-test.cpp @@ -38,15 +38,15 @@ namespace sqldb { const string uri("http://localhost:8090/sqldb"); -bool testSqlDb() { - http::CURLSession cs("", "", "", "", 0); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testSqlDb() { + const http::CURLSession cs("", "", "", "", 0); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); const failable<value> id = http::post(a, uri, cs); @@ -59,18 +59,18 @@ bool testSqlDb() { assert(content(val) == a); } - const list<value> j = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$3.55"))); - const list<value> b = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> j = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$3.55"))); + const list<value> b = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + j); { const failable<value> r = http::put(b, uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -80,7 +80,7 @@ bool testSqlDb() { { const failable<value> r = http::del(uri + p, cs); assert(hasContent(r)); - assert(content(r) == value(true)); + assert(content(r) == trueValue); } { const failable<value> val = http::get(uri + p, cs); @@ -90,35 +90,26 @@ bool testSqlDb() { return true; } -struct getLoop { - const string path; - const value entry; - http::CURLSession& cs; - getLoop(const string& path, const value& entry, http::CURLSession& cs) : path(path), entry(entry), cs(cs) { - } - const bool operator()() const { - const failable<value> val = http::get(uri + path, cs); - assert(hasContent(val)); - assert(content(val) == entry); - return true; - } -}; - -bool testGetPerf() { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$4.55"))); - const list<value> a = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) +const bool testGetPerf() { + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$4.55"))); + const list<value> a = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - http::CURLSession cs("", "", "", "", 0); + const http::CURLSession cs("", "", "", "", 0); const failable<value> id = http::post(a, uri, cs); assert(hasContent(id)); const string p = path(content(id)); - const lambda<bool()> gl = getLoop(p, a, cs); + const blambda gl = [p, a, cs]() -> const bool { + const failable<value> val = http::get(uri + p, cs); + assert(hasContent(val)); + assert(content(val) == a); + return true; + }; cout << "Sqldb get test " << time(gl, 5, 200) << " ms" << endl; return true; diff --git a/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp b/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp index 2cd25f874a..5d73b0d877 100644 --- a/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp +++ b/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp @@ -32,7 +32,7 @@ namespace tuscany { namespace pgsql { -bool testPGSql() { +const bool testPGSql() { PGSql wpg("host=localhost port=6432 dbname=db", "test"); PGSql rpg("host=localhost port=6433 dbname=db", "test"); const value k = mklist<value>("a"); @@ -50,25 +50,17 @@ bool testPGSql() { return true; } -struct getLoop { - const value k; - PGSql& pg; - getLoop(const value& k, PGSql& pg) : k(k), pg(pg) { - } - const bool operator()() const { - assert((get(k, pg)) == value(string("CCC"))); - return true; - } -}; - -bool testGetPerf() { +const bool testGetPerf() { const value k = mklist<value>("c"); PGSql wpg("host=localhost port=6432 dbname=db", "test"); PGSql rpg("host=localhost port=6433 dbname=db", "test"); assert(hasContent(post(k, string("CCC"), wpg))); sleep(1); - const lambda<bool()> gl = getLoop(k, rpg); + const blambda gl = [k, rpg]() -> const bool { + assert((get(k, rpg)) == value(string("CCC"))); + return true; + }; cout << "PGSql get test " << time(gl, 5, 200) << " ms" << endl; return true; } diff --git a/sca-cpp/trunk/components/sqldb/pgsql-test.cpp b/sca-cpp/trunk/components/sqldb/pgsql-test.cpp index d10ab5f4c2..5d7bb98cd8 100644 --- a/sca-cpp/trunk/components/sqldb/pgsql-test.cpp +++ b/sca-cpp/trunk/components/sqldb/pgsql-test.cpp @@ -32,37 +32,38 @@ namespace tuscany { namespace pgsql { -bool testPGSql() { +const bool testPGSql() { PGSql pg("host=localhost port=6432 dbname=db", "test"); const value k = mklist<value>("a"); + const value lk = mklist<value>(mklist<value>("like", "%"), mklist<value>("limit", "2")); + const value rx = mklist<value>(mklist<value>("regex", "a"), mklist<value>("limit", "2")); + const value ts = mklist<value>(mklist<value>("textsearch", "AAA"), mklist<value>("limit", "2")); + const value rxts = mklist<value>(mklist<value>("regex", "a"), mklist<value>("textsearch", "AAA"), mklist<value>("limit", "2")); assert(hasContent(post(k, string("AAA"), pg))); - assert((get(k, pg)) == value(string("AAA"))); + assert(content(get(k, pg)) == value(string("AAA"))); + assert(cadr<value>(car<value>(content(get(lk, pg)))) == value(string("AAA"))); + assert(cadr<value>(car<value>(content(get(rx, pg)))) == value(string("AAA"))); + assert(cadr<value>(car<value>(content(get(ts, pg)))) == value(string("AAA"))); + assert(cadr<value>(car<value>(content(get(rxts, pg)))) == value(string("AAA"))); + assert(hasContent(put(k, string("aaa"), pg))); - assert((get(k, pg)) == value(string("aaa"))); + assert(content(get(k, pg)) == value(string("aaa"))); assert(hasContent(del(k, pg))); assert(!hasContent(get(k, pg))); return true; } -struct getLoop { - const value k; - PGSql& pg; - getLoop(const value& k, PGSql& pg) : k(k), pg(pg) { - } - const bool operator()() const { - assert((get(k, pg)) == value(string("CCC"))); - return true; - } -}; - -bool testGetPerf() { +const bool testGetPerf() { const value k = mklist<value>("c"); PGSql pg("host=localhost port=6432 dbname=db", "test"); assert(hasContent(post(k, string("CCC"), pg))); - const lambda<bool()> gl = getLoop(k, pg); + const blambda gl = [k, pg]() -> const bool { + assert(content(get(k, pg)) == value(string("CCC"))); + return true; + }; cout << "PGSql get test " << time(gl, 5, 200) << " ms" << endl; return true; } diff --git a/sca-cpp/trunk/components/sqldb/pgsql.hpp b/sca-cpp/trunk/components/sqldb/pgsql.hpp index 581cd943e6..620aec4105 100644 --- a/sca-cpp/trunk/components/sqldb/pgsql.hpp +++ b/sca-cpp/trunk/components/sqldb/pgsql.hpp @@ -40,7 +40,7 @@ namespace pgsql { /** * Return and clear a Postgres result failure. */ -const string pgfailure(PGresult* r, PGconn* conn) { +const string pgfailure(PGresult* const r, PGconn* const conn) { const string re = PQresultErrorMessage(r); PQclear(r); if (length(re) != 0) @@ -68,11 +68,12 @@ public: mkfailure<bool>(string("Couldn't connect to postgresql database: ") + PQerrorMessage(conn)); return; } + debug(conn, "pgsql::pgsql::conn"); // Find the name of the first column in the target table // Assume that's the key we need to use string ks = string("select a.attname from pg_attribute a, pg_class c where a.attrelid = c.relfilenode and c.relname = '") + table + string("' and a.attnum in (1, 2) order by a.attnum;"); - PGresult* kr = PQexec(conn, c_str(ks)); + PGresult* const kr = PQexec(conn, c_str(ks)); if (PQresultStatus(kr) != PGRES_TUPLES_OK) { mkfailure<bool>(string("Couldn't execute postgresql column select statement: ") + pgfailure(kr, conn)); return; @@ -82,25 +83,16 @@ public: mkfailure<bool>(string("Couldn't find postgresql table key and value column names")); return; } - kname = PQgetvalue(kr, 0, 0); - vname = PQgetvalue(kr, 1, 0); + kname = c_str(string(PQgetvalue(kr, 0, 0))); + vname = c_str(string(PQgetvalue(kr, 1, 0))); PQclear(kr); } - PGSql(const PGSql& c) : owner(false), conn(c.conn), conninfo(c.conninfo), table(c.table) { + PGSql(const PGSql& c) : owner(false), conn(c.conn), conninfo(c.conninfo), table(c.table), kname(c.kname), vname(c.vname) { debug("pgsql::pgsql::copy"); } - const PGSql& operator=(const PGSql& c) { - debug("pgsql::pgsql::operator="); - if(this == &c) - return *this; - owner = false; - conn = c.conn; - conninfo = c.conninfo; - table = c.table; - return *this; - } + PGSql& operator=(const PGSql& c) = delete; ~PGSql() { debug("pgsql::~pgsql"); @@ -108,16 +100,17 @@ public: return; if (conn == NULL) return; + debug(conn, "pgsql::~pgsql::conn"); PQfinish(conn); } private: - bool owner; + const bool owner; PGconn *conn; - string conninfo; - string table; - string kname; - string vname; + const string conninfo; + const string table; + const char* kname; + const char* vname; friend const failable<bool> setup(const PGSql& pgsql); friend const failable<bool> post(const value& key, const value& val, const PGSql& pgsql); @@ -133,7 +126,7 @@ const failable<bool> setup(const PGSql& pgsql) { debug("pgsql::setup"); if (PQstatus(pgsql.conn) == CONNECTION_OK) return true; - debug("pgsql::setup::reset"); + debug(pgsql.conn, "pgsql::setup::reset::conn"); PQreset(pgsql.conn); if (PQstatus(pgsql.conn) != CONNECTION_OK) return mkfailure<bool>(string("Couldn't reconnect to postgresql database: ") + PQerrorMessage(pgsql.conn)); @@ -150,10 +143,10 @@ const failable<bool> post(const value& key, const value& val, const PGSql& pgsql debug(pgsql.table, "pgsql::post::table"); setup(pgsql); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); - const char* params[2] = { c_str(ks), c_str(vs) }; - PGresult* r = PQexecParams(pgsql.conn, c_str(string("insert into ") + pgsql.table + string(" values($1, $2);")), 2, NULL, params, NULL, NULL, 0); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); + const char* const params[2] = { c_str(ks), c_str(vs) }; + PGresult* const r = PQexecParams(pgsql.conn, c_str(string("insert into ") + pgsql.table + string(" values($1, $2);")), 2, NULL, params, NULL, NULL, 0); if (PQresultStatus(r) != PGRES_COMMAND_OK) return mkfailure<bool>(string("Couldn't execute insert postgresql SQL statement: ") + pgfailure(r, pgsql.conn)); PQclear(r); @@ -172,10 +165,10 @@ const failable<bool> put(const value& key, const value& val, const PGSql& pgsql) debug(pgsql.table, "pgsql::put::table"); setup(pgsql); - const string ks(scheme::writeValue(key)); - const string vs(scheme::writeValue(val)); - const char* params[2] = { c_str(ks), c_str(vs) }; - PGresult* r = PQexecParams(pgsql.conn, c_str(string("update ") + pgsql.table + string(" set ") + pgsql.vname + string(" = $2 where ") + pgsql.kname + string(" = $1;")), 2, NULL, params, NULL, NULL, 0); + const string ks(write(content(scheme::writeValue(key)))); + const string vs(write(content(scheme::writeValue(val)))); + const char* const params[2] = { c_str(ks), c_str(vs) }; + PGresult* const r = PQexecParams(pgsql.conn, c_str(string("update ") + pgsql.table + string(" set ") + pgsql.vname + string(" = $2 where ") + pgsql.kname + string(" = $1;")), 2, NULL, params, NULL, NULL, 0); if (PQresultStatus(r) != PGRES_COMMAND_OK) return mkfailure<bool>(string("Couldn't execute update postgresql SQL statement: ") + pgfailure(r, pgsql.conn)); const string t = PQcmdTuples(r); @@ -186,7 +179,7 @@ const failable<bool> put(const value& key, const value& val, const PGSql& pgsql) } PQclear(r); - PGresult* pr = PQexecParams(pgsql.conn, c_str(string("insert into ") + pgsql.table + string(" values($1, $2);")), 2, NULL, params, NULL, NULL, 0); + PGresult* const pr = PQexecParams(pgsql.conn, c_str(string("insert into ") + pgsql.table + string(" values($1, $2);")), 2, NULL, params, NULL, NULL, 0); if (PQresultStatus(pr) != PGRES_COMMAND_OK) return mkfailure<bool>(string("Couldn't execute insert postgresql SQL statement: ") + pgfailure(pr, pgsql.conn)); PQclear(pr); @@ -196,7 +189,58 @@ const failable<bool> put(const value& key, const value& val, const PGSql& pgsql) } /** - * Get an item from the database. + * Convert a key to an item id. + */ +const list<value> keyid(const list<value>& key) { + if (isNil(key)) + return nilListValue; + if (isList(car(key))) + return keyid(cdr(key)); + return cons<value>(car(key), keyid(cdr(key))); +} + +/** + * Convert a key to an param name / value assoc. + */ +const list<list<value> > keyparams(const list<value>& key) { + if (isNil(key)) + return nilListValue; + if (!isList(car(key))) + return keyparams(cdr(key)); + return cons<list<value> >((list<value>)car(key), keyparams(cdr(key))); +} + +/** + * Convert a get result to a list of items. + */ +const list<value> getitems(PGresult* const r, const int i, const int n) { + if (i == n) + return nilListValue; + const value key(content(scheme::readValue(string(PQgetvalue(r, i, 0))))); + const value val(content(scheme::readValue(string(PQgetvalue(r, i, 1))))); + return cons<value>(mklist<value>(key, val), getitems(r, i + 1, n)); +} + +/** + * Parse a text search query and translate single quotes to spaces and double + * quotes to single quotes. + */ +ostringstream& tsparse(ostringstream& os, const char* const c) { + if (!*c) + return os; + os << (*c == '\''? ' ' : *c == '"'? '\'' : *c); + return tsparse(os, c + 1); +} +const string tstranslate(const string& ts) { + ostringstream os; + tsparse(os, c_str(ts)); + return str(os); +} + +/** + * Get one item or a collection of items from the database. + * The key is a simple value or a list of simple values plus optional name / value + * pairs to specify regex, like, textsearch limit and offset clause */ const failable<value> get(const value& key, const PGSql& pgsql) { debug(key, "pgsql::get::key"); @@ -204,21 +248,99 @@ const failable<value> get(const value& key, const PGSql& pgsql) { debug(pgsql.table, "pgsql::get::table"); setup(pgsql); - const string ks(scheme::writeValue(key)); - const char* params[1] = { c_str(ks) }; - PGresult* r = PQexecParams(pgsql.conn, c_str(string("select * from ") + pgsql.table + string(" where ") + pgsql.kname + string(" = $1;")), 1, NULL, params, NULL, NULL, 0); + // Get item and id and get parameters from the key + const bool lk = isList(key); + const list<list<value> > kparams = lk? keyparams(key) : list<list<value> >(); + const list<value> regex = assoc<value>("regex", kparams); + const list<value> like = assoc<value>("like", kparams); + const list<value> textsearch = assoc<value>("textsearch", kparams); + const list<value> limit = assoc<value>("limit", kparams); + const list<value> offset = assoc<value>("offset", kparams); + const list<value> id = lk? keyid(key) : nilListValue; + const list<value> atable = assoc<value>("table", kparams); + const string table = isNil(atable)? pgsql.table : (string)cadr(atable); + const list<value> akname = assoc<value>("kcolumn", kparams); + const string kname = isNil(akname)? pgsql.kname : (string)cadr(akname); + const list<value> avname = assoc<value>("vcolumn", kparams); + const string vname = isNil(avname)? pgsql.vname : (string)cadr(avname); + + // Build the SQL query + const char* sqlparams[5]; + int p = 0; + int w = 0; + ostringstream sqlos; + sqlos << "select data.*"; + if (!isNil(textsearch)) { + // Text search, setup result ranking + sqlos << ", ts_rank_cd(to_tsvector(data." << vname << "), tsquery, 32) as rank"; + } + sqlos << " from " << table << " data"; + if (!isNil(textsearch)) { + // Text search, define the query + const string ts = tstranslate((string)cadr(textsearch)); + sqlparams[p++] = c_str(ts); + sqlos << ", plainto_tsquery($" << p << ") tsquery"; + } + if (!lk || !isNil(id)) { + // Query of the form key = id + sqlparams[p++] = c_str(write(content(scheme::writeValue(lk? (value)id : key)))); + sqlos << (w == 0? " where" : " and"); + sqlos << " data." << kname << " = $" << p; + w++; + } + if (!isNil(regex)) { + // Query of the form key ~ param + sqlparams[p++] = c_str((string)cadr(regex)); + sqlos << (w == 0? " where" : " and"); + sqlos << " data." << kname << " ~ $" << p; + w++; + } + if (!isNil(like)) { + // Query of the form key like param + sqlparams[p++] = c_str((string)cadr(like)); + sqlos << (w == 0? " where" : " and"); + sqlos << " data." << kname << " like $" << p; + w++; + } + if (!isNil(textsearch)) { + // Text search, apply the query + sqlos << (w == 0? " where" : " and"); + sqlos << " tsquery @@ to_tsvector(data." << vname << ") order by rank desc"; + w++; + } + if (!isNil(offset)) { + // Result pagination offset + sqlos << " offset " << atoi(c_str((string)cadr(offset))); + } + // Result limit count + const int l = isNil(limit)? 1 : atoi(c_str((string)cadr(limit))); + sqlos << " limit " << l << ";"; + + // Execute the query + const string sqls = str(sqlos); + debug(sqls, "pgsql::get::sqls"); + PGresult* r = PQexecParams(pgsql.conn, c_str(sqls), p, NULL, sqlparams, NULL, NULL, 0); if (PQresultStatus(r) != PGRES_TUPLES_OK) return mkfailure<value>(string("Couldn't execute select postgresql SQL statement: ") + pgfailure(r, pgsql.conn)); - if (PQntuples(r) < 1) { + const int n = PQntuples(r); + if (n < 1) { PQclear(r); ostringstream os; os << "Couldn't get postgresql entry: " << key; return mkfailure<value>(str(os), 404, false); } - const char* data = PQgetvalue(r, 0, 1); - const value val(scheme::readValue(string(data))); - PQclear(r); + // Return a collection of key / item pairs + if (l != 1) { + const list<value> lval = getitems(r, 0, n); + PQclear(r); + debug(lval, "pgsql::get::result"); + return (value)lval; + } + + // Return a single item + const value val(content(scheme::readValue(string(PQgetvalue(r, 0, 1))))); + PQclear(r); debug(val, "pgsql::get::result"); return val; } @@ -232,9 +354,9 @@ const failable<bool> del(const value& key, const PGSql& pgsql) { debug(pgsql.table, "pgsql::delete::table"); setup(pgsql); - const string ks(scheme::writeValue(key)); - const char* params[1] = { c_str(ks) }; - PGresult* r = PQexecParams(pgsql.conn, c_str(string("delete from ") + pgsql.table + string(" where ") + pgsql.kname + string(" = $1;")), 1, NULL, params, NULL, NULL, 0); + const string ks(write(content(scheme::writeValue(key)))); + const char* const params[1] = { c_str(ks) }; + PGresult* const r = PQexecParams(pgsql.conn, c_str(string("delete from ") + pgsql.table + string(" where ") + pgsql.kname + string(" = $1;")), 1, NULL, params, NULL, NULL, 0); if (PQresultStatus(r) != PGRES_COMMAND_OK) return mkfailure<bool>(string("Couldn't execute delete postgresql SQL statement: ") + pgfailure(r, pgsql.conn)); PQclear(r); diff --git a/sca-cpp/trunk/components/sqldb/sqldb.cpp b/sca-cpp/trunk/components/sqldb/sqldb.cpp index 9925897693..1288dd553b 100644 --- a/sca-cpp/trunk/components/sqldb/sqldb.cpp +++ b/sca-cpp/trunk/components/sqldb/sqldb.cpp @@ -38,14 +38,14 @@ namespace sqldb { /** * Get an item from the database. */ -const failable<value> get(const list<value>& params, pgsql::PGSql& pg) { +const failable<value> get(const list<value>& params, const pgsql::PGSql& pg) { return pgsql::get(car(params), pg); } /** * Post an item to the database. */ -const failable<value> post(const list<value>& params, pgsql::PGSql& pg) { +const failable<value> post(const list<value>& params, const pgsql::PGSql& pg) { const value id = append<value>(car(params), mklist(mkuuid())); const failable<bool> val = pgsql::post(id, cadr(params), pg); if (!hasContent(val)) @@ -56,7 +56,7 @@ const failable<value> post(const list<value>& params, pgsql::PGSql& pg) { /** * Put an item into the database. */ -const failable<value> put(const list<value>& params, pgsql::PGSql& pg) { +const failable<value> put(const list<value>& params, const pgsql::PGSql& pg) { const failable<bool> val = pgsql::put(car(params), cadr(params), pg); if (!hasContent(val)) return mkfailure<value>(val); @@ -66,7 +66,7 @@ const failable<value> put(const list<value>& params, pgsql::PGSql& pg) { /** * Delete an item from the database. */ -const failable<value> del(const list<value>& params, pgsql::PGSql& pg) { +const failable<value> del(const list<value>& params, const pgsql::PGSql& pg) { const failable<bool> val = pgsql::del(car(params), pg); if (!hasContent(val)) return mkfailure<value>(val); @@ -74,14 +74,23 @@ const failable<value> del(const list<value>& params, pgsql::PGSql& pg) { } /** - * Component implementation lambda function. + * Start the component. */ -class applySqldb { -public: - applySqldb(const perthread_ptr<pgsql::PGSql>& pg) : pg(pg) { - } +const failable<value> start(const list<value>& params) { + // Connect to the configured database and table + debug("sqldb::start"); + const gc_pool cp(gc_current_pool()); + const value conninfo = ((lvvlambda)car(params))(nilListValue); + const value table = ((lvvlambda)cadr(params))(nilListValue); + const lambda<const gc_ptr<pgsql::PGSql>()> newPGSql = [conninfo, table, cp]() -> const gc_ptr<pgsql::PGSql> { + debug("sqldb::newPGSql"); + const gc_scoped_pool sp(pool(cp)); + return new (gc_new<pgsql::PGSql>()) pgsql::PGSql(conninfo, table); + }; + const perthread_ptr<pgsql::PGSql> pg = *(new (gc_new<perthread_ptr<pgsql::PGSql> >()) perthread_ptr<pgsql::PGSql>(newPGSql)); - const value operator()(const list<value>& params) const { + // Return the component implementation lambda function + const lvvlambda applySqldb = [pg](const list<value>& params) -> const value { const value func(car(params)); if (func == "get") return get(cdr(params), *pg); @@ -92,40 +101,8 @@ public: if (func == "delete") return del(cdr(params), *pg); return mkfailure<value>(); - } - -private: - const perthread_ptr<pgsql::PGSql> pg; -}; - -/** - * Lambda function that creates a new database connection. - */ -class newPGSql { -public: - newPGSql(const string& conninfo, const string& table) : conninfo(conninfo), table(table) { - } - - const gc_ptr<pgsql::PGSql> operator()() const { - return new (gc_new<pgsql::PGSql>()) pgsql::PGSql(conninfo, table); - } - -private: - const string conninfo; - const string table; -}; - -/** - * Start the component. - */ -const failable<value> start(unused const list<value>& params) { - // Connect to the configured database and table - const value conninfo = ((lambda<value(const list<value>&)>)car(params))(list<value>()); - const value table = ((lambda<value(const list<value>&)>)cadr(params))(list<value>()); - const perthread_ptr<pgsql::PGSql> pg(lambda<gc_ptr<pgsql::PGSql>()>(newPGSql(conninfo, table))); - - // Return the component implementation lambda function - return value(lambda<value(const list<value>&)>(applySqldb(pg))); + }; + return value(applySqldb); } } diff --git a/sca-cpp/trunk/components/webservice/Makefile.am b/sca-cpp/trunk/components/webservice/Makefile.am index 242b97dce8..3b5a53695e 100644 --- a/sca-cpp/trunk/components/webservice/Makefile.am +++ b/sca-cpp/trunk/components/webservice/Makefile.am @@ -62,10 +62,11 @@ axis2_test_SOURCES = axis2-test.cpp axis2_test_LDFLAGS = -lxml2 -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil client_test_SOURCES = client-test.cpp -client_test_LDFLAGS = -lxml2 -lcurl -lmozjs -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil +client_test_LDFLAGS = -lxml2 -lcurl -ljansson -L${AXIS2C_LIB} -R${AXIS2C_LIB} -laxis2_engine -laxis2_axiom -laxutil dist_noinst_SCRIPTS = echo-test server-test noinst_PROGRAMS = axiom-test axis2-test client-test -TESTS = axiom-test echo-test server-test +#TESTS = axiom-test echo-test server-test +TESTS = axiom-test endif diff --git a/sca-cpp/trunk/components/webservice/axiom-test.cpp b/sca-cpp/trunk/components/webservice/axiom-test.cpp index 75ce2452fd..eaa9921d1b 100644 --- a/sca-cpp/trunk/components/webservice/axiom-test.cpp +++ b/sca-cpp/trunk/components/webservice/axiom-test.cpp @@ -45,11 +45,11 @@ const string customerElement = "<account><id>4567</id><balance>3000</balance></account>" "</customer>"; -const string echo("<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\">\n" - " <text>Hello World!</text>\n" +const string echo("<ns1:echoString xmlns:ns1=\"http://ws.apache.org/axis2/services/echo\">" + "<text>Hello World!</text>" "</ns1:echoString>"); -bool testAxiom() { +const bool testAxiom() { const Axis2Context ax; { const failable<axiom_node_t*> n = stringToAxiomNode(customerElement, ax); @@ -60,9 +60,9 @@ bool testAxiom() { } { const list<value> arg = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (nilListValue + "text" + string("Hello World!"))); const failable<axiom_node_t*> n = valuesToAxiomNode(arg, ax); assert(hasContent(n)); const failable<const string> x = axiomNodeToString(content(n), ax); diff --git a/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp b/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp index dafa6fd229..7a0869d20f 100644 --- a/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp +++ b/sca-cpp/trunk/components/webservice/axis2-dispatcher.cpp @@ -105,7 +105,7 @@ const axis2_module_ops_t dispatchOps = { dispatchFuncMap }; -axis2_module_t * dispatchModule(const axutil_env_t* env) { +axis2_module_t* dispatchModule(const axutil_env_t* env) { axis2_module_t *module = (axis2_module_t*)AXIS2_MALLOC(env->allocator, sizeof(axis2_module_t)); if (module == NULL) return NULL; diff --git a/sca-cpp/trunk/components/webservice/axis2-service.cpp b/sca-cpp/trunk/components/webservice/axis2-service.cpp index 4df0543370..41cce080b5 100644 --- a/sca-cpp/trunk/components/webservice/axis2-service.cpp +++ b/sca-cpp/trunk/components/webservice/axis2-service.cpp @@ -50,7 +50,7 @@ int AXIS2_CALL serviceFree(axis2_svc_skeleton_t* svc_skeleton, const axutil_env_ typedef struct axis2_apache2_out_transport_info { axis2_http_out_transport_info_t out_transport_info; - request_rec *request; + request_rec* request; axis2_char_t *encoding; } axis2_apache2_out_transport_info_t; @@ -66,25 +66,25 @@ axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton // Check that we have an input node if (node == NULL || axiom_node_get_node_type(node, env) != AXIOM_ELEMENT) return NULL; - axiom_element_t *e = (axiom_element_t *) axiom_node_get_data_element(node, env); + axiom_element_t* const e = (axiom_element_t*) axiom_node_get_data_element(node, env); if (e == NULL) return NULL; // Get the function name - const char* func = axiom_element_get_localname(e, env); + const char* const func = axiom_element_get_localname(e, env); if (func == NULL) return NULL; // Get the target endpoint address - const axis2_endpoint_ref_t* epr = axis2_msg_ctx_get_from(msg_ctx, env); + const axis2_endpoint_ref_t* const epr = axis2_msg_ctx_get_from(msg_ctx, env); if (epr == NULL) return NULL; - string address = axis2_endpoint_ref_get_address(epr, env); + unused const string address = axis2_endpoint_ref_get_address(epr, env); // Get the underlying HTTPD request - axis2_out_transport_info_t* tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env); - axis2_apache2_out_transport_info_t* httpinfo = (axis2_apache2_out_transport_info_t*)tinfo; - request_rec* r = httpinfo->request; + axis2_out_transport_info_t* const tinfo = axis2_msg_ctx_get_out_transport_info(msg_ctx, env); + axis2_apache2_out_transport_info_t* const httpinfo = (axis2_apache2_out_transport_info_t*)tinfo; + request_rec* const r = httpinfo->request; debug_httpdRequest(r, "webservice::serviceInvoke"); // Parse the request Axiom node and construct request expression @@ -96,9 +96,9 @@ axiom_node_t *AXIS2_CALL serviceInvoke(unused axis2_svc_skeleton_t* svc_skeleton debug(expr, "webservice::serviceInvoke::expr"); // Retrieve the target lambda function from the HTTPD request and invoke it - const value* rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module)); + const value* const rv = const_cast<const value*>((value*)ap_get_module_config(r->request_config, &axis2_module)); cout << "relay: " << rv << endl; - const lambda<value(const list<value>&)> relay = *rv; + const lvvlambda relay = *rv; const value res = relay(expr); debug(res, "webservice::serviceInvoke::result"); diff --git a/sca-cpp/trunk/components/webservice/axis2-test.cpp b/sca-cpp/trunk/components/webservice/axis2-test.cpp index d7c2f3b671..69723aa6b3 100644 --- a/sca-cpp/trunk/components/webservice/axis2-test.cpp +++ b/sca-cpp/trunk/components/webservice/axis2-test.cpp @@ -36,22 +36,23 @@ namespace tuscany { namespace webservice { -bool testEval() { +const bool testEval() { const Axis2Context ax; const value func = "http://ws.apache.org/axis2/c/samples/echoString"; const list<value> arg = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (nilListValue + "text" + string("Hello World!"))); const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:9090/axis2/services/echo")), ax); assert(hasContent(rval)); const list<value> r = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) + + (nilListValue + "text" + string("Hello World!"))); + cerr << content(rval) << endl; assert(content(rval) == r); return true; diff --git a/sca-cpp/trunk/components/webservice/axis2.hpp b/sca-cpp/trunk/components/webservice/axis2.hpp index 9bad109ff0..fd4d1f9a02 100644 --- a/sca-cpp/trunk/components/webservice/axis2.hpp +++ b/sca-cpp/trunk/components/webservice/axis2.hpp @@ -46,8 +46,8 @@ #include "sstream.hpp" #include "list.hpp" #include "value.hpp" -#include "xml.hpp" #include "monad.hpp" +#include "../../modules/xml/xml.hpp" namespace tuscany { namespace webservice { @@ -65,16 +65,9 @@ public: debug("webservice::axis2context::copy"); } - const Axis2Context& operator=(const Axis2Context& ax) { - debug("webservice::axis2context::operator="); - if(this == &ax) - return *this; - env = ax.env; - owner = false; - return *this; - } + Axis2Context& operator=(const Axis2Context& ax) = delete; - Axis2Context(const axutil_env_t* env) : env(const_cast<axutil_env_t*>(env)), owner(false) { + Axis2Context(const axutil_env_t* const env) : env(const_cast<axutil_env_t*>(env)), owner(false) { debug("webservice::axis2context::env"); } @@ -86,13 +79,13 @@ public: } private: - axutil_env_t* env; - bool owner; + axutil_env_t* const env; + const bool owner; - friend const axutil_env_t* env(const Axis2Context& ax); + friend const axutil_env_t* const env(const Axis2Context& ax); }; -const axutil_env_t* env(const Axis2Context& ax) { +const axutil_env_t* const env(const Axis2Context& ax) { return ax.env; } @@ -109,7 +102,7 @@ const string axis2Error(const Axis2Context& ax) { * Convert a string to an Axiom node. */ const failable<axiom_node_t*> stringToAxiomNode(const string& s, const Axis2Context& ax) { - axiom_node_t* node = axiom_node_create_from_buffer(env(ax), const_cast<axis2_char_t*>(c_str(s))); + axiom_node_t* const node = axiom_node_create_from_buffer(env(ax), const_cast<axis2_char_t*>(c_str(s))); if (node == NULL) return mkfailure<axiom_node_t*>(string("Couldn't convert XML to Axiom node: ") + axis2Error(ax)); return node; @@ -119,7 +112,7 @@ const failable<axiom_node_t*> stringToAxiomNode(const string& s, const Axis2Cont * Convert a list of values representing XML elements to an Axiom node. */ const failable<axiom_node_t*> valuesToAxiomNode(const list<value>& l, const Axis2Context& ax) { - const failable<list<string> > xml = writeXML(valuesToElements(l), false); + const failable<list<string> > xml = xml::writeElements(valuesToElements(l), false); if (!hasContent(xml)) return mkfailure<axiom_node_t*>(xml); ostringstream os; @@ -130,8 +123,8 @@ const failable<axiom_node_t*> valuesToAxiomNode(const list<value>& l, const Axis /** * Convert an axiom node to a string. */ -const failable<const string> axiomNodeToString(axiom_node_t* node, const Axis2Context& ax) { - const char* c = axiom_node_to_string(node, env(ax)); +const failable<const string> axiomNodeToString(axiom_node_t* const node, const Axis2Context& ax) { + const char* const c = axiom_node_to_string(node, env(ax)); if (c == NULL) return mkfailure<const string>(string("Couldn't convert Axiom node to XML: ") + axis2Error(ax)); const string s(c); @@ -142,12 +135,12 @@ const failable<const string> axiomNodeToString(axiom_node_t* node, const Axis2Co /** * Convert an axiom node to a list of values representing XML elements. */ -const failable<const list<value> > axiomNodeToValues(axiom_node_t* node, const Axis2Context& ax) { +const failable<const list<value> > axiomNodeToValues(axiom_node_t* const node, const Axis2Context& ax) { const failable<const string> s = axiomNodeToString(node, ax); if (!hasContent(s)) return mkfailure<const list<value> >(s); istringstream is(content(s)); - const failable<const list<value> > l = readXML(streamList(is)); + const failable<const list<value> > l = content(xml::readElements(streamList(is))); if (!hasContent(l)) return l; return elementsToValues(content(l)); @@ -166,11 +159,11 @@ const failable<value> evalExpr(const value& expr, const Axis2Context& ax) { const value uri(caddr<value>(expr)); // Create Axis2 client - axis2_svc_client_t *client = axis2_svc_client_create(env(ax), getenv("AXIS2C_HOME")); + axis2_svc_client_t* const client = axis2_svc_client_create(env(ax), getenv("AXIS2C_HOME")); if (client == NULL) return mkfailure<value>("Couldn't create Axis2 client: " + axis2Error(ax)); - axis2_endpoint_ref_t *epr = axis2_endpoint_ref_create(env(ax), c_str(uri)); - axis2_options_t *opt = axis2_options_create(env(ax)); + axis2_endpoint_ref_t* const epr = axis2_endpoint_ref_create(env(ax), c_str(uri)); + axis2_options_t* const opt = axis2_options_create(env(ax)); axis2_options_set_to(opt, env(ax), epr); axis2_options_set_action(opt, env(ax), (const axis2_char_t*)c_str(func)); axis2_svc_client_set_options(client, env(ax), opt); @@ -182,7 +175,7 @@ const failable<value> evalExpr(const value& expr, const Axis2Context& ax) { return mkfailure<value>(req); // Call the Web service - axiom_node_t* res = axis2_svc_client_send_receive(client, env(ax), content(req)); + axiom_node_t* const res = axis2_svc_client_send_receive(client, env(ax), content(req)); if (res == NULL) { axis2_svc_client_free(client, env(ax)); return mkfailure<value>("Couldn't invoke Axis2 service: " + axis2Error(ax)); diff --git a/sca-cpp/trunk/components/webservice/client-test.cpp b/sca-cpp/trunk/components/webservice/client-test.cpp index 16dd659b22..ca009b9594 100644 --- a/sca-cpp/trunk/components/webservice/client-test.cpp +++ b/sca-cpp/trunk/components/webservice/client-test.cpp @@ -38,43 +38,43 @@ namespace tuscany { namespace webservice { -bool testModAxis2() { +const bool testModAxis2() { const Axis2Context ax; const value func = "http://ws.apache.org/axis2/c/samples/echoString"; const list<value> arg = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (nilListValue + "text" + string("Hello World!"))); const failable<value> rval = evalExpr(mklist<value>(func, arg, string("http://localhost:8090/echo-listener")), ax); assert(hasContent(rval)); const list<value> r = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (nilListValue + "text" + string("Hello World!"))); assert(content(rval) == r); return true; } -bool testEval() { - http::CURLSession cs("", "", "", ""); +const bool testEval() { + const http::CURLSession cs("", "", "", "", 0); const value func = "http://ws.apache.org/axis2/c/samples/echoString"; const list<value> arg = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/services/echo")) + + (nilListValue + "text" + string("Hello World!"))); const failable<value> rval = http::evalExpr(mklist<value>(func, arg), "http://localhost:8090/echo-client", cs); assert(hasContent(rval)); const list<value> r = mklist<value>( - list<value>() + "ns1:echoString" - + (list<value>() + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) - + (list<value>() + "text" + string("Hello World!"))); + nilListValue + "ns1:echoString" + + (nilListValue + "@xmlns:ns1" + string("http://ws.apache.org/axis2/c/samples")) + + (nilListValue + "text" + string("Hello World!"))); assert(content(rval) == r); return true; } diff --git a/sca-cpp/trunk/components/webservice/echo-test b/sca-cpp/trunk/components/webservice/echo-test index 1056a6c668..a7bc636cab 100755 --- a/sca-cpp/trunk/components/webservice/echo-test +++ b/sca-cpp/trunk/components/webservice/echo-test @@ -20,6 +20,7 @@ # Setup axis2_prefix=`cat axis2c.prefix` export AXIS2C_HOME=$axis2_prefix +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$axis2_prefix/lib axis2="$axis2_prefix/bin/axis2_http_server" pwd=`pwd` cd "$axis2_prefix/bin" diff --git a/sca-cpp/trunk/components/webservice/server-test b/sca-cpp/trunk/components/webservice/server-test index cb12accbfb..5e3b18b376 100755 --- a/sca-cpp/trunk/components/webservice/server-test +++ b/sca-cpp/trunk/components/webservice/server-test @@ -33,6 +33,7 @@ EOF axis2_prefix=`cat axis2c.prefix` export AXIS2C_HOME=$axis2_prefix +export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$axis2_prefix/lib axis2="$axis2_prefix/bin/axis2_http_server" pwd=`pwd` cd "$axis2_prefix/bin" diff --git a/sca-cpp/trunk/components/webservice/webservice-client.cpp b/sca-cpp/trunk/components/webservice/webservice-client.cpp index 76d4905bf8..bece0b3b3a 100644 --- a/sca-cpp/trunk/components/webservice/webservice-client.cpp +++ b/sca-cpp/trunk/components/webservice/webservice-client.cpp @@ -42,10 +42,10 @@ const failable<value> apply(const value& func, const list<value>& params) { // Extract parameters const value doc = car<value>(params); - const lambda<value(const list<value>&)> l = cadr<value>(params); + const lvvlambda l = cadr<value>(params); // Call the URI property lambda function to get the configured URI - const value uri = l(list<value>()); + const value uri = l(nilListValue); // Evaluate using Axis2 return evalExpr(mklist<value>(func, doc, uri), ax); diff --git a/sca-cpp/trunk/components/webservice/webservice-listener.cpp b/sca-cpp/trunk/components/webservice/webservice-listener.cpp index 29ebef4bcb..f9c18f293a 100644 --- a/sca-cpp/trunk/components/webservice/webservice-listener.cpp +++ b/sca-cpp/trunk/components/webservice/webservice-listener.cpp @@ -44,10 +44,10 @@ extern "C" { extern module axis2_module; } -const value redirectToAxis2(const string& uri, request_rec* r, const value& relay) { - const failable<request_rec*, int> nr = httpd::internalRedirectRequest(uri, r); +const failable<value> redirectToAxis2(const string& uri, request_rec* const r, const value& relay) { + const failable<request_rec*> nr = httpd::internalRedirectRequest(uri, r); if (!hasContent(nr)) - return value(reason(nr), rcode(nr)); + return mkfailure<value>(reason(nr), rcode(nr)); ap_set_module_config(content(nr)->request_config, &axis2_module, const_cast<void*>((const void*)&relay)); return value(httpd::internalRedirect(content(nr))); } @@ -58,7 +58,7 @@ const value redirectToAxis2(const string& uri, request_rec* r, const value& rela const failable<value> handle(const list<value>& params) { // Extract HTTPD request from the params - request_rec* r = httpd::request(car(params)); + request_rec* const r = httpd::request(car(params)); debug_httpdRequest(r, "webservice::handle"); // Extract the relay lambda from the params and store it in the HTTPD request, @@ -67,7 +67,7 @@ const failable<value> handle(const list<value>& params) { cout << "relay: " << &relay << endl; // Redirect HTTPD request to Mod-axis2 - return redirectToAxis2(string("/axis2") + r->uri + r->args != NULL? string("?") + r->args : string(""), r, relay); + return redirectToAxis2(string("/axis2") + r->uri + r->args != NULL? string("?") + r->args : emptyString, r, relay); } } |