Просмотр исходного кода

ULib: some optimization plus enable db postgres async model (#3957)

* ULib: some optimization plus enable db postgres async model

* ULib: some optimization plus enable db postgres async model

* ULib: some optimization plus enable db postgres async model
stefano casazza 7 лет назад
Родитель
Сommit
9894766ab6

+ 21 - 14
frameworks/C++/ulib/src/db.usp

@@ -5,26 +5,35 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 #include "world.h"
 
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+static void handlerResult(void* res, uint32_t num_result)
+{
+   U_TRACE(5, "::handlerResult(%p,%u)", res, num_result)
+
+   U_INTERNAL_ASSERT_EQUALS(num_result, 1)
+   U_INTERNAL_ASSERT_EQUALS(PQnfields((PGresult*)res), 1)
+   U_INTERNAL_ASSERT_EQUALS(PQntuples((PGresult*)res), 1)
+
+   char* randomNumber = U_SYSCALL(PQgetvalue, "%p,%d,%d", (PGresult*)res, 0, 0);
+
+   World::handlerOneResult(ntohl(*(uint32_t*)randomNumber));
+}
+#endif
+
+static void usp_init_db() { World::handlerInitSql(); }
 static void usp_fork_db() { World::handlerForkSql(); }
 -->
 <!--#header
 -->
 <!--#code
-World::initOneResult();
-
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
-if (World::pdrv)
+if (World::pstmt)
    {
-   PGresult* res = World::execPrepared();
+   UServer_Base::handler_db1->handlerQuery();
 
-   U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 1)
-   U_INTERNAL_ASSERT_EQUALS(PQntuples(res), 1)
+   World::sendQueryPrepared();
 
-   char* randomNumber = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, 0, 0);
-
-   World::handlerOneResult(World::rnumber[0], ntohl(*(uint32_t*)randomNumber));
-
-   U_SYSCALL_VOID(PQclear, "%p", res);
+   UServer_Base::handler_db1->handlerResult(handlerResult);
    }
 else
 #endif
@@ -33,8 +42,6 @@ World::pworld_query->id = World::rnumber[0];
 
 (void) World::pstmt_query->execute();
 
-World::handlerOneResult(World::pworld_query->id, World::pworld_query->randomNumber);
+World::handlerOneResult(World::pworld_query->randomNumber);
 }
-
-World::endOneResult();
 -->

+ 241 - 169
frameworks/C++/ulib/src/fortune.h

@@ -11,238 +11,310 @@
 #include <ulib/net/server/client_image.h>
 
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
+#	include <ulib/event/event_db.h>
 #  include <ulib/orm/driver/orm_driver_pgsql.h>
 #endif
 
-class Fortune {
+class U_EXPORT Fortune {
 public:
-   uint32_t id;
-   UString message;
+	uint32_t id;
+	UString message;
 
-   Fortune(uint32_t _id) : id(_id), message(101U)
-      {
-      U_TRACE_CTOR(5, Fortune, "%u", _id)
-      }
+	Fortune(uint32_t _id) : id(_id), message(101U)
+		{
+		U_TRACE_CTOR(5, Fortune, "%u", _id)
+		}
 
-   Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
-      {
-      U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
-      }
+	Fortune(uint32_t _id, const UString& _message) : id(_id), message(_message)
+		{
+		U_TRACE_CTOR(5, Fortune, "%u,%V", _id, _message.rep)
+		}
 
-   Fortune(const Fortune& f) : id(f.id), message(f.message)
-      {
-      U_TRACE_CTOR(5, Fortune, "%p", &f)
+	Fortune(const Fortune& f) : id(f.id), message(f.message)
+		{
+		U_TRACE_CTOR(5, Fortune, "%p", &f)
 
-      U_MEMORY_TEST_COPY(f)
-      }
+		U_MEMORY_TEST_COPY(f)
+		}
 
-   ~Fortune()
-      {
-      U_TRACE_DTOR(5, Fortune)
-      }
+	~Fortune()
+		{
+		U_TRACE_DTOR(5, Fortune)
+		}
 
-   // SERVICE
+	// SERVICE
 
-   bool operator<(const Fortune& other) const { return cmp_obj(&message, &other.message); }
+	bool operator<(const Fortune& other) const { return cmp_obj(&message, &other.message); }
 
-   static int cmp_obj(const void* a, const void* b)
-      {
-      U_TRACE(5, "Fortune::cmp_obj(%p,%p)", a, b)
-
-#  ifdef U_STDCPP_ENABLE
-      /**
-       * The comparison function must follow a strict-weak-ordering
-       *
-       * 1) For all x, it is not the case that x < x (irreflexivity)
-       * 2) For all x, y, if x < y then it is not the case that y < x (asymmetry)
-       * 3) For all x, y, and z, if x < y and y < z then x < z (transitivity)
-       * 4) For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of incomparability)
-       */
-
-      return (((const Fortune*)a)->message.compare(((const Fortune*)b)->message) < 0);
-#  else
-      return (*(const Fortune**)a)->message.compare((*(const Fortune**)b)->message);
-#  endif
-      }
-
-   // JSON
+	static int cmp_obj(const void* a, const void* b)
+		{
+		U_TRACE(5, "Fortune::cmp_obj(%p,%p)", a, b)
 
-   void toJSON(UString& json)
-      {
-      U_TRACE(5, "Fortune::toJSON(%V)", json.rep)
+#	ifdef U_STDCPP_ENABLE
+		/**
+		 * The comparison function must follow a strict-weak-ordering
+		 *
+		 * 1) For all x, it is not the case that x < x (irreflexivity)
+		 * 2) For all x, y, if x < y then it is not the case that y < x (asymmetry)
+		 * 3) For all x, y, and z, if x < y and y < z then x < z (transitivity)
+		 * 4) For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of incomparability)
+		 */
 
-      json.toJSON(U_JSON_METHOD_HANDLER(id,      unsigned int));
-      json.toJSON(U_JSON_METHOD_HANDLER(message, UString));
-      }
+		return (((const Fortune*)a)->message.compare(((const Fortune*)b)->message) < 0);
+#	else
+		return (*(const Fortune**)a)->message.compare((*(const Fortune**)b)->message);
+#	endif
+		}
 
-   void fromJSON(UValue& json)
-      {
-      U_TRACE(5, "Fortune::fromJSON(%p)", &json)
+	// JSON
 
-      json.fromJSON(U_JSON_METHOD_HANDLER(id,      unsigned int));
-      json.fromJSON(U_JSON_METHOD_HANDLER(message, UString));
-      }
+	void toJSON(UString& json)
+		{
+		U_TRACE(5, "Fortune::toJSON(%V)", json.rep)
 
-   // ORM
+		json.toJSON(U_JSON_METHOD_HANDLER(id,		 unsigned int));
+		json.toJSON(U_JSON_METHOD_HANDLER(message, UString));
+		}
 
-   void bindParam(UOrmStatement* stmt)
-      {
-      U_TRACE(5, "Fortune::bindParam(%p)", stmt)
+	void fromJSON(UValue& json)
+		{
+		U_TRACE(5, "Fortune::fromJSON(%p)", &json)
 
-      stmt->bindParam(U_ORM_TYPE_HANDLER(id,      unsigned int));
-      stmt->bindParam(U_ORM_TYPE_HANDLER(message, UString));
-      }
+		json.fromJSON(U_JSON_METHOD_HANDLER(id,		unsigned int));
+		json.fromJSON(U_JSON_METHOD_HANDLER(message, UString));
+		}
 
-   void bindResult(UOrmStatement* stmt)
-      {
-      U_TRACE(5, "Fortune::bindResult(%p)", stmt)
+	// ORM
 
-      stmt->bindResult(U_ORM_TYPE_HANDLER(id,      unsigned int));
-      stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
-      }
+	void bindParam(UOrmStatement* stmt)
+		{
+		U_TRACE(5, "Fortune::bindParam(%p)", stmt)
 
-   static uint32_t uid;
-   static UString* pmessage;
-   static UVector<Fortune*>* pvfortune;
+		stmt->bindParam(U_ORM_TYPE_HANDLER(id,		  unsigned int));
+		stmt->bindParam(U_ORM_TYPE_HANDLER(message, UString));
+		}
 
-   static UOrmSession*    psql_fortune;
-   static UOrmStatement* pstmt_fortune;
+	void bindResult(UOrmStatement* stmt)
+		{
+		U_TRACE(5, "Fortune::bindResult(%p)", stmt)
 
-   static void replace(uint32_t i, uint32_t _id, const char* msg, uint32_t len)
-      {
-      U_TRACE(5, "Fortune::replace(%u,%u,%.*S,%u)", i, _id, len, msg, len)
+		stmt->bindResult(U_ORM_TYPE_HANDLER(id,		unsigned int));
+		stmt->bindResult(U_ORM_TYPE_HANDLER(message, UString));
+		}
 
-      U_INTERNAL_ASSERT_POINTER(pvfortune)
+	static uint32_t uid;
+	static char* pwbuffer;
+	static UString* pmessage;
+	static UVector<Fortune*>* pvfortune;
 
-      Fortune* elem = pvfortune->at(i);
+	static UOrmSession*	  psql_fortune;
+	static UOrmStatement* pstmt_fortune;
 
-      elem->id = _id;
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+	static PGconn* conn;
+	static UPgSqlStatement* pstmt;
+
+	static PGresult* execPrepared()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::execPrepared()")
+
+		PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 0, 0, 0, 0, 1);
+
+		U_RETURN_POINTER(res, PGresult);
+		}
+
+	static void sendQueryPrepared()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::sendQueryPrepared()")
+
+		(void) U_SYSCALL(PQsendQueryPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 0, 0, 0, 0, 1);
+		}
+#endif
+
+	static void replace(uint32_t i, uint32_t _id, const char* msg, uint32_t len)
+		{
+		U_TRACE(5, "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 initQuery()
+		{
+		U_TRACE_NO_PARAM(5, "::initQuery()")
+
+		char* ptr = UClientImage_Base::wbuffer->data();
+
+		U_INTERNAL_DUMP("wbuffer(%u) = %#.10S", UClientImage_Base::wbuffer->size(), ptr)
+
+		if (u_get_unalignedp64(ptr+48) != U_MULTICHAR_CONSTANT64('h','a','r','s','e','t','=','U'))
+			{
+			u_put_unalignedp64(ptr,	    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+			u_put_unalignedp64(ptr+8,   U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
+			u_put_unalignedp64(ptr+16,  U_MULTICHAR_CONSTANT64('1','2','2','7','\r','\n','C','o'));
+			u_put_unalignedp64(ptr+24,  U_MULTICHAR_CONSTANT64('n','t','e','n','t','-','T','y'));
+			u_put_unalignedp64(ptr+32,  U_MULTICHAR_CONSTANT64('p','e',':',' ','t','e','x','t'));
+			u_put_unalignedp64(ptr+40,  U_MULTICHAR_CONSTANT64('/','h','t','m','l',';',' ','c'));
+			u_put_unalignedp64(ptr+48,  U_MULTICHAR_CONSTANT64('h','a','r','s','e','t','=','U'));
+			u_put_unalignedp64(ptr+56,  U_MULTICHAR_CONSTANT64('T','F','-','8','\r','\n','\r','\n'));
+			u_put_unalignedp64(ptr+64,  U_MULTICHAR_CONSTANT64('<','!','d','o','c','t','y','p'));
+			u_put_unalignedp64(ptr+72,  U_MULTICHAR_CONSTANT64('e',' ','h','t','m','l','>','<'));
+			u_put_unalignedp64(ptr+80,  U_MULTICHAR_CONSTANT64('h','t','m','l','>','<','h','e'));
+			u_put_unalignedp64(ptr+88,  U_MULTICHAR_CONSTANT64('a','d','>','<','t','i','t','l'));
+			u_put_unalignedp64(ptr+96,  U_MULTICHAR_CONSTANT64('e','>','F','o','r','t','u','n'));
+			u_put_unalignedp64(ptr+104, U_MULTICHAR_CONSTANT64('e','s','<','/','t','i','t','l'));
+			u_put_unalignedp64(ptr+112, U_MULTICHAR_CONSTANT64('e','>','<','/','h','e','a','d'));
+			u_put_unalignedp64(ptr+120, U_MULTICHAR_CONSTANT64('>','<','b','o','d','y','>','<'));
+			u_put_unalignedp64(ptr+128, U_MULTICHAR_CONSTANT64('t','a','b','l','e','>','<','t'));
+			u_put_unalignedp64(ptr+136, U_MULTICHAR_CONSTANT64('r','>','<','t','h','>','i','d'));
+			u_put_unalignedp64(ptr+144, U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','t','h'));
+			u_put_unalignedp64(ptr+152, U_MULTICHAR_CONSTANT64('>','m','e','s','s','a','g','e'));
+			u_put_unalignedp64(ptr+160, U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','/','t'));
+			u_put_unalignedp16(ptr+168, U_MULTICHAR_CONSTANT16('r','>'));
+
+			pwbuffer	= ptr + U_CONSTANT_SIZE("Content-Length: 1227\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n"
+														"<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
+			}
+
+		U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(UClientImage_Base::wbuffer->data()), U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'))
+
+		UClientImage_Base::wbuffer->size_adjust_constant(U_CONSTANT_SIZE("Content-Length: 1227\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n") + 1227);
+		}
+
+	static void endQuery()
+		{
+		U_TRACE_NO_PARAM(5, "::endQuery()")
+
+		U_INTERNAL_ASSERT_POINTER(pvfortune)
+
+		Fortune* elem = pvfortune->last();
 
-      UXMLEscape::encode(msg, len, elem->message);
-      }
+		elem->id = 0;
+		elem->message.rep->replace(U_CONSTANT_TO_PARAM("Additional fortune added at request time."));
 
-   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)); }
+		pvfortune->sort(Fortune::cmp_obj);
 
-   static void doQuery(vPF handlerQuery)
-      {
-      U_TRACE(5, "Fortune::doQuery(%p)", handlerQuery)
+		char* ptr = pwbuffer;
 
-      U_INTERNAL_ASSERT_POINTER(pvfortune)
+		for (uint32_t sz, i = 0, n = pvfortune->size(); i < n; ++i)
+			{
+			elem = pvfortune->at(i);
 
-      char* pwbuffer = UClientImage_Base::wbuffer->data();
+			u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','t','r','>','<','t','d','>'));
 
-      u_put_unalignedp64(pwbuffer,     U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
-      u_put_unalignedp64(pwbuffer+8,   U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
-      u_put_unalignedp64(pwbuffer+16,  U_MULTICHAR_CONSTANT64('1','2','2','7','\r','\n','C','o'));
-      u_put_unalignedp64(pwbuffer+24,  U_MULTICHAR_CONSTANT64('n','t','e','n','t','-','T','y'));
-      u_put_unalignedp64(pwbuffer+32,  U_MULTICHAR_CONSTANT64('p','e',':',' ','t','e','x','t'));
-      u_put_unalignedp64(pwbuffer+40,  U_MULTICHAR_CONSTANT64('/','h','t','m','l',';',' ','c'));
-      u_put_unalignedp64(pwbuffer+48,  U_MULTICHAR_CONSTANT64('h','a','r','s','e','t','=','U'));
-      u_put_unalignedp64(pwbuffer+56,  U_MULTICHAR_CONSTANT64('T','F','-','8','\r','\n','\r','\n'));
-      u_put_unalignedp64(pwbuffer+64,  U_MULTICHAR_CONSTANT64('<','!','d','o','c','t','y','p'));
-      u_put_unalignedp64(pwbuffer+72,  U_MULTICHAR_CONSTANT64('e',' ','h','t','m','l','>','<'));
-      u_put_unalignedp64(pwbuffer+80,  U_MULTICHAR_CONSTANT64('h','t','m','l','>','<','h','e'));
-      u_put_unalignedp64(pwbuffer+88,  U_MULTICHAR_CONSTANT64('a','d','>','<','t','i','t','l'));
-      u_put_unalignedp64(pwbuffer+96,  U_MULTICHAR_CONSTANT64('e','>','F','o','r','t','u','n'));
-      u_put_unalignedp64(pwbuffer+104, U_MULTICHAR_CONSTANT64('e','s','<','/','t','i','t','l'));
-      u_put_unalignedp64(pwbuffer+112, U_MULTICHAR_CONSTANT64('e','>','<','/','h','e','a','d'));
-      u_put_unalignedp64(pwbuffer+120, U_MULTICHAR_CONSTANT64('>','<','b','o','d','y','>','<'));
-      u_put_unalignedp64(pwbuffer+128, U_MULTICHAR_CONSTANT64('t','a','b','l','e','>','<','t'));
-      u_put_unalignedp64(pwbuffer+136, U_MULTICHAR_CONSTANT64('r','>','<','t','h','>','i','d'));
-      u_put_unalignedp64(pwbuffer+144, U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','t','h'));
-      u_put_unalignedp64(pwbuffer+152, U_MULTICHAR_CONSTANT64('>','m','e','s','s','a','g','e'));
-      u_put_unalignedp64(pwbuffer+160, U_MULTICHAR_CONSTANT64('<','/','t','h','>','<','/','t'));
-      u_put_unalignedp16(pwbuffer+168, U_MULTICHAR_CONSTANT16('r','>'));
+			ptr = u_num2str32(elem->id, ptr+8);
 
-      pwbuffer += U_CONSTANT_SIZE("Content-Length: 1227\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n"
-                                  "<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr>");
+			u_put_unalignedp64(ptr, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','t','d'));
+									 ptr += 8;
 
-      handlerQuery();
+			*ptr++ = '>';
 
-      Fortune* elem = pvfortune->last();
+			(void) memcpy(ptr, elem->message.data(), sz = elem->message.size());
+							  ptr += sz;
 
-      elem->id = 0;
-      elem->message.rep->replace(U_CONSTANT_TO_PARAM("Additional fortune added at request time."));
+			u_put_unalignedp64(ptr,   U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
+			u_put_unalignedp16(ptr+8, U_MULTICHAR_CONSTANT16('r','>'));
+									 ptr += 8+2;
+			}
 
-      pvfortune->sort(Fortune::cmp_obj);
+		u_put_unalignedp64(ptr,    U_MULTICHAR_CONSTANT64('<','/','t','a','b','l','e','>'));
+		u_put_unalignedp64(ptr+8,  U_MULTICHAR_CONSTANT64('<','/','b','o','d','y','>','<'));
+		u_put_unalignedp64(ptr+16, U_MULTICHAR_CONSTANT64('/','h','t','m','l','>','\0','\0'));
+		}
 
-      for (uint32_t sz, i = 0, n = pvfortune->size(); i < n; ++i)
-         {
-         elem = pvfortune->at(i);
+	static void doQuery(vPF handlerQuery)
+		{
+		U_TRACE(5, "Fortune::doQuery(%p)", handlerQuery)
 
-         u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','t','r','>','<','t','d','>'));
+			initQuery();
+		handlerQuery();
+			 endQuery();
+		}
 
-         pwbuffer = u_num2str32(elem->id, pwbuffer+8);
+	static void handlerInitSql()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::handlerInitSql()")
 
-         u_put_unalignedp64(pwbuffer, U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','t','d'));
-                            pwbuffer += 8;
+#	ifdef U_STATIC_ORM_DRIVER_PGSQL
+		U_INTERNAL_DUMP("UServer_Base::handler_db2 = %p", UServer_Base::handler_db2)
 
-         *pwbuffer++ = '>';
+		if (UServer_Base::handler_db2 == U_NULLPTR)
+			{
+			U_NEW(UEventDB, UServer_Base::handler_db2, UEventDB);
+			}
+#	endif
+		}
 
-         (void) memcpy(pwbuffer, elem->message.data(), sz = elem->message.size());
-                       pwbuffer += sz;
+	static void handlerFork()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::handlerFork()")
 
-         u_put_unalignedp64(pwbuffer,   U_MULTICHAR_CONSTANT64('<','/','t','d','>','<','/','t'));
-         u_put_unalignedp16(pwbuffer+8, U_MULTICHAR_CONSTANT16('r','>'));
-                            pwbuffer += 8+2;
-         }
+		U_NEW_STRING(pmessage, UString(101U));
 
-      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'));
+		U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
 
-      UClientImage_Base::wbuffer->size_adjust_constant(pwbuffer + U_CONSTANT_SIZE("</table></body></html>"));
-      }
+		Fortune* elem;
 
-   static void handlerFork()
-      {
-      U_TRACE_NO_PARAM(5, "Fortune::handlerFork()")
+		for (uint32_t i = 0; i < 13; ++i)
+			{
+			U_NEW(Fortune, elem, Fortune(i+1));
 
-      U_NEW_STRING(pmessage, UString(101U));
+			pvfortune->push(elem);
+			}
+		}
 
-      U_NEW(UVector<Fortune*>, pvfortune, UVector<Fortune*>);
+	static void handlerForkSql()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::handlerForkSql()")
 
-      Fortune* elem;
+		if (psql_fortune == U_NULLPTR)
+			{
+			U_NEW(UOrmSession, psql_fortune, UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
 
-      for (uint32_t i = 0; i < 13; ++i)
-         {
-         U_NEW(Fortune, elem, Fortune(i+1));
+			if (psql_fortune->isReady() == false)
+				{
+				U_WARNING("Fortune::handlerForkSql(): we cound't connect to db");
 
-         pvfortune->push(elem);
-         }
-      }
+				U_DELETE(psql_fortune)
 
-   static void handlerForkSql()
-      {
-      U_TRACE_NO_PARAM(5, "Fortune::handlerForkSql()")
+				psql_fortune = U_NULLPTR;
 
-      if (psql_fortune == U_NULLPTR)
-         {
-         U_NEW(UOrmSession, psql_fortune, UOrmSession(U_CONSTANT_TO_PARAM("fortune")));
+				return;
+				}
 
-         if (psql_fortune->isReady() == false)
-            {
-            U_WARNING("Fortune::handlerForkSql(): we cound't connect to db");
+			U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
 
-            U_DELETE(psql_fortune)
+			handlerFork();
 
-            psql_fortune = U_NULLPTR;
+			pstmt_fortune->into(uid, *pmessage);
 
-            return;
-            }
+#		ifdef U_STATIC_ORM_DRIVER_PGSQL
+			if (UOrmDriver::isPGSQL())
+				{
+				UOrmDriverPgSql* pdrv = (UOrmDriverPgSql*)psql_fortune->getDriver();
 
-         U_NEW(UOrmStatement, pstmt_fortune, UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
+				 conn = (PGconn*)pdrv->UOrmDriver::connection;
+				pstmt = (UPgSqlStatement*)pstmt_fortune->getStatement();
 
-         handlerFork();
+				pstmt->prepareStatement(pdrv);
 
-         pstmt_fortune->into(uid, *pmessage);
-         }
-      }
+				UServer_Base::handler_db2->setConnection(conn);
+				}
+#		endif
+			}
+		}
 
 private:
-   U_DISALLOW_ASSIGN(Fortune)
+	U_DISALLOW_ASSIGN(Fortune)
 };
 #endif

+ 29 - 37
frameworks/C++/ulib/src/fortune.usp

@@ -5,12 +5,6 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 #include "fortune.h"
 
-static vPF handle_query;
-#ifdef U_STATIC_ORM_DRIVER_PGSQL
-static UOrmDriverPgSql* pdrv;
-static UPgSqlStatement* pstmt;
-#endif
-
 static void handlerQuery()
 {
    U_TRACE_NO_PARAM(5, "::handlerQuery()")
@@ -25,53 +19,51 @@ static void handlerQuery()
    while (Fortune::pstmt_fortune->nextRow());
 }
 
-static void handlerQueryPGSQL()
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+static void handlerResult(void* res, uint32_t num_result)
 {
-   U_TRACE_NO_PARAM(5, "::handlerQueryPGSQL()")
+   U_TRACE(5, "::handlerResult(%p,%u)", res, num_result)
+
+   U_INTERNAL_ASSERT_EQUALS(num_result, 1)
+   U_INTERNAL_ASSERT_EQUALS(PQnfields((PGresult*)res), 2)
 
-#ifdef U_STATIC_ORM_DRIVER_PGSQL
    int sz;
    char* id;
    char* ptr;
-   PGresult* res = pdrv->execPrepared(pstmt);
 
-   U_INTERNAL_ASSERT_EQUALS(PQnfields(res), 2)
+   Fortune::initQuery();
 
-   for (uint32_t i = 0, n = U_SYSCALL(PQntuples, "%p", res); i < n; ++i)
+   for (uint32_t i = 0, n = U_SYSCALL(PQntuples, "%p", (PGresult*)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);
+       id = U_SYSCALL(PQgetvalue,  "%p,%d,%d", (PGresult*)res, i, 0);
+      ptr = U_SYSCALL(PQgetvalue,  "%p,%d,%d", (PGresult*)res, i, 1);
+      sz  = U_SYSCALL(PQgetlength, "%p,%d,%d", (PGresult*)res, i, 1);
 
       Fortune::replace(i, ntohl(*(uint32_t*)id), ptr, sz);
       }
 
-   U_SYSCALL_VOID(PQclear, "%p", res);
-#endif
+   Fortune::endQuery();
 }
+#endif
 
-static void usp_fork_fortune()
-{
-   U_TRACE_NO_PARAM(5, "::usp_fork_fortune()")
-
-   Fortune::handlerForkSql();
-
-   if (UOrmDriver::isPGSQL() == false) handle_query = handlerQuery;
-   else
-      {
-      handle_query = handlerQueryPGSQL;
-
-#  ifdef U_STATIC_ORM_DRIVER_PGSQL
-      pdrv  = (UOrmDriverPgSql*) Fortune::psql_fortune->getDriver();
-      pstmt = (UPgSqlStatement*) Fortune::pstmt_fortune->getStatement();
-
-      pstmt->prepareStatement(pdrv);
-#  endif
-      }
-}
+static void usp_init_fortune() { Fortune::handlerInitSql(); }
+static void usp_fork_fortune() { Fortune::handlerForkSql(); }
 -->
 <!--#header
 -->
 <!--#code
-Fortune::doQuery(handle_query);
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+if (Fortune::pstmt)
+   {
+   UServer_Base::handler_db2->handlerQuery();
+
+   Fortune::sendQueryPrepared();
+
+   UServer_Base::handler_db2->handlerResult(handlerResult);
+   }
+else
+#endif
+{
+Fortune::doQuery(handlerQuery);
+}
 -->

+ 65 - 65
frameworks/C++/ulib/src/fortuneNoSql.h

@@ -12,104 +12,104 @@
 #  include <ulib/net/client/mongodb.h>
 #endif
 
-class FortuneNoSql {
+class U_EXPORT FortuneNoSql {
 public:
 
 #ifdef USE_MONGODB
-   static UMongoDBClient* mc;
+	static UMongoDBClient* mc;
 #endif
 
-   static void handlerQueryMongoDB()
-      {
-      U_TRACE(5, "FortuneNoSql::handlerQueryMongoDB()")
+	static void handlerQueryMongoDB()
+		{
+		U_TRACE(5, "FortuneNoSql::handlerQueryMongoDB()")
 
-      U_INTERNAL_ASSERT_POINTER(Fortune::pmessage)
+		U_INTERNAL_ASSERT_POINTER(Fortune::pmessage)
 
-#  ifdef USE_MONGODB
-      (void) mc->findAll();
+#	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);
+		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::replace(i, i+1);
 
-         Fortune::pmessage->clear();
-         }
-#  endif
-      }
+			Fortune::pmessage->clear();
+			}
+#	endif
+		}
 
-   static void handlerForkMongoDB()
-      {
-      U_TRACE_NO_PARAM(5, "FortuneNoSql::handlerForkMongoDB()")
+	static void handlerForkMongoDB()
+		{
+		U_TRACE_NO_PARAM(5, "FortuneNoSql::handlerForkMongoDB()")
 
-#  ifdef USE_MONGODB
-      if (mc == U_NULLPTR)
-         {
-         U_NEW(UMongoDBClient, mc, UMongoDBClient);
+#	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");
+			if (mc->connect(U_NULLPTR, 0) == false)
+				{
+				U_WARNING("FortuneNoSql::handlerForkMongoDB(): connection failed");
 
-            U_DELETE(mc)
+				U_DELETE(mc)
 
-            mc = U_NULLPTR;
+				mc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         if (mc->selectCollection("hello_world", "fortune") == false)
-            {
-            U_WARNING("FortuneNoSql::handlerForkMongoDB(): selectCollection() failed");
+			if (mc->selectCollection("hello_world", "fortune") == false)
+				{
+				U_WARNING("FortuneNoSql::handlerForkMongoDB(): selectCollection() failed");
 
-            U_DELETE(mc)
+				U_DELETE(mc)
 
-            mc = U_NULLPTR;
+				mc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         Fortune::handlerFork();
-         }
-#  endif
-      }
+			Fortune::handlerFork();
+			}
+#	endif
+		}
 
-   static UREDISClient_Base* rc;
+	static UREDISClient_Base* rc;
 
-   static void handlerQueryREDIS()
-      {
-      U_TRACE(5, "FortuneNoSql::handlerQueryREDIS()")
+	static void handlerQueryREDIS()
+		{
+		U_TRACE(5, "FortuneNoSql::handlerQueryREDIS()")
 
-      (void) rc->lrange(U_CONSTANT_TO_PARAM("fortunes 0 -1"));
+		(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]);
-      }
+		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(5, "Fortune::handlerForkREDIS()")
+	static void handlerForkREDIS()
+		{
+		U_TRACE_NO_PARAM(5, "Fortune::handlerForkREDIS()")
 
-      if (rc == U_NULLPTR)
-         {
-         U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
+		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);
+			if (rc->connect() == false)
+				{
+				U_WARNING("FortuneNoSql::handlerForkREDIS(): %V", rc->UClient_Base::getResponse().rep);
 
-            U_DELETE(rc)
+				U_DELETE(rc)
 
-            rc = U_NULLPTR;
+				rc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         Fortune::handlerFork();
-         }
-      }
+			Fortune::handlerFork();
+			}
+		}
 
 private:
-   U_DISALLOW_ASSIGN(FortuneNoSql)
+	U_DISALLOW_ASSIGN(FortuneNoSql)
 };
 #endif

+ 20 - 10
frameworks/C++/ulib/src/json.usp

@@ -3,6 +3,7 @@ Test type 1: JSON serialization
 TechEmpower Web Framework Benchmarks
 -->
 <!--#declaration
+static char* ptr;
 static UString* pkey;
 static UString* pvalue;
 
@@ -19,18 +20,27 @@ static void usp_init_json()
 <!--#code
 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('L','e','n','g','t','h',':',' '));
-u_put_unalignedp32(pwbuffer+16, U_MULTICHAR_CONSTANT32('2','7','\r','\n'));
-u_put_unalignedp64(pwbuffer+20, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
-u_put_unalignedp64(pwbuffer+28, U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
-u_put_unalignedp64(pwbuffer+36, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
-u_put_unalignedp64(pwbuffer+44, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
-u_put_unalignedp16(pwbuffer+52, U_MULTICHAR_CONSTANT16('\r','\n'));
+U_INTERNAL_DUMP("pwbuffer = %#.10S", pwbuffer)
 
-UValue::pstringify = pwbuffer + U_CONSTANT_SIZE("Content-Length: 27\r\nContent-Type: application/json\r\n\r\n");
+if (u_get_unalignedp64(pwbuffer+44) != U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'))
+   {
+   u_put_unalignedp64(pwbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+   u_put_unalignedp64(pwbuffer+8,  U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
+   u_put_unalignedp32(pwbuffer+16, U_MULTICHAR_CONSTANT32('2','7','\r','\n'));
+   u_put_unalignedp64(pwbuffer+20, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+   u_put_unalignedp64(pwbuffer+28, U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
+   u_put_unalignedp64(pwbuffer+36, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
+   u_put_unalignedp64(pwbuffer+44, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
+   u_put_unalignedp16(pwbuffer+52, U_MULTICHAR_CONSTANT16('\r','\n'));
+
+   ptr = pwbuffer + U_CONSTANT_SIZE("Content-Length: 27\r\nContent-Type: application/json\r\n\r\n");
+   }
+
+U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(UClientImage_Base::wbuffer->data()), U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'))
+
+UValue::pstringify = ptr;
 
 UValue(*pkey, *pvalue).stringify();
 
-UClientImage_Base::wbuffer->size_adjust_constant(UValue::pstringify);
+UClientImage_Base::wbuffer->size_adjust_constant(U_CONSTANT_SIZE("Content-Length: 27\r\nContent-Type: application/json\r\n\r\n") + 27);
 -->

+ 9 - 4
frameworks/C++/ulib/src/libFortune.cxx

@@ -2,8 +2,13 @@
 
 #include "fortune.h"
 
-uint32_t           Fortune::uid;
-UString*           Fortune::pmessage;
-UOrmSession*       Fortune::psql_fortune;
-UOrmStatement*     Fortune::pstmt_fortune;
+char*					 Fortune::pwbuffer;
+uint32_t				 Fortune::uid;
+UString*				 Fortune::pmessage;
+UOrmSession*		 Fortune::psql_fortune;
+UOrmStatement*		 Fortune::pstmt_fortune;
 UVector<Fortune*>* Fortune::pvfortune;
+#ifdef U_STATIC_ORM_DRIVER_PGSQL
+PGconn*				 Fortune::conn;
+UPgSqlStatement*	 Fortune::pstmt;
+#endif

+ 1 - 1
frameworks/C++/ulib/src/libFortuneNoSql.cxx

@@ -3,6 +3,6 @@
 #include "fortuneNoSql.h"
 
 #ifdef USE_MONGODB
-UMongoDBClient*    FortuneNoSql::mc;
+UMongoDBClient*	 FortuneNoSql::mc;
 #endif
 UREDISClient_Base* FortuneNoSql::rc;

+ 10 - 10
frameworks/C++/ulib/src/libWorld.cxx

@@ -2,16 +2,16 @@
 
 #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;
+char				  World::wbuffer[18000];
+char*				  World::ptr;
+char*				  World::pwbuffer;
+World*			  World::pworld_query;
+uint32_t			  World::rnum;
+uint32_t			  World::rnumber[501];
+UOrmSession*	  World::psql_query;
+UOrmStatement*	  World::pstmt_query;
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
-char             World::num2str[sizeof(unsigned int)];
-PGconn*          World::conn;
-UOrmDriverPgSql* World::pdrv;
+char				  World::num2str[sizeof(unsigned int)];
+PGconn*			  World::conn;
 UPgSqlStatement* World::pstmt;
 #endif

+ 9 - 9
frameworks/C++/ulib/src/libWorldNoSql.cxx

@@ -3,14 +3,14 @@
 #include "worldNoSql.h"
 
 #ifdef USE_MONGODB
-bson_t*               WorldNoSql::query;
-UMongoDBClient*       WorldNoSql::mc;
+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;
+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;

+ 18 - 1
frameworks/C++/ulib/src/plaintext.usp

@@ -1 +1,18 @@
-Hello, World!
+<!--#header
+-->
+<!--#code
+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('L','e','n','g','t','h',':',' '));
+u_put_unalignedp32(pwbuffer+16, U_MULTICHAR_CONSTANT32('1','3','\r','\n'));
+u_put_unalignedp64(pwbuffer+20, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+u_put_unalignedp64(pwbuffer+28, U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','t','e'));
+u_put_unalignedp64(pwbuffer+36, U_MULTICHAR_CONSTANT64('x','t','/','p','l','a','i','n'));
+u_put_unalignedp32(pwbuffer+44, U_MULTICHAR_CONSTANT32('\r','\n','\r','\n'));
+
+UClientImage_Base::wbuffer->size_adjust_constant(U_CONSTANT_SIZE("Content-Length: 13\r\nContent-Type: text/plain\r\n\r\n") + 13);
+
+u_put_unalignedp64(pwbuffer+48, U_MULTICHAR_CONSTANT64('H','e','l','l','o',',',' ','W'));
+u_put_unalignedp64(pwbuffer+56, U_MULTICHAR_CONSTANT64('o','r','l','d','!','\0','\0','\0'));
+-->

+ 4 - 3
frameworks/C++/ulib/src/query.usp

@@ -5,6 +5,7 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 #include "world.h"
 
+static void usp_init_query() { World::handlerInitSql(); }
 static void usp_fork_query() { World::handlerForkSql(); }
 -->
 <!--#header
@@ -15,7 +16,7 @@ uint32_t i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 World::initResult();
 
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
-if (World::pdrv)
+if (World::pstmt)
    {
    PGresult* res;
    char* randomNumber;
@@ -29,7 +30,7 @@ if (World::pdrv)
 
       randomNumber = U_SYSCALL(PQgetvalue, "%p,%d,%d", res, 0, 0);
 
-      World::handlerResult(World::rnumber[i], ntohl(*(uint32_t*)randomNumber));
+      World::handlerResult(i, ntohl(*(uint32_t*)randomNumber));
 
       U_SYSCALL_VOID(PQclear, "%p", res);
       }
@@ -43,7 +44,7 @@ for (; i < num_queries; ++i)
 
    World::pstmt_query->execute();
 
-   World::handlerResultSql(i);
+   World::handlerResult(i, World::pworld_query->randomNumber);
    }
 }
 

+ 5 - 4
frameworks/C++/ulib/src/update.usp

@@ -10,6 +10,7 @@ static char query[8192];
 #endif
 static UOrmStatement* pstmt_update;
 
+static void usp_init_update() { World::handlerInitSql(); }
 static void usp_fork_update()
 {
    U_TRACE(5, "::usp_fork_update()")
@@ -19,7 +20,7 @@ static void usp_fork_update()
    if (World::psql_query)
       {
 #  ifdef U_STATIC_ORM_DRIVER_PGSQL
-      if (World::pdrv) (void) memcpy(query, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES"));
+      if (World::pstmt) (void) memcpy(query, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES"));
       else
 #  endif
       {
@@ -38,7 +39,7 @@ uint32_t i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 World::initResult();
 
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
-if (World::pdrv)
+if (World::pstmt)
    {
    PGresult* res;
    char* pquery = query + U_CONSTANT_SIZE("UPDATE World SET randomNumber = v.randomNumber FROM (VALUES");
@@ -63,7 +64,7 @@ if (World::pdrv)
       u_put_unalignedp16(pquery, U_MULTICHAR_CONSTANT16(')',','));
                          pquery += 2;
 
-      World::handlerResult(World::rnumber[i], World::rnum);
+      World::handlerResult(i, World::rnum);
 
       U_SYSCALL_VOID(PQclear, "%p", res);
       }
@@ -92,7 +93,7 @@ for (; i < num_queries; ++i)
 
    pstmt_update->execute();
 
-   World::handlerResultSql(i);
+   World::handlerResult(i, World::pworld_query->randomNumber);
    }
 
 World::endResult();

+ 267 - 240
frameworks/C++/ulib/src/world.h

@@ -10,351 +10,378 @@
 #include <ulib/net/server/client_image.h>
 
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
+#	include <ulib/event/event_db.h>
 #  include <ulib/orm/driver/orm_driver_pgsql.h>
 #endif
 
-class World {
+class U_EXPORT World {
 public:
-   uint32_t id, randomNumber;
+	uint32_t id, randomNumber;
 
-   World()
-      {
-      U_TRACE_CTOR(5, World, "")
+	World()
+		{
+		U_TRACE_CTOR(5, World, "")
 
-      // coverity[uninit_ctor]
-#  ifdef U_COVERITY_FALSE_POSITIVE
-      id = randomNumber = 0;
-#  endif
-      }
+		// coverity[uninit_ctor]
+#	ifdef U_COVERITY_FALSE_POSITIVE
+		id = randomNumber = 0;
+#	endif
+		}
 
-   World(uint32_t _id, uint32_t _randomNumber) : id(_id), randomNumber(_randomNumber)
-      {
-      U_TRACE_CTOR(5, World, "%u,%u", _id, _randomNumber)
-      }
+	World(uint32_t _id, uint32_t _randomNumber) : id(_id), randomNumber(_randomNumber)
+		{
+		U_TRACE_CTOR(5, World, "%u,%u", _id, _randomNumber)
+		}
 
-   World(const World& w) : id(w.id), randomNumber(w.randomNumber)
-      {
-      U_TRACE_CTOR(5, World, "%p", &w)
+	World(const World& w) : id(w.id), randomNumber(w.randomNumber)
+		{
+		U_TRACE_CTOR(5, World, "%p", &w)
 
-      U_MEMORY_TEST_COPY(w)
-      }
+		U_MEMORY_TEST_COPY(w)
+		}
 
-   ~World()
-      {
-      U_TRACE_DTOR(5, World)
-      }
+	~World()
+		{
+		U_TRACE_DTOR(5, World)
+		}
 
-   // JSON
+	// JSON
 
-   void toJSON(UString& json)
-      {
-      U_TRACE(5, "World::toJSON(%V)", json.rep)
+	void toJSON(UString& json)
+		{
+		U_TRACE(5, "World::toJSON(%V)", json.rep)
 
-      json.toJSON(U_JSON_METHOD_HANDLER(id,           unsigned int));
-      json.toJSON(U_JSON_METHOD_HANDLER(randomNumber, unsigned int));
-      }
+		json.toJSON(U_JSON_METHOD_HANDLER(id,				unsigned int));
+		json.toJSON(U_JSON_METHOD_HANDLER(randomNumber,	unsigned int));
+		}
 
-   void fromJSON(UValue& json)
-      {
-      U_TRACE(5, "World::fromJSON(%p)", &json)
+	void fromJSON(UValue& json)
+		{
+		U_TRACE(5, "World::fromJSON(%p)", &json)
 
-      json.fromJSON(U_JSON_METHOD_HANDLER(id,           unsigned int));
-      json.fromJSON(U_JSON_METHOD_HANDLER(randomNumber, unsigned int));
-      }
+		json.fromJSON(U_JSON_METHOD_HANDLER(id,			  unsigned int));
+		json.fromJSON(U_JSON_METHOD_HANDLER(randomNumber, unsigned int));
+		}
 
-   // ORM
+	// ORM
 
-   void bindParam(UOrmStatement* stmt)
-      {
-      U_TRACE(5, "World::bindParam(%p)", stmt)
+	void bindParam(UOrmStatement* stmt)
+		{
+		U_TRACE(5, "World::bindParam(%p)", stmt)
 
-      stmt->bindParam(U_ORM_TYPE_HANDLER(id,           unsigned int));
-      stmt->bindParam(U_ORM_TYPE_HANDLER(randomNumber, unsigned int));
-      }
+		stmt->bindParam(U_ORM_TYPE_HANDLER(id,				 unsigned int));
+		stmt->bindParam(U_ORM_TYPE_HANDLER(randomNumber, unsigned int));
+		}
 
-   void bindResult(UOrmStatement* stmt)
-      {
-      U_TRACE(5, "World::bindResult(%p)", stmt)
+	void bindResult(UOrmStatement* stmt)
+		{
+		U_TRACE(5, "World::bindResult(%p)", stmt)
 
-      stmt->bindResult(U_ORM_TYPE_HANDLER(id,           unsigned int));
-      stmt->bindResult(U_ORM_TYPE_HANDLER(randomNumber, unsigned int));
-      }
+		stmt->bindResult(U_ORM_TYPE_HANDLER(id,			  unsigned int));
+		stmt->bindResult(U_ORM_TYPE_HANDLER(randomNumber, unsigned int));
+		}
 
-   // SERVICE
+	// SERVICE
 
-   bool operator<(const World& other) const { return cmp_obj(&id, &other.id); }
+	bool operator<(const World& other) const { return cmp_obj(&id, &other.id); }
 
-   static int cmp_obj(const void* a, const void* b)
-      {
-      U_TRACE(5, "World::cmp_obj(%p,%p)", a, b)
+	static int cmp_obj(const void* a, const void* b)
+		{
+		U_TRACE(5, "World::cmp_obj(%p,%p)", a, b)
 
-#  ifdef U_STDCPP_ENABLE
-      /**
-       * The comparison function must follow a strict-weak-ordering
-       *
-       * 1) For all x, it is not the case that x < x (irreflexivity)
-       * 2) For all x, y, if x < y then it is not the case that y < x (asymmetry)
-       * 3) For all x, y, and z, if x < y and y < z then x < z (transitivity)
-       * 4) For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of incomparability)
-       */
+#	ifdef U_STDCPP_ENABLE
+		/**
+		 * The comparison function must follow a strict-weak-ordering
+		 *
+		 * 1) For all x, it is not the case that x < x (irreflexivity)
+		 * 2) For all x, y, if x < y then it is not the case that y < x (asymmetry)
+		 * 3) For all x, y, and z, if x < y and y < z then x < z (transitivity)
+		 * 4) For all x, y, and z, if x is incomparable with y, and y is incomparable with z, then x is incomparable with z (transitivity of incomparability)
+		 */
 
-      return (((const World*)a)->id < (((const World*)b)->id));
-#  else
-      return (*(const World**)a)->id < ((*(const World**)b)->id);
-#  endif
-      }
+		return (((const World*)a)->id < (((const World*)b)->id));
+#	else
+		return (*(const World**)a)->id < ((*(const World**)b)->id);
+#	endif
+		}
 
-   static char* pwbuffer;
-   static char wbuffer[18000];
-   static uint32_t rnum, rnumber[500];
+	static char* ptr;
+	static char* pwbuffer;
+	static char wbuffer[18000];
+	static uint32_t rnum, rnumber[501];
 
-   static World*        pworld_query;
-   static UOrmSession*    psql_query;
-   static UOrmStatement* pstmt_query;
+	static World*        pworld_query;
+	static UOrmSession*	  psql_query;
+	static UOrmStatement* pstmt_query;
 
 #ifdef U_STATIC_ORM_DRIVER_PGSQL
-   static PGconn* conn;
-   static UOrmDriverPgSql* pdrv;
-   static UPgSqlStatement* pstmt;
-   static char num2str[sizeof(unsigned int)];
+	static PGconn* conn;
+	static UPgSqlStatement* pstmt;
+	static char num2str[sizeof(unsigned int)];
 
-   static bool initPipeline()
-      {
-      U_TRACE(5, "World::initPipeline()")
+	static PGresult* execPrepared()
+		{
+		U_TRACE_NO_PARAM(5, "World::execPrepared()")
 
-      if (pdrv)
-         {
-         (void) U_SYSCALL(PQsetnonblocking, "%p,%u", conn, 1);
-         (void) U_SYSCALL(PQenterBatchMode, "%p",    conn);
+		U_INTERNAL_ASSERT_MAJOR(rnumber[0], 0)
 
-         U_RETURN(true);
-         }
+		*(unsigned int*)num2str = htonl(rnumber[0]);
 
-      U_RETURN(false);
-      }
+		PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
 
-   static PGresult* execPrepared()
-      {
-      U_TRACE_NO_PARAM(5, "World::execPrepared()")
+		U_RETURN_POINTER(res, PGresult);
+		}
 
-      U_INTERNAL_ASSERT_MAJOR(rnumber[0], 0)
+	static PGresult* execPrepared(uint32_t i)
+		{
+		U_TRACE(5, "World::execPrepared(%u)", i)
 
-      *(unsigned int*)num2str = htonl(rnumber[0]);
+		U_INTERNAL_ASSERT_MAJOR(rnumber[i], 0)
 
-      PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
+		*(unsigned int*)num2str = htonl(rnumber[i]);
 
-      U_RETURN_POINTER(res, PGresult);
-      }
+		PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
 
-   static PGresult* execPrepared(uint32_t i)
-      {
-      U_TRACE(5, "World::execPrepared(%u)", i)
+		U_RETURN_POINTER(res, PGresult);
+		}
 
-      U_INTERNAL_ASSERT_MAJOR(rnumber[i], 0)
+	static void sendQueryPrepared()
+		{
+		U_TRACE_NO_PARAM(5, "World::sendQueryPrepared()")
 
-      *(unsigned int*)num2str = htonl(rnumber[i]);
+		U_INTERNAL_ASSERT_MAJOR(rnumber[0], 0)
 
-      PGresult* res = (PGresult*) U_SYSCALL(PQexecPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
+		*(unsigned int*)num2str = htonl(rnumber[0]);
 
-      U_RETURN_POINTER(res, PGresult);
-      }
+		(void) U_SYSCALL(PQsendQueryPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
+		}
 
-   static void sendQueryPrepared(uint32_t i)
-      {
-      U_TRACE(5, "World::sendQueryPrepared(%u)", i)
+	static void sendQueryPrepared(uint32_t i)
+		{
+		U_TRACE(5, "World::sendQueryPrepared(%u)", i)
 
-      U_INTERNAL_ASSERT_MAJOR(rnumber[i], 0)
+		U_INTERNAL_ASSERT_MAJOR(rnumber[i], 0)
 
-      *(unsigned int*)num2str = htonl(rnumber[i]);
+		*(unsigned int*)num2str = htonl(rnumber[i]);
 
-      (void) U_SYSCALL(PQsendQueryPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
-      }
+		(void) U_SYSCALL(PQsendQueryPrepared, "%p,%S,%u,%p,%p,%p,%u", conn, pstmt->stmtName, 1, pstmt->paramValues, pstmt->paramLengths, pstmt->paramFormats, 1);
+		}
 #endif
 
-   static void initResult()
-      {
-      U_TRACE(5, "World::initResult()")
+	static void initOneResult()
+		{
+		U_TRACE_NO_PARAM(5, "World::initOneResult()")
 
-      u_put_unalignedp64(wbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
-      u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
-      u_put_unalignedp64(wbuffer+16, U_MULTICHAR_CONSTANT64('1','3','3','3','1','\r','\n','C'));
-      u_put_unalignedp64(wbuffer+24, U_MULTICHAR_CONSTANT64('o','n','t','e','n','t','-','T'));
-      u_put_unalignedp64(wbuffer+32, U_MULTICHAR_CONSTANT64('y','p','e',':',' ','a','p','p'));
-      u_put_unalignedp64(wbuffer+40, U_MULTICHAR_CONSTANT64('l','i','c','a','t','i','o','n'));
-      u_put_unalignedp64(wbuffer+48, U_MULTICHAR_CONSTANT64('/','j','s','o','n','\r','\n','\r'));
-      u_put_unalignedp16(wbuffer+56, U_MULTICHAR_CONSTANT16('\n','['));
+		U_INTERNAL_DUMP("wbuffer = %#.10S", wbuffer)
 
-      pwbuffer = wbuffer + U_CONSTANT_SIZE("Content-Length: 13331\r\nContent-Type: application/json\r\n\r\n[");
-      }
+		if (u_get_unalignedp64(wbuffer+52) != U_MULTICHAR_CONSTANT64('\r','\n','{','"','i','d','"',':'))
+			{
+			u_put_unalignedp64(wbuffer,	 U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+			u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
+			u_put_unalignedp32(wbuffer+16, U_MULTICHAR_CONSTANT32('3','1','\r','\n'));
+			u_put_unalignedp64(wbuffer+20, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+			u_put_unalignedp64(wbuffer+28, U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
+			u_put_unalignedp64(wbuffer+36, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
+			u_put_unalignedp64(wbuffer+44, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
+			u_put_unalignedp64(wbuffer+52, U_MULTICHAR_CONSTANT64('\r','\n','{','"','i','d','"',':'));
 
-   static void endResult()
-      {
-      U_TRACE_NO_PARAM(5, "World::endResult()")
+			pwbuffer = u_num2str32(rnumber[0], wbuffer + U_CONSTANT_SIZE("Content-Length: 31\r\nContent-Type: application/json\r\n\r\n{\"id\":"));
 
-      *(pwbuffer-1) = ']';
+			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','"',':'));
+			}
 
-      uint32_t      len = pwbuffer-wbuffer,
-               body_len = len - U_CONSTANT_SIZE("Content-Length: 13331\r\nContent-Type: application/json\r\n\r\n");
+		U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(wbuffer),	U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'))
+		}
 
-      pwbuffer = u_num2str32(body_len, wbuffer + U_CONSTANT_SIZE("Content-Length: "));
+	static void endOneResult()
+		{
+		U_TRACE_NO_PARAM(5, "World::endOneResult()")
 
-      while (*pwbuffer != '\r') *pwbuffer++ = ' ';
+		*ptr = '}';
 
-      UClientImage_Base::wbuffer->setConstant(wbuffer, len);
-      }
+		uint32_t		  len = ptr-wbuffer+1,
+					body_len = len - U_CONSTANT_SIZE("Content-Length: 31\r\nContent-Type: application/json\r\n\r\n");
 
-   static void initOneResult()
-      {
-      U_TRACE(5, "World::initOneResult()")
+		U_NUM2STR16(wbuffer+U_CONSTANT_SIZE("Content-Length: "), body_len);
 
-      u_put_unalignedp64(wbuffer,    U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
-      u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
-      u_put_unalignedp32(wbuffer+16, U_MULTICHAR_CONSTANT32('3','1','\r','\n'));
-      u_put_unalignedp64(wbuffer+20, U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
-      u_put_unalignedp64(wbuffer+28, U_MULTICHAR_CONSTANT64('T','y','p','e',':',' ','a','p'));
-      u_put_unalignedp64(wbuffer+36, U_MULTICHAR_CONSTANT64('p','l','i','c','a','t','i','o'));
-      u_put_unalignedp64(wbuffer+44, U_MULTICHAR_CONSTANT64('n','/','j','s','o','n','\r','\n'));
-      u_put_unalignedp32(wbuffer+52, U_MULTICHAR_CONSTANT32('\r','\n','{','\0'));
+		UClientImage_Base::wbuffer->setConstant(wbuffer, len);
+		}
 
-      pwbuffer = wbuffer + U_CONSTANT_SIZE("Content-Length: 31\r\nContent-Type: application/json\r\n\r\n{");
-      }
+	static void handlerOneResult(uint32_t random)
+		{
+		U_TRACE(5, "World::handlerOneResult(%u)", random)
 
-   static void endOneResult()
-      {
-      U_TRACE_NO_PARAM(5, "World::endOneResult()")
+		initOneResult();
 
-      *pwbuffer = '}';
+		ptr = u_num2str32(random, pwbuffer+16);
 
-      uint32_t      len = pwbuffer-wbuffer+1,
-               body_len = len - U_CONSTANT_SIZE("Content-Length: 31\r\nContent-Type: application/json\r\n\r\n");
+		endOneResult();
+		}
 
-      (void) u_num2str32(body_len, wbuffer+U_CONSTANT_SIZE("Content-Length: "));
+	static void initResult()
+		{
+		U_TRACE_NO_PARAM(5, "World::initResult()")
 
-      UClientImage_Base::wbuffer->setConstant(wbuffer, len);
-      }
+		U_INTERNAL_DUMP("wbuffer = %#.10S", wbuffer)
 
-   static void handlerOneResult(uint32_t uid, uint32_t random)
-      {
-      U_TRACE(5, "World::handlerOneResult(%u,%u)", uid, random)
+		if (u_get_unalignedp64(wbuffer+56) != U_MULTICHAR_CONSTANT64('\n','[','{','"','i','d','"',':'))
+			{
+			u_put_unalignedp64(wbuffer,	 U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'));
+			u_put_unalignedp64(wbuffer+8,  U_MULTICHAR_CONSTANT64('L','e','n','g','t','h',':',' '));
+			u_put_unalignedp64(wbuffer+16, U_MULTICHAR_CONSTANT64('1','3','3','3','1','\r','\n','C'));
+			u_put_unalignedp64(wbuffer+24, U_MULTICHAR_CONSTANT64('o','n','t','e','n','t','-','T'));
+			u_put_unalignedp64(wbuffer+32, U_MULTICHAR_CONSTANT64('y','p','e',':',' ','a','p','p'));
+			u_put_unalignedp64(wbuffer+40, U_MULTICHAR_CONSTANT64('l','i','c','a','t','i','o','n'));
+			u_put_unalignedp64(wbuffer+48, U_MULTICHAR_CONSTANT64('/','j','s','o','n','\r','\n','\r'));
+			u_put_unalignedp64(wbuffer+56, U_MULTICHAR_CONSTANT64('\n','[','{','"','i','d','"',':'));
 
-      u_put_unalignedp32(pwbuffer, U_MULTICHAR_CONSTANT32('"','i','d','"'));
+			pwbuffer = u_num2str32(rnumber[0], wbuffer + U_CONSTANT_SIZE("Content-Length: 13331\r\nContent-Type: application/json\r\n\r\n[{\"id\":"));
 
-      pwbuffer[4] = ':';
+			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(uid, pwbuffer+5);
+		U_INTERNAL_ASSERT_EQUALS(u_get_unalignedp64(wbuffer),	U_MULTICHAR_CONSTANT64('C','o','n','t','e','n','t','-'))
 
-      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','"',':'));
+		ptr = pwbuffer;
+		}
 
-      pwbuffer = u_num2str32(random, pwbuffer+16);
-      }
+	static void endResult()
+		{
+		U_TRACE_NO_PARAM(5, "World::endResult()")
 
-   static void handlerResult(uint32_t uid, uint32_t random)
-      {
-      U_TRACE(5, "World::handlerResult(%u,%u)", uid, random)
+		*(ptr-1) = ']';
 
-      u_put_unalignedp32(pwbuffer,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-      u_put_unalignedp16(pwbuffer+4, U_MULTICHAR_CONSTANT16('"',':'));
+		uint32_t		  len = ptr-wbuffer,
+					body_len = len - U_CONSTANT_SIZE("Content-Length: 13331\r\nContent-Type: application/json\r\n\r\n");
 
-      pwbuffer = u_num2str32(uid, pwbuffer+6);
+		ptr = u_num2str32(body_len, wbuffer + U_CONSTANT_SIZE("Content-Length: "));
 
-      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','"',':'));
+		while (*ptr != '\r') *ptr++ = ' ';
 
-      pwbuffer = u_num2str32(random, pwbuffer+16);
+		UClientImage_Base::wbuffer->setConstant(wbuffer, len);
+		}
 
-      u_put_unalignedp16(pwbuffer, U_MULTICHAR_CONSTANT16('}',','));
-                         pwbuffer += 2;
-      }
+	static void addResult(uint32_t i)
+		{
+		U_TRACE(5, "World::addResult(%u)", i)
 
-   static void handlerResult(uint32_t i)
-      {
-      U_TRACE(5, "World::handlerResult(%u)", i)
+		U_INTERNAL_ASSERT_MAJOR(i, 0)
 
-      U_INTERNAL_ASSERT_POINTER(pworld_query)
+		u_put_unalignedp32(ptr,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
+		u_put_unalignedp16(ptr+4, U_MULTICHAR_CONSTANT16('"',':'));
 
-      U_INTERNAL_DUMP("pworld_query->randomNumber = %u", pworld_query->randomNumber)
-      }
+		ptr = u_num2str32(rnumber[i], ptr+6);
 
-   static void handlerResultSql(uint32_t i)
-      {
-      U_TRACE(5, "World::handlerResultSql(%u)", i)
+		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','"',':'));
+		}
 
-      U_INTERNAL_ASSERT_POINTER(pworld_query)
+	static void addRandom(uint32_t random)
+		{
+		U_TRACE(5, "World::addRandom(%u)", random)
 
-      handlerResult(rnumber[i], pworld_query->randomNumber);
-      }
+		ptr = u_num2str32(random, ptr+16);
 
-   static void doUpdateNoSql(vPFu handlerUpdateNoSql)
-      {
-      U_TRACE(5, "World::doUpdateNoSql(%p)", handlerUpdateNoSql)
+		u_put_unalignedp16(ptr, U_MULTICHAR_CONSTANT16('}',','));
+								 ptr += 2;
+		}
 
-      initResult();
+	static void handlerResult(uint32_t i, uint32_t random)
+		{
+		U_TRACE(5, "World::handlerResult(%u,%u)", i, random)
 
-      for (uint32_t i = 0, n = UHTTP::getFormFirstNumericValue(1, 500); i < n; ++i)
-         {
-         handlerUpdateNoSql(i);
+		if (i) addResult(i);
 
-         handlerResult(rnumber[i], rnum);
-         }
+		addRandom(random);
+		}
 
-      endResult();
-      }
+	static void doUpdateNoSql(vPFu handlerUpdateNoSql)
+		{
+		U_TRACE(5, "World::doUpdateNoSql(%p)", handlerUpdateNoSql)
 
-   static void handlerFork()
-      {
-      U_TRACE_NO_PARAM(5, "World::handlerFork()")
+		initResult();
 
-      if (rnumber[0] == 0) for (uint32_t i = 0; i < 500; ++i) rnumber[i] = u_get_num_random_range1(10000);
-      }
+		for (uint32_t i = 0, n = UHTTP::getFormFirstNumericValue(1, 500); i < n; ++i)
+			{
+			handlerUpdateNoSql(i);
 
-   static void handlerForkSql()
-      {
-      U_TRACE_NO_PARAM(5, "World::handlerForkSql()")
+			handlerResult(i, rnum);
+			}
 
-      if (psql_query == U_NULLPTR)
-         {
-         U_NEW(UOrmSession, psql_query, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
+		endResult();
+		}
 
-         if (psql_query->isReady() == false)
-            {
-            U_WARNING("World::handlerForkSql(): we cound't connect to db");
+	static void handlerInitSql()
+		{
+		U_TRACE_NO_PARAM(5, "World::handlerInitSql()")
 
-            U_DELETE(psql_query)
+#	ifdef U_STATIC_ORM_DRIVER_PGSQL
+		U_INTERNAL_DUMP("UServer_Base::handler_db1 = %p", UServer_Base::handler_db1)
 
-            psql_query = U_NULLPTR;
+		if (UServer_Base::handler_db1 == U_NULLPTR)
+			{
+			U_NEW(UEventDB, UServer_Base::handler_db1, UEventDB);
+			}
+#	endif
+		}
 
-            return;
-            }
+	static void handlerFork()
+		{
+		U_TRACE_NO_PARAM(5, "World::handlerFork()")
 
-         U_NEW(UOrmStatement, pstmt_query, UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
+		if (rnumber[0] == 0) for (uint32_t i = 0; i <= 500; ++i) rnumber[i] = u_get_num_random_range1(10000);
+		}
 
-         U_NEW(World, pworld_query, World);
+	static void handlerForkSql()
+		{
+		U_TRACE_NO_PARAM(5, "World::handlerForkSql()")
 
-         pstmt_query->use( pworld_query->id);
-         pstmt_query->into(pworld_query->randomNumber);
+		if (psql_query == U_NULLPTR)
+			{
+			U_NEW(UOrmSession, psql_query, UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
 
-#     ifdef U_STATIC_ORM_DRIVER_PGSQL
-         if (UOrmDriver::isPGSQL())
-            {
-            conn  = (PGconn*)(pdrv = (UOrmDriverPgSql*)psql_query->getDriver())->UOrmDriver::connection;
-            pstmt = (UPgSqlStatement*)pstmt_query->getStatement();
+			if (psql_query->isReady() == false)
+				{
+				U_WARNING("World::handlerForkSql(): we cound't connect to db");
 
-            (void) pstmt->setBindParam(pdrv);
+				U_DELETE(psql_query)
 
-            pstmt->paramValues[0]  = num2str;
-            pstmt->paramLengths[0] = sizeof(unsigned int);
-            }
-#     endif
+				psql_query = U_NULLPTR;
 
-         handlerFork();
-         }
-      }
+				return;
+				}
 
-   const char* dump(bool breset) const;
-#endif
+			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);
+
+#		ifdef U_STATIC_ORM_DRIVER_PGSQL
+			if (UOrmDriver::isPGSQL())
+				{
+				UOrmDriverPgSql* pdrv = (UOrmDriverPgSql*)psql_query->getDriver();
+
+				 conn = (PGconn*)pdrv->UOrmDriver::connection;
+				pstmt = (UPgSqlStatement*)pstmt_query->getStatement();
+
+				(void) pstmt->setBindParam(pdrv);
+
+				pstmt->paramValues[0]  = num2str;
+				pstmt->paramLengths[0] = sizeof(unsigned int);
+
+				UServer_Base::handler_db1->setConnection(conn);
+				}
+#		endif
+
+			handlerFork();
+			}
+		}
 
 private:
-   U_DISALLOW_ASSIGN(World)
+	U_DISALLOW_ASSIGN(World)
 };
 #endif

+ 169 - 195
frameworks/C++/ulib/src/worldNoSql.h

@@ -9,288 +9,262 @@
 #include <ulib/net/client/elasticsearch.h>
 
 #ifdef USE_MONGODB
-#  include <ulib/net/client/mongodb.h>
+#	include <ulib/net/client/mongodb.h>
 #endif
 
-class WorldNoSql {
+class U_EXPORT WorldNoSql {
 public:
 
-   static UString* str_rnumber;
+	static UString* str_rnumber;
 
-   static void handlerOneResult(uint32_t uid)
-      {
-      U_TRACE(5, "WorldNoSql::handlerOneResult(%u)", uid)
+	static void doOneQuery(vPFu handlerQuery)
+		{
+		U_TRACE(5, "WorldNoSql::doOneQuery(%p)", handlerQuery)
 
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
-      U_INTERNAL_ASSERT_POINTER(World::pwbuffer)
+		handlerQuery(World::rnumber[0]);
 
-      u_put_unalignedp32(World::pwbuffer, U_MULTICHAR_CONSTANT32('"','i','d','"'));
+		uint32_t sz = str_rnumber->size();
 
-      World::pwbuffer[4] = ':';
+		World::initOneResult();
 
-      World::pwbuffer = u_num2str32(uid, World::pwbuffer+5);
+		(void) memcpy(World::pwbuffer+16, str_rnumber->data(), sz);
 
-      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;
+		World::ptr = World::pwbuffer+16+sz;
 
-      uint32_t sz = str_rnumber->size();
+		World::endOneResult();
 
-      (void) memcpy(World::pwbuffer, str_rnumber->data(), sz);
-                    World::pwbuffer +=                    sz;
+		str_rnumber->clear();
+		}
 
-      str_rnumber->clear();
-      }
+	static void handlerResult(uint32_t i)
+		{
+		U_TRACE(5, "WorldNoSql::handlerResult(%u)", i)
 
-   static void handlerResult(uint32_t uid)
-      {
-      U_TRACE(5, "WorldNoSql::handlerResult(%u)", uid)
+		U_INTERNAL_ASSERT_POINTER(str_rnumber)
+		U_INTERNAL_ASSERT_POINTER(World::pwbuffer)
 
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
-      U_INTERNAL_ASSERT_POINTER(World::pwbuffer)
+		if (i) World::addResult(i);
 
-      u_put_unalignedp32(World::pwbuffer,   U_MULTICHAR_CONSTANT32('{','"','i','d'));
-      u_put_unalignedp16(World::pwbuffer+4, U_MULTICHAR_CONSTANT16('"',':'));
+		uint32_t sz = str_rnumber->size();
 
-      World::pwbuffer = u_num2str32(uid, World::pwbuffer+6);
+		(void) memcpy(World::ptr+16, str_rnumber->data(), sz);
+						  World::ptr += 16+						  sz;
 
-      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;
+		u_put_unalignedp16(World::ptr, U_MULTICHAR_CONSTANT16('}',','));
+								 World::ptr += 2;
 
-      uint32_t sz = str_rnumber->size();
+		str_rnumber->clear();
+		}
 
-      (void) memcpy(World::pwbuffer, str_rnumber->data(), sz);
-                    World::pwbuffer +=                    sz;
+	static void doQuery(vPFu handlerQuery)
+		{
+		U_TRACE(5, "WorldNoSql::doQuery(%p)", handlerQuery)
 
-      str_rnumber->clear();
+		World::initResult();
 
-      u_put_unalignedp16(World::pwbuffer, U_MULTICHAR_CONSTANT16('}',','));
-                         World::pwbuffer += 2;
-      }
+		for (uint32_t i = 0, n = UHTTP::getFormFirstNumericValue(1, 500); i < n; ++i)
+			{
+			handlerQuery(World::rnumber[i]);
 
-   static void doOneQuery(vPFu handlerQuery)
-      {
-      U_TRACE(5, "WorldNoSql::doOneQuery(%p)", handlerQuery)
+			handlerResult(i);
+			}
 
-      World::initOneResult();
+		World::endResult();
+		}
 
-      handlerQuery(World::rnumber[0]);
+	static void handlerFork()
+		{
+		U_TRACE_NO_PARAM(5, "WorldNoSql::handlerFork()")
 
-      handlerOneResult(World::rnumber[0]);
+		if (str_rnumber == U_NULLPTR) U_NEW_STRING(str_rnumber, UString);
 
-      World::endOneResult();
-      }
+		World::handlerFork();
 
-   static void doQuery(vPFu handlerQuery)
-      {
-      U_TRACE(5, "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(5, "WorldNoSql::handlerFork()")
-
-      if (str_rnumber == U_NULLPTR) U_NEW_STRING(str_rnumber, UString);
-
-      World::handlerFork();
-
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
-      }
+		U_INTERNAL_ASSERT_POINTER(str_rnumber)
+		}
 
 #ifdef USE_MONGODB
-   static bson_t* query;
-   static UMongoDBClient* mc;
+	static bson_t* query;
+	static UMongoDBClient* mc;
 #endif
 
-   static void handlerQueryMongoDB(uint32_t uid)
-      {
-      U_TRACE(5, "WorldNoSql::handlerQueryMongoDB(%u)", uid)
+	static void handlerQueryMongoDB(uint32_t uid)
+		{
+		U_TRACE(5, "WorldNoSql::handlerQueryMongoDB(%u)", uid)
 
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+		U_INTERNAL_ASSERT_POINTER(str_rnumber)
 
-#  ifdef USE_MONGODB
-      (void) mc->findOne(uid, query);
-      (void) U_JFIND(mc->vitem[0], "randomNumber", *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('.');
+		uint32_t pos = str_rnumber->find_first_of('.');
 
-      if (pos != U_NOT_FOUND) str_rnumber->size_adjust_constant(pos);
-#  endif
-      }
+		if (pos != U_NOT_FOUND) str_rnumber->size_adjust_constant(pos);
+#	endif
+		}
 
-   static void handlerUpdateMongoDB(uint32_t i)
-      {
-      U_TRACE(5, "WorldNoSql::handlerUpdateMongoDB(%u)", i)
+	static void handlerUpdateMongoDB(uint32_t i)
+		{
+		U_TRACE(5, "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
-      }
+#	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(5, "WorldNoSql::handlerForkMongoDB()")
+	static void handlerForkMongoDB()
+		{
+		U_TRACE_NO_PARAM(5, "WorldNoSql::handlerForkMongoDB()")
 
-#  ifdef USE_MONGODB
-      if (mc == U_NULLPTR)
-         {
-         U_NEW(UMongoDBClient, mc, UMongoDBClient);
+#	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");
+			if (mc->connect(U_NULLPTR, 0) == false)
+				{
+				U_WARNING("WorldNoSql::handlerForkMongoDB(): connection failed");
 
-            U_DELETE(mc)
+				U_DELETE(mc)
 
-            mc = U_NULLPTR;
+				mc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         if (mc->selectCollection("hello_world", "world") == false)
-            {
-            U_WARNING("WorldNoSql::handlerForkMongoDB(): selectCollection() failed");
+			if (mc->selectCollection("hello_world", "world") == false)
+				{
+				U_WARNING("WorldNoSql::handlerForkMongoDB(): selectCollection() failed");
 
-            U_DELETE(mc)
+				U_DELETE(mc)
 
-            mc = U_NULLPTR;
+				mc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
+			query = (bson_t*) U_SYSCALL_NO_PARAM(bson_new);  
 
-         handlerFork();
-         }
-#  endif
-      }
+			handlerFork();
+			}
+#	endif
+		}
 
-   static char rc_buffer[128];
-   static UREDISClient_Base* rc;
+	static char rc_buffer[128];
+	static UREDISClient_Base* rc;
 
-   static void handlerQueryREDIS(uint32_t uid)
-      {
-      U_TRACE(5, "WorldNoSql::handlerQueryREDIS(%u)", uid)
+	static void handlerQueryREDIS(uint32_t uid)
+		{
+		U_TRACE(5, "WorldNoSql::handlerQueryREDIS(%u)", uid)
 
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+		U_INTERNAL_ASSERT_POINTER(str_rnumber)
 
-      char* ptr = rc_buffer+U_CONSTANT_SIZE("world:");
+		char* ptr = rc_buffer+U_CONSTANT_SIZE("world:");
 
-      (void) rc->get(ptr, U_CONSTANT_SIZE("world:")+u_num2str32(uid, ptr)-ptr);
+		(void) rc->get(ptr, U_CONSTANT_SIZE("world:")+u_num2str32(uid, ptr)-ptr);
 
-      *str_rnumber = rc->vitem[0];
-      }
+		*str_rnumber = rc->vitem[0];
+		}
 
-   static void handlerUpdateREDIS(uint32_t i)
-      {
-      U_TRACE(5, "WorldNoSql::handlerUpdateREDIS(%u)", i)
+	static void handlerUpdateREDIS(uint32_t i)
+		{
+		U_TRACE(5, "WorldNoSql::handlerUpdateREDIS(%u)", i)
 
-      char* start = rc_buffer+U_CONSTANT_SIZE("world:");
-      char* ptr = u_num2str32(World::rnumber[i], start);
+		char* start = rc_buffer+U_CONSTANT_SIZE("world:");
+		char* ptr = u_num2str32(World::rnumber[i], start);
 
-      (void) rc->get(start, ptr-start);
+		(void) rc->get(start, ptr-start);
 
-      *ptr = ' ';
-       ptr = u_num2str32(World::rnum = u_get_num_random_range1(10000), ptr+1);
+		*ptr = ' ';
+		 ptr = u_num2str32(World::rnum = u_get_num_random_range1(10000), ptr+1);
 
-      (void) rc->mset(start, ptr-start);
-      }
+		(void) rc->mset(start, ptr-start);
+		}
 
-   static void handlerForkREDIS()
-      {
-      U_TRACE_NO_PARAM(5, "WorldNoSql::handlerForkREDIS()")
+	static void handlerForkREDIS()
+		{
+		U_TRACE_NO_PARAM(5, "WorldNoSql::handlerForkREDIS()")
 
-      if (rc == U_NULLPTR)
-         {
-         U_NEW(UREDISClient<UTCPSocket>, rc, UREDISClient<UTCPSocket>);
+		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);
+			if (rc->connect() == false)
+				{
+				U_WARNING("WorldNoSql::handlerForkREDIS(): %V", rc->UClient_Base::getResponse().rep);
 
-            U_DELETE(rc)
+				U_DELETE(rc)
 
-            rc = U_NULLPTR;
+				rc = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         U_MEMCPY(rc_buffer, "world:", U_CONSTANT_SIZE("world:"));
+			U_MEMCPY(rc_buffer, "world:", U_CONSTANT_SIZE("world:"));
 
-         handlerFork();
-         }
-      }
+			handlerFork();
+			}
+		}
 
-   static char* pbuffer1;
-   static char* pbuffer2;
-   static char es_buffer1[128];
-   static char es_buffer2[128];
-   static UElasticSearchClient* es;
+	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\":\"")
+#	define U_QLEN U_CONSTANT_SIZE("{\"query\":{\"match\":{\"_id\":\"")
 
-   static void handlerQueryElasticSearch(uint32_t uid)
-      {
-      U_TRACE(5, "WorldNoSql::handlerQueryElasticSearch(%u)", uid)
+	static void handlerQueryElasticSearch(uint32_t uid)
+		{
+		U_TRACE(5, "WorldNoSql::handlerQueryElasticSearch(%u)", uid)
 
-      U_INTERNAL_ASSERT_POINTER(str_rnumber)
+		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) 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);
-      }
+		(void) U_JFIND(es->getContent(), "randomNumber", *str_rnumber);
+		}
 
-   static void handlerUpdateElasticSearch(uint32_t i)
-      {
-      U_TRACE(5, "WorldNoSql::handlerUpdateElasticSearch(%u)", i)
+	static void handlerUpdateElasticSearch(uint32_t i)
+		{
+		U_TRACE(5, "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));
+		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\":\""));
-      }
+		(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(5, "WorldNoSql::handlerForkElasticSearch()")
+	static void handlerForkElasticSearch()
+		{
+		U_TRACE_NO_PARAM(5, "WorldNoSql::handlerForkElasticSearch()")
 
-      if (es == U_NULLPTR)
-         {
-         U_NEW(UElasticSearchClient, es, UElasticSearchClient);
+		if (es == U_NULLPTR)
+			{
+			U_NEW(UElasticSearchClient, es, UElasticSearchClient);
 
-         if (es->connect() == false)
-            {
-            U_WARNING("WorldNoSql::handlerForkElasticSearch(): connection disabled or failed");
+			if (es->connect() == false)
+				{
+				U_WARNING("WorldNoSql::handlerForkElasticSearch(): connection disabled or failed");
 
-            U_DELETE(es)
+				U_DELETE(es)
 
-            es = U_NULLPTR;
+				es = U_NULLPTR;
 
-            return;
-            }
+				return;
+				}
 
-         U_MEMCPY(es_buffer1, "{\"query\":{\"match\":{\"_id\":\"", U_QLEN);
+			U_MEMCPY(es_buffer1, "{\"query\":{\"match\":{\"_id\":\"", U_QLEN);
 
-         handlerFork();
-         }
-      }
+			handlerFork();
+			}
+		}
 
 private:
-   U_DISALLOW_ASSIGN(WorldNoSql)
+	U_DISALLOW_ASSIGN(WorldNoSql)
 };
 #endif