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