- log(DEBUG, "Couldn't allocate PGconn structure, aborting: %s", PQerrorMessage(sql));
- Close();
- return false;
- }
-
- if(PQstatus(sql) == CONNECTION_BAD)
- {
- log(DEBUG, "PQconnectStart failed: %s", PQerrorMessage(sql));
- Close();
- return false;
- }
-
- ShowStatus();
-
- if(PQsetnonblocking(sql, 1) == -1)
- {
- log(DEBUG, "Couldn't set connection nonblocking: %s", PQerrorMessage(sql));
- Close();
- return false;
- }
-
- /* OK, we've initalised the connection, now to get it hooked into the socket engine
- * and then start polling it.
- */
-
- log(DEBUG, "Old DNS socket: %d", this->fd);
- this->fd = PQsocket(sql);
- log(DEBUG, "New SQL socket: %d", this->fd);
-
- if(this->fd <= -1)
- {
- log(DEBUG, "PQsocket says we have an invalid FD: %d", this->fd);
- Close();
- return false;
+ if((status == WREAD) || (status == WWRITE))
+ {
+ if(!qinprog)
+ {
+ /* Parse the command string and dispatch it */
+
+ /* Pointer to the buffer we screw around with substitution in */
+ char* query;
+ /* Pointer to the current end of query, where we append new stuff */
+ char* queryend;
+ /* Total length of the unescaped parameters */
+ unsigned int paramlen;
+
+ paramlen = 0;
+
+ for(ParamL::iterator i = req.query.p.begin(); i != req.query.p.end(); i++)
+ {
+ paramlen += i->size();
+ }
+
+ /* To avoid a lot of allocations, allocate enough memory for the biggest the escaped query could possibly be.
+ * sizeofquery + (totalparamlength*2) + 1
+ *
+ * The +1 is for null-terminating the string for PQsendQuery()
+ */
+
+ query = new char[req.query.q.length() + (paramlen*2) + 1];
+ queryend = query;
+
+ /* Okay, now we have a buffer large enough we need to start copying the query into it and escaping and substituting
+ * the parameters into it...
+ */
+
+ for(unsigned int i = 0; i < req.query.q.length(); i++)
+ {
+ if(req.query.q[i] == '?')
+ {
+ /* We found a place to substitute..what fun.
+ * Use the PgSQL calls to escape and write the
+ * escaped string onto the end of our query buffer,
+ * then we "just" need to make sure queryend is
+ * pointing at the right place.
+ */
+
+ if(req.query.p.size())
+ {
+ int error = 0;
+ size_t len = 0;
+
+#ifdef PGSQL_HAS_ESCAPECONN
+ len = PQescapeStringConn(sql, queryend, req.query.p.front().c_str(), req.query.p.front().length(), &error);
+#else
+ len = PQescapeString (queryend, req.query.p.front().c_str(), req.query.p.front().length());
+#endif
+ if(error)
+ {
+ Instance->Log(DEBUG, "BUG: Apparently PQescapeStringConn() failed somehow...don't know how or what to do...");
+ }
+
+ /* Incremenet queryend to the end of the newly escaped parameter */
+ queryend += len;
+
+ /* Remove the parameter we just substituted in */
+ req.query.p.pop_front();
+ }
+ else
+ {
+ Instance->Log(DEBUG, "BUG: Found a substitution location but no parameter to substitute :|");
+ break;
+ }
+ }
+ else
+ {
+ *queryend = req.query.q[i];
+ queryend++;
+ }
+ }
+
+ /* Null-terminate the query */
+ *queryend = 0;
+ req.query.q = query;
+
+ if(PQsendQuery(sql, query))
+ {
+ qinprog = true;
+ delete[] query;
+ return SQLerror();
+ }
+ else
+ {
+ delete[] query;
+ return SQLerror(QSEND_FAIL, PQerrorMessage(sql));
+ }
+ }
+ }
+ return SQLerror(BAD_CONN, "Can't query until connection is complete");