diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-12-11 06:13:02 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2012-12-11 06:13:02 +0000 |
commit | 36adc76235fb0a38e7042bc751f988b71627e2a0 (patch) | |
tree | fc83b3f4e0afeb3932c8d200f5493f0a8d6c4619 /sca-cpp | |
parent | 86b1de85536e93c59a25702a5a2d3e384202ffd2 (diff) |
Changes to get successful C++11 based build. Code cleanup, dependency upgrades, and const + inline optimizations in components, samples, and app hosting server.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1420007 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp')
90 files changed, 1428 insertions, 1813 deletions
diff --git a/sca-cpp/trunk/INSTALL b/sca-cpp/trunk/INSTALL index c66c88bce5..80a4d8472f 100644 --- a/sca-cpp/trunk/INSTALL +++ b/sca-cpp/trunk/INSTALL @@ -31,11 +31,11 @@ The installation script will display each command as it's executed. That's all you need to do to build and install the Tuscany SCA runtime on Ubuntu Server. -Automated installation on Max OS X 10.7.4 -========================================= +Automated installation on Max OS X 10.8 +======================================= -Tuscany provides an automated install script for Mac OS X 10.7.4 and Xcode 4.1. -You can start with a fresh Mac OS X 10.7.4 + Xcode 4.1 system and the script +Tuscany provides an automated install script for Mac OS X 10.8 and Xcode 4.4. +You can start with a fresh Mac OS X 10.8 + Xcode 4.4 system and the script will take care of all the download, build and installation steps for you. macos/macos-install: @@ -89,12 +89,11 @@ XML: libxml2-2.7.7 (http://xmlsoft.org/) CURL: -curl-7-24.0 +curl-7-28.0 (http://curl.haxx.se) +built with c-ares-1.9.1 (http://c-ares.haxx.se) JSON: -Mozilla SpiderMonkey libmozjs 1.8.5 and -(https://developer.mozilla.org/en/SpiderMonkey) -built with Mozilla nspr-4.8.8 +Jansson 2.4 (http://www.digip.org/jansson/) Key/value persistent store: tinycdb-0.77 (http://www.corpit.ru/mjt/tinycdb.html) @@ -143,16 +142,13 @@ Apache Vysper 0.5 (http://mina.apache.org/) Libstrophe (http://code.stanziq.com/strophe/) build it from source at git://github.com/jsdelfino/libstrophe.git -Key/value persistent store: -Google LevelDB 1.2 (http://code.google.com/p/leveldb/) - SQL database: PostgreSQL 9.1.2 (http://www.postgresql.org/) PgBouncer 1.5 (http://wiki.postgresql.org/wiki/PgBouncer) Logging: Facebook Scribe 2.2 (http://github.com/facebook/scribe/downloads) -requires Apache Thrift 0.2.0 (http://incubator.apache.org/thrift/) +requires Apache Thrift 0.8.0 (http://incubator.apache.org/thrift/) Cloud deployment: Apache Libcloud 0.3.1 (http://incubator.apache.org/libcloud/) @@ -228,7 +224,7 @@ most useful options and the corresponding dependencies installed under $build: ./configure --prefix=$build/tuscany-sca-cpp-bin \ --enable-threads --enable-maintainer-mode \ ---with-curl=$build/curl-7.24.0-bin --with-libxml2=$build/libxml2-2.7.7-bin \ +--with-curl=$build/curl-7.28.0-bin --with-libxml2=$build/libxml2-2.7.7-bin \ --with-apr=$build/apr-1.4.6-bin --with-apr-util=$build/apr-util-1.4.1-bin \ --with-httpd=$build/httpd-2.4.2-bin \ --with-memcached=$build/memcached-1.4.7-bin \ @@ -238,7 +234,7 @@ most useful options and the corresponding dependencies installed under $build: --enable-python --with-python=$build/python-2.7.3-bin \ --enable-sqldb --with-pgsql=$build/postgresql-9.1.2-bin \ --with-pgbouncer=$build/pgbouncer-1.5-bin \ ---enable-log --with-thrift=$build/thrift-0.2.0-bin \ +--enable-log --with-thrift=$build/thrift-0.8.0-bin \ --with-scribe=$build/scribe-2.2-bin \ --enable-oauth --with-liboauth=$build/liboauth-0.9.1-bin \ --enable-mod-security --with-mod-security=$build/modsecurity-apache-2.6.6-bin \ diff --git a/sca-cpp/trunk/README b/sca-cpp/trunk/README index 1d81008041..bca9c53f74 100644 --- a/sca-cpp/trunk/README +++ b/sca-cpp/trunk/README @@ -6,8 +6,8 @@ in C++ and integrated with the Apache HTTPD server. It supports SCA components written in C++ and Python. Experimental support for other programming languages is under construction. SCA bindings are -available for the JSON-RPC, ATOMPub and RSS protocols. User signin is -implemented using OpenID and OAuth. +available for REST services and the JSON-RPC, ATOMPub and RSS protocols. +User signin is implemented using OpenID and OAuth. Several useful SCA components are provided on top of the SCA runtime, which can be used to help assemble distributed SCA composite applications: @@ -18,7 +18,6 @@ Constdb: fast persistent store for mostly constant data, using TinyCDB; Filedb: key/value persistent store, using plain files; Http: HTTP client, using Libcurl; Smtp: SMTP client, using Libcurl; -Kvdb: fast key/value persistent store, using LevelDB; Log: distributed logger, using Facebook Scribe; Queue: AMQP queuing, using Apache Qpid/C; Sqldb: SQL database, using PostgreSQL and PgBouncer; @@ -78,7 +77,6 @@ Here's a rough guide to the Tuscany SCA source tree: | | |-- constdb TinyCDB constant persistent store | | |-- filedb Plain file persistent store | | |-- http HTTP client - | | |-- kvdb LevelDB key/value persistent store | | |-- log Scribe logger | | |-- queue AMQP message queue | | |-- smtp SMTP client @@ -99,6 +97,7 @@ Here's a rough guide to the Tuscany SCA source tree: | |-- macos Automated install on Mac OS X 10.7.4 | |-- ubuntu Automated install on Ubuntu 12.04 | |-- patches Temporary patches to some of the dependencies + | |-- unmaintained Unmaintained or outdated modules | |-- branches Topic and release branches | 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/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); } } diff --git a/sca-cpp/trunk/configure.ac b/sca-cpp/trunk/configure.ac index e3f3de7e61..eb626c710a 100644 --- a/sca-cpp/trunk/configure.ac +++ b/sca-cpp/trunk/configure.ac @@ -119,7 +119,7 @@ AC_ARG_ENABLE(maintainer-mode, [AS_HELP_STRING([--enable-maintainer-mode], [comp if test "${want_maintainer_mode}" = "true"; then cxxflags="${cxxflags} -ggdb -g3 -Werror -Wall -Wextra -Wno-ignored-qualifiers -Wno-strict-aliasing -Winit-self -Wmissing-include-dirs -Wcast-qual -Wcast-align -Wwrite-strings -Wpointer-arith -Waddress -Wredundant-decls -std=c++0x -fmessage-length=0" if test "${cxxtype}" = "clang"; then - cxxflags="${cxxflags} -O1 -stdlib=libc++" + cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments -Wno-return-type-c-linkage" else cxxflags="${cxxflags} -O2 -Wlogical-op -Wconversion" fi @@ -128,7 +128,7 @@ if test "${want_maintainer_mode}" = "true"; then else cxxflags="${cxxflags} -g -std=c++0x -fmessage-length=0" if test "${cxxtype}" = "clang"; then - cxxflags="${cxxflags} -O1 -stdlib=libc++" + cxxflags="${cxxflags} -O2 -stdlib=libc++ -Qunused-arguments" else cxxflags="${cxxflags} -O2" fi @@ -286,28 +286,21 @@ AC_SUBST(LIBXML2_LIB) LIBS="-L${LIBXML2_LIB} ${defaultlibs}" AC_CHECK_LIB([xml2], [xmlInitParser], [], [AC_MSG_ERROR([couldn't find a suitable libxml2, use --with-libxml2=PATH])]) -# Configure path to libmozjs includes and lib. -AC_MSG_CHECKING([for js-include]) -AC_ARG_WITH([js-include], [AC_HELP_STRING([--with-js-include=PATH], [path to installed SpiderMonkey include dir - [default=/usr/include]])], [ - JS_INCLUDE="${withval}" +# Configure path to jansson includes and lib. +AC_MSG_CHECKING([for jansson]) +AC_ARG_WITH([jansson], [AC_HELP_STRING([--with-jansson=PATH], [path to installed jansson [default=/usr]])], [ + JANSSON_INCLUDE="${withval}/include" + JANSSON_LIB="${withval}/lib" AC_MSG_RESULT("${withval}") ], [ - JS_INCLUDE="/usr/include" - AC_MSG_RESULT(/usr/include) -]) -AC_MSG_CHECKING([for js-lib]) -AC_ARG_WITH([js-lib], [AC_HELP_STRING([--with-js-lib=PATH], [path to installed SpiderMonkey lib dir [default=/usr/lib]])], [ - JS_LIB="${withval}" - AC_MSG_RESULT("${withval}") -], [ - JS_LIB="/usr/lib" - AC_MSG_RESULT(/usr/lib) + JANSSON_INCLUDE="/usr/include" + JANSSON_LIB="/usr/lib" + AC_MSG_RESULT(/usr) ]) -AC_SUBST(JS_INCLUDE) -AC_SUBST(JS_LIB) -LIBS="-L${JS_LIB} ${defaultlibs}" -AC_CHECK_LIB([mozjs], [JS_NewContext], [], [AC_MSG_ERROR([couldn't find a suitable libmozjs, use --with-js-lib=PATH])]) +AC_SUBST(JANSSON_INCLUDE) +AC_SUBST(JANSSON_LIB) +LIBS="-L${JANSSON_LIB} ${defaultlibs}" +AC_CHECK_LIB([jansson], [json_loads], [], [AC_MSG_ERROR([couldn't find a suitable libjansson, use --with-jansson=PATH])]) # Configure path to Apache APR and HTTPD includes and libs. AC_MSG_CHECKING([for apr]) @@ -411,9 +404,9 @@ LIBS="-L${TINYCDB_LIB} ${defaultlibs}" AC_CHECK_LIB([cdb], [cdb_make_start], [], [AC_MSG_ERROR([couldn't find a suitable libcdb, use --with-tinycdb=PATH])]) # Configure default includes and ldflags -cxxflags="${cxxflags} ${INCLUDES} -I. -I${TUSCANY_SCACPP}/kernel -I${APR_INCLUDE} -I${APRUTIL_INCLUDE} -I${HTTPD_INCLUDE} -I${LIBXML2_INCLUDE} -I${JS_INCLUDE} -I${LIBCURL_INCLUDE}" +cxxflags="${cxxflags} ${INCLUDES} -I. -I${TUSCANY_SCACPP}/kernel -I${APR_INCLUDE} -I${APRUTIL_INCLUDE} -I${HTTPD_INCLUDE} -I${LIBXML2_INCLUDE} -I${JANSSON_INCLUDE} -I${LIBCURL_INCLUDE}" ldflags="${ldflags} -ldl -L${APR_LIB} -R${APR_LIB} -lapr-1 -L${APRUTIL_LIB} -R${APRUTIL_LIB} -laprutil-1" -ldflags="${ldflags} -L${LIBCURL_LIB} -R${LIBCURL_LIB} -L${JS_LIB} -R${JS_LIB} -L${LIBXML2_LIB} -R${LIBXML2_LIB}" +ldflags="${ldflags} -L${LIBCURL_LIB} -R${LIBCURL_LIB} -L${JANSSON_LIB} -R${JANSSON_LIB} -L${LIBXML2_LIB} -R${LIBXML2_LIB}" # Enable Python support. AC_MSG_CHECKING([whether to enable Python support]) @@ -597,7 +590,7 @@ if test "${want_java}" = "true"; then # IBM J9 VM AC_MSG_NOTICE([checking for J9 Java VM]) JAVA_LIBJVM=`dirname "${JAVA_LIBJVM_SO}"` - JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -R${JAVA_LIBJAVA} -L${JAVA_LIBJVM} -R${JAVA_LIBJVM}" + JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -Wl,-R${JAVA_LIBJAVA} -L${JAVA_LIBJVM} -Wl,-R${JAVA_LIBJVM}" LIBS="${JAVA_CHECK_LIB} ${defaultlibs}" AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava -ljvm -ljsig"], [], [-ljvm -ljsig]) if test "${JAVA_LDFLAGS}" != ""; then @@ -609,7 +602,7 @@ if test "${want_java}" = "true"; then JAVA_LIBJVM_SO=`find ${JAVA_PREFIX}/jre/lib -name libjvm.so | grep server` JAVA_LIBJVM=`dirname "${JAVA_LIBJVM_SO}"` AC_MSG_NOTICE([libjava ${JAVA_LIBJAVA} libjvm ${LIBJVM}]) - JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -R${JAVA_LIBJAVA} -L${JAVA_LIBJVM} -R${JAVA_LIBJVM}" + JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -Wl,-R${JAVA_LIBJAVA} -L${JAVA_LIBJVM} -Wl,-R${JAVA_LIBJVM}" LIBS="${JAVA_CHECK_LIB} ${defaultlibs}" AC_CHECK_LIB([java], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -ljava -ljvm -lverify"], [], [-ljvm -lverify]) if test "${JAVA_LDFLAGS}" != ""; then @@ -623,7 +616,7 @@ if test "${want_java}" = "true"; then JAVA_LIBHARMONYVM=`dirname "${JAVA_LIBHARMONYVM_SO}"` JAVA_LIBJAVA=`dirname "${JAVA_LIBHARMONYVM}"` AC_MSG_NOTICE([checking for Apache Harmony Java VM]) - JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -R${JAVA_LIBJAVA} -L${JAVA_LIBHARMONYVM} -R${JAVA_LIBHARMONYVM}" + JAVA_CHECK_LIB="-L${JAVA_LIBJAVA} -Wl,-R${JAVA_LIBJAVA} -L${JAVA_LIBHARMONYVM} -Wl,-R${JAVA_LIBHARMONYVM}" LIBS="${JAVA_CHECK_LIB} ${defaultlibs}" AC_CHECK_LIB([harmonyvm], [JNI_CreateJavaVM], [JAVA_LDFLAGS="${JAVA_CHECK_LIB} -lharmonyvm -lhythr -licuuc -lch ${JAVA_LIBHARMONYVM}/libicudata.so.34"], [], [-lhythr -licuuc -lch ${JAVA_LIBHARMONYVM}/libicudata.so.34]) if test "${JAVA_LDFLAGS}" != ""; then @@ -1006,7 +999,7 @@ if test "${want_chat}" = "true"; then AC_MSG_RESULT(${HOME}/vysper-1.0.0) ]) AC_SUBST(VYSPER_PREFIX) - AC_CHECK_FILE([${VYSPER_PREFIX}/lib/vysper-core-0.5.jar], [want_vysper=true], []) + AC_CHECK_FILE([${VYSPER_PREFIX}/lib/vysper-core-0.6.jar], [want_vysper=true], []) if test "${want_vysper}" = "true"; then AM_CONDITIONAL([WANT_VYSPER], true) else @@ -1117,6 +1110,7 @@ AC_CONFIG_FILES([Makefile modules/openid/Makefile modules/oauth/Makefile modules/wsgi/Makefile + modules/xml/Makefile components/Makefile components/cache/Makefile components/log/Makefile diff --git a/sca-cpp/trunk/hosting/server/client-test.cpp b/sca-cpp/trunk/hosting/server/client-test.cpp index c0a01b5237..7295556e08 100644 --- a/sca-cpp/trunk/hosting/server/client-test.cpp +++ b/sca-cpp/trunk/hosting/server/client-test.cpp @@ -27,7 +27,7 @@ #include "string.hpp" #include "client-test.hpp" -int main(const int argc, const char** argv) { +int main(const int argc, const char** const argv) { tuscany::cout << "Testing..." << tuscany::endl; tuscany::server::testURI = argc > 1? argv[1] : "https://jane:jane@www.example.com:8453"; diff --git a/sca-cpp/trunk/hosting/server/client-test.hpp b/sca-cpp/trunk/hosting/server/client-test.hpp index 7d85fc99a6..9d887e0558 100644 --- a/sca-cpp/trunk/hosting/server/client-test.hpp +++ b/sca-cpp/trunk/hosting/server/client-test.hpp @@ -36,7 +36,7 @@ namespace tuscany { namespace server { -string testURI = "http://localhost:8090"; +gc_mutable_ref<string> testURI = (string)"http://localhost:8090"; bool testBlobs = true; ostream* curlWriter(const string& s, ostream* os) { @@ -45,8 +45,8 @@ ostream* curlWriter(const string& s, ostream* os) { } const bool testGetDoc() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); { ostringstream os; const failable<list<ostream*> > r = http::get<ostream*>(curlWriter, &os, testURI + "/", ch); @@ -62,201 +62,139 @@ const bool testGetDoc() { return true; } -struct getDocLoop { - http::CURLSession& ch; - getDocLoop(http::CURLSession& ch) : ch(ch) { - } - const bool operator()() const { +const bool testGetDocPerf() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda gl = [ch]() -> const bool { const failable<value> r = http::getcontent(testURI + "/", ch); assert(hasContent(r)); assert(contains(car(list<value>(content(r))), "<base href=\"/\"/>")); return true; - } -}; - -const bool testGetDocPerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> gl = getDocLoop(ch); + }; cout << "GET doc test " << time(gl, 10, 50) << " ms" << endl; return true; } -struct getCompositeLoop { - http::CURLSession& ch; - getCompositeLoop(http::CURLSession& ch) : ch(ch) { - } - const bool operator()() const { +const bool testGetCompositePerf() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda gl = [ch]() -> const bool { const failable<value> r = http::getcontent(testURI + "/r/Editor/composites/test", ch); assert(hasContent(r)); return true; - } -}; - -const bool testGetCompositePerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> gl = getCompositeLoop(ch); + }; cout << "GET composite test " << time(gl, 10, 50) << " ms" << endl; return true; } -struct getPageLoop { - http::CURLSession& ch; - getPageLoop(http::CURLSession& ch) : ch(ch) { - } - const bool operator()() const { +const bool testGetPagePerf() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda gl = [ch]() -> const bool { const failable<value> r = http::getcontent(testURI + "/r/Editor/pages/test", ch); assert(hasContent(r)); return true; - } -}; - -const bool testGetPagePerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> gl = getPageLoop(ch); + }; cout << "GET page test " << time(gl, 10, 50) << " ms" << endl; return true; } -struct getAppLoop { - http::CURLSession& ch; - getAppLoop(http::CURLSession& ch) : ch(ch) { - } - const bool operator()() const { +const bool testGetAppPerf() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda gl = [ch]() -> const bool { const failable<value> r = http::getcontent(testURI + "/r/Editor/apps/test", ch); assert(hasContent(r)); return true; - } -}; - -const bool testGetAppPerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> gl = getAppLoop(ch); + }; cout << "GET app test " << time(gl, 10, 50) << " ms" << endl; return true; } const bool testEval() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch); assert(hasContent(r)); assert(content(r) == string("Hello")); return true; } -struct evalLoop { - const string uri; - http::CURLSession& ch; - evalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) { - } - const bool operator()() const { - const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), uri, ch); - assert(hasContent(r)); - assert(content(r) == string("Hello")); - return true; - } -}; - const value blob(string(2048, 'A')); const list<value> blobs = mklist(blob, blob); -struct blobEvalLoop { - const string uri; - http::CURLSession& ch; - blobEvalLoop(const string& uri, http::CURLSession& ch) : uri(uri), ch(ch) { - } - const bool operator()() const { - const failable<value> r = content(http::evalExpr(mklist<value>(string("echo"), blobs), uri, ch)); +const bool testEvalPerf() { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda el = [ch]() -> const bool { + const failable<value> r = http::evalExpr(mklist<value>(string("echo"), string("Hello")), testURI, ch); assert(hasContent(r)); - assert(content(r) == blobs); + assert(content(r) == string("Hello")); return true; - } -}; - -const bool testEvalPerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> el = evalLoop(testURI, ch); + }; cout << "JSON-RPC eval echo test " << time(el, 5, 200) << " ms" << endl; if (testBlobs) { - const lambda<bool()> bel = blobEvalLoop(testURI, ch); + const blambda bel = [ch]() -> const bool { + const failable<value> r = content(http::evalExpr(mklist<value>(string("echo"), blobs), testURI, ch)); + assert(hasContent(r)); + assert(content(r) == blobs); + return true; + }; cout << "JSON-RPC eval blob test " << time(bel, 5, 200) << " ms" << endl; } return true; } -bool testPost() { - gc_scoped_pool pool; - 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 testPost() { + const gc_scoped_pool pool; + 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 ch("", "", "", "", 0); + const http::CURLSession ch("", "", "", "", 0); const failable<value> id = http::post(a, testURI, ch); assert(hasContent(id)); return true; } -struct postLoop { - const string uri; - const value val; - http::CURLSession& ch; - postLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) { - } - const bool operator()() const { - const failable<value> id = http::post(val, uri, ch); - assert(hasContent(id)); - return true; - } -}; - -struct postBlobLoop { - const string uri; - const value val; - http::CURLSession& ch; - postBlobLoop(const string& uri, const value& val, http::CURLSession& ch) : uri(uri), val(val), ch(ch) { - } - const bool operator()() const { - gc_scoped_pool pool; - const failable<value> id = http::post(val, uri, ch); - assert(hasContent(id)); - return true; - } -}; - const bool testPostPerf() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 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> val = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const list<value> val = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - const lambda<bool()> pl = postLoop(testURI, val, ch); + const blambda pl = [val, ch]() -> const bool { + const failable<value> id = http::post(val, testURI, ch); + assert(hasContent(id)); + return true; + }; cout << "ATOMPub POST small test " << time(pl, 5, 200) << " ms" << endl; } if (testBlobs) { - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "blob1" + blob) - + (list<value>() + "blob2" + blob) - + (list<value>() + "price" + string("$2.99"))); - const list<value> val = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "blob1" + blob) + + (nilListValue + "blob2" + blob) + + (nilListValue + "price" + string("$2.99"))); + const list<value> val = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - const lambda<bool()> pl = postBlobLoop(testURI, val, ch); + const blambda pl = [val, ch]() -> const bool { + const gc_scoped_pool pool; + const failable<value> id = http::post(val, testURI, ch); + assert(hasContent(id)); + return true; + }; cout << "ATOMPub POST blob test " << time(pl, 5, 200) << " ms" << endl; } return true; @@ -264,15 +202,19 @@ const bool testPostPerf() { #ifdef WANT_THREADS -const bool postThread(const string& uri, const int count, const value& val) { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> pl = postLoop(uri, val, ch); +const bool postThread(const int count, const value& val) { + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda pl = [val, ch]() -> const bool { + const failable<value> id = http::post(val, testURI, ch); + assert(hasContent(id)); + return true; + }; time(pl, 0, count); return true; } -const list<future<bool> > startPost(worker& w, const int threads, const lambda<bool()>& l) { +const list<future<bool> > startPost(const worker& w, const int threads, const blambda& l) { if (threads == 0) return list<future<bool> >(); return cons(submit(w, l), startPost(w, threads - 1, l)); @@ -285,36 +227,27 @@ const bool checkPost(const list<future<bool> >& r) { return checkPost(cdr(r)); } -struct postThreadLoop { - const lambda<bool()> l; - worker& w; - const int threads; - postThreadLoop(const lambda<bool()>& l, worker& w, const int threads) : l(l), w(w), threads(threads) { - } - const bool operator()() const { - list<future<bool> > r = startPost(w, threads, l); - checkPost(r); - return true; - } -}; - const bool testPostThreadPerf() { - gc_scoped_pool pool; + const gc_scoped_pool pool; const int count = 50; const int threads = 10; - worker w(threads); - - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const value val = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const worker w(threads); + + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const value val = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postThread), testURI, count, val); - const lambda<bool()> ptl = postThreadLoop(pl, w, threads); - double t = time(ptl, 0, 1) / (threads * count); + const blambda pl= curry(lambda<const bool(const int, const value)>(postThread), count, val); + const blambda ptl = [pl, w, threads]() -> const bool { + list<future<bool> > r = startPost(w, threads, pl); + checkPost(r); + return true; + }; + const double t = time(ptl, 0, 1) / (threads * count); cout << "ATOMPub POST thread test " << t << " ms" << endl; return true; @@ -323,17 +256,21 @@ const bool testPostThreadPerf() { #else const bool postProc(const string& uri, const int count, const value& val) { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - const lambda<bool()> pl = postLoop(uri, val, ch); + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const blambda pl = [val, ch]() -> const bool { + const failable<value> id = http::post(val, testURI, ch); + assert(hasContent(id)); + return true; + }; time(pl, 0, count); return true; } -const list<pid_t> startPost(const int procs, const lambda<bool()>& l) { +const list<pid_t> startPost(const int procs, const blambda& l) { if (procs == 0) return list<pid_t>(); - pid_t pid = fork(); + const pid_t pid = fork(); if (pid == 0) { assert(l() == true); exit(0); @@ -350,34 +287,26 @@ const bool checkPost(const list<pid_t>& r) { return checkPost(cdr(r)); } -struct postForkLoop { - const lambda<bool()> l; - const int procs; - postForkLoop(const lambda<bool()>& l, const int procs) : l(l), procs(procs) { - } - const bool operator()() const { - list<pid_t> r = startPost(procs, l); - checkPost(r); - return true; - } -}; - const bool testPostForkPerf() { - gc_scoped_pool pool; + const gc_scoped_pool pool; const int count = 50; const int procs = 10; - const list<value> i = list<value>() + "content" + (list<value>() + "item" - + (list<value>() + "name" + string("Apple")) - + (list<value>() + "price" + string("$2.99"))); - const value val = list<value>() + (list<value>() + "entry" - + (list<value>() + "title" + string("item")) - + (list<value>() + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + const list<value> i = nilListValue + "content" + (nilListValue + "item" + + (nilListValue + "name" + string("Apple")) + + (nilListValue + "price" + string("$2.99"))); + const value val = nilListValue + (nilListValue + "entry" + + (nilListValue + "title" + string("item")) + + (nilListValue + "id" + string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b")) + i); - const lambda<bool()> pl= curry(lambda<bool(const string, const int, const value)>(postProc), testURI, count, val); - const lambda<bool()> ptl = postForkLoop(pl, procs); - double t = time(ptl, 0, 1) / (procs * count); + const blambda pl= curry(lambda<const bool(const string, const int, const value)>(postProc), testURI, count, val); + const blambda ptl = [pl, procs]() -> const bool { + list<pid_t> r = startPost(procs, pl); + checkPost(r); + return true; + }; + const double t = time(ptl, 0, 1) / (procs * count); cout << "ATOMPub POST fork test " << t << " ms" << endl; return true; @@ -386,25 +315,25 @@ const bool testPostForkPerf() { #endif const bool testPut() { - gc_scoped_pool pool; - 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 gc_scoped_pool pool; + 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 ch("", "", "", "", 0); - value rc = content(http::put(a, testURI + "/111", ch)); - assert(rc == value(true)); + const http::CURLSession ch("", "", "", "", 0); + const value rc = content(http::put(a, testURI + "/111", ch)); + assert(rc == trueValue); return true; } const bool testDel() { - gc_scoped_pool pool; - http::CURLSession ch("", "", "", "", 0); - value rc = content(http::del(testURI + "/111", ch)); - assert(rc == value(true)); + const gc_scoped_pool pool; + const http::CURLSession ch("", "", "", "", 0); + const value rc = content(http::del(testURI + "/111", ch)); + assert(rc == trueValue); return true; } diff --git a/sca-cpp/trunk/patches/scribe-2.2.patch b/sca-cpp/trunk/patches/scribe-2.2.patch index 16c2e3871e..2f6b096719 100644 --- a/sca-cpp/trunk/patches/scribe-2.2.patch +++ b/sca-cpp/trunk/patches/scribe-2.2.patch @@ -10,6 +10,23 @@ #include <boost/filesystem/operations.hpp> #include <boost/filesystem/convenience.hpp> +--- src/conn_pool.cpp ++++ src/conn_pool.cpp +@@ -271,11 +271,11 @@ + ++iter) { + msgs.push_back(**iter); + } +- ResultCode result = TRY_LATER; ++ ResultCode::type result = ResultCode::TRY_LATER; + try { + result = resendClient->Log(msgs); + +- if (result == OK) { ++ if (result == ResultCode::OK) { + if (g_Handler) { + g_Handler->incrementCounter("sent", size); + } + --- src/file.cpp +++ src/file.cpp @@ -74,9 +74,21 @@ @@ -56,6 +73,32 @@ LOG_OPER("Starting scribe server on port %lu", g_Handler->port); fflush(stderr); +@@ -409,13 +411,13 @@ + } + + +-ResultCode scribeHandler::Log(const vector<LogEntry>& messages) { +- ResultCode result; ++ResultCode::type scribeHandler::Log(const vector<LogEntry>& messages) { ++ ResultCode::type result; + + scribeHandlerLock.acquireRead(); + + if (throttleRequest(messages)) { +- result = TRY_LATER; ++ result = ResultCode::TRY_LATER; + goto end; + } + +@@ -463,7 +465,7 @@ + addMessage(*msg_iter, store_list); + } + +- result = OK; ++ result = ResultCode::OK; + + end: + scribeHandlerLock.release(); @@ -583,6 +585,8 @@ throw runtime_error("No port number configured"); } @@ -68,6 +111,15 @@ --- src/scribe_server.h +++ src/scribe_server.h +@@ -42,7 +42,7 @@ + void initialize(); + void reinitialize(); + +- scribe::thrift::ResultCode Log(const std::vector<scribe::thrift::LogEntry>& messages); ++ scribe::thrift::ResultCode::type Log(const std::vector<scribe::thrift::LogEntry>& messages); + + void getVersion(std::string& _return) {_return = "2.2";} + facebook::fb303::fb_status getStatus(); @@ -51,6 +51,7 @@ void setStatusDetails(const std::string& new_status_details); @@ -76,3 +128,4 @@ // number of threads processing new Thrift connections size_t numThriftServerThreads; + diff --git a/sca-cpp/trunk/patches/thrift-0.2.0.patch b/sca-cpp/trunk/patches/thrift-0.8.0.patch index a834faca02..09b4412c3a 100644 --- a/sca-cpp/trunk/patches/thrift-0.2.0.patch +++ b/sca-cpp/trunk/patches/thrift-0.8.0.patch @@ -1,6 +1,6 @@ --- lib/cpp/src/server/TNonblockingServer.cpp +++ lib/cpp/src/server/TNonblockingServer.cpp -@@ -622,8 +622,8 @@ +@@ -989,8 +989,8 @@ hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; sprintf(port, "%d", port_); @@ -14,26 +14,28 @@ --- lib/cpp/src/server/TNonblockingServer.h +++ lib/cpp/src/server/TNonblockingServer.h -@@ -65,6 +65,9 @@ - // Server socket file descriptor +@@ -126,6 +126,9 @@ + /// Server socket file descriptor int serverSocket_; -+ // Host server runs on ++ /// Host server runs on + std::string host_; + - // Port server runs on + /// Port server runs on int port_; -@@ -117,10 +120,12 @@ +@@ -294,11 +297,13 @@ + TNonblockingServer( + const boost::shared_ptr<Processor>& processor, + const boost::shared_ptr<TProtocolFactory>& protocolFactory, ++ const std::string host, + int port, + const boost::shared_ptr<ThreadManager>& threadManager = + boost::shared_ptr<ThreadManager>(), + THRIFT_OVERLOAD_IF(Processor, TProcessor)) : +- TServer(processor) { ++ TServer(processor), ++ host_(host) { + + init(port); - TNonblockingServer(boost::shared_ptr<TProcessor> processor, - boost::shared_ptr<TProtocolFactory> protocolFactory, -+ std::string host, - int port, - boost::shared_ptr<ThreadManager> threadManager = boost::shared_ptr<ThreadManager>()) : - TServer(processor), - serverSocket_(-1), -+ host_(host), - port_(port), - threadManager_(threadManager), - eventBase_(NULL), diff --git a/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp b/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp index 9907650316..16f01cd85c 100644 --- a/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp +++ b/sca-cpp/trunk/samples/store-cpp/fruits-catalog.cpp @@ -35,27 +35,19 @@ namespace store { /** * Returns the catalog. */ -struct convert { - const lambda<value(const list<value>&)> converter; - const string currency; - convert(const lambda<value(const list<value>&)>& converter, const string& currency) : converter(converter), currency(currency) { - } - const value operator()(const value& price) const { - return converter(mklist<value>("convert", string("USD"), currency, price)); - } -}; - const list<value> mkfruit(const string& name, const string& code, const string& symbol, const double price) { - return list<value>() + + return nilListValue + mklist<value>("name", name) + mklist<value>("currencyCode", code) + mklist<value>("currencySymbol", symbol) + mklist<value>("price", price); } -const failable<value> items(const lambda<value(const list<value>&)>& converter, const lambda<value(const list<value>&)>& currencyCode) { - const string currency(currencyCode(list<value>())); +const failable<value> items(const lvvlambda& converter, const lvvlambda& currencyCode) { + const string currency(currencyCode(nilListValue)); const string symbol(converter(mklist<value>("symbol", currency))); - const lambda<value(const value&)> conv(convert(converter, currency)); + const vvlambda conv = [converter, currency](const value& price) -> const value { + return converter(mklist<value>("convert", string("USD"), currency, price)); + }; - return value(list<value>() + + return value(nilListValue + mkfruit("Apple", currency, symbol, conv(2.99)) + mkfruit("Orange", currency, symbol, conv(3.55)) + mkfruit("Pear", currency, symbol, conv(1.55))); diff --git a/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp b/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp index 2771d7cd9c..e65aa0d392 100644 --- a/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp +++ b/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp @@ -38,7 +38,7 @@ const string cartId("1234"); * Get the shopping cart from the cache. Return an empty * cart if not found. */ -const list<value> getcart(const value& id, const lambda<value(const list<value>&)>& cache) { +const list<value> getcart(const value& id, const lvvlambda& cache) { const value cart = cache(mklist<value>("get", mklist<value>(id))); cerr << "cart value: " << cart << "\n"; const failable<value> fcart = cart; @@ -46,14 +46,14 @@ const list<value> getcart(const value& id, const lambda<value(const list<value>& cerr << "cart content: " << content(fcart) << "\n"; cerr << "cart reason: " << reason(fcart) << "\n"; if (isNil(cart)) - return value(list<value>()); + return value(nilListValue); return (list<value>)cart; } /** * Post a new item to the cart. Create a new cart if necessary. */ -const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)>& cache) { +const failable<value> post(unused const list<value>& collection, const value& item, const lvvlambda& cache) { const value id(mkuuid()); const list<value> newItem(mklist<value>("entry", cadr<value>(car<value>(item)), mklist<value>("id", id), cadddr<value>(car<value>(item)))); const list<value> cart(cons<value>(newItem, getcart(cartId, cache))); @@ -75,7 +75,7 @@ const value find(const value& id, const list<value>& cart) { /** * Return items from the cart. */ -const failable<value> get(const list<value>& id, const lambda<value(const list<value>&)>& cache) { +const failable<value> get(const list<value>& id, const lvvlambda& cache) { if (isNil(id)) return value(mklist<value>(append(mklist<value>("feed", mklist<value>("title", string("Your Cart")), mklist<value>("id", cartId)), getcart(cartId, cache)))); return find(car(id), getcart(cartId, cache)); @@ -84,10 +84,10 @@ const failable<value> get(const list<value>& id, const lambda<value(const list<v /** * Delete items from the cart. */ -const failable<value> del(const list<value>& id, unused const lambda<value(const list<value>&)>& cache) { +const failable<value> del(const list<value>& id, unused const lvvlambda& cache) { if (isNil(id)) return cache(mklist<value>("delete", mklist<value>(cartId))); - return value(true); + return trueValue; } /** @@ -109,7 +109,7 @@ const double sum(const list<value>& items) { /** * Return the total price of the items in the cart. */ -const failable<value> total(const lambda<value(const list<value>&)>& cache) { +const failable<value> total(const lvvlambda& cache) { const list<value> cart(getcart(cartId, cache)); return value(sum(cart)); } diff --git a/sca-cpp/trunk/samples/store-java/Makefile.am b/sca-cpp/trunk/samples/store-java/Makefile.am index f32ae72812..3db20ac390 100644 --- a/sca-cpp/trunk/samples/store-java/Makefile.am +++ b/sca-cpp/trunk/samples/store-java/Makefile.am @@ -22,11 +22,16 @@ if WANT_JAVA dist_sample_SCRIPTS = start stop ssl-start sampledir=$(prefix)/samples/store-java -AM_JAVACFLAGS = -cp ${top_builddir}/modules/java/libmod-tuscany-java-${PACKAGE_VERSION}.jar:${JAVAROOT} dist_sample_JAVA = store/*.java + +SUFFIXES = .class +AM_JAVACFLAGS = -cp ${top_builddir}/modules/java/libmod-tuscany-java-${PACKAGE_VERSION}.jar:${JAVAROOT} +.java.class: + ${JAVAC} ${AM_JAVACFLAGS} store/*.java + CLEANFILES = *.stamp store/*.class -nobase_dist_sample_DATA = store.composite htdocs/*.html store/*.* +nobase_dist_sample_DATA = store.composite htdocs/*.html store/*.java store/CurrencyConverterImpl.class store/CurrencyConverter.class store/FruitsCatalogImpl.class store/ShoppingCartImpl.class dist_noinst_SCRIPTS = server-test TESTS = server-test diff --git a/sca-cpp/trunk/samples/store-scheme/Makefile.am b/sca-cpp/trunk/samples/store-scheme/Makefile.am index 2330d45422..36aa8ecb2d 100644 --- a/sca-cpp/trunk/samples/store-scheme/Makefile.am +++ b/sca-cpp/trunk/samples/store-scheme/Makefile.am @@ -25,6 +25,6 @@ EXTRA_DIST = script-test.scm dist_noinst_SCRIPTS = server-test noinst_PROGRAMS = script-test script_test_SOURCES = script-test.cpp -script_test_LDFLAGS = -lxml2 -lmozjs +script_test_LDFLAGS = -lxml2 -ljansson TESTS = script-test server-test diff --git a/sca-cpp/trunk/samples/store-scheme/script-test.cpp b/sca-cpp/trunk/samples/store-scheme/script-test.cpp index 0d5a9ccf9d..676865e771 100644 --- a/sca-cpp/trunk/samples/store-scheme/script-test.cpp +++ b/sca-cpp/trunk/samples/store-scheme/script-test.cpp @@ -28,16 +28,16 @@ #include "stream.hpp" #include "string.hpp" #include "list.hpp" -#include "xml.hpp" -#include "../../modules/scheme/driver.hpp" +#include "../../modules/xml/xml.hpp" #include "../../modules/json/json.hpp" +#include "../../modules/scheme/driver.hpp" namespace store { using namespace tuscany; -bool testScript() { - gc_scoped_pool pool; +const bool testScript() { + const gc_scoped_pool pool; ifstream is("script-test.scm"); ostringstream os; @@ -49,9 +49,9 @@ bool testScript() { return true; } -bool testEval() { +const bool testEval() { { - gc_scoped_pool pool; + const gc_scoped_pool pool; ifstream is("script-test.scm"); ostringstream os; scheme::setupDisplay(os); @@ -65,7 +65,7 @@ bool testEval() { } { - gc_scoped_pool pool; + const gc_scoped_pool pool; ifstream is("script-test.scm"); ostringstream os; scheme::setupDisplay(os); diff --git a/sca-cpp/trunk/components/kvdb/Makefile.am b/sca-cpp/trunk/unmaintained/components/kvdb/Makefile.am index 3212f3f5c8..3212f3f5c8 100644 --- a/sca-cpp/trunk/components/kvdb/Makefile.am +++ b/sca-cpp/trunk/unmaintained/components/kvdb/Makefile.am diff --git a/sca-cpp/trunk/components/kvdb/client-test.cpp b/sca-cpp/trunk/unmaintained/components/kvdb/client-test.cpp index 5f0ef21d00..5f0ef21d00 100644 --- a/sca-cpp/trunk/components/kvdb/client-test.cpp +++ b/sca-cpp/trunk/unmaintained/components/kvdb/client-test.cpp diff --git a/sca-cpp/trunk/components/kvdb/kvdb-test b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb-test index 420b98559c..420b98559c 100755 --- a/sca-cpp/trunk/components/kvdb/kvdb-test +++ b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb-test diff --git a/sca-cpp/trunk/components/kvdb/kvdb.componentType b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.componentType index 1c56ab6807..1c56ab6807 100644 --- a/sca-cpp/trunk/components/kvdb/kvdb.componentType +++ b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.componentType diff --git a/sca-cpp/trunk/components/kvdb/kvdb.composite b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.composite index 378f418cfc..378f418cfc 100644 --- a/sca-cpp/trunk/components/kvdb/kvdb.composite +++ b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.composite diff --git a/sca-cpp/trunk/components/kvdb/kvdb.cpp b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.cpp index 0df8f13882..0df8f13882 100644 --- a/sca-cpp/trunk/components/kvdb/kvdb.cpp +++ b/sca-cpp/trunk/unmaintained/components/kvdb/kvdb.cpp diff --git a/sca-cpp/trunk/components/kvdb/leveldb b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb index f9c54465f6..f9c54465f6 100755 --- a/sca-cpp/trunk/components/kvdb/leveldb +++ b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb diff --git a/sca-cpp/trunk/components/kvdb/leveldb-test.cpp b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb-test.cpp index b3b4ea7fd7..b3b4ea7fd7 100644 --- a/sca-cpp/trunk/components/kvdb/leveldb-test.cpp +++ b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb-test.cpp diff --git a/sca-cpp/trunk/components/kvdb/leveldb.hpp b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb.hpp index 05a89a76f7..05a89a76f7 100644 --- a/sca-cpp/trunk/components/kvdb/leveldb.hpp +++ b/sca-cpp/trunk/unmaintained/components/kvdb/leveldb.hpp diff --git a/sca-cpp/trunk/components/kvdb/server-test b/sca-cpp/trunk/unmaintained/components/kvdb/server-test index ebf01b9b4b..ebf01b9b4b 100755 --- a/sca-cpp/trunk/components/kvdb/server-test +++ b/sca-cpp/trunk/unmaintained/components/kvdb/server-test |