Browse Source

Ulib: enable db pipeline (#3873)

* Ulib

* Ulib: enable db pipeline

* Ulib: enable db pipeline

* Ulib: enable db pipeline

* Ulib: enable db pipeline

* Ulib: enable db pipeline

* Ulib: enable db pipeline

* Ulib: avoid misconfigured metadata

* Ulib: remove discussed parts
stefano casazza 7 years ago
parent
commit
7c26c731d4

+ 8 - 8
frameworks/C++/ulib/benchmark_config.json

@@ -7,7 +7,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "None",
       "database": "None",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -24,7 +24,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "None",
       "database": "None",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -41,7 +41,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "None",
       "database": "None",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -58,7 +58,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "None",
       "database": "None",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -79,7 +79,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "MySQL",
       "database": "MySQL",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -100,7 +100,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "Postgres",
       "database": "Postgres",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -120,7 +120,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "Postgres",
       "database": "Postgres",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",
@@ -141,7 +141,7 @@
       "approach": "Realistic",
       "approach": "Realistic",
       "classification": "Platform",
       "classification": "Platform",
       "database": "MongoDB",
       "database": "MongoDB",
-      "framework": "ULib",
+      "framework": "None",
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "None",
       "platform": "None",

+ 9 - 59
frameworks/C++/ulib/src/cached_worlds.usp

@@ -6,11 +6,6 @@ TechEmpower Web Framework Benchmarks
 #include "world.h"
 #include "world.h"
 
 
 static UCache* cache;
 static UCache* cache;
-static World* pworld_query;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_query;
-#endif
 
 
 static void usp_init_cached_worlds()
 static void usp_init_cached_worlds()
 {
 {
@@ -25,12 +20,10 @@ static void usp_init_cached_worlds()
       return;
       return;
       }
       }
 
 
-   U_NEW(World, pworld_query, World);
-
+   World world_query;
    UOrmStatement stmt_query(sql_query, U_CONSTANT_TO_PARAM("SELECT * FROM World"));
    UOrmStatement stmt_query(sql_query, U_CONSTANT_TO_PARAM("SELECT * FROM World"));
 
 
-   stmt_query.into(*pworld_query);
-
+   stmt_query.into(world_query);
    stmt_query.execute();
    stmt_query.execute();
 
 
    // creat and fill the cache
    // creat and fill the cache
@@ -40,67 +33,24 @@ static void usp_init_cached_worlds()
    (void) cache->open(U_STRING_FROM_CONSTANT("/tmp/ULib_cached_worlds.cache"), 10000 * 64, U_NULLPTR, true);
    (void) cache->open(U_STRING_FROM_CONSTANT("/tmp/ULib_cached_worlds.cache"), 10000 * 64, U_NULLPTR, true);
 
 
    do {
    do {
-      cache->add(pworld_query->id, pworld_query->randomNumber);
+      cache->add(world_query.id, world_query.randomNumber);
       }
       }
    while (stmt_query.nextRow());
    while (stmt_query.nextRow());
 
 
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
-#endif
+   World::handlerFork();
 }
 }
 
 
-#ifdef DEBUG
-static void usp_end_cached_worlds()
+static void handlerQuery(uint32_t i)
 {
 {
-   U_TRACE(5, "::usp_end_cached_worlds()")
+   U_TRACE(5, "::handlerQuery(%u)", i)
 
 
-   if (cache)
-      {
-      U_DELETE(cache)
-      U_DELETE(pworld_query)
+   U_INTERNAL_ASSERT_POINTER(cache)
 
 
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_query)
-#  endif
-      }
+   World::rnum = cache->getNumber(World::rnumber[i]);
 }
 }
-#endif
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR('[');
-#endif
-
-while (true)
-   {
-   pworld_query->randomNumber = cache->getNumber((pworld_query->id = u_get_num_random(10000-1)));
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
-#else
-   World* pworld;
-
-   U_NEW(World, pworld, World(*pworld_query));
-
-   pvworld_query->push_back(pworld);
-#endif
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
-#endif
-   }
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR(']');
-#else
-USP_OBJ_JSON_stringify(*pvworld_query);
-pvworld_query->clear();
-#endif
+World::doUpdateNoSql(handlerQuery);
 -->
 -->

+ 22 - 58
frameworks/C++/ulib/src/db.usp

@@ -5,74 +5,38 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World*         pworld_db;
-static UOrmSession*   psql_db;
-static UOrmStatement* pstmt_db;
-
-static void usp_fork_db()
-{
-   U_TRACE(5, "::usp_fork_db()")
-
-   U_NEW(UOrmSession, psql_db, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
-
-   if (psql_db->isReady() == false)
-      {
-      U_WARNING("usp_fork_db(): we cound't connect to db");
-
-      U_DELETE(psql_db)
-
-      psql_db = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW(UOrmStatement, pstmt_db, UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
-
-   U_NEW(World, pworld_db, World);
-
-   pstmt_db->use( pworld_db->id);
-   pstmt_db->into(pworld_db->randomNumber);
-}
-
-#ifdef DEBUG
-static void usp_end_db()
-{
-   U_TRACE(5, "::usp_end_db()")
-
-   if (pstmt_db)
-      {
-      U_DELETE(pstmt_db)
-      U_DELETE(pworld_db)
-      U_DELETE(psql_db)
-      }
-}
-#endif
+static void usp_fork_db() { World::handlerForkSql(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-pworld_db->id = u_get_num_random(10000-1);
+World::initOneResult();
 
 
-pstmt_db->execute();
+World::pworld_query->id = World::rnumber[0];
 
 
-#ifdef AS_cpoll_cppsp_DO
-char* ptr = UClientImage_Base::wbuffer->pend();
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+if (World::pdrv)
+   {
+   World::pstmt->setBindParam();
 
 
-u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
+   PGresult* res = World::pdrv->execPrepared(World::pstmt);
 
 
-ptr = u_num2str32(pworld_db->id, ptr+6);
+   U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 1)
+   U_INTERNAL_ASSERT_EQUALS(PQntuples(res), 1)
 
 
-u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+   char* randomNumber = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, 0, 0);
 
 
-ptr = u_num2str32(pworld_db->randomNumber, ptr+16);
+   World::handlerOneResult(World::pworld_query->id, ntohl(*(uint32_t*)randomNumber));
 
 
-*ptr++ = '}';
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-#else
-USP_OBJ_JSON_stringify(*pworld_db);
+   U_SYSCALL_VOID(PQclear, "%p", res);
+   }
+else
 #endif
 #endif
+{
+(void) World::pstmt_query->execute();
+
+World::handlerOneResult(World::pworld_query->id, World::pworld_query->randomNumber);
+}
+
+World::endOneResult();
 -->
 -->

+ 3 - 48
frameworks/C++/ulib/src/edb.usp

@@ -3,57 +3,12 @@ Test type 2: Single database query
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static char buffer[128];
-static UElasticSearchClient* es;
-
-#define QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
-
-static void usp_fork_edb()
-{
-   U_TRACE(5, "::usp_fork_edb()")
-
-   U_NEW(UElasticSearchClient, es, UElasticSearchClient);
-
-   if (es->connect() == false)
-      {
-      U_WARNING("usp_fork_edb(): connection disabled or failed");
-
-      U_DELETE(es)
-
-      es = U_NULLPTR;
-
-      return;
-      }
-
-   U_MEMCPY(buffer, "{\"query\":{\"match\":{\"_id\":\"", QLEN);
-}
-
-#ifdef DEBUG
-static void usp_end_edb()
-{
-   U_TRACE(5, "::usp_end_edb()")
-
-   if (es) U_DELETE(es)
-}
-#endif
+static void usp_fork_edb() { WorldNoSql::handlerForkElasticSearch(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id;
-UString result;
-
-(void) es->sendPOST(U_CONSTANT_TO_PARAM("/tfb/world/_search"), buffer, u__snprintf(buffer+QLEN, 128, U_CONSTANT_TO_PARAM("%u\"}}}"), id = u_get_num_random(10000-1))+QLEN);
-
-(void) U_JFIND(es->getContent(), "randomNumber", result);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", id, result.rep);
-#else
-World world(id, result.strtoul());
-USP_OBJ_JSON_stringify(world);
-#endif
+WorldNoSql::doOneQuery(WorldNoSql::handlerQueryElasticSearch);
 -->
 -->

+ 3 - 93
frameworks/C++/ulib/src/equery.usp

@@ -3,102 +3,12 @@ Test type 3: Multiple database queries
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static char buffer[128];
-static UElasticSearchClient* es;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_query;
-#endif
-
-#define QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
-
-static void usp_fork_equery()
-{
-   U_TRACE(5, "::usp_fork_equery()")
-
-   U_NEW(UElasticSearchClient, es, UElasticSearchClient);
-
-   if (es->connect() == false)
-      {
-      U_WARNING("usp_fork_equery(): connection disabled or failed");
-
-      U_DELETE(es)
-
-      es = U_NULLPTR;
-
-      return;
-      }
-
-   U_MEMCPY(buffer, "{\"query\":{\"match\":{\"_id\":\"", QLEN);
-
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
-#endif
-}
-
-#ifdef DEBUG
-static void usp_end_equery()
-{
-   U_TRACE(5, "::usp_end_equery()")
-
-   if (es)
-      {
-      U_DELETE(es)
-
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_query)
-#  endif
-      }
-}
-#endif
+static void usp_fork_equery() { WorldNoSql::handlerForkElasticSearch(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id;
-UString rnumber;
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR('[');
-#endif
-
-while (true)
-   {
-   (void) es->sendPOST(U_CONSTANT_TO_PARAM("/tfb/world/_search"), buffer, QLEN+u__snprintf(buffer+QLEN, 128, U_CONSTANT_TO_PARAM("%u\"}}}"), id = u_get_num_random(10000-1)));
-
-   rnumber.clear();
-
-   (void) U_JFIND(es->getContent(), "randomNumber", rnumber);
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", id, rnumber.rep);
-#else
-   World* pworld;
-
-   U_NEW(World, pworld, World(id, rnumber.strtoul()));
-
-   pvworld_query->push_back(pworld);
-#endif
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
-#endif
-
-   rnumber.clear();
-   }
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR(']');
-#else
-USP_OBJ_JSON_stringify(*pvworld_query);
-pvworld_query->clear();
-#endif
+WorldNoSql::doQuery(WorldNoSql::handlerQueryElasticSearch);
 -->
 -->

+ 8 - 90
frameworks/C++/ulib/src/eupdate.usp

@@ -3,108 +3,26 @@ Test type 5: Database updates
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
-
-static char* pbuffer1;
-static char* pbuffer2;
-static char buffer1[128];
-static char buffer2[128];
-static UElasticSearchClient* es;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_update;
-#endif
-
-#define ULEN U_CONSTANT_SIZE("/tfb/world/")
-#define QLEN U_CONSTANT_SIZE("{\"doc\":{\"_id\":\"")
+#include "worldNoSql.h"
 
 
 static void usp_fork_eupdate()
 static void usp_fork_eupdate()
 {
 {
    U_TRACE(5, "::usp_fork_eupdate()")
    U_TRACE(5, "::usp_fork_eupdate()")
 
 
-   U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+   WorldNoSql::handlerForkElasticSearch();
 
 
-   if (es->connect() == false)
+   if (WorldNoSql::es)
       {
       {
-      U_WARNING("usp_fork_eupdate(): connection disabled or failed");
-
-      U_DELETE(es)
+      (void) memcpy(WorldNoSql::es_buffer1,       U_CONSTANT_TO_PARAM("/tfb/world/"));
+      WorldNoSql::pbuffer1 = WorldNoSql::es_buffer1 + U_CONSTANT_SIZE("/tfb/world/");
 
 
-      es = U_NULLPTR;
-
-      return;
+      (void) memcpy(WorldNoSql::es_buffer2,       U_CONSTANT_TO_PARAM("{\"doc\":{\"_id\":\""));
+      WorldNoSql::pbuffer2 = WorldNoSql::es_buffer2 + U_CONSTANT_SIZE("{\"doc\":{\"_id\":\"");
       }
       }
-
-   U_MEMCPY(buffer1, "/tfb/world/", ULEN);
-
-   pbuffer1 = buffer1 + ULEN;
-
-   U_MEMCPY(buffer2, "{\"doc\":{\"_id\":\"", QLEN);
-
-   pbuffer2 = buffer2 + QLEN;
-
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
-#endif
 }
 }
-
-#ifdef DEBUG
-static void usp_end_eupdate()
-{
-   U_TRACE(5, "::usp_end_eupdate()")
-
-   if (es)
-      {
-      U_DELETE(es)
-
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_update)
-#  endif
-      }
-}
-#endif
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t len1, len2, id, rnum;
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR('[');
-#endif
-
-while (true)
-   {
-   len1 = u__snprintf(pbuffer1, 100, U_CONSTANT_TO_PARAM("%u/_update"), id = u_get_num_random(10000-1));
-   len2 = u__snprintf(pbuffer2, 100, U_CONSTANT_TO_PARAM("%u\"}}"),   rnum = u_get_num_random(10000-1));
-
-   (void) es->sendPOST(buffer1, len1+ULEN, buffer2, len2+QLEN);
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", id, rnum);
-#else
-   World* pworld;
-
-   U_NEW(World, pworld, World(id, rnum));
-
-   pvworld_update->push_back(pworld);
-#endif
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
-#endif
-   }
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR(']');
-#else
-USP_OBJ_JSON_stringify(*pvworld_update);
-pvworld_update->clear();
-#endif
+World::doUpdateNoSql(WorldNoSql::handlerUpdateElasticSearch);
 -->
 -->

+ 166 - 16
frameworks/C++/ulib/src/fortune.h

@@ -5,6 +5,14 @@
 
 
 #include <ulib/orm/orm.h>
 #include <ulib/orm/orm.h>
 #include <ulib/json/value.h>
 #include <ulib/json/value.h>
+#include <ulib/utility/uhttp.h>
+#include <ulib/orm/orm_driver.h>
+#include <ulib/utility/xml_escape.h>
+#include <ulib/net/server/client_image.h>
+
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+#  include <ulib/orm/driver/orm_driver_pgsql.h>
+#endif
 
 
 class Fortune {
 class Fortune {
 public:
 public:
@@ -18,14 +26,9 @@ public:
    uint32_t id;
    uint32_t id;
    UString message;
    UString message;
 
 
-   Fortune()
+   Fortune(uint32_t _id) : id(_id), message(101U)
       {
       {
-      U_TRACE_CTOR(5, Fortune, "")
-
-      // coverity[uninit_ctor]
-#  ifdef U_COVERITY_FALSE_POSITIVE
-      id = 0;
-#  endif
+      U_TRACE_CTOR(5, Fortune, "%u", _id)
       }
       }
 
 
    Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
    Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
@@ -33,7 +36,7 @@ public:
       U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
       U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
       }
       }
 
 
-   Fortune(const Fortune& f) : id(f.id), message((void*)U_STRING_TO_PARAM(f.message))
+   Fortune(const Fortune& f) : id(f.id), message(f.message)
       {
       {
       U_TRACE_CTOR(5, Fortune, "%p", &f)
       U_TRACE_CTOR(5, Fortune, "%p", &f)
 
 
@@ -105,21 +108,168 @@ public:
       stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
       stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
       }
       }
 
 
-#ifdef DEBUG
-   const char* dump(bool breset) const
+   static uint32_t uid;
+   static UString* pmessage;
+   static UVector<Fortune*>* pvfortune;
+
+   static UOrmSession*    psql_fortune;
+   static UOrmStatement* pstmt_fortune;
+
+   static void replace(uint32_t i, uint32_t _id, const char* msg, uint32_t len)
+      {
+      U_TRACE(0, "Fortune::replace(%u,%u,%.*S,%u)", i, _id, len, msg, len)
+
+      U_INTERNAL_ASSERT_POINTER(pvfortune)
+
+      Fortune* elem = pvfortune->at(i);
+
+      elem->id = _id;
+
+      UXMLEscape::encode(msg, len, elem->message);
+      }
+
+   static void replace(uint32_t i)                                       { replace(i, uid, U_STRING_TO_PARAM(*pmessage)); }
+   static void replace(uint32_t i, uint32_t _id)                         { replace(i, _id, U_STRING_TO_PARAM(*pmessage)); }
+   static void replace(uint32_t i,               const UString& message) { replace(i, i+1, U_STRING_TO_PARAM(message)); }
+   static void replace(uint32_t i, uint32_t _id, const UString& message) { replace(i, _id, U_STRING_TO_PARAM(message)); }
+
+   static void doQuery(vPF handlerQuery)
+      {
+      U_TRACE(0, "Fortune::doQuery(%p)", handlerQuery)
+
+      U_INTERNAL_ASSERT_POINTER(pvfortune)
+
+      char* pwbuffer = UClientImage_Base::wbuffer->data();
+
+      u_put_unalignedp64(pwbuffer,     U_MULTICHAR_CONSTANT64('<','!','d','o','c','t','y','p'));
+      u_put_unalignedp64(pwbuffer+8,   U_MULTICHAR_CONSTANT64('e',' ','h','t','m','l','>','<'));
+      u_put_unalignedp64(pwbuffer+16,  U_MULTICHAR_CONSTANT64('h','t','m','l','>','<','h','e'));
+      u_put_unalignedp64(pwbuffer+24,  U_MULTICHAR_CONSTANT64('a','d','>','<','t','i','t','l'));
+      u_put_unalignedp64(pwbuffer+32,  U_MULTICHAR_CONSTANT64('e','>','F','o','r','t','u','n'));
+      u_put_unalignedp64(pwbuffer+40,  U_MULTICHAR_CONSTANT64('e','s','<','/','t','i','t','l'));
+      u_put_unalignedp64(pwbuffer+48,  U_MULTICHAR_CONSTANT64('e','>','<','/','h','e','a','d'));
+      u_put_unalignedp64(pwbuffer+56,  U_MULTICHAR_CONSTANT64('>','<','b','o','d','y','>','<'));
+      u_put_unalignedp64(pwbuffer+64,  U_MULTICHAR_CONSTANT64('t','a','b','l','e','>','<','t'));
+      u_put_unalignedp64(pwbuffer+72,  U_MULTICHAR_CONSTANT64('r','>','<','t','h','>','i','d'));
+      u_put_unalignedp64(pwbuffer+80,  U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','t','h'));
+      u_put_unalignedp64(pwbuffer+88,  U_MULTICHAR_CONSTANT64('>','m','e','s','s','a','g','e'));
+      u_put_unalignedp64(pwbuffer+96,  U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','/','t'));
+      u_put_unalignedp16(pwbuffer+104, U_MULTICHAR_CONSTANT16('r','>'));
+
+      pwbuffer += U_CONSTANT_SIZE("<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
+
+      handlerQuery();
+
+      Fortune* elem = pvfortune->last();
+
+      elem->id = 0;
+      elem->message.rep->replace(U_CONSTANT_TO_PARAM("Additional fortune added at request time."));
+
+      pvfortune->sort(Fortune::cmp_obj);
+
+      for (uint32_t sz, i = 0, n = pvfortune->size(); i < n; ++i)
+         {
+         elem = pvfortune->at(i);
+
+         u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','t','r','>','<','t','d','>'));
+
+         pwbuffer = u_num2str32(elem->id, pwbuffer+8);
+
+         u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','t','d'));
+                            pwbuffer += 8;
+
+         *pwbuffer++ = '>';
+
+         (void) memcpy(pwbuffer, elem->message.data(), sz = elem->message.size());
+                       pwbuffer += sz;
+
+         u_put_unalignedp64(pwbuffer,   U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
+         u_put_unalignedp16(pwbuffer+8, U_MULTICHAR_CONSTANT16('r','>'));
+                            pwbuffer += 8+2;
+         }
+
+      u_put_unalignedp64(pwbuffer,    U_MULTICHAR_CONSTANT64('<','/','t','a','b','l','e','>'));
+      u_put_unalignedp64(pwbuffer+8,  U_MULTICHAR_CONSTANT64('<','/','b','o','d','y','>','<'));
+      u_put_unalignedp64(pwbuffer+16, U_MULTICHAR_CONSTANT64('/','h','t','m','l','>','\0','\0'));
+
+      UClientImage_Base::wbuffer->size_adjust(pwbuffer + U_CONSTANT_SIZE("</table></body></html>"));
+
+      UHTTP::mime_index = U_html;
+      }
+
+   static void handlerFork()
       {
       {
-      *UObjectIO::os << "id               " << id              << '\n'
-                     << "message (UString " << (void*)&message << ')';
+      U_TRACE_NO_PARAM(0, "Fortune::handlerFork()")
+
+      U_NEW_STRING(pmessage, UString(101U));
 
 
-      if (breset)
+      U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
+
+      Fortune* elem;
+
+      for (uint32_t i = 0; i < 13; ++i)
          {
          {
-         UObjectIO::output();
+         U_NEW(Fortune, elem, Fortune(i+1));
+
+         pvfortune->push(elem);
+         }
+      }
+
+   static void handlerForkSql()
+      {
+      U_TRACE_NO_PARAM(0, "Fortune::handlerForkSql()")
+
+      if (psql_fortune == U_NULLPTR)
+         {
+         U_NEW(UOrmSession, psql_fortune, UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
+
+         if (psql_fortune->isReady() == false)
+            {
+            U_WARNING("Fortune::handlerForkSql(): we cound't connect to db");
+
+            U_DELETE(psql_fortune)
+
+            psql_fortune = U_NULLPTR;
 
 
-         return UObjectIO::buffer_output;
+            return;
+            }
+
+         U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
+
+         handlerFork();
+
+         pstmt_fortune->into(uid, *pmessage);
          }
          }
+      }
 
 
-      return U_NULLPTR;
+#ifdef DEBUG
+   static void handlerEnd()
+      {
+      U_TRACE_NO_PARAM(0, "Fortune::handlerEnd()")
+
+      U_INTERNAL_ASSERT_POINTER(pmessage)
+      U_INTERNAL_ASSERT_POINTER(pvfortune)
+
+      U_DELETE(pmessage)
+      U_DELETE(pvfortune)
       }
       }
+
+   static void handlerEndSql()
+      {
+      U_TRACE_NO_PARAM(0, "Fortune::handlerEndSql()")
+
+      if (pstmt_fortune)
+         {
+         handlerEnd();
+
+         U_DELETE(psql_fortune)
+         U_DELETE(pstmt_fortune)
+
+         pstmt_fortune = U_NULLPTR;
+         }
+      }
+
+   const char* dump(bool breset) const;
 #endif
 #endif
 
 
 private:
 private:

+ 49 - 84
frameworks/C++/ulib/src/fortune.usp

@@ -5,106 +5,71 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "fortune.h"
 #include "fortune.h"
 
 
-static Fortune*           pfortune;
-static Fortune*           pfortune2add;
-static UString*           pencoded;
-static UOrmSession*       psql_fortune;
-static UOrmStatement*     pstmt_fortune;
-static UVector<Fortune*>* pvfortune;
+static vPF handle_query;
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+static UOrmDriverPgSql* pdrv;
+static UPgSqlStatement* pstmt;
+#endif
 
 
-static void usp_fork_fortune()
+static void handlerQuery()
 {
 {
-   U_TRACE(5, "::usp_fork_fortune()")
-
-   U_NEW(UOrmSession, psql_fortune, UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
-
-   if (psql_fortune->isReady() == false)
-      {
-      U_WARNING("usp_fork_fortune(): we cound't connect to db");
+   U_TRACE_NO_PARAM(5, "::handlerQuery()")
 
 
-      U_DELETE(psql_fortune)
+   uint32_t i = 0;
 
 
-      psql_fortune = U_NULLPTR;
+   Fortune::pstmt_fortune->execute();
 
 
-      return;
+   do {
+      Fortune::replace(i++);
       }
       }
-
-   U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
-
-// if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
-
-   U_NEW(Fortune, pfortune, Fortune);
-
-   pstmt_fortune->into(*pfortune);
-
-   U_NEW_STRING(pencoded, UString(100U));
-   U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
-   U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
+   while (Fortune::pstmt_fortune->nextRow());
 }
 }
 
 
-#ifdef DEBUG
-static void usp_end_fortune()
+static void handlerQueryPGSQL()
 {
 {
-   U_TRACE(5, "::usp_end_fortune()")
-
-   if (pstmt_fortune)
-      {
-      U_DELETE(pstmt_fortune)
-      U_DELETE(pfortune)
-      U_DELETE(pencoded)
-      U_DELETE(pvfortune)
-      U_DELETE(pfortune2add)
-      U_DELETE(psql_fortune)
-      }
-}
-#endif
--->
-<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
-uint32_t sz;
-Fortune* item;
-char* ptr = UClientImage_Base::wbuffer->pend();
-
-U_NEW(Fortune, item, Fortune(*pfortune2add));
+   U_TRACE_NO_PARAM(5, "::handlerQueryPGSQL()")
 
 
-pvfortune->push_back(item);
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+   int sz;
+   char* id;
+   char* ptr;
+   PGresult* res = pdrv->execPrepared(pstmt);
 
 
-pstmt_fortune->execute();
+   U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 2)
 
 
-do {
-   U_NEW(Fortune, item, Fortune(*pfortune));
-
-   pvfortune->push_back(item);
-   }
-while (pstmt_fortune->nextRow());
-
-pvfortune->sort(Fortune::cmp_obj);
-
-for (uint32_t i = 0, n = pvfortune->size(); i < n; ++i)
-   {
-   Fortune* elem = (*pvfortune)[i];
-
-   UXMLEscape::encode(elem->message, *pencoded);
-
-   sz = pencoded->size();
-
-   u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','t','r','>','<','t','d','>'));
+   for (uint32_t i = 0, n = U_SYSCALL(PQntuples, "%p", res); i < n; ++i)
+      {
+       id = U_SYSCALL(PQgetvalue,  "%p,%d,%d", res, i, 0);
+      ptr = U_SYSCALL(PQgetvalue,  "%p,%d,%d", res, i, 1);
+      sz  = U_SYSCALL(PQgetlength, "%p,%d,%d", res, i, 1);
 
 
-   ptr = u_num2str32(elem->id, ptr+8);
+      Fortune::replace(i, ntohl(*(uint32_t*)id), ptr, sz);
+      }
 
 
-   u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','t','d'));
-                      ptr += 8;
+   U_SYSCALL_VOID(PQclear, "%p", res);
+#endif
+}
 
 
-   *ptr++ = '>';
+static void usp_fork_fortune()
+{
+   U_TRACE_NO_PARAM(5, "::usp_fork_fortune()")
 
 
-   (void) memcpy(ptr, pencoded->data(), sz);
-                 ptr +=                 sz;
+   Fortune::handlerForkSql();
 
 
-   u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
-   u_put_unalignedp16(ptr+8, U_MULTICHAR_CONSTANT16('r','>'));
-                      ptr += 10;
-   }
+   if (UOrmDriver::isPGSQL() == false) handle_query = handlerQuery;
+   else
+      {
+      handle_query = handlerQueryPGSQL;
 
 
-UClientImage_Base::wbuffer->size_adjust(ptr);
+#  ifdef U_STATIC_ORM_DRIVER_PGSQL
+      pdrv  = (UOrmDriverPgSql*) Fortune::psql_fortune->getDriver();
+      pstmt = (UPgSqlStatement*) Fortune::pstmt_fortune->getStatement();
 
 
-pvfortune->clear();
---></table></body></html>
+      pstmt->prepareStatement(pdrv);
+#  endif
+      }
+}
+-->
+<!--#code
+Fortune::doQuery(handle_query);
+-->

+ 147 - 0
frameworks/C++/ulib/src/fortuneNoSql.h

@@ -0,0 +1,147 @@
+// fortuneNoSql.h
+
+#ifndef FORTUNE_NO_SQL_H
+#define FORTUNE_NO_SQL_H 1
+
+#include "fortune.h"
+
+#include <ulib/net/client/redis.h>
+#include <ulib/net/client/elasticsearch.h>
+
+#ifdef USE_MONGODB
+#  include <ulib/net/client/mongodb.h>
+#endif
+
+class FortuneNoSql {
+public:
+
+#ifdef USE_MONGODB
+   static UMongoDBClient* mc;
+#endif
+
+   static void handlerQueryMongoDB()
+      {
+      U_TRACE(0, "FortuneNoSql::handlerQueryMongoDB()")
+
+      U_INTERNAL_ASSERT_POINTER(Fortune::pmessage)
+
+#  ifdef USE_MONGODB
+      (void) mc->findAll();
+
+      for (uint32_t i = 0, n = mc->vitem.size(); i < n; ++i)
+         {
+         (void) U_JFIND(mc->vitem[i], "message", *Fortune::pmessage);
+
+         Fortune::replace(i, i+1);
+
+         Fortune::pmessage->clear();
+         }
+#  endif
+      }
+
+   static void handlerForkMongoDB()
+      {
+      U_TRACE_NO_PARAM(0, "FortuneNoSql::handlerForkMongoDB()")
+
+#  ifdef USE_MONGODB
+      if (mc == U_NULLPTR)
+         {
+         U_NEW(UMongoDBClient, mc, UMongoDBClient);
+
+         if (mc->connect(U_NULLPTR, 0) == false)
+            {
+            U_WARNING("FortuneNoSql::handlerForkMongoDB(): connection failed");
+
+            U_DELETE(mc)
+
+            mc = U_NULLPTR;
+
+            return;
+            }
+
+         if (mc->selectCollection("hello_world", "fortune") == false)
+            {
+            U_WARNING("FortuneNoSql::handlerForkMongoDB(): selectCollection() failed");
+
+            U_DELETE(mc)
+
+            mc = U_NULLPTR;
+
+            return;
+            }
+
+         Fortune::handlerFork();
+         }
+#  endif
+      }
+
+   static UREDISClient_Base* rc;
+
+   static void handlerQueryREDIS()
+      {
+      U_TRACE(0, "FortuneNoSql::handlerQueryREDIS()")
+
+      (void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
+
+      for (uint32_t i = 0, n = rc->vitem.size(); i < n; ++i) Fortune::replace(i, rc->vitem[i]);
+      }
+
+   static void handlerForkREDIS()
+      {
+      U_TRACE_NO_PARAM(0, "Fortune::handlerForkREDIS()")
+
+      if (rc == U_NULLPTR)
+         {
+         U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
+
+         if (rc->connect() == false)
+            {
+            U_WARNING("FortuneNoSql::handlerForkREDIS(): %V", rc->UClient_Base::getResponse().rep);
+
+            U_DELETE(rc)
+
+            rc = U_NULLPTR;
+
+            return;
+            }
+
+         Fortune::handlerFork();
+         }
+      }
+
+#ifdef DEBUG
+   static void handlerEndMongoDB()
+      {
+      U_TRACE_NO_PARAM(0, "FortuneNoSql::handlerEndMongoDB()")
+
+#  ifdef USE_MONGODB
+      if (mc)
+         {
+         Fortune::handlerEnd();
+
+         U_DELETE(mc)
+
+         mc = U_NULLPTR;
+         }
+#  endif
+      }
+
+   static void handlerEndREDIS()
+      {
+      U_TRACE_NO_PARAM(0, "FortuneNoSql::handlerEndREDIS()")
+
+      if (rc)
+         {
+         Fortune::handlerEnd();
+
+         U_DELETE(rc)
+
+         rc = U_NULLPTR;
+         }
+      }
+#endif
+
+private:
+   U_DISALLOW_ASSIGN(FortuneNoSql)
+};
+#endif

+ 15 - 31
frameworks/C++/ulib/src/json.usp

@@ -3,49 +3,33 @@ Test type 1: JSON serialization
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#ifdef AS_cpoll_cppsp_DO
-#undef AS_cpoll_cppsp_DO
-#endif
-#ifdef AS_cpoll_cppsp_DO
-#  include <json/json.h>
-#else
 static UString* pkey;
 static UString* pkey;
 static UString* pvalue;
 static UString* pvalue;
-#endif
 
 
 static void usp_init_json()
 static void usp_init_json()
 {
 {
    U_TRACE(5, "::usp_init_json()")
    U_TRACE(5, "::usp_init_json()")
 
 
-#ifndef AS_cpoll_cppsp_DO
    U_NEW_STRING(pkey,   UString(U_CONSTANT_TO_PARAM("message")));
    U_NEW_STRING(pkey,   UString(U_CONSTANT_TO_PARAM("message")));
    U_NEW_STRING(pvalue, UString(U_CONSTANT_TO_PARAM("Hello, World!")));
    U_NEW_STRING(pvalue, UString(U_CONSTANT_TO_PARAM("Hello, World!")));
-#endif
 }
 }
-
-#ifdef DEBUG
-static void usp_end_json()
-{
-   U_TRACE(5, "::usp_end_json()")
-
-#ifndef AS_cpoll_cppsp_DO
-   U_DELETE(pkey)
-   U_DELETE(pvalue)
-#endif
-}
-#endif
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-#ifndef AS_cpoll_cppsp_DO
-UValue::stringify(*UClientImage_Base::wbuffer, UValue(*pkey, *pvalue));
-#else
-json_object* hello = json_object_new_object();
-json_object_object_add(hello, "message", json_object_new_string("Hello, World!"));
-const char* hello_str = json_object_to_json_string(hello);
-USP_PUTS_STRING(hello_str);
-json_object_put(hello);
-#endif
+char* pwbuffer = UClientImage_Base::wbuffer->data();
+
+u_put_unalignedp64(pwbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+u_put_unalignedp64(pwbuffer+8,  U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
+u_put_unalignedp64(pwbuffer+16, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
+u_put_unalignedp64(pwbuffer+24, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
+u_put_unalignedp16(pwbuffer+32, U_MULTICHAR_CONSTANT16('\r','\n'));
+
+UValue::pstringify = pwbuffer + U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n");
+
+UValue(*pkey, *pvalue).stringify();
+
+UClientImage_Base::wbuffer->size_adjust(UValue::pstringify);
+
+U_http_info.endHeader = (uint32_t)-U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n");
 -->
 -->

+ 26 - 0
frameworks/C++/ulib/src/libFortune.cxx

@@ -0,0 +1,26 @@
+// fortune.cpp
+
+#include "fortune.h"
+
+uint32_t           Fortune::uid;
+UString*           Fortune::pmessage;
+UOrmSession*       Fortune::psql_fortune;
+UOrmStatement*     Fortune::pstmt_fortune;
+UVector<Fortune*>* Fortune::pvfortune;
+
+#ifdef DEBUG
+const char* Fortune::dump(bool breset) const
+{
+   *UObjectIO::os << "id               " << id              << '\n'
+                  << "message (UString " << (void*)&message << ')';
+
+   if (breset)
+      {
+      UObjectIO::output();
+
+      return UObjectIO::buffer_output;
+      }
+
+   return U_NULLPTR;
+}
+#endif

+ 8 - 0
frameworks/C++/ulib/src/libFortuneNoSql.cxx

@@ -0,0 +1,8 @@
+// fortuneNoSql.cpp
+
+#include "fortuneNoSql.h"
+
+#ifdef USE_MONGODB
+UMongoDBClient*    FortuneNoSql::mc;
+#endif
+UREDISClient_Base* FortuneNoSql::rc;

+ 32 - 0
frameworks/C++/ulib/src/libWorld.cxx

@@ -0,0 +1,32 @@
+// world.cpp
+
+#include "world.h"
+
+char             World::wbuffer[18000];
+char*            World::pwbuffer;
+World*           World::pworld_query;
+uint32_t         World::rnum;
+uint32_t         World::rnumber[500];
+UOrmSession*     World::psql_query;
+UOrmStatement*   World::pstmt_query;
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+UOrmDriverPgSql* World::pdrv;
+UPgSqlStatement* World::pstmt;
+#endif
+
+#ifdef DEBUG
+const char* World::dump(bool breset) const
+{
+   *UObjectIO::os << "id           " << id            << '\n'
+                  << "randomNumber " << randomNumber;
+
+   if (breset)
+      {
+      UObjectIO::output();
+
+      return UObjectIO::buffer_output;
+      }
+
+   return U_NULLPTR;
+}
+#endif

+ 16 - 0
frameworks/C++/ulib/src/libWorldNoSql.cxx

@@ -0,0 +1,16 @@
+// worldNoSql.cpp
+
+#include "worldNoSql.h"
+
+#ifdef USE_MONGODB
+bson_t*               WorldNoSql::query;
+UMongoDBClient*       WorldNoSql::mc;
+#endif
+char                  WorldNoSql::rc_buffer[128];
+char                  WorldNoSql::es_buffer1[128];
+char                  WorldNoSql::es_buffer2[128];
+char*                 WorldNoSql::pbuffer1;
+char*                 WorldNoSql::pbuffer2;
+UString*              WorldNoSql::str_rnumber;
+UREDISClient_Base*    WorldNoSql::rc;
+UElasticSearchClient* WorldNoSql::es;

+ 3 - 79
frameworks/C++/ulib/src/mdb.usp

@@ -3,88 +3,12 @@ Test type 2: Single database query
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static bson_t* query;
-static UMongoDBClient* mc;
-
-static void usp_fork_mdb()
-{
-   U_TRACE(5, "::usp_fork_mdb()")
-
-   U_NEW(UMongoDBClient, mc, UMongoDBClient);
-
-   if (mc->connect(U_NULLPTR, 0) == false)
-      {
-      U_WARNING("usp_fork_mdb(): connection failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   if (mc->selectCollection("hello_world", "world") == false)
-      {
-      U_WARNING("usp_fork_mdb(): selectCollection() failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
-}
-
-#ifdef DEBUG
-static void usp_end_mdb()
-{
-   U_TRACE(5, "::usp_end_mdb()")
-
-   if (query)
-      {
-      U_DELETE(mc)
-
-      U_SYSCALL_VOID(bson_destroy, "%p", query);
-      }
-}
-#endif
+static void usp_fork_mdb() { WorldNoSql::handlerForkMongoDB(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id;
-UString result;
-
-(void) mc->findOne(id = u_get_num_random(10000-1), query);
-
-(void) U_JFIND(mc->vitem[0], "randomNumber", result);
-
-#ifdef AS_cpoll_cppsp_DO
-char* ptr   = UClientImage_Base::wbuffer->pend();
-uint32_t sz = result.size();
-
-u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
-
-ptr = u_num2str32(id, ptr+6);
-
-u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
-                   ptr += 16;
-
-(void) memcpy(ptr, result.data(), sz);
-              ptr +=              sz;
-
-*ptr++ = '}';
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-#else
-World world(id, result.strtoul());
-USP_OBJ_JSON_stringify(world);
-#endif
+WorldNoSql::doOneQuery(WorldNoSql::handlerQueryMongoDB);
 -->
 -->

+ 5 - 107
frameworks/C++/ulib/src/mfortune.usp

@@ -3,112 +3,10 @@ Test type 4: Fortunes
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "fortune.h"
+#include "fortuneNoSql.h"
 
 
-static UString* pencoded;
-static UMongoDBClient* mc;
-static Fortune* pfortune2add;
-static UVector<Fortune*>* pvfortune;
-
-static void usp_fork_mfortune()
-{
-   U_TRACE(5, "::usp_fork_mfortune()")
-
-   U_NEW(UMongoDBClient, mc, UMongoDBClient);
-
-   if (mc->connect(U_NULLPTR, 0) == false)
-      {
-      U_WARNING("usp_fork_mfortune(): connection failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   if (mc->selectCollection("hello_world", "fortune") == false)
-      {
-      U_WARNING("usp_fork_mfortune(): selectCollection() failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW_STRING(pencoded, UString(100U));
-   U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
-   U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
-}
-
-#ifdef DEBUG
-static void usp_end_mfortune()
-{
-   U_TRACE(5, "::usp_end_mfortune()")
-
-   if (pencoded)
-      {
-      U_DELETE(mc)
-      U_DELETE(pencoded)
-      U_DELETE(pvfortune)
-      U_DELETE(pfortune2add)
-      }
-}
-#endif
+static void usp_fork_mfortune() { FortuneNoSql::handlerForkMongoDB(); }
+-->
+<!--#code
+Fortune::doQuery(FortuneNoSql::handlerQueryMongoDB);
 -->
 -->
-<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
-Fortune* item;
-UString result;
-uint32_t i, n, sz;
-char* ptr = UClientImage_Base::wbuffer->pend();
-
-U_NEW(Fortune, item, Fortune(*pfortune2add));
-
-pvfortune->push_back(item);
-
-(void) mc->findAll();
-
-for (i = 0, n = mc->vitem.size(); i < n; ++i)
-   {
-   (void) U_JFIND(mc->vitem[i], "message", result);
-
-   U_NEW(Fortune, item, Fortune(i+1, result));
-
-   result.clear();
-
-   pvfortune->push_back(item);
-   }
-
-pvfortune->sort(Fortune::cmp_obj);
-
-for (i = 0, ++n; i < n; ++i)
-   {
-   Fortune* elem = (*pvfortune)[i];
-
-   UXMLEscape::encode(elem->message, *pencoded);
-
-   sz = pencoded->size();
-
-   u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','t','r','>','<','t','d','>'));
-
-   ptr = u_num2str32(elem->id, ptr+8);
-
-   u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','t','d'));
-                      ptr += 8;
-
-   *ptr++ = '>';
-
-   (void) memcpy(ptr, pencoded->data(), sz);
-                 ptr +=                 sz;
-
-   u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
-   u_put_unalignedp16(ptr+8, U_MULTICHAR_CONSTANT16('r','>'));
-                      ptr += 10;
-   }
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-
-pvfortune->clear();
---></table></body></html>

+ 3 - 120
frameworks/C++/ulib/src/mquery.usp

@@ -3,129 +3,12 @@ Test type 3: Multiple database queries
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static bson_t* query;  
-static UMongoDBClient* mc;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_query;
-#endif
-
-static void usp_fork_mquery()
-{
-   U_TRACE(5, "::usp_fork_mquery()")
-
-   U_NEW(UMongoDBClient, mc, UMongoDBClient);
-
-   if (mc->connect(U_NULLPTR, 0) == false)
-      {
-      U_WARNING("usp_fork_mquery(): connection disabled or failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   if (mc->selectCollection("hello_world", "world") == false)
-      {
-      U_WARNING("usp_fork_mquery(): selectCollection() failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
-
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
-#endif
-}
-
-#ifdef DEBUG
-static void usp_end_mquery()
-{
-   U_TRACE(5, "::usp_end_mquery()")
-
-   if (query)
-      {
-      U_DELETE(mc)
-
-      U_SYSCALL_VOID(bson_destroy, "%p", query);
-
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_query)
-#  endif
-      }
-}
-#endif
+static void usp_fork_mquery() { WorldNoSql::handlerForkMongoDB(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id;
-UString rnumber;
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-char* ptr = UClientImage_Base::wbuffer->pend();
-
-*ptr++ = '[';
-#endif
-
-while (true)
-   {
-   (void) mc->findOne(id = u_get_num_random(10000-1), query);
-
-   (void) U_JFIND(mc->vitem[0], "randomNumber", rnumber);
-
-#ifdef AS_cpoll_cppsp_DO
-   uint32_t sz = rnumber.size();
-
-   u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-   u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
-
-   ptr = u_num2str32(id, ptr+6);
-
-   u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-   u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
-                      ptr += 16;
-
-   (void) memcpy(ptr, rnumber.data(), sz);
-                 ptr +=               sz;
-
-   *ptr++ = '}';
-#else
-   World* pworld;
-
-   U_NEW(World, pworld, World(id, rnumber.strtoul()));
-
-   pvworld_query->push_back(pworld);
-#endif
-
-   rnumber.clear();
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   *ptr++ = ',';
-#endif
-   }
-
-#ifdef AS_cpoll_cppsp_DO
-*ptr++ = ']';
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-#else
-USP_OBJ_JSON_stringify(*pvworld_query);
-pvworld_query->clear();
-#endif
+WorldNoSql::doQuery(WorldNoSql::handlerQueryMongoDB);
 -->
 -->

+ 3 - 118
frameworks/C++/ulib/src/mupdate.usp

@@ -3,127 +3,12 @@ Test type 5: Database updates
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static bson_t* query;  
-static UMongoDBClient* mc;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_update;
-#endif
-
-static void usp_fork_mupdate()
-{
-   U_TRACE(5, "::usp_fork_mupdate()")
-
-   U_NEW(UMongoDBClient, mc, UMongoDBClient);
-
-   if (mc->connect(U_NULLPTR, 0) == false)
-      {
-      U_WARNING("usp_fork_mupdate(): connection disabled or failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   if (mc->selectCollection("hello_world", "world") == false)
-      {
-      U_WARNING("usp_fork_mupdate(): selectCollection() failed");
-
-      U_DELETE(mc)
-
-      mc = U_NULLPTR;
-
-      return;
-      }
-
-   query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
-
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
-#endif
-}
-
-#ifdef DEBUG
-static void usp_end_mupdate()
-{
-   U_TRACE(5, "::usp_end_mupdate()")
-
-   if (query)
-      {
-      U_DELETE(mc)
-
-      U_SYSCALL_VOID(bson_destroy, "%p", query);
-
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_update)
-#  endif
-      }
-}
-#endif
+static void usp_fork_mupdate() { WorldNoSql::handlerForkMongoDB(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id, rnum;
-//mongoc_bulk_operation_t* bulk = mc->createBulk(false);
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-char* ptr = UClientImage_Base::wbuffer->pend();
-
-*ptr++ = '[';
-#endif
-
-while (true)
-   {
-// mc->updateOneBulk(bulk, id = u_get_num_random(10000-1), "randomNumber", rnum = u_get_num_random(10000-1));
-
-   if (mc->findOne(id = u_get_num_random(10000-1), query) &&
-       mc->update( id, "randomNumber", rnum = u_get_num_random(10000-1)))
-      {
-#  ifdef AS_cpoll_cppsp_DO
-      u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-      u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
-
-      ptr = u_num2str32(id, ptr+6);
-
-      u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-      u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
-
-      ptr = u_num2str32(rnum, ptr+16);
-
-      *ptr++ = '}';
-#  else
-      World* pworld;
-
-      U_NEW(World, pworld, World(id, rnum));
-
-      pvworld_update->push_back(pworld);
-#  endif
-      }
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   *ptr++ = ',';
-#endif
-   }
-
-// (void) mc->executeBulk(bulk);
-
-#ifdef AS_cpoll_cppsp_DO
-*ptr++ = ']';
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-#else
-USP_OBJ_JSON_stringify(*pvworld_update);
-pvworld_update->clear();
-#endif
+World::doUpdateNoSql(WorldNoSql::handlerUpdateMongoDB);
 -->
 -->

+ 32 - 96
frameworks/C++/ulib/src/query.usp

@@ -5,116 +5,52 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World*         pworld_query;
-static UOrmSession*   psql_query;
-static UOrmStatement* pstmt_query;
-
-#ifndef AS_cpoll_cppsp_DO
-static UVector<World*>* pvworld_query;
-#endif
-
-static void usp_fork_query()
-{
-   U_TRACE(5, "::usp_fork_query()")
-
-   U_NEW(UOrmSession, psql_query, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
-
-   if (psql_query->isReady() == false)
-      {
-      U_WARNING("usp_fork_query(): we cound't connect to db");
-
-      U_DELETE(psql_query)
-
-      psql_query = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW(UOrmStatement, pstmt_query, UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
-
-// if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
-
-   U_NEW(World, pworld_query, World);
-
-   pstmt_query->use( pworld_query->id);
-   pstmt_query->into(pworld_query->randomNumber);
-
-#ifndef AS_cpoll_cppsp_DO
-   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
-#endif
-}
-
-#ifdef DEBUG
-static void usp_end_query()
-{
-   U_TRACE(5, "::usp_end_query()")
-
-   if (pstmt_query)
-      {
-      U_DELETE(pstmt_query)
-      U_DELETE(pworld_query)
-      U_DELETE(psql_query)
-
-#  ifndef AS_cpoll_cppsp_DO
-      U_DELETE(pvworld_query)
-#  endif
-      }
-}
-#endif
+static void usp_fork_query() { World::handlerForkSql(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
-<!--#code
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-char* ptr = UClientImage_Base::wbuffer->pend();
+<!--#vcode
+uint32_t num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
-*ptr++ = '[';
-#endif
-
-while (true)
+/*
+if (num_queries >= 20 &&
+    UServer_Base::startParallelization())
    {
    {
-   pworld_query->id = u_get_num_random(10000-1);
-
-   pstmt_query->execute();
+   return;
+   }
+*/
+-->
+<!--#code
+World::initResult();
 
 
-#ifdef AS_cpoll_cppsp_DO
-   u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-   u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
+for (uint32_t i = 0; i < num_queries; ++i)
+   {
+   World::pworld_query->id = World::rnumber[i];
 
 
-   ptr = u_num2str32(pworld_query->id, ptr+6);
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+   if (World::pdrv)
+      {
+      World::pstmt->setBindParam();
 
 
-   u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-   u_put_unalignedp64(ptr+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+      PGresult* res = World::pdrv->execPrepared(World::pstmt);
 
 
-   ptr = u_num2str32(pworld_query->randomNumber, ptr+16);
+      U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 1)
+      U_INTERNAL_ASSERT_EQUALS(PQntuples(res), 1)
 
 
-   *ptr++ = '}';
-#else
-   World* pworld;
+      char* randomNumber = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, 0, 0);
 
 
-   U_NEW(World, pworld, World(*pworld_query));
+      World::handlerResult(World::pworld_query->id, ntohl(*(uint32_t*)randomNumber));
 
 
-   pvworld_query->push_back(pworld);
+      U_SYSCALL_VOID(PQclear, "%p", res);
+      }
+   else
 #endif
 #endif
+   {
+   World::pstmt_query->execute();
 
 
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   *ptr++ = ',';
-#endif
+   World::handlerResultSql(i);
+   }
    }
    }
 
 
-#ifdef AS_cpoll_cppsp_DO
-*ptr++ = ']';
-
-UClientImage_Base::wbuffer->size_adjust(ptr);
-#else
-USP_OBJ_JSON_stringify(*pvworld_query);
-pvworld_query->clear();
-#endif
+World::endResult();
 -->
 -->

+ 3 - 44
frameworks/C++/ulib/src/rdb.usp

@@ -3,53 +3,12 @@ Test type 2: Single database query
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static char buffer[128];
-static char* ptr = buffer+6;
-static UREDISClient_Base* rc;
-
-static void usp_fork_rdb()
-{
-   U_TRACE(5, "::usp_fork_rdb()")
-
-   U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
-
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rdb(): %V", rc->UClient_Base::getResponse().rep);
-
-      U_DELETE(rc)
-
-      rc = U_NULLPTR;
-
-      return;
-      }
-
-   U_MEMCPY(buffer, "world:", U_CONSTANT_SIZE("world:"));
-}
-
-#ifdef DEBUG
-static void usp_end_rdb()
-{
-   U_TRACE(5, "::usp_end_rdb()")
-
-   if (rc) U_DELETE(rc)
-}
-#endif
+static void usp_fork_rdb() { WorldNoSql::handlerForkREDIS(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-uint32_t id;
-
-(void) rc->get(buffer, 6+u_num2str32(id = u_get_num_random(10000-1), ptr)-ptr);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", id, rc->vitem[0].rep);
-#else
-World world(id, rc->vitem[0].strtoul());
-USP_OBJ_JSON_stringify(world);
-#endif
+WorldNoSql::doOneQuery(WorldNoSql::handlerQueryREDIS);
 -->
 -->

+ 4 - 77
frameworks/C++/ulib/src/rfortune.usp

@@ -3,82 +3,9 @@ Test type 4: Fortunes
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "fortune.h"
+#include "fortuneNoSql.h"
 
 
-static UString* pencoded;
-static UREDISClient_Base* rc;
-static Fortune* pfortune2add;
-static UVector<Fortune*>* pvfortune;
-
-static void usp_fork_rfortune()
-{
-   U_TRACE(5, "::usp_fork_rfortune()")
-
-   U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
-
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rfortune(): %V", rc->UClient_Base::getResponse().rep);
-
-      U_DELETE(rc)
-
-      rc = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW_STRING(pencoded, UString(100U));
-   U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
-   U_NEW(Fortune, pfortune2add, Fortune(0, U_STRING_FROM_CONSTANT("Additional fortune added at request time.")));
-}
-
-#ifdef DEBUG
-static void usp_end_rfortune()
-{
-   U_TRACE(5, "::usp_end_rfortune()")
-
-   if (pencoded)
-      {
-      U_DELETE(rc)
-      U_DELETE(pencoded)
-      U_DELETE(pvfortune)
-      U_DELETE(pfortune2add)
-      }
-}
-#endif
+static void usp_fork_rfortune() { FortuneNoSql::handlerForkREDIS(); }
+-->
+Fortune::doQuery(FortuneNoSql::handlerQueryREDIS);
 -->
 -->
-<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
-Fortune* item;
-uint32_t i, n;
-
-U_NEW(Fortune, item, Fortune(*pfortune2add));
-
-pvfortune->push_back(item);
-
-(void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
-
-for (i = 0, n = rc->vitem.size(); i < n; ++i)
-   {
-   U_NEW(Fortune, item, Fortune(i+1, rc->vitem[i]));
-
-   pvfortune->push_back(item);
-   }
-
-pvfortune->sort(Fortune::cmp_obj);
-
-for (i = 0, ++n; i < n; ++i)
-   {
-   Fortune* elem = (*pvfortune)[i];
-
-   UXMLEscape::encode(elem->message, *pencoded);
-
-   USP_PRINTF_ADD(
-      "<tr>"
-      "<td>%u</td>"
-      "<td>%v</td>"
-      "</tr>",
-      elem->id, pencoded->rep);
-   }
-
-pvfortune->clear();
---></table></body></html>

+ 3 - 89
frameworks/C++/ulib/src/rquery.usp

@@ -3,98 +3,12 @@ Test type 3: Multiple database queries
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static char buffer[8192];
-static UREDISClient_Base* rc;
-static UVector<World*>* pvworld_query;
-
-static void usp_fork_rquery()
-{
-   U_TRACE(5, "::usp_fork_rquery()")
-
-   U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
-
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rquery(): %V", rc->UClient_Base::getResponse().rep);
-
-      U_DELETE(rc)
-
-      rc = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW(UVector<World*>, pvworld_query, UVector<World*>(500));
-}
-
-#ifdef DEBUG
-static void usp_end_rquery()
-{
-   U_TRACE(5, "::usp_end_rquery()")
-
-   if (pvworld_query)
-      {
-      U_DELETE(rc)
-      U_DELETE(pvworld_query)
-      }
-}
-#endif
+static void usp_fork_rquery() { WorldNoSql::handlerForkREDIS(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-World* pworld;
-UStringRep* rep;
-char* pbuffer = buffer;
-int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR('[');
-#endif
-
-for (i = 0; i < num_queries; ++i)
-   {
-   U_NEW(World, pworld, World);
-
-   pvworld_query->push_back(pworld);
-
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
-
-   pbuffer = u_num2str32(pworld->id = u_get_num_random(10000-1), pbuffer+7);
-   }
-
-(void) rc->mget(buffer, pbuffer-buffer);
-
-i = 0;
-
-while (true)
-   {
-   pworld = pvworld_query->at(i);
-
-   rep = rc->vitem[i].rep;
-
-   pworld->randomNumber = rep->strtoul();
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld->id, rep);
-#endif
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
-#endif
-   }
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR(']');
-#else
-USP_OBJ_JSON_stringify(*pvworld_query);
-#endif
-pvworld_query->clear();
+WorldNoSql::doQuery(WorldNoSql::handlerQueryREDIS);
 -->
 -->

+ 3 - 93
frameworks/C++/ulib/src/rupdate.usp

@@ -3,102 +3,12 @@ Test type 5: Database updates
 TechEmpower Web Framework Benchmarks
 TechEmpower Web Framework Benchmarks
 -->
 -->
 <!--#declaration
 <!--#declaration
-#include "world.h"
+#include "worldNoSql.h"
 
 
-static char buffer[8192];
-static UREDISClient_Base* rc;
-static UVector<World*>* pvworld;
-
-static void usp_fork_rupdate()
-{
-   U_TRACE(5, "::usp_fork_rupdate()")
-
-   U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
-
-   if (rc->connect() == false)
-      {
-      U_WARNING("usp_fork_rupdate(): %V", rc->UClient_Base::getResponse().rep);
-
-      U_DELETE(rc)
-
-      rc = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW(UVector<World*>, pvworld, UVector<World*>(500));
-}
-
-#ifdef DEBUG
-static void usp_end_rupdate()
-{
-   U_TRACE(5, "::usp_end_rupdate()")
-
-   if (pvworld)
-      {
-      U_DELETE(rc)
-      U_DELETE(pvworld)
-      }
-}
-#endif
+static void usp_fork_rupdate() { WorldNoSql::handlerForkREDIS(); }
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-World* pworld;
-char* pbuffer = buffer;
-int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR('[');
-#endif
-
-for (i = 0; i < num_queries; ++i)
-   {
-   U_NEW(World, pworld, World);
-
-   pvworld->push_back(pworld);
-
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
-
-   pbuffer = u_num2str32(pworld->id = u_get_num_random(10000-1), pbuffer+7);
-   }
-
-(void) rc->mget(buffer, pbuffer-buffer);
-
-i = 0;
-pbuffer = buffer;
-
-while (true)
-   {
-   pworld = pvworld->at(i);
-
-   u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
-
-   pbuffer = u_num2str32(pworld->id, pbuffer+7);
-  *pbuffer = ' ';
-   pbuffer = u_num2str32(pworld->randomNumber = u_get_num_random(10000-1), pbuffer+1);
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld->id, pworld->randomNumber);
-#endif
-
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   USP_PUTS_CHAR(',');
-#endif
-   }
-
-(void) rc->mset(buffer, pbuffer-buffer);
-
-#ifdef AS_cpoll_cppsp_DO
-USP_PUTS_CHAR(']');
-#else
-USP_OBJ_JSON_stringify(*pvworld);
-#endif
-pvworld->clear();
+World::doUpdateNoSql(WorldNoSql::handlerUpdateREDIS);
 -->
 -->

+ 60 - 117
frameworks/C++/ulib/src/update.usp

@@ -5,164 +5,107 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static bool             bpgsql;
-static World*           pworld_update;
-static UOrmSession*     psql_update;
-static UOrmStatement*   pstmt;
-static UOrmStatement*   pstmt1;
-static UVector<World*>* pvworld_update;
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+static char query[8192];
+#endif
+static UOrmStatement* pstmt_update;
 
 
 static void usp_fork_update()
 static void usp_fork_update()
 {
 {
    U_TRACE(5, "::usp_fork_update()")
    U_TRACE(5, "::usp_fork_update()")
 
 
-   U_NEW(UOrmSession, psql_update, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+   World::handlerForkSql();
 
 
-   if (psql_update->isReady() == false)
+   if (World::psql_query)
       {
       {
-      U_WARNING("usp_fork_update(): we cound't connect to db");
-
-      U_DELETE(psql_update)
-
-      psql_update = U_NULLPTR;
-
-      return;
-      }
-
-   U_NEW(World,           pworld_update,  World);
-   U_NEW(UVector<World*>, pvworld_update, UVector<World*>(500));
-
-   U_NEW(UOrmStatement, pstmt, UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
-
-   pstmt->use( pworld_update->id);
-   pstmt->into(pworld_update->randomNumber);
-
-   if ((bpgsql = UOrmDriver::isPGSQL()) == false)
+#  ifdef U_STATIC_ORM_DRIVER_PGSQL
+      if (World::pdrv) (void) memcpy(query, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES"));
+      else
+#  endif
       {
       {
-      U_NEW(UOrmStatement, pstmt1, UOrmStatement(*psql_update, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
+      U_NEW(UOrmStatement, pstmt_update, UOrmStatement(*World::psql_query, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
 
 
-      pstmt1->use(pworld_update->randomNumber, pworld_update->id);
+      pstmt_update->use(World::pworld_query->randomNumber, World::pworld_query->id);
       }
       }
-// else *psql_update << "SET synchronous_commit TO OFF";
-}
-
-#ifdef DEBUG
-static void usp_end_update()
-{
-   U_TRACE(5, "::usp_end_update()")
-
-   if (pstmt)
-      {
-      U_DELETE(pstmt)
-      U_DELETE(pworld_update)
-      U_DELETE(pvworld_update)
-
-      if (bpgsql == false) U_DELETE(pstmt1)
-
-      U_DELETE(psql_update)
       }
       }
 }
 }
-#endif
 -->
 -->
 <!--#header
 <!--#header
-Content-Type: application/json
 -->
 -->
-<!--#code
-char* ptr;
-World* pworld;
-char query[8192];
-int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
-
-(void) UClientImage_Base::wbuffer->reserve(36U * num_queries);
+<!--#vcode
+uint32_t num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
-if (bpgsql)
+/*
+if (num_queries >= 20 &&
+    UServer_Base::startParallelization())
    {
    {
-   (void) memcpy(query,          "UPDATE World SET randomNumber = v.randomNumber FROM (VALUES",
-                 U_CONSTANT_SIZE("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES"));
-   ptr = query + U_CONSTANT_SIZE("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES");
+   return;
    }
    }
+*/
+-->
+<!--#code
+World::initResult();
 
 
-while (true)
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+if (World::pdrv)
    {
    {
-   pworld_update->id = u_get_num_random(10000-1);
-
-   pstmt->execute();
+   PGresult* res;
+   char* pquery = query + U_CONSTANT_SIZE("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES");
 
 
-   pworld_update->randomNumber = u_get_num_random(10000-1);
-
-   if (bpgsql == false) pstmt1->execute();
+   for (uint32_t i = 0; i < num_queries; ++i)
+      {
+      *pquery++ = '(';
 
 
-   U_NEW(World, pworld, World(*pworld_update));
+      pquery = u_num2str32(World::pworld_query->id = World::rnumber[i], pquery);
 
 
-   pvworld_update->push_back(pworld);
+      World::pstmt->setBindParam();
 
 
-   if (++i == num_queries) break;
-   }
+      res = World::pdrv->execPrepared(World::pstmt);
 
 
-#ifdef AS_cpoll_cppsp_DO
-char* p = UClientImage_Base::wbuffer->pend();
+      U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 1)
+      U_INTERNAL_ASSERT_EQUALS(PQntuples(res), 1)
 
 
-*p++ = '[';
-#endif
+      (void) U_SYSCALL(PQgetvalue, "%p,%d,%d", res, 0, 0);
 
 
-if (bpgsql) pvworld_update->sort(World::cmp_obj);
+      *pquery++ = ',';
 
 
-i = 0;
+      pquery = u_num2str32(World::pworld_query->randomNumber = u_get_num_random_range1(10000), pquery);
 
 
-while (true)
-   {
-   if (bpgsql)
-      {
-      pworld = pvworld_update->at(i);
+      u_put_unalignedp16(pquery, U_MULTICHAR_CONSTANT16(')',','));
+                         pquery += 2;
 
 
-      *ptr++ = '(';
+      World::handlerResultSql(i);
 
 
-      ptr = u_num2str32(pworld->id, ptr);
-
-      *ptr++ = ',';
-
-      ptr = u_num2str32(pworld->randomNumber, ptr);
-
-      u_put_unalignedp16(ptr, U_MULTICHAR_CONSTANT16(')',','));
-                         ptr += 2;
+      U_SYSCALL_VOID(PQclear, "%p", res);
       }
       }
 
 
-#ifdef AS_cpoll_cppsp_DO
-   u_put_unalignedp32(p,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-   u_put_unalignedp16(p+4, U_MULTICHAR_CONSTANT16('"',':'));
+   World::endResult();
 
 
-   p = u_num2str32(pworld->id, p+6);
+   (void) memcpy(pquery-1, ") AS v (id,randomNumber) WHERE World.id = v.id;",
+           U_CONSTANT_SIZE(") AS v (id,randomNumber) WHERE World.id = v.id;")+1);
 
 
-   u_put_unalignedp64(p,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
-   u_put_unalignedp64(p+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+   res = (PGresult*) U_SYSCALL(PQexec, "%p,%S", (PGconn*)World::pdrv->UOrmDriver::connection, query);
 
 
-   p = u_num2str32(pworld->randomNumber, p+16);
-
-   *p++ = '}';
-#endif
+   U_INTERNAL_ASSERT_EQUALS(PQresultStatus(res), PGRES_COMMAND_OK)
 
 
-   if (++i == num_queries) break;
-
-#ifdef AS_cpoll_cppsp_DO
-   *p++ = ',';
-#endif
+   U_SYSCALL_VOID(PQclear, "%p", res);
    }
    }
-
-#ifdef AS_cpoll_cppsp_DO
-*p++ = ']';
-
-UClientImage_Base::wbuffer->size_adjust(p);
-#else
-USP_OBJ_JSON_stringify(*pvworld_update);
+else
 #endif
 #endif
+{
+for (uint32_t i = 0; i < num_queries; ++i)
+   {
+   World::pworld_query->id = World::rnumber[i];
 
 
-pvworld_update->clear();
+   World::pstmt_query->execute();
 
 
-if (bpgsql)
-   {
-   (void) memcpy(ptr-1,                 ") AS v (id,randomNumber) WHERE World.id = v.id;",
-                        U_CONSTANT_SIZE(") AS v (id,randomNumber) WHERE World.id = v.id;")+1);
+   World::pworld_query->randomNumber = u_get_num_random_range1(10000);
+
+   pstmt_update->execute();
 
 
-   if (psql_update->query(query, ptr + U_CONSTANT_SIZE(") AS v (id,randomNumber) WHERE World.id = v.id;") - query) == false) UHTTP::setInternalError(); 
+   World::handlerResultSql(i);
    }
    }
+
+World::endResult();
+}
 -->
 -->

+ 192 - 8
frameworks/C++/ulib/src/world.h

@@ -5,6 +5,13 @@
 
 
 #include <ulib/orm/orm.h>
 #include <ulib/orm/orm.h>
 #include <ulib/json/value.h>
 #include <ulib/json/value.h>
+#include <ulib/utility/uhttp.h>
+#include <ulib/orm/orm_driver.h>
+#include <ulib/net/server/client_image.h>
+
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+#  include <ulib/orm/driver/orm_driver_pgsql.h>
+#endif
 
 
 class World {
 class World {
 public:
 public:
@@ -104,21 +111,198 @@ public:
 #  endif
 #  endif
       }
       }
 
 
-#ifdef DEBUG
-   const char* dump(bool breset) const
+   static char* pwbuffer;
+   static char wbuffer[18000];
+   static uint32_t rnum, rnumber[500];
+
+   static World*        pworld_query;
+   static UOrmSession*    psql_query;
+   static UOrmStatement* pstmt_query;
+
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+   static UOrmDriverPgSql* pdrv;
+   static UPgSqlStatement* pstmt;
+#endif
+
+   static void initResult()
+      {
+      U_TRACE(0, "World::initResult()")
+
+      u_put_unalignedp64(wbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+      u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
+      u_put_unalignedp64(wbuffer+16, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
+      u_put_unalignedp64(wbuffer+24, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
+      u_put_unalignedp32(wbuffer+32, U_MULTICHAR_CONSTANT32('\r','\n','[','\0'));
+
+      pwbuffer = wbuffer + U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n[");
+
+      U_http_info.endHeader = (uint32_t)-U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n");
+      }
+
+   static void endResult()
       {
       {
-      *UObjectIO::os << "id           " << id            << '\n'
-                     << "randomNumber " << randomNumber;
+      U_TRACE_NO_PARAM(0, "World::endResult()")
+
+      *(pwbuffer-1) = ']';
+
+      UClientImage_Base::wbuffer->setConstant(wbuffer, pwbuffer-wbuffer);
+      }
+
+   static void initOneResult()
+      {
+      U_TRACE(0, "World::initOneResult()")
+
+      u_put_unalignedp64(wbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+      u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
+      u_put_unalignedp64(wbuffer+16, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
+      u_put_unalignedp64(wbuffer+24, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
+      u_put_unalignedp32(wbuffer+32, U_MULTICHAR_CONSTANT32('\r','\n','{','\0'));
+
+      pwbuffer = wbuffer + U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n{");
+
+      U_http_info.endHeader = (uint32_t)-U_CONSTANT_SIZE("Content-Type: application/json\r\n\r\n");
+      }
+
+   static void endOneResult()
+      {
+      U_TRACE_NO_PARAM(0, "World::endOneResult()")
+
+      *pwbuffer = '}';
+
+      UClientImage_Base::wbuffer->setConstant(wbuffer, pwbuffer-wbuffer+1);
+      }
+
+   static void handlerOneResult(uint32_t uid, uint32_t random)
+      {
+      U_TRACE(0, "World::handlerOneResult(%u,%u)", uid, random)
+
+      u_put_unalignedp32(pwbuffer, U_MULTICHAR_CONSTANT32('"','i','d','"'));
+
+      pwbuffer[4] = ':';
+
+      pwbuffer = u_num2str32(uid, pwbuffer+5);
+
+      u_put_unalignedp64(pwbuffer,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
+      u_put_unalignedp64(pwbuffer+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+
+      pwbuffer = u_num2str32(random, pwbuffer+16);
+      }
+
+   static void handlerResult(uint32_t uid, uint32_t random)
+      {
+      U_TRACE(0, "World::handlerResult(%u,%u)", uid, random)
+
+      u_put_unalignedp32(pwbuffer,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
+      u_put_unalignedp16(pwbuffer+4, U_MULTICHAR_CONSTANT16('"',':'));
+
+      pwbuffer = u_num2str32(uid, pwbuffer+6);
+
+      u_put_unalignedp64(pwbuffer,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
+      u_put_unalignedp64(pwbuffer+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+
+      pwbuffer = u_num2str32(random, pwbuffer+16);
+
+      u_put_unalignedp16(pwbuffer, U_MULTICHAR_CONSTANT16('}',','));
+                         pwbuffer += 2;
+      }
 
 
-      if (breset)
+   static void handlerResult(uint32_t i)
+      {
+      U_TRACE(0, "World::handlerResult(%u)", i)
+
+      U_INTERNAL_ASSERT_POINTER(pworld_query)
+
+      U_INTERNAL_DUMP("pworld_query->randomNumber = %u", pworld_query->randomNumber)
+      }
+
+   static void handlerResultSql(uint32_t i)
+      {
+      U_TRACE(0, "World::handlerResultSql(%u)", i)
+
+      U_INTERNAL_ASSERT_POINTER(pworld_query)
+
+      handlerResult(rnumber[i], pworld_query->randomNumber);
+      }
+
+   static void doUpdateNoSql(vPFu handlerUpdateNoSql)
+      {
+      U_TRACE(0, "World::doUpdateNoSql(%p)", handlerUpdateNoSql)
+
+      initResult();
+
+      for (uint32_t i = 0, n = UHTTP::getFormFirstNumericValue(1, 500); i < n; ++i)
+         {
+         handlerUpdateNoSql(i);
+
+         handlerResult(rnumber[i], rnum);
+         }
+
+      endResult();
+      }
+
+   static void handlerFork()
+      {
+      U_TRACE_NO_PARAM(0, "World::handlerFork()")
+
+      if (rnumber[0] == 0) for (uint32_t i = 0; i < 500; ++i) rnumber[i] = u_get_num_random_range1(10000);
+      }
+
+   static void handlerForkSql()
+      {
+      U_TRACE_NO_PARAM(0, "World::handlerForkSql()")
+
+      if (psql_query == U_NULLPTR)
          {
          {
-         UObjectIO::output();
+         U_NEW(UOrmSession, psql_query, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+
+         if (psql_query->isReady() == false)
+            {
+            U_WARNING("World::handlerForkSql(): we cound't connect to db");
+
+            U_DELETE(psql_query)
+
+            psql_query = U_NULLPTR;
+
+            return;
+            }
+
+         U_NEW(UOrmStatement, pstmt_query, UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+
+         U_NEW(World, pworld_query, World);
+
+         pstmt_query->use( pworld_query->id);
+         pstmt_query->into(pworld_query->randomNumber);
 
 
-         return UObjectIO::buffer_output;
+#     ifdef U_STATIC_ORM_DRIVER_PGSQL
+         if (UOrmDriver::isPGSQL())
+            {
+            pdrv  = (UOrmDriverPgSql*) World::psql_query->getDriver();
+            pstmt = (UPgSqlStatement*) World::pstmt_query->getStatement();
+
+            (void) ((UPgSqlStatement*)pstmt)->setBindParam(pdrv);
+            }
+#     endif
+
+         handlerFork();
          }
          }
+      }
+
+#ifdef DEBUG
+   static void handlerEndSql()
+      {
+      U_TRACE_NO_PARAM(0, "World::handlerEndSql()")
+
+      if (pstmt_query)
+         {
+         U_DELETE( pstmt_query)
+         U_DELETE(pworld_query)
+         U_DELETE(  psql_query)
 
 
-      return U_NULLPTR;
+         pstmt_query = U_NULLPTR;
+         }
       }
       }
+
+   const char* dump(bool breset) const;
 #endif
 #endif
 
 
 private:
 private:

+ 356 - 0
frameworks/C++/ulib/src/worldNoSql.h

@@ -0,0 +1,356 @@
+// worldNoSql.h
+
+#ifndef WORLD_NO_SQL_H
+#define WORLD_NO_SQL_H 1
+
+#include "world.h"
+
+#include <ulib/net/client/redis.h>
+#include <ulib/net/client/elasticsearch.h>
+
+#ifdef USE_MONGODB
+#  include <ulib/net/client/mongodb.h>
+#endif
+
+class WorldNoSql {
+public:
+
+   static UString* str_rnumber;
+
+   static void handlerOneResult(uint32_t uid)
+      {
+      U_TRACE(0, "WorldNoSql::handlerOneResult(%u)", uid)
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+      U_INTERNAL_ASSERT_POINTER(World::pwbuffer)
+
+      u_put_unalignedp32(World::pwbuffer, U_MULTICHAR_CONSTANT32('"','i','d','"'));
+
+      World::pwbuffer[4] = ':';
+
+      World::pwbuffer = u_num2str32(uid, World::pwbuffer+5);
+
+      u_put_unalignedp64(World::pwbuffer,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
+      u_put_unalignedp64(World::pwbuffer+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+                         World::pwbuffer += 16;
+
+      uint32_t sz = str_rnumber->size();
+
+      (void) memcpy(World::pwbuffer, str_rnumber->data(), sz);
+                    World::pwbuffer +=                    sz;
+
+      str_rnumber->clear();
+      }
+
+   static void handlerResult(uint32_t uid)
+      {
+      U_TRACE(0, "WorldNoSql::handlerResult(%u)", uid)
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+      U_INTERNAL_ASSERT_POINTER(World::pwbuffer)
+
+      u_put_unalignedp32(World::pwbuffer,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
+      u_put_unalignedp16(World::pwbuffer+4, U_MULTICHAR_CONSTANT16('"',':'));
+
+      World::pwbuffer = u_num2str32(uid, World::pwbuffer+6);
+
+      u_put_unalignedp64(World::pwbuffer,   U_MULTICHAR_CONSTANT64(',','"','r','a','n','d','o','m'));
+      u_put_unalignedp64(World::pwbuffer+8, U_MULTICHAR_CONSTANT64('N','u','m','b','e','r','"',':'));
+                         World::pwbuffer += 16;
+
+      uint32_t sz = str_rnumber->size();
+
+      (void) memcpy(World::pwbuffer, str_rnumber->data(), sz);
+                    World::pwbuffer +=                    sz;
+
+      str_rnumber->clear();
+
+      u_put_unalignedp16(World::pwbuffer, U_MULTICHAR_CONSTANT16('}',','));
+                         World::pwbuffer += 2;
+      }
+
+   static void doOneQuery(vPFu handlerQuery)
+      {
+      U_TRACE(0, "WorldNoSql::doOneQuery(%p)", handlerQuery)
+
+      World::initOneResult();
+
+      handlerQuery(World::rnumber[0]);
+
+      handlerOneResult(World::rnumber[0]);
+
+      World::endOneResult();
+      }
+
+   static void doQuery(vPFu handlerQuery)
+      {
+      U_TRACE(0, "WorldNoSql::doQuery(%p)", handlerQuery)
+
+      World::initResult();
+
+      for (uint32_t i = 0, n = UHTTP::getFormFirstNumericValue(1, 500); i < n; ++i)
+         {
+         handlerQuery(World::rnumber[i]);
+
+         handlerResult(World::rnumber[i]);
+         }
+
+      World::endResult();
+      }
+
+   static void handlerFork()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerFork()")
+
+      if (str_rnumber == U_NULLPTR) U_NEW_STRING(str_rnumber, UString);
+
+      World::handlerFork();
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+      }
+
+#ifdef USE_MONGODB
+   static bson_t* query;
+   static UMongoDBClient* mc;
+#endif
+
+   static void handlerQueryMongoDB(uint32_t uid)
+      {
+      U_TRACE(0, "WorldNoSql::handlerQueryMongoDB(%u)", uid)
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+
+#  ifdef USE_MONGODB
+      (void) mc->findOne(uid, query);
+      (void) U_JFIND(mc->vitem[0], "randomNumber", *str_rnumber);
+
+      uint32_t pos = str_rnumber->find_first_of('.');
+
+      if (pos != U_NOT_FOUND) str_rnumber->size_adjust_constant(pos);
+#  endif
+      }
+
+   static void handlerUpdateMongoDB(uint32_t i)
+      {
+      U_TRACE(0, "WorldNoSql::handlerUpdateMongoDB(%u)", i)
+
+#  ifdef USE_MONGODB
+      (void) mc->findOne(World::rnumber[i], query);
+      (void) mc->update( World::rnumber[i], "randomNumber", World::rnum = u_get_num_random_range1(10000));
+#  endif
+      }
+
+   static void handlerForkMongoDB()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerForkMongoDB()")
+
+#  ifdef USE_MONGODB
+      if (mc == U_NULLPTR)
+         {
+         U_NEW(UMongoDBClient, mc, UMongoDBClient);
+
+         if (mc->connect(U_NULLPTR, 0) == false)
+            {
+            U_WARNING("WorldNoSql::handlerForkMongoDB(): connection failed");
+
+            U_DELETE(mc)
+
+            mc = U_NULLPTR;
+
+            return;
+            }
+
+         if (mc->selectCollection("hello_world", "world") == false)
+            {
+            U_WARNING("WorldNoSql::handlerForkMongoDB(): selectCollection() failed");
+
+            U_DELETE(mc)
+
+            mc = U_NULLPTR;
+
+            return;
+            }
+
+         query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
+
+         handlerFork();
+         }
+#  endif
+      }
+
+   static char rc_buffer[128];
+   static UREDISClient_Base* rc;
+
+   static void handlerQueryREDIS(uint32_t uid)
+      {
+      U_TRACE(0, "WorldNoSql::handlerQueryREDIS(%u)", uid)
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+
+      char* ptr = rc_buffer+U_CONSTANT_SIZE("world:");
+
+      (void) rc->get(ptr, U_CONSTANT_SIZE("world:")+u_num2str32(uid, ptr)-ptr);
+
+      *str_rnumber = rc->vitem[0];
+      }
+
+   static void handlerUpdateREDIS(uint32_t i)
+      {
+      U_TRACE(0, "WorldNoSql::handlerUpdateREDIS(%u)", i)
+
+      char* start = rc_buffer+U_CONSTANT_SIZE("world:");
+      char* ptr = u_num2str32(World::rnumber[i], start);
+
+      (void) rc->get(start, ptr-start);
+
+      *ptr = ' ';
+       ptr = u_num2str32(World::rnum = u_get_num_random_range1(10000), ptr+1);
+
+      (void) rc->mset(start, ptr-start);
+      }
+
+   static void handlerForkREDIS()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerForkREDIS()")
+
+      if (rc == U_NULLPTR)
+         {
+         U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
+
+         if (rc->connect() == false)
+            {
+            U_WARNING("WorldNoSql::handlerForkREDIS(): %V", rc->UClient_Base::getResponse().rep);
+
+            U_DELETE(rc)
+
+            rc = U_NULLPTR;
+
+            return;
+            }
+
+         U_MEMCPY(rc_buffer, "world:", U_CONSTANT_SIZE("world:"));
+
+         handlerFork();
+         }
+      }
+
+   static char* pbuffer1;
+   static char* pbuffer2;
+   static char es_buffer1[128];
+   static char es_buffer2[128];
+   static UElasticSearchClient* es;
+
+#  define U_QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
+
+   static void handlerQueryElasticSearch(uint32_t uid)
+      {
+      U_TRACE(0, "WorldNoSql::handlerQueryElasticSearch(%u)", uid)
+
+      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+
+      (void) es->sendPOST(U_CONSTANT_TO_PARAM("/tfb/world/_search"), es_buffer1, U_QLEN+
+                                                         u__snprintf(es_buffer1+ U_QLEN,
+                                                              sizeof(es_buffer1)-U_QLEN, U_CONSTANT_TO_PARAM("%u\"}}}"), uid));
+
+      (void) U_JFIND(es->getContent(), "randomNumber", *str_rnumber);
+      }
+
+   static void handlerUpdateElasticSearch(uint32_t i)
+      {
+      U_TRACE(0, "WorldNoSql::handlerUpdateElasticSearch(%u)", i)
+
+      uint32_t len1 = u__snprintf(pbuffer1, 100, U_CONSTANT_TO_PARAM("%u/_update"), World::rnumber[i]),
+               len2 = u__snprintf(pbuffer2, 100, U_CONSTANT_TO_PARAM("%u\"}}"), World::rnum = u_get_num_random_range1(10000));
+
+      (void) es->sendPOST(es_buffer1, len1+U_CONSTANT_SIZE("/tfb/world/"), es_buffer2, len2+U_CONSTANT_SIZE("{\"doc\":{\"_id\":\""));
+      }
+
+   static void handlerForkElasticSearch()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerForkElasticSearch()")
+
+      if (es == U_NULLPTR)
+         {
+         U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+
+         if (es->connect() == false)
+            {
+            U_WARNING("WorldNoSql::handlerForkElasticSearch(): connection disabled or failed");
+
+            U_DELETE(es)
+
+            es = U_NULLPTR;
+
+            return;
+            }
+
+         U_MEMCPY(es_buffer1, "{\"query\":{\"match\":{\"_id\":\"", U_QLEN);
+
+         handlerFork();
+         }
+      }
+
+#ifdef DEBUG
+   static void handlerEnd()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerEnd()")
+
+      if (str_rnumber)
+         {
+         U_DELETE(str_rnumber)
+
+         str_rnumber = U_NULLPTR;
+         }
+      }
+
+   static void handlerEndMongoDB()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerEndMongoDB()")
+
+#  ifdef USE_MONGODB
+      if (query)
+         {
+         U_DELETE(mc)
+
+         U_SYSCALL_VOID(bson_destroy, "%p", query);
+
+         query = U_NULLPTR;
+
+         handlerEnd();
+         }
+#  endif
+      }
+
+   static void handlerEndREDIS()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerEndREDIS()")
+
+      if (rc)
+         {
+         U_DELETE(rc)
+
+         rc = U_NULLPTR;
+
+         handlerEnd();
+         }
+      }
+
+   static void handlerEndElasticSearch()
+      {
+      U_TRACE_NO_PARAM(0, "WorldNoSql::handlerEndElasticSearch()")
+
+      if (es)
+         {
+         U_DELETE(es)
+
+         es = U_NULLPTR;
+
+         handlerEnd();
+         }
+      }
+#endif
+
+private:
+   U_DISALLOW_ASSIGN(WorldNoSql)
+};
+#endif

+ 3 - 2
frameworks/C++/ulib/ulib-mongodb.dockerfile

@@ -73,7 +73,8 @@ RUN USP_FLAGS="-DAS_cpoll_cppsp_DO" \
 RUN make install && \
 RUN make install && \
 	 cd examples/userver && make install && \
 	 cd examples/userver && make install && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
-    make mdb.la mquery.la mupdate.la mfortune.la && \
+    AM_LDFLAGS="-lFortune -lFortuneNoSql" make mfortune.la && \
+	 AM_LDFLAGS="-lWorld -lWorldNoSql" make mdb.la mquery.la mupdate.la && \
     cp .libs/mdb.so .libs/mquery.so .libs/mupdate.so .libs/mfortune.so $ULIB_DOCUMENT_ROOT
     cp .libs/mdb.so .libs/mquery.so .libs/mupdate.so .libs/mfortune.so $ULIB_DOCUMENT_ROOT
 
 
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
@@ -82,7 +83,7 @@ ADD ./ /ulib
 WORKDIR /ulib
 WORKDIR /ulib
 
 
 ENV MONGODB_HOST=tfb-database
 ENV MONGODB_HOST=tfb-database
-ENV UMEMPOOL="96,0,0,47,16401,-14,-20,-18,26"
+ENV UMEMPOOL="96,0,0,97,16417,-14,-20,-18,26"
 
 
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
     $IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg
     $IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg

+ 3 - 2
frameworks/C++/ulib/ulib-mysql.dockerfile

@@ -68,7 +68,8 @@ RUN USP_FLAGS="-DAS_cpoll_cppsp_DO" \
 RUN make install && \
 RUN make install && \
 	 cd examples/userver && make install && \
 	 cd examples/userver && make install && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
-    make db.la query.la update.la fortune.la cached_worlds.la && \
+    AM_LDFLAGS="-lFortune" make fortune.la && \
+	 AM_LDFLAGS="-lWorld" make db.la query.la update.la cached_worlds.la && \
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
 
 
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
@@ -78,7 +79,7 @@ WORKDIR /ulib
 
 
 ENV ORM_DRIVER="mysql"
 ENV ORM_DRIVER="mysql"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
-ENV UMEMPOOL="581,0,0,59,16409,-7,-20,-23,31"
+ENV UMEMPOOL="96,0,0,97,16417,-14,-20,-18,26"
 
 
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
     $IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg
     $IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg

+ 4 - 3
frameworks/C++/ulib/ulib-postgres.dockerfile

@@ -15,7 +15,7 @@ RUN apt update -yqq && \
     liborc-0.4-0 \
     liborc-0.4-0 \
     libmcrypt-dev libicu-dev \
     libmcrypt-dev libicu-dev \
     re2c libnuma-dev \
     re2c libnuma-dev \
-	 postgresql-server-dev-all libcap2-bin && \
+	 postgresql-server-dev-all libcap2-bin libldap-dev && \
 	 add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 apt update -yqq && \
 	 apt update -yqq && \
 	 apt install -yqq gcc-8 g++-8
 	 apt install -yqq gcc-8 g++-8
@@ -68,7 +68,8 @@ RUN USP_FLAGS="-DAS_cpoll_cppsp_DO" \
 RUN make install && \
 RUN make install && \
 	 cd examples/userver && make install && \
 	 cd examples/userver && make install && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
-    make db.la query.la update.la fortune.la cached_worlds.la && \
+    AM_LDFLAGS="-lFortune" make fortune.la && \
+	 AM_LDFLAGS="-lWorld" make db.la query.la update.la cached_worlds.la && \
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
 
 
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
@@ -77,7 +78,7 @@ ADD ./ /ulib
 WORKDIR /ulib
 WORKDIR /ulib
 
 
 ENV ORM_DRIVER="pgsql"
 ENV ORM_DRIVER="pgsql"
-ENV UMEMPOOL="581,0,0,59,16409,-7,-20,-23,31"
+ENV UMEMPOOL="96,0,0,97,16417,-14,-20,-18,26"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 
 
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \

+ 4 - 3
frameworks/C++/ulib/ulib-postgres_fit.dockerfile

@@ -15,7 +15,7 @@ RUN apt update -yqq && \
     liborc-0.4-0 \
     liborc-0.4-0 \
     libmcrypt-dev libicu-dev \
     libmcrypt-dev libicu-dev \
     re2c libnuma-dev \
     re2c libnuma-dev \
-	 postgresql-server-dev-all libcap2-bin && \
+	 postgresql-server-dev-all libcap2-bin libldap-dev && \
 	 add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 add-apt-repository ppa:ubuntu-toolchain-r/test -y && \
 	 apt update -yqq && \
 	 apt update -yqq && \
 	 apt install -yqq gcc-8 g++-8
 	 apt install -yqq gcc-8 g++-8
@@ -68,7 +68,8 @@ RUN USP_FLAGS="-DAS_cpoll_cppsp_DO" \
 RUN make install && \
 RUN make install && \
 	 cd examples/userver && make install && \
 	 cd examples/userver && make install && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
 	 cd ../../src/ulib/net/server/plugin/usp && \
-    make db.la query.la update.la fortune.la cached_worlds.la && \
+    AM_LDFLAGS="-lFortune" make fortune.la && \
+	 AM_LDFLAGS="-lWorld" make db.la query.la update.la cached_worlds.la && \
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
     cp .libs/db.so .libs/query.so .libs/update.so .libs/fortune.so .libs/cached_worlds.so $ULIB_DOCUMENT_ROOT
 
 
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
 ENV PATH=${ULIB_ROOT}/bin:${PATH}
@@ -77,7 +78,7 @@ ADD ./ /ulib
 WORKDIR /ulib
 WORKDIR /ulib
 
 
 ENV ORM_DRIVER="pgsql"
 ENV ORM_DRIVER="pgsql"
-ENV UMEMPOOL="581,0,0,59,16409,-7,-20,-23,31"
+ENV UMEMPOOL="96,0,0,97,16417,-14,-20,-18,26"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 ENV ORM_OPTION="host=tfb-database user=benchmarkdbuser password=benchmarkdbpass dbname=hello_world client_encoding=UTF8"
 
 
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \
 CMD setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp && \