123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <%!-lpq%><%!-I/usr/include/postgresql%><%@ class mypage %><%#
- #include <libpq-fe.h>
- #include <postgres.h>
- #include <catalog/pg_type.h>
- #include <json/json.h>
- #include <cpoll/threadpool.H>
- #include <list>
- #include "connectioninfo.H"
- #include "generic_pool.H"
- #include "world.H"
- using namespace CP;
- using namespace cppsp;
- using namespace std;
- struct myStatement
- {
- public:
- PGconn* db;
- int paramLengths[1];
- int paramFormats[1];
- File f;
- Poll* p;
- bool addedToPoll=false;
- myStatement() {
- db=doConnect_pg(NULL);
- Oid oid=INT4OID;
- PGresult* res;
- if((res=PQprepare(db, "zxcvb", "SELECT randomnumber FROM World where id=$1", 1, &oid))==NULL)
- goto fail;
- PQclear(res);
- paramLengths[0] = sizeof(int);
- paramFormats[0] = 1; //binary
- return;
- fail:
- doDisconnect_pg(NULL,db);
- throw runtime_error("error preparing statement");
- }
- ~myStatement() {
- if(addedToPoll) {
- p->del(f);
- }
- f.deinit();
- doDisconnect_pg(NULL,db);
- }
- void exec(int id) {
- const char *params[1];
- id=htonl(id);
- params[0]=(const char*)&id;
- PQsendQueryPrepared(db,"zxcvb",1,params,paramLengths,paramFormats,1/*binary*/);
- }
- };
- myStatement* cStatement(void*) {
- return new myStatement();
- }
- void dStatement(void*, myStatement* s) {
- delete s;
- }
- genericPool<myStatement*,128> stmtPool(&cStatement,&dStatement);
- %><%$
- int queries=1;
- world* items;
- int n=0;
- myStatement* stmt;
- //asynchronously load the data in the doInit() function, and defer page rendering until data is available
- void doInit() override {
- auto it=request->queryString.find("queries");
- if(it!=request->queryString.end()) {
- queries=atoi((*it).second);
- }
- if(queries<1)queries=1;
- if(queries>500)queries=500;
- int i;
- items=(world*)sp->alloc(sizeof(world)*queries);
- stmt=stmtPool.get();
- if(!stmt->addedToPoll) {
- poll->add(stmt->f);
- stmt->addedToPoll=true;
- stmt->p=poll;
- }
- beginGetItems();
- }
- void beginGetItems() {
- if(n>=queries) {
- stmtPool.put(stmt);
- Page::doInit();
- return;
- }
- items[n++].id=rand()%10000;
- stmt->exec(items[n-1].id);
- stmt->f.waitForEvent(Events::in,{&mypage::evtIn,this});
- }
- void evtIn(int) {
- PGresult* res;
- res=PQgetResult(stmt->db);
- PGresult* res1;
- while((res1=PQgetResult(stmt->db))!=NULL) {
- PQclear(res1);
- }
- int tmp;
- if(PQntuples(res)>0)
- tmp=*(const int*)PQgetvalue(res,0,0);
- else tmp=0;
- items[n-1].rnd=ntohl(tmp);
- PQclear(res);
- beginGetItems();
- }
- %>[<%
- for (int i=0;i<queries;i++){
- if(i>0) output.write(',');
- %>{"id":<%=items[i].id%>,"randomNumber":<%=items[i].rnd%>}<%
- }
- response->headers["Content-Type"]="application/json";
- response->headers["Server"]="cppsp/0.2";
- %>]
|