You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tuscany.apache.org by js...@apache.org on 2010/08/16 08:15:25 UTC

svn commit: r985799 - in /tuscany/sca-cpp/trunk: components/cache/ components/chat/ components/nosqldb/ components/sqldb/ kernel/ modules/http/ modules/java/ modules/scheme/ samples/store-cluster/ samples/store-cluster/domains/jane/ samples/store-clust...

Author: jsdelfino
Date: Mon Aug 16 06:15:24 2010
New Revision: 985799

URL: http://svn.apache.org/viewvc?rev=985799&view=rev
Log:
Test Postgresql hot standby + replication and integrated Postgresql database in store-cluster sample. Add a front cache component which can be used to wire a cache component and a database component.

Added:
    tuscany/sca-cpp/trunk/components/cache/frontcache.cpp
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-backup
      - copied, changed from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-start
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf   (with props)
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf   (with props)
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test   (with props)
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp
      - copied, changed from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp
    tuscany/sca-cpp/trunk/components/sqldb/standby-test
      - copied, changed from r985561, tuscany/sca-cpp/trunk/components/sqldb/server-test
    tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-master-conf
      - copied, changed from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop
    tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-standby-conf
      - copied, changed from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql
Modified:
    tuscany/sca-cpp/trunk/components/cache/Makefile.am
    tuscany/sca-cpp/trunk/components/cache/client-test.cpp
    tuscany/sca-cpp/trunk/components/cache/memcache.composite
    tuscany/sca-cpp/trunk/components/cache/memcache.cpp
    tuscany/sca-cpp/trunk/components/cache/memcache.hpp
    tuscany/sca-cpp/trunk/components/cache/server-test
    tuscany/sca-cpp/trunk/components/chat/xmpp.hpp
    tuscany/sca-cpp/trunk/components/nosqldb/nosqldb.cpp
    tuscany/sca-cpp/trunk/components/nosqldb/tinycdb.hpp
    tuscany/sca-cpp/trunk/components/sqldb/Makefile.am
    tuscany/sca-cpp/trunk/components/sqldb/pgsql
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-start
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop
    tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp
    tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp
    tuscany/sca-cpp/trunk/components/sqldb/server-test
    tuscany/sca-cpp/trunk/components/sqldb/sqldb-test
    tuscany/sca-cpp/trunk/components/sqldb/sqldb.composite
    tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp
    tuscany/sca-cpp/trunk/kernel/list.hpp
    tuscany/sca-cpp/trunk/kernel/value.hpp
    tuscany/sca-cpp/trunk/modules/http/httpd-conf
    tuscany/sca-cpp/trunk/modules/java/eval.hpp
    tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp
    tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am
    tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
    tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
    tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop
    tuscany/sca-cpp/trunk/samples/store-cluster/start
    tuscany/sca-cpp/trunk/samples/store-cluster/stop
    tuscany/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp
    tuscany/sca-cpp/trunk/samples/store-sql/ssl-start
    tuscany/sca-cpp/trunk/samples/store-sql/start
    tuscany/sca-cpp/trunk/samples/store-sql/stop
    tuscany/sca-cpp/trunk/samples/store-sql/store.composite

Modified: tuscany/sca-cpp/trunk/components/cache/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/Makefile.am?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/components/cache/Makefile.am Mon Aug 16 06:15:24 2010
@@ -27,12 +27,18 @@ memcached.prefix: $(top_builddir)/config
 
 EXTRA_DIST = memcache.composite
 
-comp_LTLIBRARIES = libmemcache.la
+comp_LTLIBRARIES = libmemcache.la libfrontcache.la
+
 libmemcache_la_SOURCES = memcache.cpp
 noinst_DATA = libmemcache.so
 libmemcache.so:
 	ln -s .libs/libmemcache.so
 
+libfrontcache_la_SOURCES = frontcache.cpp
+noinst_DATA = libfrontcache.so
+libfrontcache.so:
+	ln -s .libs/libfrontcache.so
+
 memcache_test_SOURCES = memcache-test.cpp
 memcache_test_LDFLAGS = -lxml2
 

Modified: tuscany/sca-cpp/trunk/components/cache/client-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/client-test.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/client-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/client-test.cpp Mon Aug 16 06:15:24 2010
@@ -36,9 +36,10 @@
 namespace tuscany {
 namespace cache {
 
-const string uri("http://localhost:8090/memcache");
+const string memcacheuri("http://localhost:8090/memcache");
+const string frontcacheuri("http://localhost:8090/frontcache");
 
-bool testCache() {
+bool testCache(const string& uri) {
     http::CURLSession cs;
 
     const list<value> i = list<value>()
@@ -84,6 +85,14 @@ bool testCache() {
     return true;
 }
 
+bool testMemcache() {
+    return testCache(memcacheuri);
+}
+
+bool testFrontcache() {
+    return testCache(frontcacheuri);
+}
+
 struct getLoop {
     const string path;
     const value entry;
@@ -91,7 +100,7 @@ struct getLoop {
     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);
+        const failable<value> val = http::get(memcacheuri + path, cs);
         assert(hasContent(val));
         assert(content(val) == entry);
         return true;
@@ -105,7 +114,7 @@ bool testGetPerf() {
     const value a = mklist<value>(string("item"), string("cart-53d67a61-aa5e-4e5e-8401-39edeba8b83b"), i);
 
     http::CURLSession cs;
-    const failable<value> id = http::post(a, uri, cs);
+    const failable<value> id = http::post(a, memcacheuri, cs);
     assert(hasContent(id));
     const string p = path(content(id));
 
@@ -121,7 +130,8 @@ bool testGetPerf() {
 int main() {
     tuscany::cout << "Testing..." << tuscany::endl;
 
-    tuscany::cache::testCache();
+    tuscany::cache::testMemcache();
+    tuscany::cache::testFrontcache();
     tuscany::cache::testGetPerf();
 
     tuscany::cout << "OK" << tuscany::endl;

Added: tuscany/sca-cpp/trunk/components/cache/frontcache.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/frontcache.cpp?rev=985799&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/frontcache.cpp (added)
+++ tuscany/sca-cpp/trunk/components/cache/frontcache.cpp Mon Aug 16 06:15:24 2010
@@ -0,0 +1,125 @@
+/*
+ * 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$ */
+
+/**
+ * A front cache component implementation which coordinates access to two
+ * levels of backend read/write caches or stores. Each cache or store is
+ * accessed through two references: a writer reference and a reader reference.
+ *
+ * This is useful if your level2 store is made of a master and slave
+ * replicated databases, you can then wire the writer reference to the master
+ * database and the reader reference to one your slave databases (assuming
+ * that the updates eventually get replicated to the slave database,in the
+ * meantime the updates will be retrieved from the level1 cache).
+ */
+
+#include "string.hpp"
+#include "function.hpp"
+#include "list.hpp"
+#include "value.hpp"
+#include "monad.hpp"
+
+namespace tuscany {
+namespace frontcache {
+
+/**
+ * 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) {
+
+    // Lookup level1 cache
+    const value val1 = rcache1(mklist<value>("get", key));
+    if (!isNil(val1))
+        return val1;
+
+    // Lookup level2 cache
+    const value val2 = rcache2(mklist<value>("get", key));
+    if (isNil(val2))
+        return mkfailure<value>("Couldn't get cache entry");
+
+    // Update level1 cache
+    wcache1(mklist<value>("put", key, val2));
+
+    return val2;
+}
+
+/**
+ * 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 value id = append<value>(key, mklist(mkuuid()));
+
+    // Update level1 cache
+    wcache1(mklist<value>("put", id, val));
+
+    // Update level2 cache
+    wcache2(mklist<value>("put", id, val));
+
+    return id;
+}
+
+/**
+ * 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) {
+
+    // Update level1 cache
+    wcache1(mklist<value>("put", key, val));
+
+    // Update level2 cache
+    wcache2(mklist<value>("put", key, val));
+
+    return value(true);
+}
+
+/**
+ * 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) {
+
+    // Delete from level1 cache
+    wcache1(mklist<value>("delete", key));
+
+    // Delete from level2 cache
+    wcache2(mklist<value>("delete", key));
+
+    return value(true);
+}
+
+}
+}
+
+extern "C" {
+
+const tuscany::value apply(const tuscany::list<tuscany::value>& params) {
+    const tuscany::value func(car(params));
+    if (func == "get")
+        return tuscany::frontcache::get(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params));
+    if (func == "post")
+        return tuscany::frontcache::post(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params));
+    if (func == "put")
+        return tuscany::frontcache::put(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params), caddddddr(params));
+    if (func == "delete")
+        return tuscany::frontcache::del(cadr(params), caddr(params), cadddr(params), caddddr(params), cadddddr(params));
+    return tuscany::mkfailure<tuscany::value>();
+}
+
+}

Modified: tuscany/sca-cpp/trunk/components/cache/memcache.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcache.composite?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcache.composite (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcache.composite Mon Aug 16 06:15:24 2010
@@ -28,6 +28,25 @@
             <t:binding.http uri="memcache"/>
         </service>
         <property name="servers">localhost,localhost:11212,localhost:11213</property>
-    </component>     
+    </component>
+
+    <component name="l2cache">
+        <implementation.cpp path="." library="libmemcache"/>
+        <service name="l2cache">
+            <t:binding.http uri="l2cache"/>
+        </service>
+        <property name="servers">localhost:11411,localhost:11412,localhost:11413</property>
+    </component>
+
+    <component name="frontcache">
+        <implementation.cpp path="." library="libfrontcache"/>
+        <service name="frontcache">
+            <t:binding.http uri="frontcache"/>
+        </service>
+        <reference name="l1reader" target="memcache"/>
+        <reference name="l1writer" target="memcache"/>
+        <reference name="l2reader" target="l2cache"/>
+        <reference name="l2writer" target="l2cache"/>
+    </component>
 
 </composite>

Modified: tuscany/sca-cpp/trunk/components/cache/memcache.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcache.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcache.cpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcache.cpp Mon Aug 16 06:15:24 2010
@@ -23,10 +23,7 @@
  * Memcached-based cache component implementation.
  */
 
-#include <apr_uuid.h>
-
 #include "string.hpp"
-
 #include "function.hpp"
 #include "list.hpp"
 #include "value.hpp"
@@ -46,16 +43,8 @@ const failable<value> get(const list<val
 /**
  * Post an item to the cache.
  */
-const value uuidValue() {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return value(string(buf, APR_UUID_FORMATTED_LENGTH));
-}
-
 const failable<value> post(const list<value>& params, memcache::MemCached& ch) {
-    const value id = append<value>(car(params), mklist(uuidValue()));
+    const value id = append<value>(car(params), mklist(mkuuid()));
     const failable<bool> val = memcache::post(id, cadr(params), ch);
     if (!hasContent(val))
         return mkfailure<value>(reason(val));

Modified: tuscany/sca-cpp/trunk/components/cache/memcache.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/memcache.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/memcache.hpp (original)
+++ tuscany/sca-cpp/trunk/components/cache/memcache.hpp Mon Aug 16 06:15:24 2010
@@ -91,10 +91,10 @@ private:
         apr_memcache_server_t *server;
         const apr_status_t sc = apr_memcache_server_create(pool, c_str(host), (apr_port_t)port, 1, 1, 1, 600, &server);
         if (sc != APR_SUCCESS)
-            return mkfailure<bool>("Could not create server");
+            return mkfailure<bool>("Could not create memcached server");
         const apr_status_t as = apr_memcache_add_server(mc, server);
         if (as != APR_SUCCESS)
-            return mkfailure<bool>("Could not add server");
+            return mkfailure<bool>("Could not add memcached server");
         return true;
     }
 
@@ -131,7 +131,7 @@ const failable<bool> post(const value& k
     const string vs(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)
-        return mkfailure<bool>("Could not add entry");
+        return mkfailure<bool>("Could not add memcached entry");
 
     debug(true, "memcache::post::result");
     return true;
@@ -148,7 +148,7 @@ const failable<bool> put(const value& ke
     const string vs(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)
-        return mkfailure<bool>("Could not set entry");
+        return mkfailure<bool>("Could not set memcached entry");
 
     debug(true, "memcache::put::result");
     return true;
@@ -164,9 +164,8 @@ const failable<value> get(const value& k
     char *data;
     apr_size_t size;
     const apr_status_t rc = apr_memcache_getp(cache.mc, cache.pool, nospaces(c_str(ks)), &data, &size, NULL);
-    if (rc != APR_SUCCESS) {
-        return mkfailure<value>("Could not get entry");
-    }
+    if (rc != APR_SUCCESS)
+        return mkfailure<value>("Could not get memcached entry");
     const value val(scheme::readValue(string(data, size)));
 
     debug(val, "memcache::get::result");
@@ -182,7 +181,7 @@ const failable<bool> del(const value& ke
     const string ks(scheme::writeValue(key));
     const apr_status_t rc = apr_memcache_delete(cache.mc, nospaces(c_str(ks)), 0);
     if (rc != APR_SUCCESS)
-        return mkfailure<bool>("Could not delete entry");
+        return mkfailure<bool>("Could not delete memcached entry");
 
     debug(true, "memcache::delete::result");
     return true;

Modified: tuscany/sca-cpp/trunk/components/cache/server-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/cache/server-test?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/cache/server-test (original)
+++ tuscany/sca-cpp/trunk/components/cache/server-test Mon Aug 16 06:15:24 2010
@@ -29,6 +29,9 @@ EOF
 ./memcached-start 11211
 ./memcached-start 11212
 ./memcached-start 11213
+./memcached-start 11411
+./memcached-start 11412
+./memcached-start 11413
 ../../modules/http/httpd-start tmp
 sleep 2
 
@@ -41,5 +44,8 @@ rc=$?
 ./memcached-stop 11211
 ./memcached-stop 11212
 ./memcached-stop 11213
+./memcached-stop 11411
+./memcached-stop 11412
+./memcached-stop 11413
 sleep 2
 return $rc

Modified: tuscany/sca-cpp/trunk/components/chat/xmpp.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/chat/xmpp.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/chat/xmpp.hpp (original)
+++ tuscany/sca-cpp/trunk/components/chat/xmpp.hpp Mon Aug 16 06:15:24 2010
@@ -26,8 +26,6 @@
  * XMPP support functions.
  */
 
-#include <apr_uuid.h>
-
 #include "strophe.h"
 extern "C" {
 #include "common.h"
@@ -64,18 +62,10 @@ private:
 /**
  * Represents an XMPP client.
  */
-const string resourceUUID() {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return string(buf, APR_UUID_FORMATTED_LENGTH);
-}
-
 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 + "/" + resourceUUID()));
+        xmpp_conn_set_jid(conn, c_str(jid + "/" + mkuuid()));
         xmpp_conn_set_pass(conn, c_str(pass));
     }
 

Modified: tuscany/sca-cpp/trunk/components/nosqldb/nosqldb.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/nosqldb/nosqldb.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/nosqldb/nosqldb.cpp (original)
+++ tuscany/sca-cpp/trunk/components/nosqldb/nosqldb.cpp Mon Aug 16 06:15:24 2010
@@ -23,10 +23,7 @@
  * TinyCDB-based database component implementation.
  */
 
-#include <apr_uuid.h>
-
 #include "string.hpp"
-
 #include "function.hpp"
 #include "list.hpp"
 #include "value.hpp"
@@ -46,16 +43,8 @@ const failable<value> get(const list<val
 /**
  * Post an item to the database.
  */
-const value uuidValue() {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return value(string(buf, APR_UUID_FORMATTED_LENGTH));
-}
-
 const failable<value> post(const list<value>& params, tinycdb::TinyCDB& cdb) {
-    const value id = append<value>(car(params), mklist(uuidValue()));
+    const value id = append<value>(car(params), mklist(mkuuid()));
     const failable<bool> val = tinycdb::post(id, cadr(params), cdb);
     if (!hasContent(val))
         return mkfailure<value>(reason(val));

Modified: tuscany/sca-cpp/trunk/components/nosqldb/tinycdb.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/nosqldb/tinycdb.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/nosqldb/tinycdb.hpp (original)
+++ tuscany/sca-cpp/trunk/components/nosqldb/tinycdb.hpp Mon Aug 16 06:15:24 2010
@@ -141,13 +141,13 @@ const failable<int> cdbopen(TinyCDB& cdb
     struct stat st;
     const int s = stat(c_str(cdb.name), &st);
     if (s == -1)
-        return mkfailure<int>(string("Couldn't read database stat ") + cdb.name);
+        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)
-            return mkfailure<int>(string("Couldn't open database file ") + cdb.name);
+            return mkfailure<int>(string("Couldn't open tinycdb database file ") + cdb.name);
         debug(cdb.fd, "tinycdb::open::fd");
         cdb.st = st;
         return cdb.fd;
@@ -162,7 +162,7 @@ const failable<int> cdbopen(TinyCDB& cdb
         // Reopen database
         const int newfd = open(c_str(cdb.name), O_RDONLY);
         if (newfd == -1)
-            return mkfailure<int>(string("Couldn't open database file ") + cdb.name);
+            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;
@@ -171,7 +171,7 @@ const failable<int> cdbopen(TinyCDB& cdb
 
         // We got a different fd, dup it to the current fd then close it
         if (fcntl(newfd, F_DUPFD, cdb.fd) == -1)
-            return mkfailure<int>(string("Couldn't dup database file handle ") + cdb.name);
+            return mkfailure<int>(string("Couldn't dup tinycdb database file handle ") + cdb.name);
         close(newfd);
 
         debug(cdb.fd, "tinycdb::open::fd");
@@ -212,9 +212,9 @@ const failable<bool> rewrite(const lambd
     // Read the db header
     unsigned int pos = 0;
     if (lseek(fd, 0, SEEK_SET) != 0)
-        return mkfailure<bool>("Could not seek to database start");
+        return mkfailure<bool>("Could not seek to tinycdb database start");
     if (::read(fd, buf, 2048) != 2048)
-        return mkfailure<bool>("Could not read database header");
+        return mkfailure<bool>("Could not read tinycdb database header");
     pos += 2048;
     unsigned int eod = cdb_unpack(buf);
     debug(pos, "tinycdb::rewrite::eod");
@@ -222,9 +222,9 @@ const failable<bool> rewrite(const lambd
     // Read and add the existing entries
     while(pos < eod) {
         if (eod - pos < 8)
-            return mkfailure<bool>("Invalid database format, couldn't read entry header");
+            return mkfailure<bool>("Invalid tinycdb database format, couldn't read entry header");
         if (::read(fd, buf, 8) != 8)
-            return mkfailure<bool>("Couldn't read entry header");
+            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);
@@ -233,9 +233,9 @@ const failable<bool> rewrite(const lambd
         // Read existing entry
         buf = mkbuffer(buf, elen);
         if (eod - pos < elen)
-            return mkfailure<bool>("Invalid database format, couldn't read entry");
+            return mkfailure<bool>("Invalid tinycdb database format, couldn't read entry");
         if ((unsigned int)::read(fd, buf, elen) != elen)
-            return mkfailure<bool>("Couldn't read entry");
+            return mkfailure<bool>("Couldn't read tinycdb entry");
         pos += elen;
 
         // Apply the update function to the entry
@@ -251,10 +251,10 @@ const failable<bool> rewrite(const lambd
 
         // Add the entry to the new db
         if (cdb_make_add(&cdbm, buf, klen, ((unsigned char*)buf)+klen, vlen) == -1)
-            return mkfailure<bool>("Could not add entry");
+            return mkfailure<bool>("Could not add tinycdb entry");
     }
     if (pos != eod)
-        return mkfailure<bool>("Invalid database format");
+        return mkfailure<bool>("Invalid tinycdb database format");
 
     // Call the finish function
     const failable<bool> f = finish(cdbm);
@@ -263,7 +263,7 @@ const failable<bool> rewrite(const lambd
 
     // Save the new db
     if (cdb_make_finish(&cdbm) == -1)
-        return mkfailure<bool>("Could not save database");
+        return mkfailure<bool>("Could not save tinycdb database");
 
     return true;
 }
@@ -274,7 +274,7 @@ const failable<bool> rewrite(const lambd
     string tmpname = dbname(cdb) + ".XXXXXX";
     int tmpfd = mkstemp(const_cast<char*>(c_str(tmpname)));
     if (tmpfd == -1)
-        return mkfailure<bool>("Could not create temporary database");
+        return mkfailure<bool>("Could not create temporary tinycdb database");
 
     // Rewrite the db, apply the update function to each entry
     buffer buf = mkbuffer(2048);
@@ -287,7 +287,7 @@ const failable<bool> rewrite(const lambd
 
     // Atomically replace the db and reopen it in read mode
     if (rename(c_str(tmpname), c_str(dbname(cdb))) == -1)
-        return mkfailure<bool>("Could not rename temporary database");
+        return mkfailure<bool>("Could not rename temporary tinycdb database");
     cdbclose(cdb);
     failable<int> ffd = cdbopen(cdb);
     if (!hasContent(ffd))
@@ -305,7 +305,7 @@ struct postUpdate {
     }
     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");
+            return mkfailure<bool>("Key already exists in tinycdb database");
         return true;
     }
 };
@@ -317,7 +317,7 @@ struct postFinish {
     }
     const failable<bool> operator()(struct cdb_make& cdbm) const {
         if (cdb_make_add(&cdbm, c_str(ks), length(ks), c_str(vs), length(vs)) == -1)
-            return mkfailure<bool>("Could not add entry");
+            return mkfailure<bool>("Could not add tinycdb entry");
         return true;
     }
 };
@@ -363,7 +363,7 @@ struct putFinish {
     }
     const failable<bool> operator()(struct cdb_make& cdbm) const {
         if (cdb_make_add(&cdbm, c_str(ks), length(ks), c_str(vs), length(vs)) == -1)
-            return mkfailure<bool>("Could not add entry");
+            return mkfailure<bool>("Could not add tinycdb entry");
         return true;
     }
 };
@@ -404,7 +404,7 @@ const failable<value> get(const value& k
 
     cdbi_t vlen;
     if (cdb_seek(fd, c_str(ks), length(ks), &vlen) <= 0)
-        return mkfailure<value>("Could not get entry");
+        return mkfailure<value>("Could not get tinycdb entry");
     char* data = gc_cnew(vlen + 1);
     cdb_bread(fd, data, vlen);
     data[vlen] = '\0';

Modified: tuscany/sca-cpp/trunk/components/sqldb/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/Makefile.am?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/Makefile.am Mon Aug 16 06:15:24 2010
@@ -22,7 +22,7 @@ INCLUDES = -I${PGSQL_INCLUDE}
 incl_HEADERS = *.hpp
 incldir = $(prefix)/include/components/sqldb
 
-dist_comp_SCRIPTS = pgsql-start pgsql-stop pgsql
+dist_comp_SCRIPTS = pgsql-conf pgsql-start pgsql-stop pgsql pgsql-standby-conf
 compdir=$(prefix)/components/sqldb
 
 comp_DATA = pgsql.prefix
@@ -42,11 +42,14 @@ libsqldb.so:
 pgsql_test_SOURCES = pgsql-test.cpp
 pgsql_test_LDFLAGS = -L${PGSQL_LIB} -R${PGSQL_LIB} -lpq
 
+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
 
-dist_noinst_SCRIPTS = sqldb-test server-test
-noinst_PROGRAMS = pgsql-test client-test
-TESTS = sqldb-test server-test
+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
 
 endif

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql Mon Aug 16 06:15:24 2010
@@ -21,5 +21,15 @@
 here=`readlink -f $0`; here=`dirname $here`
 pgsql_prefix=`cat $here/pgsql.prefix`
 
-$pgsql_prefix/bin/psql -c "$1" db
+if [ "$2" = "" ]; then
+    host="localhost"
+    port="5432"
+    cmd="$1"
+else
+    host="$1"
+    port="$2"
+    cmd="$3"
+fi
+
+$pgsql_prefix/bin/psql -h $host -p $port -c "$cmd" db
 

Copied: tuscany/sca-cpp/trunk/components/sqldb/pgsql-backup (from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-start)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-backup?p2=tuscany/sca-cpp/trunk/components/sqldb/pgsql-backup&p1=tuscany/sca-cpp/trunk/components/sqldb/pgsql-start&r1=985561&r2=985799&rev=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-start (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-backup Mon Aug 16 06:15:24 2010
@@ -17,21 +17,25 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Start postgresql
+# Backup postgresql data directory
 here=`readlink -f $0`; here=`dirname $here`
 root=`readlink -f $1`
 
-pgsql_prefix=`cat $here/pgsql.prefix`
-mkdir -p $root/sqldb
-mkdir -p $root/logs
-if [ ! -f $root/sqldb/postgresql.conf ]; then
-    $pgsql_prefix/bin/pg_ctl init -D $root/sqldb 1>/dev/null 2>&1
-    createdb="true"
+if [ "$2" = "" ]; then
+    host="localhost"
+    port="5432"
+else
+    host="$2"
+    port="$3"
 fi
 
-$pgsql_prefix/bin/pg_ctl start -D $root/sqldb -l $root/logs/postgresql 1>/dev/null 2>&1
-sleep 2
-if [ "$createdb" = "true" ]; then
-    $pgsql_prefix/bin/createdb db 1>/dev/null 2>&1
-fi
+pgsql_prefix=`cat $here/pgsql.prefix`
+$pgsql_prefix/bin/psql -h $host -p $port -c "SELECT pg_start_backup('backup', true)" db 1>>$root/logs/postgresql 2>&1
+
+echo "Content-type: application/x-compressed"
+echo
+
+tar -C $root/sqldb -cz data
+
+$pgsql_prefix/bin/psql -h $host -p $port -c "SELECT pg_stop_backup()" db 1>>$root/logs/postgresql 2>&1
 

Added: tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf?rev=985799&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf (added)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf Mon Aug 16 06:15:24 2010
@@ -0,0 +1,105 @@
+#!/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.
+
+# Configure a postgresql master server
+here=`readlink -f $0`; here=`dirname $here`
+mkdir -p $1
+root=`readlink -f $1`
+
+addr=$2
+if [ "$addr" = "" ]; then
+    ip="*"
+    port="5432"
+else
+    ip=`$here/../../modules/http/httpd-addr ip $addr`
+    if [ "$ip" = "" ]; then
+        ip="*"
+    fi
+    port=`$here/../../modules/http/httpd-addr port $addr`
+fi
+
+pgsql_prefix=`cat $here/pgsql.prefix`
+mkdir -p $root/sqldb/data
+chmod 700 $root/sqldb/data
+mkdir -p $root/sqldb/archive
+mkdir -p $root/logs
+if [ ! -f $root/sqldb/data/postgresql.conf ]; then
+    $pgsql_prefix/bin/pg_ctl init -D $root/sqldb/data 1>>$root/logs/postgresql 2>&1
+    cp $root/sqldb/data/postgresql.conf $root/sqldb/data/postgresql-init.conf
+    cp $root/sqldb/data/pg_hba.conf $root/sqldb/data/pg_hba-init.conf
+fi
+
+# Generate server configuration
+cp $root/sqldb/data/postgresql-init.conf $root/sqldb/data/postgresql.conf
+cat >>$root/sqldb/data/postgresql.conf <<EOF
+
+# Generated by: pgsql-conf $*
+
+# Listen
+listen_addresses = '$ip'
+port = $port
+
+# Setup archival
+archive_mode = on
+archive_command = 'cp %p $root/sqldb/archive/%f'
+
+# Setup hot standby with streaming replication
+wal_level = hot_standby
+max_wal_senders = 5
+wal_keep_segments = 32
+
+EOF
+
+# Generate client auth configuration
+cp $root/sqldb/data/pg_hba-init.conf $root/sqldb/data/pg_hba.conf
+cat >>$root/sqldb/data/pg_hba.conf <<EOF
+
+# Generated by: pgsql-conf $*
+# TYPE  DATABASE        USER            CIDR-ADDRESS            METHOD
+host    all             all             samenet                 trust
+host    replication     all             samenet                 trust
+
+EOF
+
+# Create the db
+$pgsql_prefix/bin/pg_ctl start -w -D $root/sqldb/data -l $root/logs/postgresql 1>>$root/logs/postgresql 2>&1
+$pgsql_prefix/bin/createdb -h localhost -p $port db 1>>$root/logs/postgresql 2>&1
+$pgsql_prefix/bin/pg_ctl stop -w -D $root/sqldb/data 1>>$root/logs/postgresql 2>&1
+
+# Generate database backup script
+mkdir -p $root/sqldb/scripts
+cat >$root/sqldb/scripts/backup <<EOF
+#!/bin/sh
+$here/pgsql-backup $root localhost $port
+EOF
+chmod 700 $root/sqldb/scripts/backup
+
+# Configure HTTPD to serve backup and archive files
+if [ -f "$root/conf/httpd.conf" ]; then
+    cat >>$root/conf/httpd.conf <<EOF
+# Generated by: pgsql-conf $*
+
+# Serve PostgreSQL backup and WAL archive files
+ScriptAlias /pgsql-backup "$root/sqldb/scripts/backup"
+Alias /pgsql-archive "$root/sqldb/archive"
+
+EOF
+
+fi
+

Propchange: tuscany/sca-cpp/trunk/components/sqldb/pgsql-conf
------------------------------------------------------------------------------
    svn:executable = *

Added: tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf?rev=985799&view=auto
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf (added)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf Mon Aug 16 06:15:24 2010
@@ -0,0 +1,122 @@
+#!/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.
+
+# Configure a postgresql hot standby server
+here=`readlink -f $0`; here=`dirname $here`
+mkdir -p $1
+root=`readlink -f $1`
+
+# Master server address
+if [ "$2" = "" ]; then
+    mhost="localhost"
+    mport="5432"
+    mhttpport="80"
+else
+    mhost="$2"
+    mport="$3"
+    mhttpport="$4"
+fi
+
+# Server address
+addr=$5
+if [ "$addr" = "" ]; then
+    ip="*"
+    port="5432"
+else
+    ip=`$here/../../modules/http/httpd-addr ip $addr`
+    if [ "$ip" = "" ]; then
+        ip="*"
+    fi
+    port=`$here/../../modules/http/httpd-addr port $addr`
+fi
+
+pgsql_prefix=`cat $here/pgsql.prefix`
+mkdir -p $root/sqldb/data
+chmod 700 $root/sqldb/data
+mkdir -p $root/sqldb/archive
+mkdir -p $root/logs
+
+# Initialize from a backup of the master
+if [ ! -f $root/sqldb/data/postgresql.conf ]; then
+    (wget http://$mhost:$mhttpport/pgsql-backup -O - | tar -C $root/sqldb -xz) 1>>$root/logs/postgresql 2>&1
+    rm -rf $root/sqldb/data/postmaster.pid $root/sqldb/data/pg_xlog
+    mkdir -p $root/sqldb/data/pg_xlog/archive_status
+    chmod 700 $root/sqldb/data/pg_xlog/archive_status
+fi
+
+# Generate server configuration
+cp $root/sqldb/data/postgresql-init.conf $root/sqldb/data/postgresql.conf
+cat >>$root/sqldb/data/postgresql.conf <<EOF
+
+# Generated by: standby-conf $*
+
+# Listen
+listen_addresses = '$ip'
+port = $port
+
+# Setup archival
+archive_mode = on
+archive_command = 'cp %p $root/sqldb/archive/%f'
+
+# Setup hot standby with streaming replication
+wal_level = hot_standby
+max_wal_senders = 5
+wal_keep_segments = 32
+
+# Enable hot standby
+hot_standby = on
+
+EOF
+
+# Generate recovery configuration
+cat >$root/sqldb/data/recovery.conf << EOF
+# Generated by: pgsql-slave-conf $*
+
+# Start in standby mode
+standby_mode = 'on'
+primary_conninfo = 'host=$mhost port=$mport'
+
+# Failover
+trigger_file = '$root/sqldb/failover'
+
+restore_command = 'wget http://$mhost:$mhttpport/pgsql-archive/%f -O "%p"'
+
+EOF
+
+# Generate database backup script
+mkdir -p $root/sqldb/scripts
+cat >$root/sqldb/scripts/backup <<EOF
+#!/bin/sh
+$here/pgsql-backup $root localhost $port
+EOF
+chmod 700 $root/sqldb/scripts/backup
+
+# Configure HTTPD to serve backup and archive files
+if [ -f "$root/conf/httpd.conf" ]; then
+    cat >>$root/conf/httpd.conf <<EOF
+# Generated by: pgsql-conf $*
+
+# Serve PostgreSQL backup and WAL archive files
+ScriptAlias /pgsql-backup "$root/sqldb/scripts/backup"
+Alias /pgsql-archive "$root/sqldb/archive"
+
+EOF
+
+fi
+

Propchange: tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-conf
------------------------------------------------------------------------------
    svn:executable = *

Added: tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test?rev=985799&view=auto
==============================================================================
Files tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test (added) and tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test Mon Aug 16 06:15:24 2010 differ

Propchange: tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test
------------------------------------------------------------------------------
    svn:executable = *

Copied: tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp (from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp?p2=tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp&p1=tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp&r1=985561&r2=985799&rev=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-standby-test.cpp Mon Aug 16 06:15:24 2010
@@ -20,7 +20,7 @@
 /* $Rev$ $Date$ */
 
 /**
- * Test PostgreSQL access functions.
+ * Test PostgreSQL hot standby support.
  */
 
 #include <assert.h>
@@ -33,15 +33,19 @@ namespace tuscany {
 namespace pgsql {
 
 bool testPGSql() {
-    PGSql pg("dbname=db", "test");
+    PGSql wpg("host=localhost port=5432 dbname=db", "test");
+    PGSql rpg("host=localhost port=5433 dbname=db", "test");
     const value k = mklist<value>("a");
 
-    assert(hasContent(post(k, string("AAA"), pg)));
-    assert((get(k, pg)) == value(string("AAA")));
-    assert(hasContent(put(k, string("aaa"), pg)));
-    assert((get(k, pg)) == value(string("aaa")));
-    assert(hasContent(del(k, pg)));
-    assert(!hasContent(get(k, pg)));
+    assert(hasContent(post(k, string("AAA"), wpg)));
+    sleep(1);
+    assert((get(k, rpg)) == value(string("AAA")));
+    assert(hasContent(put(k, string("aaa"), wpg)));
+    sleep(1);
+    assert((get(k, rpg)) == value(string("aaa")));
+    assert(hasContent(del(k, wpg)));
+    sleep(1);
+    assert(!hasContent(get(k, rpg)));
 
     return true;
 }
@@ -59,10 +63,12 @@ struct getLoop {
 
 bool testGetPerf() {
     const value k = mklist<value>("c");
-    PGSql pg("dbname=db", "test");
-    assert(hasContent(post(k, string("CCC"), pg)));
+    PGSql wpg("host=localhost port=5432 dbname=db", "test");
+    PGSql rpg("host=localhost port=5433 dbname=db", "test");
+    assert(hasContent(post(k, string("CCC"), wpg)));
+    sleep(1);
 
-    const lambda<bool()> gl = getLoop(k, pg);
+    const lambda<bool()> gl = getLoop(k, rpg);
     cout << "PGSql get test " << time(gl, 5, 200) << " ms" << endl;
     return true;
 }

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql-start
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-start?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-start (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-start Mon Aug 16 06:15:24 2010
@@ -24,14 +24,6 @@ root=`readlink -f $1`
 pgsql_prefix=`cat $here/pgsql.prefix`
 mkdir -p $root/sqldb
 mkdir -p $root/logs
-if [ ! -f $root/sqldb/postgresql.conf ]; then
-    $pgsql_prefix/bin/pg_ctl init -D $root/sqldb 1>/dev/null 2>&1
-    createdb="true"
-fi
-
-$pgsql_prefix/bin/pg_ctl start -D $root/sqldb -l $root/logs/postgresql 1>/dev/null 2>&1
-sleep 2
-if [ "$createdb" = "true" ]; then
-    $pgsql_prefix/bin/createdb db 1>/dev/null 2>&1
-fi
+$pgsql_prefix/bin/pg_ctl start -w -D $root/sqldb/data -l $root/logs/postgresql 1>>$root/logs/postgresql 2>&1
+sleep 1
 

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop Mon Aug 16 06:15:24 2010
@@ -22,7 +22,6 @@ here=`readlink -f $0`; here=`dirname $he
 root=`readlink -f $1`
 
 pgsql_prefix=`cat $here/pgsql.prefix`
-mkdir -p $root/sqldb
 mkdir -p $root/logs
-$pgsql_prefix/bin/pg_ctl stop -D $root/sqldb 1>/dev/null 2>&1
+$pgsql_prefix/bin/pg_ctl stop -w -D $root/sqldb/data 1>>$root/logs/postgresql 2>&1
 

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql-test.cpp Mon Aug 16 06:15:24 2010
@@ -33,7 +33,7 @@ namespace tuscany {
 namespace pgsql {
 
 bool testPGSql() {
-    PGSql pg("dbname=db", "test");
+    PGSql pg("host=localhost port=5432 dbname=db", "test");
     const value k = mklist<value>("a");
 
     assert(hasContent(post(k, string("AAA"), pg)));
@@ -59,7 +59,7 @@ struct getLoop {
 
 bool testGetPerf() {
     const value k = mklist<value>("c");
-    PGSql pg("dbname=db", "test");
+    PGSql pg("host=localhost port=5432 dbname=db", "test");
     assert(hasContent(post(k, string("CCC"), pg)));
 
     const lambda<bool()> gl = getLoop(k, pg);

Modified: tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/pgsql.hpp Mon Aug 16 06:15:24 2010
@@ -40,10 +40,13 @@ namespace pgsql {
 /**
  * Return and clear a Postgres result failure.
  */
-const string pgfailure(PGresult* r) {
-    const string e = PQresultErrorMessage(r);
+const string pgfailure(PGresult* r, PGconn* conn) {
+    const string re = PQresultErrorMessage(r);
     PQclear(r);
-    return e;
+    if (length(re) != 0)
+        return re;
+    const string ce = PQerrorMessage(conn);
+    return ce;
 }
 
 /**
@@ -54,19 +57,23 @@ public:
     PGSql() : owner(false) {
     }
 
-    PGSql(const string& conninfo, const string& table) : owner(true), conninfo(conninfo), table(table) {
-        init();
+    PGSql(const string& conninfo, const string& table) : owner(true), conn(NULL), conninfo(conninfo), table(table) {
+        conn = PQconnectdb(c_str(conninfo));
+        if (PQstatus(conn) != CONNECTION_OK) {
+            mkfailure<bool>(string("Could not connect to postgresql database: ") + PQerrorMessage(conn));
+            return;
+        }
+        setup(true);
     }
 
-    PGSql(const PGSql& c) : owner(false) {
-        conninfo = c.conninfo;
-        conn = c.conn;
-        table = c.table;
+    PGSql(const PGSql& c) : owner(false), conn(c.conn), conninfo(c.conninfo), table(c.table) {
     }
 
     ~PGSql() {
         if (!owner)
             return;
+        if (conn == NULL)
+            return;
         PQfinish(conn);
     }
 
@@ -76,28 +83,37 @@ private:
     string conninfo;
     string table;
 
+    friend const failable<bool> setup(const PGSql& pgsql);
     friend const failable<bool> post(const value& key, const value& val, const PGSql& pgsql);
     friend const failable<bool> put(const value& key, const value& val, const PGSql& pgsql);
     friend const failable<value> get(const value& key, const PGSql& pgsql);
     friend const failable<bool> del(const value& key, const PGSql& pgsql);
 
     /**
-     * Initialize the database connection
+     * Setup the database connection.
      */
-    const failable<bool> init() {
-        conn = PQconnectdb(c_str(conninfo));
-        if (PQstatus(conn) != CONNECTION_OK)
-            return mkfailure<bool>(string("Could not connect to database: ") + PQerrorMessage(conn));
+    const failable<bool> setup(const bool init) const {
+
+        // Check the status of the connection and reconnect if necessary
+        if (!init) {
+            if (PQstatus(conn) == CONNECTION_OK)
+                return true;
+            debug("pgsql::setup::reset");
+            PQreset(conn);
+            if (PQstatus(conn) != CONNECTION_OK)
+                return mkfailure<bool>(string("Could not reconnect to postgresql database: ") + PQerrorMessage(conn));
+        }
+        debug("pgsql::setup::init");
 
         // 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));
         if (PQresultStatus(kr) != PGRES_TUPLES_OK)
-            return mkfailure<bool>(string("Could not execute column select statement: ") + pgfailure(kr));
+            return mkfailure<bool>(string("Could not execute postgresql column select statement: ") + pgfailure(kr, conn));
         if (PQntuples(kr) != 2) {
             PQclear(kr);
-            return mkfailure<bool>(string("Could not find table key and value column names"));
+            return mkfailure<bool>(string("Could not find postgresql table key and value column names"));
         }
         const string kname = PQgetvalue(kr, 0, 0);
         const string vname = PQgetvalue(kr, 1, 0);
@@ -107,25 +123,25 @@ private:
         {
             PGresult* r = PQprepare(conn, "post", c_str(string("insert into ") + table + string(" values($1, $2);")), 2, NULL);
             if (PQresultStatus(r) != PGRES_COMMAND_OK)
-                return mkfailure<bool>(string("Could not prepare post SQL statement: ") + pgfailure(r));
+                return mkfailure<bool>(string("Could not prepare post postgresql SQL statement: ") + pgfailure(r, conn));
             PQclear(r);
         }
         {
             PGresult* r = PQprepare(conn, "put", c_str(string("update ") + table + string(" set ") + vname + string(" = $2 where ") + kname + string(" = $1;")), 2, NULL);
             if (PQresultStatus(r) != PGRES_COMMAND_OK)
-                return mkfailure<bool>(string("Could not prepare put SQL statement: ") + pgfailure(r));
+                return mkfailure<bool>(string("Could not prepare put postgresql SQL statement: ") + pgfailure(r, conn));
             PQclear(r);
         }
         {
             PGresult* r = PQprepare(conn, "get", c_str(string("select * from ") + table + string(" where ") + kname + string(" = $1;")), 1, NULL);
             if (PQresultStatus(r) != PGRES_COMMAND_OK)
-                return mkfailure<bool>(string("Could not prepare get SQL statement: ") + pgfailure(r));
+                return mkfailure<bool>(string("Could not prepare get postgresql SQL statement: ") + pgfailure(r, conn));
             PQclear(r);
         }
         {
             PGresult* r = PQprepare(conn, "delete", c_str(string("delete from ") + table + string(" where ") + kname + string(" = $1;")), 1, NULL);
             if (PQresultStatus(r) != PGRES_COMMAND_OK)
-                return mkfailure<bool>(string("Could not prepare delete SQL statement: ") + pgfailure(r));
+                return mkfailure<bool>(string("Could not prepare delete postgresql SQL statement: ") + pgfailure(r, conn));
             PQclear(r);
         }
         return true;
@@ -133,6 +149,13 @@ private:
 };
 
 /**
+ * Setup the database connection if necessary.
+ */
+const failable<bool> setup(const PGSql& pgsql) {
+    return pgsql.setup(false);
+}
+
+/**
  * Post a new item to the database.
  */
 const failable<bool> post(const value& key, const value& val, const PGSql& pgsql) {
@@ -140,13 +163,14 @@ const failable<bool> post(const value& k
     debug(val, "pgsql::post::value");
     debug(pgsql.conninfo, "pgsql::post::conninfo");
     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 = PQexecPrepared(pgsql.conn, "post", 2, params, NULL, NULL, 0);
     if (PQresultStatus(r) != PGRES_COMMAND_OK)
-        return mkfailure<bool>(string("Could not execute post SQL statement: ") + pgfailure(r));
+        return mkfailure<bool>(string("Could not execute insert postgresql SQL statement: ") + pgfailure(r, pgsql.conn));
     PQclear(r);
 
     debug(true, "pgsql::post::result");
@@ -161,13 +185,14 @@ const failable<bool> put(const value& ke
     debug(val, "pgsql::put::value");
     debug(pgsql.conninfo, "pgsql::put::conninfo");
     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 = PQexecPrepared(pgsql.conn, "put", 2, params, NULL, NULL, 0);
     if (PQresultStatus(r) != PGRES_COMMAND_OK)
-        return mkfailure<bool>(string("Could not execute put SQL statement: ") + pgfailure(r));
+        return mkfailure<bool>(string("Could not execute update postgresql SQL statement: ") + pgfailure(r, pgsql.conn));
     const string t = PQcmdTuples(r);
     if (t != "0") {
         PQclear(r);
@@ -178,7 +203,7 @@ const failable<bool> put(const value& ke
 
     PGresult* pr = PQexecPrepared(pgsql.conn, "post", 2, params, NULL, NULL, 0);
     if (PQresultStatus(pr) != PGRES_COMMAND_OK)
-        return mkfailure<bool>(string("Could not execute post SQL statement: ") + pgfailure(pr));
+        return mkfailure<bool>(string("Could not execute insert postgresql SQL statement: ") + pgfailure(pr, pgsql.conn));
     PQclear(pr);
 
     debug(true, "pgsql::put::result");
@@ -192,15 +217,16 @@ const failable<value> get(const value& k
     debug(key, "pgsql::get::key");
     debug(pgsql.conninfo, "pgsql::get::conninfo");
     debug(pgsql.table, "pgsql::get::table");
+    setup(pgsql);
 
     const string ks(scheme::writeValue(key));
     const char* params[1] = { c_str(ks) };
     PGresult* r = PQexecPrepared(pgsql.conn, "get", 1, params, NULL, NULL, 0);
     if (PQresultStatus(r) != PGRES_TUPLES_OK)
-        return mkfailure<value>(string("Could not execute get SQL statement: ") + pgfailure(r));
+        return mkfailure<value>(string("Could not execute select postgresql SQL statement: ") + pgfailure(r, pgsql.conn));
     if (PQntuples(r) < 1) {
         PQclear(r);
-        return mkfailure<value>(string("Could not get entry: ") + PQerrorMessage(pgsql.conn));
+        return mkfailure<value>(string("Could not get postgresql entry: ") + PQerrorMessage(pgsql.conn));
     }
     const char* data = PQgetvalue(r, 0, 1);
     const value val(scheme::readValue(string(data)));
@@ -217,12 +243,13 @@ const failable<bool> del(const value& ke
     debug(key, "pgsql::delete::key");
     debug(pgsql.conninfo, "pgsql::delete::conninfo");
     debug(pgsql.table, "pgsql::delete::table");
+    setup(pgsql);
 
     const string ks(scheme::writeValue(key));
     const char* params[1] = { c_str(ks) };
     PGresult* r = PQexecPrepared(pgsql.conn, "delete", 1, params, NULL, NULL, 0);
     if (PQresultStatus(r) != PGRES_COMMAND_OK)
-        return mkfailure<bool>(string("Could not execute delete SQL statement: ") + pgfailure(r));
+        return mkfailure<bool>(string("Could not execute delete postgresql SQL statement: ") + pgfailure(r, pgsql.conn));
     PQclear(r);
 
     debug(true, "pgsql::delete::result");

Modified: tuscany/sca-cpp/trunk/components/sqldb/server-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/server-test?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/server-test (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/server-test Mon Aug 16 06:15:24 2010
@@ -19,6 +19,11 @@
 
 # Setup
 ../../modules/http/httpd-conf tmp localhost 8090 ../../modules/http/htdocs
+./pgsql-conf tmp
+./pgsql-start tmp
+./pgsql "drop table test;" 1>/dev/null 2>&1
+./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1
+
 ../../modules/server/server-conf tmp
 ../../modules/server/scheme-conf tmp
 cat >>tmp/conf/httpd.conf <<EOF
@@ -26,9 +31,6 @@ SCAContribution `pwd`/
 SCAComposite sqldb.composite
 EOF
 
-./pgsql-start tmp
-./pgsql "drop table test;" 1>/dev/null 2>&1
-./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1
 ../../modules/http/httpd-start tmp
 sleep 2
 
@@ -39,5 +41,4 @@ rc=$?
 # Cleanup
 ../../modules/http/httpd-stop tmp
 ./pgsql-stop tmp
-sleep 2
 return $rc

Modified: tuscany/sca-cpp/trunk/components/sqldb/sqldb-test
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/sqldb-test?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/sqldb-test (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/sqldb-test Mon Aug 16 06:15:24 2010
@@ -18,6 +18,7 @@
 #  under the License.
 
 # Setup
+./pgsql-conf tmp
 ./pgsql-start tmp
 ./pgsql "drop table test;" 1>/dev/null 2>&1
 ./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1

Modified: tuscany/sca-cpp/trunk/components/sqldb/sqldb.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/sqldb.composite?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/sqldb.composite (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/sqldb.composite Mon Aug 16 06:15:24 2010
@@ -24,7 +24,7 @@
         
     <component name="sqldb">
         <implementation.cpp path="." library="libsqldb"/>
-        <property name="conninfo">dbname=db</property>
+        <property name="conninfo">host=localhost port=5432 dbname=db</property>
         <property name="table">test</property>
         <service name="sqldb">
             <t:binding.http uri="sqldb"/>

Modified: tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/sqldb.cpp Mon Aug 16 06:15:24 2010
@@ -23,10 +23,7 @@
  * PostgreSQL-based database component implementation.
  */
 
-#include <apr_uuid.h>
-
 #include "string.hpp"
-
 #include "function.hpp"
 #include "list.hpp"
 #include "value.hpp"
@@ -46,16 +43,8 @@ const failable<value> get(const list<val
 /**
  * Post an item to the database.
  */
-const value uuidValue() {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return value(string(buf, APR_UUID_FORMATTED_LENGTH));
-}
-
 const failable<value> post(const list<value>& params, pgsql::PGSql& pg) {
-    const value id = append<value>(car(params), mklist(uuidValue()));
+    const value id = append<value>(car(params), mklist(mkuuid()));
     const failable<bool> val = pgsql::post(id, cadr(params), pg);
     if (!hasContent(val))
         return mkfailure<value>(reason(val));

Copied: tuscany/sca-cpp/trunk/components/sqldb/standby-test (from r985561, tuscany/sca-cpp/trunk/components/sqldb/server-test)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/components/sqldb/standby-test?p2=tuscany/sca-cpp/trunk/components/sqldb/standby-test&p1=tuscany/sca-cpp/trunk/components/sqldb/server-test&r1=985561&r2=985799&rev=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/server-test (original)
+++ tuscany/sca-cpp/trunk/components/sqldb/standby-test Mon Aug 16 06:15:24 2010
@@ -18,26 +18,22 @@
 #  under the License.
 
 # Setup
-../../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 sqldb.composite
-EOF
-
-./pgsql-start tmp
-./pgsql "drop table test;" 1>/dev/null 2>&1
-./pgsql "create table test(key text, value text);" 1>/dev/null 2>&1
-../../modules/http/httpd-start tmp
+../../modules/http/httpd-conf tmp/master localhost 8090 tmp/master/htdocs
+./pgsql-conf tmp/master 5432
+./pgsql-start tmp/master
+./pgsql localhost 5432 "drop table test;" 1>/dev/null 2>&1
+./pgsql localhost 5432 "create table test(key text, value text);" 1>/dev/null 2>&1
+../../modules/http/httpd-start tmp/master
 sleep 2
+./pgsql-standby-conf tmp/standby localhost 5432 8090 5433
+./pgsql-start tmp/standby
 
 # Test
-./client-test 2>/dev/null
+./pgsql-standby-test 2>/dev/null
 rc=$?
 
 # Cleanup
-../../modules/http/httpd-stop tmp
-./pgsql-stop tmp
-sleep 2
+../../modules/http/httpd-stop tmp/master
+./pgsql-stop tmp/standby
+./pgsql-stop tmp/master
 return $rc

Modified: tuscany/sca-cpp/trunk/kernel/list.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/list.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/list.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/list.hpp Mon Aug 16 06:15:24 2010
@@ -313,27 +313,55 @@ template<typename T> const list<T> cdr(c
 }
 
 /**
- * Returns the car of the cdr of a list.
+ * Returns the car of the cdr (the 2nd element) of a list.
  */
 template<typename T> const T cadr(const list<T>& p) {
     return car(cdr(p));
 }
 
 /**
- * Returns the car of the cdr of the cdr of a list.
+ * Returns the 3rd element of a list.
  */
 template<typename T> const T caddr(const list<T>& p) {
     return car(cdr(cdr(p)));
 }
 
 /**
- * Returns the car of the cdr of the cdr of the cdr of a list.
+ * Returns the 4th element of a list.
  */
 template<typename T> const T cadddr(const list<T>& p) {
     return car(cdr(cdr(cdr(p))));
 }
 
 /**
+ * Returns the 5th element of a list.
+ */
+template<typename T> const T caddddr(const list<T>& p) {
+    return car(cdr(cdr(cdr(cdr(p)))));
+}
+
+/**
+ * Returns the 6th element of a list.
+ */
+template<typename T> const T cadddddr(const list<T>& p) {
+    return car(cdr(cdr(cdr(cdr(cdr(p))))));
+}
+
+/**
+ * Returns the 7th element of a list.
+ */
+template<typename T> const T caddddddr(const list<T>& p) {
+    return car(cdr(cdr(cdr(cdr(cdr(cdr(p)))))));
+}
+
+/**
+ * Returns the 8th element of a list.
+ */
+template<typename T> const T cadddddddr(const list<T>& p) {
+    return car(cdr(cdr(cdr(cdr(cdr(cdr(cdr(p))))))));
+}
+
+/**
  * Returns the cdr of a cdr of a list.
  */
 template<typename T> const list<T> cddr(const list<T>& p) {

Modified: tuscany/sca-cpp/trunk/kernel/value.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/kernel/value.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/kernel/value.hpp (original)
+++ tuscany/sca-cpp/trunk/kernel/value.hpp Mon Aug 16 06:15:24 2010
@@ -27,6 +27,7 @@
  */
 
 #include <stdlib.h>
+#include <apr_uuid.h>
 #include "string.hpp"
 #include "sstream.hpp"
 #include "gc.hpp"
@@ -589,5 +590,16 @@ const value path(const list<value>& p) {
     return string("/") + car(p) + path(cdr(p));
 }
 
+/**
+ * Make a uuid value.
+ */
+const value mkuuid() {
+    apr_uuid_t id;
+    apr_uuid_get(&id);
+    char buf[APR_UUID_FORMATTED_LENGTH];
+    apr_uuid_format(buf, &id);
+    return value(string(buf, APR_UUID_FORMATTED_LENGTH));
+}
+
 }
 #endif /* tuscany_value_hpp */

Modified: tuscany/sca-cpp/trunk/modules/http/httpd-conf
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/http/httpd-conf?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/http/httpd-conf (original)
+++ tuscany/sca-cpp/trunk/modules/http/httpd-conf Mon Aug 16 06:15:24 2010
@@ -76,6 +76,7 @@ LoadModule setenvif_module ${modules_pre
 LoadModule log_config_module ${modules_prefix}/modules/mod_log_config.so
 </IfModule>
 LoadModule vhost_alias_module ${modules_prefix}/modules/mod_vhost_alias.so
+LoadModule cgi_module ${modules_prefix}/modules/mod_cgi.so
 
 LoadModule mod_tuscany_ssltunnel $here/libmod_tuscany_ssltunnel.so
 

Modified: tuscany/sca-cpp/trunk/modules/java/eval.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/java/eval.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/java/eval.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/java/eval.hpp Mon Aug 16 06:15:24 2010
@@ -26,7 +26,6 @@
  * Java component implementation evaluation logic.
  */
 #include <jni.h>
-#include <apr_uuid.h>
 
 #include "list.hpp"
 #include "value.hpp"
@@ -292,12 +291,8 @@ jobject JNICALL nativeInvoke(JNIEnv* env
  * of this function as java.util.UUID seems to behave differently with different JDKs.
  */
 jobject JNICALL nativeUUID(JNIEnv* env) {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    string s(buf, APR_UUID_FORMATTED_LENGTH);
-    return env->NewStringUTF(c_str(s));
+    const value uuid = mkuuid();
+    return env->NewStringUTF(c_str(uuid));
 }
 
 /**

Modified: tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp (original)
+++ tuscany/sca-cpp/trunk/modules/scheme/primitive.hpp Mon Aug 16 06:15:24 2010
@@ -26,8 +26,6 @@
  * Script evaluator primitive functions.
  */
 
-#include <apr_general.h>
-#include <apr_uuid.h>
 #include "stream.hpp"
 #include "function.hpp"
 #include "list.hpp"
@@ -144,11 +142,7 @@ const value logProc(const list<value>& a
 }
 
 const value uuidProc(unused const list<value>& args) {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return string(buf, APR_UUID_FORMATTED_LENGTH);
+    return mkuuid();
 }
 
 const value cadrProc(unused const list<value>& args) {

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/Makefile.am Mon Aug 16 06:15:24 2010
@@ -21,7 +21,7 @@ if WANT_OPENID
 if WANT_LOG
 if WANT_QUEUE
 
-dist_sample_SCRIPTS = start stop ssl-start ssl-stop proxy-conf proxy-ssl-conf server-conf server-ssl-conf tunnel-ssl-conf
+dist_sample_SCRIPTS = start stop ssl-start ssl-stop proxy-conf proxy-ssl-conf server-conf server-ssl-conf tunnel-ssl-conf sqldb-master-conf sqldb-standby-conf
 sampledir = $(prefix)/samples/store-cluster
 
 nobase_dist_sample_DATA = htdocs/*.html htdocs/domains/*/*.html domains/*/*.py domains/*/*.composite

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/domains/jane/store.composite Mon Aug 16 06:15:24 2010
@@ -58,15 +58,44 @@
         <t:implementation.python script="currency-converter.py"/>
         <service name="CurrencyConverter">
             <t:binding.jsonrpc uri="currencyConverter"/>
-        </service>        
-    </component>     
+        </service>
+    </component>
 
     <component name="Cache">
-        <implementation.cpp path="../../../../components/cache" library="libmemcache"/>
+        <implementation.cpp path="../../../../components/cache" library="libfrontcache"/>
         <service name="Cache">
             <t:binding.atom uri="cache"/>
         </service>
+        <reference name="l1reader" target="Memcache"/>
+        <reference name="l1writer" target="Memcache"/>
+        <reference name="l2reader" target="Standbydb"/>
+        <reference name="l2writer" target="Masterdb"/>
+    </component>
+
+    <component name="Memcache">
+        <implementation.cpp path="../../../../components/cache" library="libmemcache"/>
+        <service name="Memcache">
+            <t:binding.atom uri="memcache"/>
+        </service>
         <property name="servers">localhost:11211,localhost:11212,localhost:11213</property>
-    </component>     
+    </component>
+
+    <component name="Masterdb">
+        <implementation.cpp path="../../../../components/sqldb" library="libsqldb"/>
+        <property name="conninfo">host=localhost port=5432 dbname=db</property>
+        <property name="table">store</property>
+        <service name="Masterdb">
+            <t:binding.atom uri="masterdb"/>
+        </service>
+    </component>
+
+    <component name="Standbydb">
+        <implementation.cpp path="../../../../components/sqldb" library="libsqldb"/>
+        <property name="conninfo">host=localhost port=5433 dbname=db</property>
+        <property name="table">store</property>
+        <service name="Standbydb">
+            <t:binding.atom uri="standbydb"/>
+        </service>
+    </component>
 
 </composite>

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/domains/joe/store.composite Mon Aug 16 06:15:24 2010
@@ -58,15 +58,44 @@
         <t:implementation.python script="currency-converter.py"/>
         <service name="CurrencyConverter">
             <t:binding.jsonrpc uri="currencyConverter"/>
-        </service>        
-    </component>     
+        </service>
+    </component>
 
     <component name="Cache">
-        <implementation.cpp path="../../../../components/cache" library="libmemcache"/>
+        <implementation.cpp path="../../../../components/cache" library="libfrontcache"/>
         <service name="Cache">
             <t:binding.atom uri="cache"/>
         </service>
+        <reference name="l1reader" target="Memcache"/>
+        <reference name="l1writer" target="Memcache"/>
+        <reference name="l2reader" target="Standbydb"/>
+        <reference name="l2writer" target="Masterdb"/>
+    </component>
+
+    <component name="Memcache">
+        <implementation.cpp path="../../../../components/cache" library="libmemcache"/>
+        <service name="Memcache">
+            <t:binding.atom uri="memcache"/>
+        </service>
         <property name="servers">localhost:11211,localhost:11212,localhost:11213</property>
-    </component>     
+    </component>
+
+    <component name="Masterdb">
+        <implementation.cpp path="../../../../components/sqldb" library="libsqldb"/>
+        <property name="conninfo">host=localhost port=5432 dbname=db</property>
+        <property name="table">store</property>
+        <service name="Masterdb">
+            <t:binding.atom uri="masterdb"/>
+        </service>
+    </component>
+
+    <component name="Standbydb">
+        <implementation.cpp path="../../../../components/sqldb" library="libsqldb"/>
+        <property name="conninfo">host=localhost port=5434 dbname=db</property>
+        <property name="table">store</property>
+        <service name="Standbydb">
+            <t:binding.atom uri="standbydb"/>
+        </service>
+    </component>
 
 </composite>

Copied: tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-master-conf (from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-master-conf?p2=tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-master-conf&p1=tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop&r1=985561&r2=985799&rev=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql-stop (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-master-conf Mon Aug 16 06:15:24 2010
@@ -17,12 +17,19 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Stop postgresql
-here=`readlink -f $0`; here=`dirname $here`
-root=`readlink -f $1`
+root=$1
+port=$2
 
-pgsql_prefix=`cat $here/pgsql.prefix`
-mkdir -p $root/sqldb
-mkdir -p $root/logs
-$pgsql_prefix/bin/pg_ctl stop -D $root/sqldb 1>/dev/null 2>&1
+# Configure a database server
+if [ ! -f $root/sqldb/data/postgresql.conf ]; then
+    create="true"
+else
+    create="false"
+fi
+../../components/sqldb/pgsql-conf $root $port
+if [ "$create" = "true" ]; then
+    ../../components/sqldb/pgsql-start $root
+    ../../components/sqldb/pgsql localhost $port "create table store(key text, value text);" 1>/dev/null 2>&1
+    ../../components/sqldb/pgsql-stop $root
+fi
 

Copied: tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-standby-conf (from r985561, tuscany/sca-cpp/trunk/components/sqldb/pgsql)
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-standby-conf?p2=tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-standby-conf&p1=tuscany/sca-cpp/trunk/components/sqldb/pgsql&r1=985561&r2=985799&rev=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/components/sqldb/pgsql (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/sqldb-standby-conf Mon Aug 16 06:15:24 2010
@@ -17,9 +17,12 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
-# Run SQL command
-here=`readlink -f $0`; here=`dirname $here`
-pgsql_prefix=`cat $here/pgsql.prefix`
+root=$1
+mhost=$2
+mport=$3
+mhttpport=$4
+port=$5
 
-$pgsql_prefix/bin/psql -c "$1" db
+# Configure a standby database server
+../../components/sqldb/pgsql-standby-conf $root $mhost $mport $mhttpport $port
 

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/ssl-stop Mon Aug 16 06:15:24 2010
@@ -20,9 +20,12 @@
 ../../modules/http/httpd-stop tmp/server1
 ../../modules/http/httpd-stop tmp/server2
 ../../modules/http/httpd-stop tmp/server3
+
 ../../modules/http/httpd-stop tmp/proxy1
 ../../modules/http/httpd-stop tmp/proxy2
+
 ../../components/cache/memcached-stop 127.0.0.1:11411
 ../../components/cache/memcached-stop 127.0.0.1:11412
 ../../components/cache/memcached-stop 127.0.0.1:11413
+
 ../../modules/http/httpd-stop tmp/tunnel1

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/start
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/start?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/start (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/start Mon Aug 16 06:15:24 2010
@@ -22,15 +22,25 @@
 ../../components/cache/memcached-start 11212
 ../../components/cache/memcached-start 11213
 
-# Start three app servers
+# Start three app servers, with a master database and
+# two hot standby databases
 ./server-conf tmp/server1 8101
+./sqldb-master-conf tmp/server1 5432
+../../components/sqldb/pgsql-start tmp/server1
 ../../modules/http/httpd-start tmp/server1
+sleep 1
 
 ./server-conf tmp/server2 8102
+./sqldb-standby-conf tmp/server2 localhost 5432 8101 5433
+../../components/sqldb/pgsql-start tmp/server2
 ../../modules/http/httpd-start tmp/server2
+sleep 1
 
 ./server-conf tmp/server3 8103
+./sqldb-standby-conf tmp/server3 localhost 5432 8101 5434
+../../components/sqldb/pgsql-start tmp/server3
 ../../modules/http/httpd-start tmp/server3
+sleep 1
 
 # Start two proxy balancers
 ./proxy-conf tmp/proxy1 8091

Modified: tuscany/sca-cpp/trunk/samples/store-cluster/stop
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cluster/stop?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cluster/stop (original)
+++ tuscany/sca-cpp/trunk/samples/store-cluster/stop Mon Aug 16 06:15:24 2010
@@ -17,11 +17,18 @@
 #  specific language governing permissions and limitations
 #  under the License.
 
+../../components/sqldb/pgsql-stop tmp/server2
+../../components/sqldb/pgsql-stop tmp/server3
+../../components/sqldb/pgsql-stop tmp/server1
+
 ../../modules/http/httpd-stop tmp/server1
 ../../modules/http/httpd-stop tmp/server2
 ../../modules/http/httpd-stop tmp/server3
+
 ../../modules/http/httpd-stop tmp/proxy1
 ../../modules/http/httpd-stop tmp/proxy2
+
 ../../components/cache/memcached-stop 11211
 ../../components/cache/memcached-stop 11212
 ../../components/cache/memcached-stop 11213
+

Modified: tuscany/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp (original)
+++ tuscany/sca-cpp/trunk/samples/store-cpp/shopping-cart.cpp Mon Aug 16 06:15:24 2010
@@ -23,8 +23,6 @@
  * Shopping cart component implementation.
  */
 
-#include <apr_general.h>
-#include <apr_uuid.h>
 #include "string.hpp"
 #include "function.hpp"
 #include "list.hpp"
@@ -42,27 +40,21 @@ const string cartId("1234");
  */
 const list<value> getcart(const value& id, const lambda<value(const list<value>&)> cache) {
     const value cart = cache(mklist<value>("get", mklist<value>(id)));
+    cerr << "cart value: " << cart << "\n";
+    const failable<value> fcart = cart;
+    cerr << "cart fvalue: " << fcart << "\n";
+    cerr << "cart content: " << content(fcart) << "\n";
+    cerr << "cart reason: " << reason(fcart) << "\n";
     if (isNil(cart))
         return value(list<value>());
     return (list<value>)cart;
 }
 
 /**
- * Returns a UUID.
- */
-const value uuid() {
-    apr_uuid_t uuid;
-    apr_uuid_get(&uuid);
-    char buf[APR_UUID_FORMATTED_LENGTH];
-    apr_uuid_format(buf, &uuid);
-    return string(buf, APR_UUID_FORMATTED_LENGTH);
-}
-
-/**
  * Post a new item to the cart. Create a new cart if necessary.
  */
 const failable<value> post(unused const list<value>& collection, const value& item, const lambda<value(const list<value>&)> cache) {
-    const value id(uuid());
+    const value id(mkuuid());
     const list<value> newItem(mklist<value>(car<value>(item), id, caddr<value>(item)));
     const list<value> cart(cons<value>(newItem, getcart(cartId, cache)));
     cache(mklist<value>("put", mklist<value>(cartId), cart));

Modified: tuscany/sca-cpp/trunk/samples/store-sql/ssl-start
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-sql/ssl-start?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-sql/ssl-start (original)
+++ tuscany/sca-cpp/trunk/samples/store-sql/ssl-start Mon Aug 16 06:15:24 2010
@@ -21,6 +21,7 @@
 ../../modules/http/ssl-cert-conf tmp localhost
 ../../modules/http/httpd-conf tmp localhost 8090 htdocs
 ../../modules/http/httpd-ssl-conf tmp 8453
+../../modules/http/httpd-auth-conf tmp
 ../../modules/server/server-conf tmp
 ../../modules/server/scheme-conf tmp
 cat >>tmp/conf/httpd.conf <<EOF
@@ -30,6 +31,8 @@ SCAComposite store.composite
 
 EOF
 
+../../components/cache/memcached-start
+../../components/sqldb/pgsql-conf tmp
 ../../components/sqldb/pgsql-start tmp
 ../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
 ../../modules/http/httpd-start tmp

Modified: tuscany/sca-cpp/trunk/samples/store-sql/start
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-sql/start?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-sql/start (original)
+++ tuscany/sca-cpp/trunk/samples/store-sql/start Mon Aug 16 06:15:24 2010
@@ -27,6 +27,8 @@ SCAComposite store.composite
 
 EOF
 
+../../components/cache/memcached-start
+../../components/sqldb/pgsql-conf tmp
 ../../components/sqldb/pgsql-start tmp
 ../../components/sqldb/pgsql "create table store(key text, value text);" 1>/dev/null 2>&1
 ../../modules/http/httpd-start tmp

Modified: tuscany/sca-cpp/trunk/samples/store-sql/stop
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-sql/stop?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-sql/stop (original)
+++ tuscany/sca-cpp/trunk/samples/store-sql/stop Mon Aug 16 06:15:24 2010
@@ -19,3 +19,4 @@
 
 ../../modules/http/httpd-stop tmp
 ../../components/sqldb/pgsql-stop tmp
+../../components/cache/memcached-stop

Modified: tuscany/sca-cpp/trunk/samples/store-sql/store.composite
URL: http://svn.apache.org/viewvc/tuscany/sca-cpp/trunk/samples/store-sql/store.composite?rev=985799&r1=985798&r2=985799&view=diff
==============================================================================
--- tuscany/sca-cpp/trunk/samples/store-sql/store.composite (original)
+++ tuscany/sca-cpp/trunk/samples/store-sql/store.composite Mon Aug 16 06:15:24 2010
@@ -49,7 +49,7 @@
         <service name="Total">
             <t:binding.jsonrpc uri="total"/>
         </service>        
-        <reference name="cache" target="Sqldb"/>
+        <reference name="cache" target="Cache"/>
     </component>
     
     <component name="CurrencyConverter">
@@ -59,9 +59,28 @@
         </service>        
     </component>     
 
+    <component name="Cache">
+        <implementation.cpp path="../../components/cache" library="libfrontcache"/>
+        <service name="Cache">
+            <t:binding.atom uri="cache"/>
+        </service>
+        <reference name="l1reader" target="Memcache"/>
+        <reference name="l1writer" target="Memcache"/>
+        <reference name="l2reader" target="Sqldb"/>
+        <reference name="l2writer" target="Sqldb"/>
+    </component>     
+
+    <component name="Memcache">
+        <implementation.cpp path="../../components/cache" library="libmemcache"/>
+        <service name="Memcache">
+            <t:binding.atom uri="memcache"/>
+        </service>
+        <property name="servers">localhost:11211</property>
+    </component>     
+
     <component name="Sqldb">
         <implementation.cpp path="../../components/sqldb" library="libsqldb"/>
-        <property name="conninfo">dbname=db</property>
+        <property name="conninfo">host=localhost port=5432 dbname=db</property>
         <property name="table">store</property>
         <service name="Sqldb">
             <t:binding.atom uri="sqldb"/>