|
@@ -0,0 +1,184 @@
|
|
|
|
+<!--#
|
|
|
|
+Test 5: Database updates
|
|
|
|
+
|
|
|
|
+This test is a variation of Test #3 that exercises the ORM's persistence of
|
|
|
|
+objects and the database driver's performance at running UPDATE statements or similar.
|
|
|
|
+
|
|
|
|
+Requirements
|
|
|
|
+
|
|
|
|
+1. The recommended URI is /updates.
|
|
|
|
+
|
|
|
|
+2. For every request, an integer query string parameter named queries must be retrieved from the request.
|
|
|
|
+ The parameter specifies the number of rows to fetch and update in preparing the HTTP response (see below).
|
|
|
|
+
|
|
|
|
+3. The queries parameter must be bounded to between 1 and 500. If the parameter is missing, is not an integer,
|
|
|
|
+ or is an integer less than 1, the value should be interpreted as 1; if greater than 500, the value should be interpreted as 500.
|
|
|
|
+
|
|
|
|
+3. The schema for World is id (int, primary key) and randomNumber (int).
|
|
|
|
+
|
|
|
|
+4. The request handler must retrieve a set of World objects, equal in count to the queries parameter, from the World database table.
|
|
|
|
+
|
|
|
|
+5. Each row must be selected randomly in the same fashion as the single database query test (Test #2 above).
|
|
|
|
+
|
|
|
|
+6. At least the randomNumber field must be read from the database result set.
|
|
|
|
+
|
|
|
|
+7. Each World object must have its randomNumber field updated to a new random integer between 1 and 10000.
|
|
|
|
+
|
|
|
|
+8. Each World object must be persisted to the database with its new randomNumber value.
|
|
|
|
+
|
|
|
|
+9. Use of batch updates is acceptable but not required.
|
|
|
|
+
|
|
|
|
+10. Use of transactions is acceptable but not required.
|
|
|
|
+
|
|
|
|
+11. For raw tests (that is, tests without an ORM), each updated row must receive a unique new randomNumber value.
|
|
|
|
+ It is not acceptable to change the randomNumber value of all rows to the same random number using an UPDATE ... WHERE id IN (...) clause.
|
|
|
|
+
|
|
|
|
+12. Each World object must be added to a list or array.
|
|
|
|
+
|
|
|
|
+13. The list or array must be serialized to JSON and sent as a response.
|
|
|
|
+
|
|
|
|
+14. The response content type must be set to application/json.
|
|
|
|
+
|
|
|
|
+15. The response headers must include either Content-Length or Transfer-Encoding.
|
|
|
|
+
|
|
|
|
+16. The response headers must include Server and Date.
|
|
|
|
+
|
|
|
|
+17. Use of an in-memory cache of World objects or rows by the application is not permitted.
|
|
|
|
+
|
|
|
|
+18. Use of prepared statements for SQL database tests (e.g., for MySQL) is encouraged but not required.
|
|
|
|
+
|
|
|
|
+19. gzip compression is not permitted.
|
|
|
|
+
|
|
|
|
+20. Server support for HTTP Keep-Alive is strongly encouraged but not required.
|
|
|
|
+
|
|
|
|
+21. If HTTP Keep-Alive is enabled, no maximum Keep-Alive timeout is specified by this test.
|
|
|
|
+
|
|
|
|
+22. The request handler will be exercised at 256 concurrency only.
|
|
|
|
+
|
|
|
|
+23. The request handler will be exercised with query counts of 1, 5, 10, 15, and 20.
|
|
|
|
+
|
|
|
|
+24. The request handler will be exercised using GET requests.
|
|
|
|
+
|
|
|
|
+Example request:
|
|
|
|
+
|
|
|
|
+GET /updates?queries=10 HTTP/1.1
|
|
|
|
+Host: server
|
|
|
|
+User-Agent: Mozilla/5.0 (X11; Linux x86_64) Gecko/20130501 Firefox/30.0 AppleWebKit/600.00 Chrome/30.0.0000.0 Trident/10.0 Safari/600.00
|
|
|
|
+Cookie: uid=12345678901234567890; __utma=1.1234567890.1234567890.1234567890.1234567890.12; wd=2560x1600
|
|
|
|
+Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
|
|
|
|
+Accept-Language: en-US,en;q=0.5
|
|
|
|
+Connection: keep-alive
|
|
|
|
+
|
|
|
|
+Example response:
|
|
|
|
+
|
|
|
|
+HTTP/1.1 200 OK
|
|
|
|
+Content-Type: application/json; charset=UTF-8
|
|
|
|
+Content-Length: 315
|
|
|
|
+Server: Example
|
|
|
|
+Date: Wed, 17 Apr 2013 12:00:00 GMT
|
|
|
|
+
|
|
|
|
+[{"id":4174,"randomNumber":331},{"id":51,"randomNumber":6544},{"id":4462,"randomNumber":952},{"id":2221,"randomNumber":532},{"id":9276,"randomNumber":3097},{"id":3056,"randomNumber":7293},{"id":6964,"randomNumber":620},{"id":675,"randomNumber":6601},{"id":8414,"randomNumber":6569},{"id":2753,"randomNumber":4065}]
|
|
|
|
+-->
|
|
|
|
+<!--#declaration
|
|
|
|
+#include "world.h"
|
|
|
|
+
|
|
|
|
+#define AS_cpoll_cppsp_DO
|
|
|
|
+
|
|
|
|
+#ifndef AS_cpoll_cppsp_DO
|
|
|
|
+static UValue* pvalue;
|
|
|
|
+#endif
|
|
|
|
+static UOrmSession* psql_updates;
|
|
|
|
+static UOrmStatement* pstmt1;
|
|
|
|
+static UOrmStatement* pstmt2;
|
|
|
|
+static World* pworld_updates;
|
|
|
|
+static UVector<World*>* pvworld_updates;
|
|
|
|
+
|
|
|
|
+static void usp_init_updates()
|
|
|
|
+{
|
|
|
|
+ U_TRACE(5, "::usp_init_updates()")
|
|
|
|
+
|
|
|
|
+ psql_updates = U_NEW(UOrmSession(U_CONSTANT_TO_PARAM("hello_world")));
|
|
|
|
+ pstmt1 = U_NEW(UOrmStatement(*psql_updates, U_CONSTANT_TO_PARAM("SELECT randomNumber FROM World WHERE id = ?")));
|
|
|
|
+ pstmt2 = U_NEW(UOrmStatement(*psql_updates, U_CONSTANT_TO_PARAM("UPDATE World SET randomNumber = ? WHERE id = ?")));
|
|
|
|
+
|
|
|
|
+ if (pstmt1 == 0 ||
|
|
|
|
+ pstmt2 == 0)
|
|
|
|
+ {
|
|
|
|
+ U_ERROR("usp_init_updates(): we cound't connect to db, exiting...");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ pworld_updates = U_NEW(World);
|
|
|
|
+ pvworld_updates = U_NEW(UVector<World*>(500));
|
|
|
|
+
|
|
|
|
+ pstmt1->use( pworld_updates->id);
|
|
|
|
+ pstmt1->into(pworld_updates->randomNumber);
|
|
|
|
+ pstmt2->use( pworld_updates->randomNumber, pworld_updates->id);
|
|
|
|
+
|
|
|
|
+#ifndef AS_cpoll_cppsp_DO
|
|
|
|
+ pvalue = U_NEW(UValue(ARRAY_VALUE));
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void usp_end_updates()
|
|
|
|
+{
|
|
|
|
+ U_TRACE(5, "::usp_end_updates()")
|
|
|
|
+
|
|
|
|
+ delete pstmt1;
|
|
|
|
+ delete pstmt2;
|
|
|
|
+ delete psql_updates;
|
|
|
|
+ delete pvworld_updates;
|
|
|
|
+ delete pworld_updates;
|
|
|
|
+#ifndef AS_cpoll_cppsp_DO
|
|
|
|
+ delete pvalue;
|
|
|
|
+#endif
|
|
|
|
+}
|
|
|
|
+-->
|
|
|
|
+<!--#args
|
|
|
|
+queries;
|
|
|
|
+-->
|
|
|
|
+<!--#header
|
|
|
|
+Content-Type: application/json; charset=UTF-8
|
|
|
|
+-->
|
|
|
|
+<!--#code
|
|
|
|
+int i = 0, num_queries = queries.strtol();
|
|
|
|
+
|
|
|
|
+ if (num_queries < 1) num_queries = 1;
|
|
|
|
+else if (num_queries > 500) num_queries = 500;
|
|
|
|
+
|
|
|
|
+#ifdef AS_cpoll_cppsp_DO
|
|
|
|
+USP_PUTS_CHAR('[');
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+while (true)
|
|
|
|
+ {
|
|
|
|
+ pworld_updates->id = u_get_num_random(10000);
|
|
|
|
+
|
|
|
|
+ pstmt1->execute();
|
|
|
|
+
|
|
|
|
+ U_INTERNAL_DUMP("pworld_updates->randomNumber = %d", pworld_updates->randomNumber)
|
|
|
|
+
|
|
|
|
+ pworld_updates->randomNumber = u_get_num_random(10000);
|
|
|
|
+
|
|
|
|
+ pstmt2->execute();
|
|
|
|
+
|
|
|
|
+#ifdef AS_cpoll_cppsp_DO
|
|
|
|
+ USP_PRINTF("{\"id\":%d,\"randomNumber\":%d}", pworld_updates->id, pworld_updates->randomNumber);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+ pvworld_updates->push_back(U_NEW(World(*pworld_updates)));
|
|
|
|
+
|
|
|
|
+ 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_updates);
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+pvworld_updates->clear();
|
|
|
|
+-->
|