Browse Source

ULib: substitute for #1888

stefanocasazza 9 years ago
parent
commit
d080110de9

+ 5 - 1
frameworks/C++/ulib/README.md

@@ -10,21 +10,25 @@ This is the [ULib](http://stefanocasazza.github.io/ULib/) portion of a [benchmar
 
 
 * [Database test source (SQL)](src/db.usp)
 * [Database test source (SQL)](src/db.usp)
 * [Database test source (REDIS)](src/rdb.usp)
 * [Database test source (REDIS)](src/rdb.usp)
+* [Database test source (MONGODB)](src/mdb.usp)
 
 
 ### Variable Query Test
 ### Variable Query Test
 
 
 * [Variable Query test source (SQL)](src/query.usp)
 * [Variable Query test source (SQL)](src/query.usp)
 * [Variable Query test source (REDIS)](src/rquery.usp)
 * [Variable Query test source (REDIS)](src/rquery.usp)
+* [Variable Query test source (MONGODB)](src/mquery.usp)
 
 
 ### Fortune Query Test
 ### Fortune Query Test
 
 
 * [Fortune Query test source (SQL)](src/fortune.usp)
 * [Fortune Query test source (SQL)](src/fortune.usp)
 * [Fortune Query test source (REDIS)](src/rfortune.usp)
 * [Fortune Query test source (REDIS)](src/rfortune.usp)
+* [Fortune Query test source (MONGODB)](src/mfortune.usp)
 
 
 ### Variable Query (update) Test
 ### Variable Query (update) Test
 
 
 * [Variable Query (update) test source (SQL)](src/update.usp)
 * [Variable Query (update) test source (SQL)](src/update.usp)
 * [Variable Query (update) test source (REDIS)](src/rupdate.usp)
 * [Variable Query (update) test source (REDIS)](src/rupdate.usp)
+* [Variable Query (update) test source (MONGODB)](src/mupdate.usp)
 
 
 ### Plaintext Test
 ### Plaintext Test
 
 
@@ -80,7 +84,7 @@ Content-Type: application/json
 HTTP/1.1 200 OK
 HTTP/1.1 200 OK
 Date: Thu, 03 Jul 2014 10:14:51 GMT
 Date: Thu, 03 Jul 2014 10:14:51 GMT
 Server: ULib 
 Server: ULib 
-Content-Type: text/html
+Content-Type: text/html; charset=UTF-8
 Content-Length: 1227
 Content-Length: 1227
 
 
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td>&lt;script&gt;alert(&quot;This should not be displayed in a browser alert box.&quot;);&lt;/script&gt;</td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren&apos;t broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>
 <!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><tr><td>11</td><td>&lt;script&gt;alert(&quot;This should not be displayed in a browser alert box.&quot;);&lt;/script&gt;</td></tr><tr><td>4</td><td>A bad random number generator: 1, 1, 1, 1, 1, 4.33e+67, 1, 1, 1</td></tr><tr><td>5</td><td>A computer program does what you tell it to do, not what you want it to do.</td></tr><tr><td>2</td><td>A computer scientist is someone who fixes things that aren&apos;t broken.</td></tr><tr><td>8</td><td>A list is only as strong as its weakest link. — Donald Knuth</td></tr><tr><td>0</td><td>Additional fortune added at request time.</td></tr><tr><td>3</td><td>After enough decimal places, nobody gives a damn.</td></tr><tr><td>7</td><td>Any program that runs right is obsolete.</td></tr><tr><td>10</td><td>Computers make very fast, very accurate mistakes.</td></tr><tr><td>6</td><td>Emacs is a nice operating system, but I prefer UNIX. — Tom Christaensen</td></tr><tr><td>9</td><td>Feature: A bug with seniority.</td></tr><tr><td>1</td><td>fortune: No such file or directory</td></tr><tr><td>12</td><td>フレームワークのベンチマーク</td></tr></table></body></html>

+ 26 - 5
frameworks/C++/ulib/benchmark_config.json

@@ -12,7 +12,7 @@
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "ULib",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib",
       "display_name": "ULib",
@@ -30,7 +30,7 @@
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "ULib",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib",
       "display_name": "ULib",
@@ -51,7 +51,7 @@
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "ULib",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-mysql",
       "display_name": "ULib-mysql",
@@ -72,7 +72,7 @@
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "ULib",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-postgres",
       "display_name": "ULib-postgres",
@@ -92,12 +92,33 @@
       "language": "C++",
       "language": "C++",
       "orm": "Micro",
       "orm": "Micro",
       "platform": "ULib",
       "platform": "ULib",
-      "webserver": "userver_tcp",
+      "webserver": "ULib",
       "os": "Linux",
       "os": "Linux",
       "database_os": "Linux",
       "database_os": "Linux",
       "display_name": "ULib-sqlite",
       "display_name": "ULib-sqlite",
       "notes": "",
       "notes": "",
       "versus": ""
       "versus": ""
+    },
+    "mongodb": {
+      "setup_file": "setup_mongodb",
+      "db_url": "/mdb",
+      "query_url": "/mquery?queries=",
+      "fortune_url": "/mfortune",
+      "update_url": "/mupdate?queries=",
+      "port": 8080,
+      "approach": "Realistic",
+      "classification": "Platform",
+      "database": "MongoDB",
+      "framework": "ULib",
+      "language": "C++",
+      "orm": "Micro",
+      "platform": "ULib",
+      "webserver": "ULib",
+      "os": "Linux",
+      "database_os": "Linux",
+      "display_name": "ULib-mongodb",
+      "notes": "",
+      "versus": ""
     }
     }
   }]
   }]
 }
 }

+ 2 - 2
frameworks/C++/ulib/setup_json.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -11,7 +11,7 @@ sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/ben
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
 
 
 # 2. Start ULib Server (userver_tcp)
 # 2. Start ULib Server (userver_tcp)
-export UMEMPOOL="58,0,0,40,273,-15,-14,-20,36"
+export UMEMPOOL="58,0,0,41,273,-15,-14,-20,36"
 
 
 # Never use setcap inside of TRAVIS 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \
 [ "$TRAVIS" != "true" ] || { \

+ 24 - 0
frameworks/C++/ulib/setup_mongodb.sh

@@ -0,0 +1,24 @@
+#!/bin/bash
+
+fw_depends ulib
+
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
+
+# 1. Change ULib Server (userver_tcp) configuration
+sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
+sed -i "s|LISTEN_BACKLOG .*|LISTEN_BACKLOG 256|g"								  $IROOT/ULib/benchmark.cfg
+sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"					  $IROOT/ULib/benchmark.cfg
+sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT/ULib/benchmark.cfg
+
+# 2. Start ULib Server (userver_tcp)
+export MONGODB_HOST=$DBHOST
+export UMEMPOOL="1057,0,0,49,274,-14,-15,-24,40"
+
+# Never use setcap inside of TRAVIS 
+[ "$TRAVIS" != "true" ] || { \
+if [ `ulimit -r` -eq 99 ]; then
+	sudo setcap cap_sys_nice,cap_sys_resource,cap_net_bind_service,cap_net_raw+eip $IROOT/ULib/bin/userver_tcp
+fi
+}
+
+$IROOT/ULib/bin/userver_tcp -c $IROOT/ULib/benchmark.cfg &

+ 2 - 2
frameworks/C++/ulib/setup_mysql.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg
@@ -12,7 +12,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 
 # 2. Start ULib Server (userver_tcp)
 # 2. Start ULib Server (userver_tcp)
 export ORM_DRIVER="mysql"
 export ORM_DRIVER="mysql"
-export UMEMPOOL="545,0,0,41,275,-14,-13,-25,41"
+export UMEMPOOL="545,0,0,49,275,-14,-13,-25,41"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=hello_world"
 
 
 # Never use setcap inside of TRAVIS 
 # Never use setcap inside of TRAVIS 

+ 2 - 2
frameworks/C++/ulib/setup_plaintext.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"										$IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"										$IROOT/ULib/benchmark.cfg
@@ -11,7 +11,7 @@ sed -i "s|PREFORK_CHILD .*|PREFORK_CHILD ${MAX_THREADS}|g"						$IROOT/ULib/benc
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" $IROOT/ULib/benchmark.cfg
 sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 8000|g" $IROOT/ULib/benchmark.cfg
 
 
 # 2. Start ULib Server (userver_tcp)
 # 2. Start ULib Server (userver_tcp)
-export UMEMPOOL="58,0,0,39,16401,-14,-15,11,25"
+export UMEMPOOL="58,0,0,41,16401,-14,-15,11,25"
 
 
 # Never use setcap inside of TRAVIS 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \
 [ "$TRAVIS" != "true" ] || { \

+ 1 - 1
frameworks/C++/ulib/setup_postgres.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 2 * $MAX_THREADS ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET -2|g"								  $IROOT/ULib/benchmark.cfg

+ 2 - 2
frameworks/C++/ulib/setup_redis.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -12,7 +12,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 
 # 2. Start ULib Server (userver_tcp)
 # 2. Start ULib Server (userver_tcp)
 export REDIS_HOST=$DBHOST
 export REDIS_HOST=$DBHOST
-export UMEMPOOL="1057,0,0,39,274,-14,-15,-24,40"
+export UMEMPOOL="1261,0,0,49,274,-14,-15,-24,40"
 
 
 # Never use setcap inside of TRAVIS 
 # Never use setcap inside of TRAVIS 
 [ "$TRAVIS" != "true" ] || { \
 [ "$TRAVIS" != "true" ] || { \

+ 2 - 2
frameworks/C++/ulib/setup_sqlite.sh

@@ -2,7 +2,7 @@
 
 
 fw_depends ulib
 fw_depends ulib
 
 
-MAX_THREADS=$((2 * $MAX_THREADS))
+MAX_THREADS=$(( 3 * $MAX_THREADS / 2 ))
 
 
 # 1. Change ULib Server (userver_tcp) configuration
 # 1. Change ULib Server (userver_tcp) configuration
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
 sed -i "s|TCP_LINGER_SET .*|TCP_LINGER_SET 0|g"									  $IROOT/ULib/benchmark.cfg
@@ -12,7 +12,7 @@ sed -i "s|CLIENT_FOR_PARALLELIZATION .*|CLIENT_FOR_PARALLELIZATION 100|g" $IROOT
 
 
 # 2. Start ULib Server (userver_tcp)
 # 2. Start ULib Server (userver_tcp)
 export ORM_DRIVER="sqlite"
 export ORM_DRIVER="sqlite"
-export UMEMPOOL="545,0,0,41,275,-14,-13,-25,41"
+export UMEMPOOL="545,0,0,49,275,-14,-13,-25,41"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${IROOT}/ULib/db/%.*s"
 export ORM_OPTION="host=${DBHOST} user=benchmarkdbuser password=benchmarkdbpass character-set=utf8 dbname=${IROOT}/ULib/db/%.*s"
 
 
 # Never use setcap inside of TRAVIS 
 # Never use setcap inside of TRAVIS 

+ 4 - 0
frameworks/C++/ulib/source_code

@@ -1,12 +1,16 @@
 ./src/db.usp
 ./src/db.usp
 ./src/rdb.usp
 ./src/rdb.usp
+./src/mdb.usp
 ./src/world.h
 ./src/world.h
 ./src/json.usp
 ./src/json.usp
 ./src/fortune.h
 ./src/fortune.h
 ./src/query.usp
 ./src/query.usp
 ./src/rquery.usp
 ./src/rquery.usp
+./src/mquery.usp
 ./src/update.usp
 ./src/update.usp
 ./src/rupdate.usp
 ./src/rupdate.usp
+./src/mupdate.usp
 ./src/fortune.usp
 ./src/fortune.usp
 ./src/rfortune.usp
 ./src/rfortune.usp
+./src/mfortune.usp
 ./src/plaintext.usp
 ./src/plaintext.usp

+ 1 - 1
frameworks/C++/ulib/src/db.usp

@@ -23,7 +23,7 @@ static void usp_fork_db()
       {
       {
       pstmt_db = U_NEW(UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
       pstmt_db = U_NEW(UOrmStatement(*psql_db, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
 
-      if (pstmt_db == 0) U_ERROR("usp_fork_db(): we cound't connect to db");
+      if (pstmt_db == 0) U_WARNING("usp_fork_db(): we cound't connect to db");
 
 
       pworld_db = U_NEW(World);
       pworld_db = U_NEW(World);
 
 

+ 1 - 1
frameworks/C++/ulib/src/fortune.usp

@@ -22,7 +22,7 @@ static void usp_fork_fortune()
       {
       {
       pstmt_fortune = U_NEW(UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
       pstmt_fortune = U_NEW(UOrmStatement(*psql_fortune, U_CONSTANT_TO_PARAM("SELECT id, message FROM Fortune")));
 
 
-      if (pstmt_fortune == 0) U_ERROR("usp_fork_fortune(): we cound't connect to db");
+      if (pstmt_fortune == 0) U_WARNING("usp_fork_fortune(): we cound't connect to db");
 
 
       if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
       if (UOrmDriver::isPGSQL()) *psql_fortune << "BEGIN ISOLATION LEVEL SERIALIZABLE; COMMIT";
 
 

+ 81 - 0
frameworks/C++/ulib/src/mdb.usp

@@ -0,0 +1,81 @@
+<!--#
+Test type 2: Single database query
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static World* pworld;
+static UString* jquery;
+static UMongoDBClient* mc;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+#endif
+
+static void usp_fork_mdb()
+{
+   U_TRACE(5, "::usp_fork_mdb()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mdb(): connection failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mdb(): selectCollection() failed");
+
+      return;
+      }
+
+   pworld = U_NEW(World);
+   jquery = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue = U_NEW(UValue(OBJECT_VALUE));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mdb()
+{
+   U_TRACE(5, "::usp_end_mdb()")
+
+   delete mc;
+
+   if (pworld)
+      {
+      delete pworld;
+      delete jquery;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+UString result;
+
+(void) mc->findOne(pworld->id = u_get_num_random(10000));
+
+(void) UValue::jread(mc->vitem[0], *jquery, result); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+
+pworld->randomNumber = u_strtoul(result.data(), result.end());
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PRINTF_ADD("{\"id\":%u,\"randomNumber\":%v}", pworld->id, result.rep);
+#else
+USP_JSON_stringify(*pvalue, World, *pworld);
+pvalue->clear();
+#endif
+-->

+ 89 - 0
frameworks/C++/ulib/src/mfortune.usp

@@ -0,0 +1,89 @@
+<!--#
+Test type 4: Fortunes
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "fortune.h"
+
+static UString* jquery;
+static UString* pencoded;
+static UMongoDBClient* mc;
+static Fortune* pfortune2add;
+static UVector<Fortune*>* pvfortune;
+
+static void usp_fork_mfortune()
+{
+   U_TRACE(5, "::usp_fork_mfortune()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mfortune(): connection failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "Fortune") == false)
+      {
+      U_WARNING("usp_fork_mfortune(): selectCollection() failed");
+
+      return;
+      }
+
+   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'message'"));
+   pencoded     = U_NEW(UString(100U));
+   pvfortune    = U_NEW(UVector<Fortune*>);
+   pfortune2add = U_NEW(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()")
+
+   delete mc;
+
+   if (jquery)
+      {
+      delete jquery;
+      delete pencoded;
+      delete pvfortune;
+      delete pfortune2add;
+      }
+}
+#endif
+-->
+<!doctype html><html><head><title>Fortunes</title></head><body><table><tr><th>id</th><th>message</th></tr><!--#code
+uint32_t i, n;
+UString result;
+
+(void) mc->findAll();
+
+pvfortune->push_back(U_NEW(Fortune(*pfortune2add)));
+
+for (i = 0, n = mc->vitem.size(); i < n; ++i)
+   {
+   (void) UValue::jread(mc->vitem[i], *jquery, result); // { "_id" : 5.000000, "id" : 5.000000, "message" : "A computer program does what you tell it to do, not what you want it to do." }
+
+   pvfortune->push_back(U_NEW(Fortune(i+1, result)));
+   }
+
+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>

+ 105 - 0
frameworks/C++/ulib/src/mquery.usp

@@ -0,0 +1,105 @@
+<!--#
+Test type 3: Multiple database queries
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static UString* jquery;
+static UMongoDBClient* mc;
+static World* pworld_query;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_query;
+#endif
+
+static void usp_fork_mquery()
+{
+   U_TRACE(5, "::usp_fork_mquery()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mquery(): connection disabled or failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mquery(): selectCollection() failed");
+
+      return;
+      }
+
+   jquery       = U_NEW(U_STRING_FROM_CONSTANT("{'randomNumber'"));
+   pworld_query = U_NEW(World);
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue        = U_NEW(UValue(ARRAY_VALUE));
+   pvworld_query = U_NEW(UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mquery()
+{
+   U_TRACE(5, "::usp_end_mquery()")
+
+   delete mc;
+
+   if (jquery)
+      {
+      delete jquery;
+      delete pworld_query;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+      delete pvworld_query;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+UString rnumber;
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   (void) mc->findOne(pworld_query->id = u_get_num_random(10000));
+
+   (void) UValue::jread(mc->vitem[0], *jquery, rnumber); // { "_id" : 8980.000000, "id" : 8980.000000, "randomNumber" : 2131.000000 }
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%v}", pworld_query->id, rnumber.rep);
+#else
+   pworld_query->randomNumber = u_strtoul(rnumber.data(), rnumber.end());
+
+   pvworld_query->push_back(U_NEW(World(*pworld_query)));
+#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_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
+pvalue->clear();
+pvworld_query->clear();
+#endif
+-->

+ 99 - 0
frameworks/C++/ulib/src/mupdate.usp

@@ -0,0 +1,99 @@
+<!--#
+Test type 5: Database updates
+TechEmpower Web Framework Benchmarks
+-->
+<!--#declaration
+#include "world.h"
+
+static UMongoDBClient* mc;
+static World* pworld_update;
+
+#ifndef AS_cpoll_cppsp_DO
+static UValue* pvalue;
+static UVector<World*>* pvworld_update;
+#endif
+
+static void usp_fork_mupdate()
+{
+   U_TRACE(5, "::usp_fork_mupdate()")
+
+   mc = U_NEW(UMongoDBClient);
+
+   if (mc->connect() == false)
+      {
+      U_WARNING("usp_fork_mupdate(): connection disabled or failed");
+
+      return;
+      }
+
+   if (mc->selectCollection("hello_world", "World") == false)
+      {
+      U_WARNING("usp_fork_mupdate(): selectCollection() failed");
+
+      return;
+      }
+
+   pworld_update = U_NEW(World);
+
+#ifndef AS_cpoll_cppsp_DO
+   pvalue         = U_NEW(UValue(ARRAY_VALUE));
+   pvworld_update = U_NEW(UVector<World*>(500));
+#endif
+}
+
+#ifdef DEBUG
+static void usp_end_mupdate()
+{
+   U_TRACE(5, "::usp_end_mupdate()")
+
+   delete mc;
+
+   if (pworld_update)
+      {
+      delete pworld_update;
+
+#  ifndef AS_cpoll_cppsp_DO
+      delete pvalue;
+      delete pvworld_update;
+#  endif
+      }
+}
+#endif
+-->
+<!--#header
+Content-Type: application/json
+-->
+<!--#code
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
+
+#ifdef AS_cpoll_cppsp_DO
+USP_PUTS_CHAR('[');
+#endif
+
+while (true)
+   {
+   (void) mc->findOne(pworld_update->id = u_get_num_random(10000));
+
+   (void) mc->update(pworld_update->id, "randomNumber", pworld_update->randomNumber = u_get_num_random(10000));
+
+#ifdef AS_cpoll_cppsp_DO
+   USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
+#else
+   pvworld_update->push_back(U_NEW(World(*pworld_update)));
+#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_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
+pvalue->clear();
+pvworld_update->clear();
+#endif
+-->

+ 15 - 29
frameworks/C++/ulib/src/query.usp

@@ -5,13 +5,13 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World*           pworld_query;
-static UOrmSession*     psql_query;
-static UOrmStatement*   pstmt_query;
-static UVector<World*>* pvworld_query;
+static World*         pworld_query;
+static UOrmSession*   psql_query;
+static UOrmStatement* pstmt_query;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
 static UValue* pvalue;
+static UVector<World*>* pvworld_query;
 #endif
 #endif
 
 
 static void usp_fork_query()
 static void usp_fork_query()
@@ -24,7 +24,7 @@ static void usp_fork_query()
       {
       {
       pstmt_query = U_NEW(UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
       pstmt_query = U_NEW(UOrmStatement(*psql_query, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
 
 
-      if (pstmt_query == 0) U_ERROR("usp_fork_query(): we cound't connect to db");
+      if (pstmt_query == 0) U_WARNING("usp_fork_query(): we cound't connect to db");
 
 
       if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
       if (UOrmDriver::isPGSQL()) *psql_query << "BEGIN TRANSACTION";
 
 
@@ -33,10 +33,9 @@ static void usp_fork_query()
       pstmt_query->use( pworld_query->id);
       pstmt_query->use( pworld_query->id);
       pstmt_query->into(pworld_query->randomNumber);
       pstmt_query->into(pworld_query->randomNumber);
 
 
-      pvworld_query = U_NEW(UVector<World*>(500));
-
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue = U_NEW(UValue(ARRAY_VALUE));
+      pvalue        = U_NEW(UValue(ARRAY_VALUE));
+      pvworld_query = U_NEW(UVector<World*>(500));
 #  endif
 #  endif
       }
       }
 }
 }
@@ -48,36 +47,23 @@ static void usp_end_query()
 
 
    if (pstmt_query)
    if (pstmt_query)
       {
       {
-      delete   pstmt_query;
-      delete    psql_query;
-      delete pvworld_query;
-      delete  pworld_query;
+      delete pstmt_query;
+      delete psql_query;
+      delete pworld_query;
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
       delete pvalue;
+      delete pvworld_query;
 #  endif
 #  endif
       }
       }
 }
 }
 #endif
 #endif
 -->
 -->
-<!--#args
-queries;
--->
 <!--#header
 <!--#header
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-int i = 0, num_queries;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
 USP_PUTS_CHAR('[');
@@ -91,9 +77,9 @@ while (true)
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_query->id, pworld_query->randomNumber);
-#endif
-
+#else
    pvworld_query->push_back(U_NEW(World(*pworld_query)));
    pvworld_query->push_back(U_NEW(World(*pworld_query)));
+#endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;
 
 
@@ -107,6 +93,6 @@ USP_PUTS_CHAR(']');
 #else
 #else
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
 pvalue->clear();
 pvalue->clear();
-#endif
 pvworld_query->clear();
 pvworld_query->clear();
+#endif
 -->
 -->

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

@@ -30,6 +30,8 @@ static void usp_fork_rdb()
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
    pvalue = U_NEW(UValue(OBJECT_VALUE));
    pvalue = U_NEW(UValue(OBJECT_VALUE));
 #endif
 #endif
+
+   u__memcpy(u_buffer, "world:", U_CONSTANT_SIZE("world:"), __PRETTY_FUNCTION__);
 }
 }
 
 
 #ifdef DEBUG
 #ifdef DEBUG
@@ -56,9 +58,6 @@ Content-Type: application/json
 <!--#code
 <!--#code
 UStringRep* rep;
 UStringRep* rep;
 
 
-u_put_unalignedp32(u_buffer,   U_MULTICHAR_CONSTANT32('w','o','r','l'));
-u_put_unalignedp16(u_buffer+4, U_MULTICHAR_CONSTANT16('d',':'));
-
 (void) rc->get(u_buffer, 6+u_num2str32(u_buffer+6, pworld->id = u_get_num_random(10000)));
 (void) rc->get(u_buffer, 6+u_num2str32(u_buffer+6, pworld->id = u_get_num_random(10000)));
 
 
 rep = rc->vitem[0].rep;
 rep = rc->vitem[0].rep;

+ 9 - 22
frameworks/C++/ulib/src/rquery.usp

@@ -6,7 +6,7 @@ TechEmpower Web Framework Benchmarks
 #include "world.h"
 #include "world.h"
 
 
 static UREDISClient_Base* rc;
 static UREDISClient_Base* rc;
-static UVector<World*>* pvworld;
+static UVector<World*>* pvworld_query;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
 static UValue* pvalue;
@@ -25,7 +25,7 @@ static void usp_fork_rquery()
       return;
       return;
       }
       }
 
 
-   pvworld = U_NEW(UVector<World*>(500));
+   pvworld_query = U_NEW(UVector<World*>(500));
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
    pvalue = U_NEW(UValue(ARRAY_VALUE));
    pvalue = U_NEW(UValue(ARRAY_VALUE));
@@ -39,9 +39,9 @@ static void usp_end_rquery()
 
 
    delete rc;
    delete rc;
 
 
-   if (pvworld)
+   if (pvworld_query)
       {
       {
-      delete pvworld;
+      delete pvworld_query;
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
       delete pvalue;
@@ -50,27 +50,14 @@ static void usp_end_rquery()
 }
 }
 #endif
 #endif
 -->
 -->
-<!--#args
-queries;
--->
 <!--#header
 <!--#header
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
 World* pworld;
 World* pworld;
 UStringRep* rep;
 UStringRep* rep;
-int i, num_queries;
 char* pbuffer = u_buffer;
 char* pbuffer = u_buffer;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
 USP_PUTS_CHAR('[');
@@ -78,7 +65,7 @@ USP_PUTS_CHAR('[');
 
 
 for (i = 0; i < num_queries; ++i)
 for (i = 0; i < num_queries; ++i)
    {
    {
-   pvworld->push_back(pworld = U_NEW(World));
+   pvworld_query->push_back(pworld = U_NEW(World));
 
 
    u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
    u_put_unalignedp64(pbuffer, U_MULTICHAR_CONSTANT64(' ','w','o','r','l','d',':','\0'));
 
 
@@ -91,7 +78,7 @@ i = 0;
 
 
 while (true)
 while (true)
    {
    {
-   pworld = pvworld->at(i);
+   pworld = pvworld_query->at(i);
 
 
    rep = rc->vitem[i].rep;
    rep = rc->vitem[i].rep;
 
 
@@ -111,8 +98,8 @@ while (true)
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR(']');
 USP_PUTS_CHAR(']');
 #else
 #else
-USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld);
+USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_query);
 pvalue->clear();
 pvalue->clear();
 #endif
 #endif
-pvworld->clear();
+pvworld_query->clear();
 -->
 -->

+ 1 - 14
frameworks/C++/ulib/src/rupdate.usp

@@ -50,26 +50,13 @@ static void usp_end_rupdate()
 }
 }
 #endif
 #endif
 -->
 -->
-<!--#args
-queries;
--->
 <!--#header
 <!--#header
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
 World* pworld;
 World* pworld;
-int i, num_queries;
 char* pbuffer = u_buffer;
 char* pbuffer = u_buffer;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
 USP_PUTS_CHAR('[');

+ 17 - 30
frameworks/C++/ulib/src/update.usp

@@ -5,14 +5,14 @@ TechEmpower Web Framework Benchmarks
 <!--#declaration
 <!--#declaration
 #include "world.h"
 #include "world.h"
 
 
-static World*           pworld_update;
-static UOrmSession*     psql_update;
-static UOrmStatement*   pstmt1;
-static UOrmStatement*   pstmt2;
-static UVector<World*>* pvworld_update;
+static World*         pworld_update;
+static UOrmSession*   psql_update;
+static UOrmStatement* pstmt1;
+static UOrmStatement* pstmt2;
 
 
 #ifndef AS_cpoll_cppsp_DO
 #ifndef AS_cpoll_cppsp_DO
 static UValue* pvalue;
 static UValue* pvalue;
+static UVector<World*>* pvworld_update;
 #endif
 #endif
 
 
 static void usp_fork_update()
 static void usp_fork_update()
@@ -29,19 +29,20 @@ static void usp_fork_update()
       if (pstmt1 == 0 ||
       if (pstmt1 == 0 ||
           pstmt2 == 0)
           pstmt2 == 0)
          {
          {
-         U_ERROR("usp_fork_update(): we cound't connect to db");
+         U_WARNING("usp_fork_update(): we cound't connect to db");
          }
          }
 
 
+		if (UOrmDriver::isPGSQL()) *psql_update << "SET synchronous_commit TO OFF";
+
       pworld_update = U_NEW(World);
       pworld_update = U_NEW(World);
 
 
       pstmt1->use( pworld_update->id);
       pstmt1->use( pworld_update->id);
       pstmt1->into(pworld_update->randomNumber);
       pstmt1->into(pworld_update->randomNumber);
       pstmt2->use( pworld_update->randomNumber, pworld_update->id);
       pstmt2->use( pworld_update->randomNumber, pworld_update->id);
 
 
-      pvworld_update = U_NEW(UVector<World*>(500));
-
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
-      pvalue = U_NEW(UValue(ARRAY_VALUE));
+      pvalue         = U_NEW(UValue(ARRAY_VALUE));
+      pvworld_update = U_NEW(UVector<World*>(500));
 #  endif
 #  endif
       }
       }
 }
 }
@@ -56,36 +57,22 @@ static void usp_end_update()
       {
       {
       delete pstmt1;
       delete pstmt1;
       delete pstmt2;
       delete pstmt2;
-
-      delete    psql_update;
-      delete pvworld_update;
-      delete  pworld_update;
+      delete psql_update;
+      delete pworld_update;
 
 
 #  ifndef AS_cpoll_cppsp_DO
 #  ifndef AS_cpoll_cppsp_DO
       delete pvalue;
       delete pvalue;
+      delete pvworld_update;
 #  endif
 #  endif
       }
       }
 }
 }
 #endif
 #endif
 -->
 -->
-<!--#args
-queries;
--->
 <!--#header
 <!--#header
 Content-Type: application/json
 Content-Type: application/json
 -->
 -->
 <!--#code
 <!--#code
-int i = 0, num_queries;
-const char* ptr = queries.data();
-
-if (u__isdigit(*ptr) == false) num_queries = 1;
-else
-   {
-   num_queries = u_strtoul(ptr, queries.end());
-
-        if (num_queries <   1) num_queries = 1;
-   else if (num_queries > 500) num_queries = 500;
-   }
+int i = 0, num_queries = UHTTP::getFormFirstNumericValue(1, 500);
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
 USP_PUTS_CHAR('[');
 USP_PUTS_CHAR('[');
@@ -103,9 +90,9 @@ while (true)
 
 
 #ifdef AS_cpoll_cppsp_DO
 #ifdef AS_cpoll_cppsp_DO
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
    USP_PRINTF("{\"id\":%u,\"randomNumber\":%u}", pworld_update->id, pworld_update->randomNumber);
-#endif
-
+#else
    pvworld_update->push_back(U_NEW(World(*pworld_update)));
    pvworld_update->push_back(U_NEW(World(*pworld_update)));
+#endif
 
 
    if (++i == num_queries) break;
    if (++i == num_queries) break;
 
 
@@ -119,6 +106,6 @@ USP_PUTS_CHAR(']');
 #else
 #else
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
 USP_JSON_stringify(*pvalue, UVector<World*>, *pvworld_update);
 pvalue->clear();
 pvalue->clear();
-#endif
 pvworld_update->clear();
 pvworld_update->clear();
+#endif
 -->
 -->

+ 26 - 10
toolset/setup/linux/frameworks/ulib.sh

@@ -1,6 +1,5 @@
 #!/bin/bash
 #!/bin/bash
 
 
-
 RETCODE=$(fw_exists ${IROOT}/ulib.installed)
 RETCODE=$(fw_exists ${IROOT}/ulib.installed)
 [ ! "$RETCODE" == 0 ] || { \
 [ ! "$RETCODE" == 0 ] || { \
   source $IROOT/ulib.installed
   source $IROOT/ulib.installed
@@ -21,11 +20,22 @@ fi
 # TODO: This should already be installed and unnecessary.
 # TODO: This should already be installed and unnecessary.
 sudo apt-get install -y postgresql-server-dev-all
 sudo apt-get install -y postgresql-server-dev-all
 
 
-# make use of FIFO scheduling policy possible
-type setcap >/dev/null 2>/dev/null
-
-if [ $? -ne 0 ]; then
-   sudo apt-get install -y libcap2-bin
+# make use of FIFO scheduling policy possible (we must avoid use of test because bash signal trapping)
+#type setcap >/dev/null 2>/dev/null
+
+#if [ $? -ne 0 ]; then
+  sudo apt-get install -y libcap2-bin
+#fi
+
+# We need to install mongo-c-driver (we don't have a ubuntu package)
+RETCODE=$(fw_exists ${IROOT}/mongo-c-driver.installed)
+if [ "$RETCODE" != 0 ]; then
+  wget https://github.com/mongodb/mongo-c-driver/releases/download/1.1.10/mongo-c-driver-1.1.10.tar.gz
+  tar -xzf mongo-c-driver-1.1.10.tar.gz
+  cd mongo-c-driver-1.1.10/
+  ./configure --prefix=$IROOT --libdir=$IROOT
+  make && sudo make install
+  touch ${IROOT}/mongo-c-driver.installed
 fi
 fi
 
 
 # Add a simple configuration file to it
 # Add a simple configuration file to it
@@ -75,7 +85,8 @@ USP_FLAGS="-DAS_cpoll_cppsp_DO" \
    --with-mysql --with-pgsql --with-sqlite3 \
    --with-mysql --with-pgsql --with-sqlite3 \
    --without-ssl --without-pcre --without-expat \
    --without-ssl --without-pcre --without-expat \
    --without-libz --without-libuuid --without-magic --without-libares \
    --without-libz --without-libuuid --without-magic --without-libares \
-   --enable-static-orm-driver='mysql pgsql sqlite' --enable-static-server-plugin=http
+   --enable-static-orm-driver='mysql pgsql sqlite' --enable-static-server-plugin=http \
+	--with-mongodb --with-mongodb-includes="-I$IROOT/include/libbson-1.0 -I$IROOT/include/libmongoc-1.0" --with-mongodb-ldflags="-L$IROOT"
 #  --enable-debug \
 #  --enable-debug \
 #USP_LIBS="-ljson" \
 #USP_LIBS="-ljson" \
 
 
@@ -85,9 +96,11 @@ cp -r tests/examples/benchmark/FrameworkBenchmarks/ULib/db $ULIB_ROOT
 cd examples/userver
 cd examples/userver
 make install
 make install
 
 
-# 3. Compile usp pages for benchmark
+# 3. Compile usp pages for benchmark (no more REDIS)
 cd ../../src/ulib/net/server/plugin/usp
 cd ../../src/ulib/net/server/plugin/usp
-make db.la fortune.la json.la plaintext.la query.la update.la rdb.la rquery.la rupdate.la rfortune.la
+make json.la plaintext.la  db.la  query.la  update.la  fortune.la \
+                          mdb.la mquery.la mupdate.la mfortune.la
+#                         rdb.la rquery.la rupdate.la rfortune.la
 
 
 # Check that compilation worked
 # Check that compilation worked
 if [ ! -e .libs/db.so ]; then
 if [ ! -e .libs/db.so ]; then
@@ -95,7 +108,10 @@ if [ ! -e .libs/db.so ]; then
 fi
 fi
 
 
 mkdir -p $ULIB_DOCUMENT_ROOT
 mkdir -p $ULIB_DOCUMENT_ROOT
-cp .libs/db.so .libs/fortune.so .libs/json.so .libs/plaintext.so .libs/query.so .libs/update.so .libs/rdb.so .libs/rquery.so .libs/rupdate.so .libs/rfortune.so $ULIB_DOCUMENT_ROOT
+cp .libs/json.so .libs/plaintext.so \
+	.libs/db.so  .libs/query.so  .libs/update.so  .libs/fortune.so \
+	.libs/mdb.so .libs/mquery.so .libs/mupdate.so .libs/mfortune.so $ULIB_DOCUMENT_ROOT
+#  .libs/rdb.so .libs/rquery.so .libs/rupdate.so .libs/rfortune.so \
 
 
 echo "export ULIB_VERSION=${ULIB_VERSION}" >> $IROOT/ulib.installed
 echo "export ULIB_VERSION=${ULIB_VERSION}" >> $IROOT/ulib.installed
 echo "export ULIB_ROOT=${ULIB_ROOT}" >> $IROOT/ulib.installed
 echo "export ULIB_ROOT=${ULIB_ROOT}" >> $IROOT/ulib.installed