Forráskód Böngészése

Update Drogon to the latest version (#4582)

Optimize the 'Updates' test
An Tao 6 éve
szülő
commit
9156f80c0c

+ 1 - 1
frameworks/C++/drogon/drogon-raw.dockerfile

@@ -34,7 +34,7 @@ RUN git clone https://github.com/an-tao/drogon
 
 WORKDIR $DROGON_ROOT
 
-RUN git checkout 1e1bcbf781d9e2cf3a9d4110ef6fc6875c41a1bd
+RUN git checkout 92d7867ee4eeaf072cf7112f7773661a26d3c185
 
 RUN ./build.sh
 

+ 1 - 1
frameworks/C++/drogon/drogon.dockerfile

@@ -34,7 +34,7 @@ RUN git clone https://github.com/an-tao/drogon
 
 WORKDIR $DROGON_ROOT
 
-RUN git checkout 1e1bcbf781d9e2cf3a9d4110ef6fc6875c41a1bd
+RUN git checkout 92d7867ee4eeaf072cf7112f7773661a26d3c185
 
 RUN ./build.sh
 

+ 135 - 138
frameworks/C++/drogon/drogon_benchmark/config-raw.json

@@ -1,142 +1,139 @@
 /* This is a JSON format configuration file
-*/
+ */
 {
-  //ssl:the global ssl files setting
-  /*
-  "ssl": {
-    "cert": "../../trantor/trantor/tests/server.pem",
-    "key": "../../trantor/trantor/tests/server.pem"
-  },*/
-  "listeners": [
-    {
-      //address:ip address,0.0.0.0 by default
-      "address": "0.0.0.0",
-      //port:port number
-      "port": 8080,
-      //https:if use https for security,false by default
-      "https": false
+    //ssl:the global ssl files setting
+    /*
+    "ssl": {
+      "cert": "../../trantor/trantor/tests/server.pem",
+      "key": "../../trantor/trantor/tests/server.pem"
+    },*/
+    "listeners": [{
+        //address:ip address,0.0.0.0 by default
+        "address": "0.0.0.0",
+        //port:port number
+        "port": 8080,
+        //https:if use https for security,false by default
+        "https": false
+    }],
+    "db_clients": [{
+        //name:Name of the client,'default' by default
+        //"name":"",
+        //rdbms:server type, "postgreSQL" by default
+        "rdbms": "postgreSQL",
+        //host:server address,localhost by default
+        "host": "tfb-database",
+        //port:server port, 5432 by default
+        "port": 5432,
+        //dbname:Database name
+        "dbname": "hello_world",
+        //user:'postgres' by default
+        "user": "benchmarkdbuser",
+        //passwd:'' by default
+        "passwd": "benchmarkdbpass",
+        //is_fast: false by default, if it is true, the client is faster but user can't call
+        //any synchronous interface of it.
+        "is_fast": true,
+        //connection_number:1 by default
+        "connection_number": 1
+    }],
+    "app": {
+        //threads_num:the number of IO threads,1 by default, if the value is set to 0, the number of threads
+        //will be the number of processors.
+        "threads_num": 0,
+        //enable_session:false by default
+        "enable_session": false,
+        "session_timeout": 0,
+        //document_root:Root path of HTTP document,defaut path is ./
+        "document_root": "./",
+        /* file_types:
+         * HTTP download file types,The file types supported by drogon
+         * by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
+         * "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
+         * "gif", "bmp", "ico", "icns", etc. */
+        "file_types": [
+            "gif",
+            "png",
+            "jpg",
+            "js",
+            "css",
+            "html",
+            "ico",
+            "swf",
+            "xap",
+            "apk",
+            "cur",
+            "xml"
+        ],
+        //max_connections:max connections number,100000 by default
+        "max_connections": 100000,
+        //max_connections_per_ip:max connections number per clinet,0 by default which means no limit
+        "max_connections_per_ip": 0,
+        //Load_dynamic_views: false by default, when set to true, drogon will
+        //compile and load dynamically "CSP View Files" in directories defined
+        //by "dynamic_views_path"
+        //"load_dynamic_views":true,
+        //dynamic_views_path: if the path isn't prefixed with / or ./,
+        //it will be relative path of document_root path
+        //"dynamic_views_path":["./views"],
+        //log:set log output,drogon output logs to stdout by default
+        "log": {
+            //log_path:log file path,empty by default,in which case,log will output to the stdout
+            //"log_path": "./",
+            //logfile_base_name:log file base name,empty by default which means drogon will name logfile as
+            //drogon.log ...
+            "logfile_base_name": "",
+            //log_size_limit:100000000 bytes by default,
+            //When the log file size reaches "log_size_limit", the log file will be switched.
+            "log_size_limit": 100000000,
+            //log_level:"DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
+            //The TRACE level is only valid when built in DEBUG mode.
+            "log_level": "WARN"
+        },
+        //run_as_daemon:false by default
+        "run_as_daemon": false,
+        //relaunch_on_error:false by default,if true,the program will be restart by parent after exit;
+        "relaunch_on_error": false,
+        //use_sendfile:true by default,if ture,the program will
+        //use sendfile() system-call to send static file to client;
+        "use_sendfile": true,
+        //use_gzip:true by default,use gzip to compress the response body's content;
+        "use_gzip": false,
+        //static_files_cache_time:5 (seconds) by default,the time in which static file response is cached,
+        //0 means cache forever,the negative value means no cache
+        "static_files_cache_time": 5,
+        //simple_controllers_map:Configuring mapping from path to simple controller
+        "simple_controllers_map": [
+            {
+                "path": "/db",
+                "controller": "DbCtrlRaw",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/fortunes",
+                "controller": "FortuneCtrlRaw",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/queries",
+                "controller": "QueriesCtrlRaw",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/updates",
+                "controller": "UpdatesCtrlRaw",
+                "http_methods": [
+                    "get"
+                ]
+            }
+        ],
+        //idle_connection_timeout: defaults to 60 seconds, the lifetime 
+        //of the connection without read or write
+        "idle_connection_timeout": 60
     }
-  ],
-  "db_clients": [
-    {
-      //name:Name of the client,'default' by default
-      //"name":"",
-      //rdbms:server type, "postgreSQL" by default
-      "rdbms": "postgreSQL",
-      //host:server address,localhost by default
-      "host": "tfb-database",
-      //port:server port, 5432 by default
-      "port": 5432,
-      //dbname:Database name
-      "dbname": "hello_world",
-      //user:'postgres' by default
-      "user": "benchmarkdbuser",
-      //passwd:'' by default
-      "passwd": "benchmarkdbpass",
-      //connection_number:1 by default
-      "connection_number": 1
-    }
-  ],
-  "app": {
-    //threads_num:the number of IO threads,1 by default, if the value is set to 0, the number of threads
-    //will be the number of processors.
-    "threads_num": 0,
-    //enable_session:false by default
-    "enable_session": false,
-    "session_timeout": 0,
-    //document_root:Root path of HTTP document,defaut path is ./
-    "document_root": "./",
-    /* file_types:
-     * HTTP download file types,The file types supported by drogon
-     * by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
-     * "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
-     * "gif", "bmp", "ico", "icns", etc. */
-    "file_types": [
-      "gif",
-      "png",
-      "jpg",
-      "js",
-      "css",
-      "html",
-      "ico",
-      "swf",
-      "xap",
-      "apk",
-      "cur",
-      "xml"
-    ],
-    //max_connections:max connections number,100000 by default
-    "max_connections": 100000,
-    //max_connections_per_ip:max connections number per clinet,0 by default which means no limit
-    "max_connections_per_ip": 0,
-    //Load_dynamic_views: false by default, when set to true, drogon will
-    //compile and load dynamically "CSP View Files" in directories defined
-    //by "dynamic_views_path"
-    //"load_dynamic_views":true,
-    //dynamic_views_path: if the path isn't prefixed with / or ./,
-    //it will be relative path of document_root path
-    //"dynamic_views_path":["./views"],
-    //log:set log output,drogon output logs to stdout by default
-    "log": {
-      //log_path:log file path,empty by default,in which case,log will output to the stdout
-      //"log_path": "./",
-      //logfile_base_name:log file base name,empty by default which means drogon will name logfile as
-      //drogon.log ...
-      "logfile_base_name": "",
-      //log_size_limit:100000000 bytes by default,
-      //When the log file size reaches "log_size_limit", the log file will be switched.
-      "log_size_limit": 100000000,
-      //log_level:"DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
-      //The TRACE level is only valid when built in DEBUG mode.
-      "log_level": "WARN"
-    },
-    //run_as_daemon:false by default
-    "run_as_daemon": false,
-    //relaunch_on_error:false by default,if true,the program will be restart by parent after exit;
-    "relaunch_on_error": false,
-    //use_sendfile:true by default,if ture,the program will
-    //use sendfile() system-call to send static file to client;
-    "use_sendfile": true,
-    //use_gzip:true by default,use gzip to compress the response body's content;
-    "use_gzip": false,
-    //static_files_cache_time:5 (seconds) by default,the time in which static file response is cached,
-    //0 means cache forever,the negative value means no cache
-    "static_files_cache_time": 5,
-    //simple_controllers_map:Configuring mapping from path to simple controller
-    "simple_controllers_map": [
-      {
-        "path": "/db",
-        "controller": "DbCtrlRaw",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/fortunes",
-        "controller": "FortuneCtrlRaw",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/queries",
-        "controller": "QueriesCtrlRaw",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/updates",
-        "controller": "UpdatesCtrlRaw",
-        "http_methods": [
-          "get"
-        ]
-      }
-    ],
-    //idle_connection_timeout: defaults to 60 seconds, the lifetime 
-    //of the connection without read or write
-    "idle_connection_timeout": 60,
-    //enable_fast_db_client: Defaults to false
-    "enable_fast_db_client": true
-  }
 }

+ 151 - 154
frameworks/C++/drogon/drogon_benchmark/config.json

@@ -1,158 +1,155 @@
 /* This is a JSON format configuration file
-*/
+ */
 {
-  //ssl:the global ssl files setting
-  /*
-  "ssl": {
-    "cert": "../../trantor/trantor/tests/server.pem",
-    "key": "../../trantor/trantor/tests/server.pem"
-  },*/
-  "listeners": [
-    {
-      //address:ip address,0.0.0.0 by default
-      "address": "0.0.0.0",
-      //port:port number
-      "port": 8080,
-      //https:if use https for security,false by default
-      "https": false
-    }
-  ],
-  "db_clients": [
-    {
-      //name:Name of the client,'default' by default
-      //"name":"",
-      //rdbms:server type, "postgreSQL" by default
-      "rdbms": "postgreSQL",
-      //host:server address,localhost by default
-      "host": "tfb-database",
-      //port:server port, 5432 by default
-      "port": 5432,
-      //dbname:Database name
-      "dbname": "hello_world",
-      //user:'postgres' by default
-      "user": "benchmarkdbuser",
-      //passwd:'' by default
-      "passwd": "benchmarkdbpass",
-      //connection_number:1 by default
-      "connection_number": 1
-    }
-  ],
-  "app": {
-    //threads_num:the number of IO threads,1 by default, if the value is set to 0, the number of threads
-    //will be the number of processors.
-    "threads_num": 0,
-    //enable_session:false by default
-    "enable_session": false,
-    "session_timeout": 0,
-    //document_root:Root path of HTTP document,defaut path is ./
-    "document_root": "./",
-    /* file_types:
-     * HTTP download file types,The file types supported by drogon
-     * by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
-     * "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
-     * "gif", "bmp", "ico", "icns", etc. */
-    "file_types": [
-      "gif",
-      "png",
-      "jpg",
-      "js",
-      "css",
-      "html",
-      "ico",
-      "swf",
-      "xap",
-      "apk",
-      "cur",
-      "xml"
-    ],
-    //max_connections:max connections number,100000 by default
-    "max_connections": 100000,
-    //max_connections_per_ip:max connections number per clinet,0 by default which means no limit
-    "max_connections_per_ip": 0,
-    //Load_dynamic_views: false by default, when set to true, drogon will
-    //compile and load dynamically "CSP View Files" in directories defined
-    //by "dynamic_views_path"
-    //"load_dynamic_views":true,
-    //dynamic_views_path: if the path isn't prefixed with / or ./,
-    //it will be relative path of document_root path
-    //"dynamic_views_path":["./views"],
-    //log:set log output,drogon output logs to stdout by default
-    "log": {
-      //log_path:log file path,empty by default,in which case,log will output to the stdout
-      //"log_path": "./",
-      //logfile_base_name:log file base name,empty by default which means drogon will name logfile as
-      //drogon.log ...
-      "logfile_base_name": "",
-      //log_size_limit:100000000 bytes by default,
-      //When the log file size reaches "log_size_limit", the log file will be switched.
-      "log_size_limit": 100000000,
-      //log_level:"DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
-      //The TRACE level is only valid when built in DEBUG mode.
-      "log_level": "WARN"
-    },
-    //run_as_daemon:false by default
-    "run_as_daemon": false,
-    //relaunch_on_error:false by default,if true,the program will be restart by parent after exit;
-    "relaunch_on_error": false,
-    //use_sendfile:true by default,if ture,the program will
-    //use sendfile() system-call to send static file to client;
-    "use_sendfile": true,
-    //use_gzip:true by default,use gzip to compress the response body's content;
-    "use_gzip": false,
-    //static_files_cache_time:5 (seconds) by default,the time in which static file response is cached,
-    //0 means cache forever,the negative value means no cache
-    "static_files_cache_time": 5,
-    //simple_controllers_map:Configuring mapping from path to simple controller
-    "simple_controllers_map": [
-      {
-        "path": "/plaintext",
-        "controller": "PlaintextCtrl",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/json",
-        "controller": "JsonCtrl",
-        "http_methods": [
-          "get"
+    //ssl:the global ssl files setting
+    /*
+    "ssl": {
+      "cert": "../../trantor/trantor/tests/server.pem",
+      "key": "../../trantor/trantor/tests/server.pem"
+    },*/
+    "listeners": [{
+        //address:ip address,0.0.0.0 by default
+        "address": "0.0.0.0",
+        //port:port number
+        "port": 8080,
+        //https:if use https for security,false by default
+        "https": false
+    }],
+    "db_clients": [{
+        //name:Name of the client,'default' by default
+        //"name":"",
+        //rdbms:server type, "postgreSQL" by default
+        "rdbms": "postgreSQL",
+        //host:server address,localhost by default
+        "host": "tfb-database",
+        //port:server port, 5432 by default
+        "port": 5432,
+        //dbname:Database name
+        "dbname": "hello_world",
+        //user:'postgres' by default
+        "user": "benchmarkdbuser",
+        //passwd:'' by default
+        "passwd": "benchmarkdbpass",
+        //is_fast: false by default, if it is true, the client is faster but user can't call
+        //any synchronous interface of it.
+        "is_fast": true,
+        //connection_number:1 by default
+        "connection_number": 1
+    }],
+    "app": {
+        //threads_num:the number of IO threads,1 by default, if the value is set to 0, the number of threads
+        //will be the number of processors.
+        "threads_num": 0,
+        //enable_session:false by default
+        "enable_session": false,
+        "session_timeout": 0,
+        //document_root:Root path of HTTP document,defaut path is ./
+        "document_root": "./",
+        /* file_types:
+         * HTTP download file types,The file types supported by drogon
+         * by default are "html", "js", "css", "xml", "xsl", "txt", "svg",
+         * "ttf", "otf", "woff2", "woff" , "eot", "png", "jpg", "jpeg",
+         * "gif", "bmp", "ico", "icns", etc. */
+        "file_types": [
+            "gif",
+            "png",
+            "jpg",
+            "js",
+            "css",
+            "html",
+            "ico",
+            "swf",
+            "xap",
+            "apk",
+            "cur",
+            "xml"
         ],
-        "filters": []
-      },
-      {
-        "path": "/db",
-        "controller": "DbCtrl",
-        "http_methods": [
-          "get"
+        //max_connections:max connections number,100000 by default
+        "max_connections": 100000,
+        //max_connections_per_ip:max connections number per clinet,0 by default which means no limit
+        "max_connections_per_ip": 0,
+        //Load_dynamic_views: false by default, when set to true, drogon will
+        //compile and load dynamically "CSP View Files" in directories defined
+        //by "dynamic_views_path"
+        //"load_dynamic_views":true,
+        //dynamic_views_path: if the path isn't prefixed with / or ./,
+        //it will be relative path of document_root path
+        //"dynamic_views_path":["./views"],
+        //log:set log output,drogon output logs to stdout by default
+        "log": {
+            //log_path:log file path,empty by default,in which case,log will output to the stdout
+            //"log_path": "./",
+            //logfile_base_name:log file base name,empty by default which means drogon will name logfile as
+            //drogon.log ...
+            "logfile_base_name": "",
+            //log_size_limit:100000000 bytes by default,
+            //When the log file size reaches "log_size_limit", the log file will be switched.
+            "log_size_limit": 100000000,
+            //log_level:"DEBUG" by default,options:"TRACE","DEBUG","INFO","WARN"
+            //The TRACE level is only valid when built in DEBUG mode.
+            "log_level": "WARN"
+        },
+        //run_as_daemon:false by default
+        "run_as_daemon": false,
+        //relaunch_on_error:false by default,if true,the program will be restart by parent after exit;
+        "relaunch_on_error": false,
+        //use_sendfile:true by default,if ture,the program will
+        //use sendfile() system-call to send static file to client;
+        "use_sendfile": true,
+        //use_gzip:true by default,use gzip to compress the response body's content;
+        "use_gzip": false,
+        //static_files_cache_time:5 (seconds) by default,the time in which static file response is cached,
+        //0 means cache forever,the negative value means no cache
+        "static_files_cache_time": 5,
+        //simple_controllers_map:Configuring mapping from path to simple controller
+        "simple_controllers_map": [
+            {
+                "path": "/plaintext",
+                "controller": "PlaintextCtrl",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/json",
+                "controller": "JsonCtrl",
+                "http_methods": [
+                    "get"
+                ],
+                "filters": []
+            },
+            {
+                "path": "/db",
+                "controller": "DbCtrl",
+                "http_methods": [
+                    "get"
+                ],
+                "filters": []
+            },
+            {
+                "path": "/fortunes",
+                "controller": "FortuneCtrl",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/queries",
+                "controller": "QueriesCtrl",
+                "http_methods": [
+                    "get"
+                ]
+            },
+            {
+                "path": "/updates",
+                "controller": "UpdatesCtrl",
+                "http_methods": [
+                    "get"
+                ]
+            }
         ],
-        "filters": []
-      },
-      {
-        "path": "/fortunes",
-        "controller": "FortuneCtrl",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/queries",
-        "controller": "QueriesCtrl",
-        "http_methods": [
-          "get"
-        ]
-      },
-      {
-        "path": "/updates",
-        "controller": "UpdatesCtrl",
-        "http_methods": [
-          "get"
-        ]
-      }
-    ],
-    //idle_connection_timeout: defaults to 60 seconds, the lifetime 
-    //of the connection without read or write
-    "idle_connection_timeout": 60,
-    //enable_fast_db_client: Defaults to false
-    "enable_fast_db_client": true
-  }
-}
+        //idle_connection_timeout: defaults to 60 seconds, the lifetime 
+        //of the connection without read or write
+        "idle_connection_timeout": 60
+    }
+}

+ 69 - 29
frameworks/C++/drogon/drogon_benchmark/controllers/UpdatesCtrlRaw.cc

@@ -1,5 +1,61 @@
 #include "UpdatesCtrlRaw.h"
 using namespace drogon::orm;
+const void update(const std::shared_ptr<std::vector<Result>> &results,
+                  const std::shared_ptr<std::function<void(const HttpResponsePtr &)>> &callbackPtr,
+                  const DbClientPtr &client)
+{
+
+    auto size = results->size();
+    std::string sql;
+    sql.reserve(256);
+    sql.append("update world set randomnumber=case id ");
+    int placeholdersCounter = 1;
+    for (size_t i = 0; i < size; i++)
+    {
+        auto tmpStr = drogon::utils::formattedString("when $%d then $%d ", placeholdersCounter, placeholdersCounter + 1);
+        placeholdersCounter += 2;
+        sql.append(tmpStr);
+    }
+    sql.append("else randomnumber end where id in (");
+    for (size_t i = 0; i < size; i++)
+    {
+        auto tmpStr = drogon::utils::formattedString("$%d,", placeholdersCounter);
+        ++placeholdersCounter;
+        sql.append(tmpStr);
+    }
+    sql[sql.length() - 1] = ')';
+
+    auto sqlBinder = *client << std::move(sql);
+
+    auto jsonPtr = std::make_shared<Json::Value>();
+    jsonPtr->resize(0);
+    for (auto &r : *results)
+    {
+        auto randId = rand() % 10000 + 1;
+        auto id = r[0]["id"].as<int>();
+        sqlBinder << id;
+        sqlBinder << randId;
+        Json::Value j;
+        j["id"] = id;
+        j["randomnumber"] = randId;
+        jsonPtr->append(std::move(j));
+    }
+    for (auto &r : *results)
+    {
+        sqlBinder << r[0]["id"].as<int>();
+    }
+
+    sqlBinder >>
+        [jsonPtr = std::move(jsonPtr), callbackPtr](const Result &r) mutable {
+            (*callbackPtr)(HttpResponse::newHttpJsonResponse(*jsonPtr));
+        } >>
+        [callbackPtr](const DrogonDbException &e) {
+            Json::Value ret;
+            ret["result"] = "error!";
+            auto resp = HttpResponse::newHttpJsonResponse(ret);
+            (*callbackPtr)(resp);
+        };
+}
 void UpdatesCtrlRaw::asyncHandleHttpRequest(const HttpRequestPtr &req, const std::function<void(const HttpResponsePtr &)> &callback)
 {
     //write your application logic here
@@ -7,7 +63,7 @@ void UpdatesCtrlRaw::asyncHandleHttpRequest(const HttpRequestPtr &req, const std
     std::call_once(once, []() {
         srand(time(NULL));
     });
-    int queries = 1;
+    size_t queries = 1;
     auto &parameter = req->getParameter("queries");
     if (!parameter.empty())
     {
@@ -20,36 +76,20 @@ void UpdatesCtrlRaw::asyncHandleHttpRequest(const HttpRequestPtr &req, const std
     auto json = std::make_shared<Json::Value>();
     json->resize(0);
     auto callbackPtr = std::shared_ptr<std::function<void(const HttpResponsePtr &)>>(new std::function<void(const HttpResponsePtr &)>(callback));
-    auto counter = std::make_shared<int>(queries);
+    auto resultSetPtr = std::make_shared<std::vector<Result>>();
+    resultSetPtr->reserve(queries);
     auto client = app().getFastDbClient();
-    for (int i = 0; i < queries; i++)
+    for (size_t i = 0; i < queries; i++)
     {
         int id = rand() % 10000 + 1;
-        *client << "select randomnumber from world where id=$1" << id >>
-            [callbackPtr, counter, json, id, client](const Result &r) mutable {
-                auto randId = rand() % 10000 + 1;
-                *client << "update world set randomnumber=$1 where id=$2"
-                        << randId
-                        << id >>
-                    [id, json = std::move(json), randId, counter = std::move(counter), callbackPtr](const Result &r) mutable {
-                        (*counter)--;
-
-                        Json::Value j;
-                        j["id"] = id;
-                        j["randomnumber"] = randId;
-                        json->append(std::move(j));
-
-                        if ((*counter) == 0)
-                        {
-                            (*callbackPtr)(HttpResponse::newHttpJsonResponse(*json));
-                        }
-                    } >>
-                    [callbackPtr](const DrogonDbException &e) {
-                        Json::Value ret;
-                        ret["result"] = "error!";
-                        auto resp = HttpResponse::newHttpJsonResponse(ret);
-                        (*callbackPtr)(resp);
-                    };
+        *client << "select * from world where id=$1"
+                << id >>
+            [callbackPtr, resultSetPtr, client, queries](const Result &r) mutable {
+                resultSetPtr->push_back(r);
+                if (resultSetPtr->size() == queries)
+                {
+                    update(resultSetPtr, callbackPtr, client);
+                }
             } >>
             [callbackPtr](const DrogonDbException &e) {
                 Json::Value ret;
@@ -58,4 +98,4 @@ void UpdatesCtrlRaw::asyncHandleHttpRequest(const HttpRequestPtr &req, const std
                 (*callbackPtr)(resp);
             };
     }
-}
+}