| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748 |
- /*
- * Copyright (c) 2014, Oculus VR, Inc.
- * All rights reserved.
- *
- * This source code is licensed under the BSD-style license found in the
- * LICENSE file in the root directory of this source tree. An additional grant
- * of patent rights can be found in the PATENTS file in the same directory.
- *
- */
- #include "PostgreSQLInterface.h"
- #include "VariadicSQLParser.h"
- // libpq-fe.h is part of PostgreSQL which must be installed on this computer to use the PostgreRepository
- #include "libpq-fe.h"
- #ifdef _CONSOLE_1
- #include "Console1Includes.h"
- #elif defined(_WIN32)
- #include <winsock2.h> // htonl
- #elif defined(_CONSOLE_2)
- #include "Console2Includes.h"
- #else
- #include <arpa/inet.h>
- #endif
- // alloca
- #ifdef _COMPATIBILITY_1
- #elif defined(_WIN32)
- #include <malloc.h>
- #else
- //#include <stdlib.h>
- #endif
- #include "RakString.h"
- #include "RakAssert.h"
- #include "BitStream.h"
- #include "FormatString.h"
- #include "LinuxStrings.h"
- #define PQEXECPARAM_FORMAT_TEXT 0
- #define PQEXECPARAM_FORMAT_BINARY 1
- PostgreSQLInterface::PostgreSQLInterface()
- {
- pgConn=0;
- isConnected=false;
- lastError[0]=0;
- pgConnAllocatedHere=false;
- }
- PostgreSQLInterface::~PostgreSQLInterface()
- {
- if (isConnected && pgConnAllocatedHere)
- PQfinish(pgConn);
- }
- bool PostgreSQLInterface::Connect(const char *conninfo)
- {
- if (isConnected==false)
- {
- _conninfo=conninfo;
- pgConn=PQconnectdb(conninfo);
- ConnStatusType status = PQstatus(pgConn);
- isConnected=status==CONNECTION_OK;
- if (isConnected==false)
- {
- PQfinish(pgConn);
- return false;
- }
- pgConnAllocatedHere=true;
- }
- return isConnected;
- }
- void PostgreSQLInterface::AssignConnection(PGconn *_pgConn)
- {
- pgConnAllocatedHere=false;
- pgConn=_pgConn;
- ConnStatusType status = PQstatus(pgConn);
- isConnected=status==CONNECTION_OK;
- }
- PGconn *PostgreSQLInterface::GetPGConn(void) const
- {
- return pgConn;
- }
- void PostgreSQLInterface::Disconnect(void)
- {
- if (isConnected)
- {
- PQfinish(pgConn);
- isConnected=false;
- }
- }
- void PostgreSQLInterface::Rollback(void)
- {
- PGresult *result = PQexec(pgConn, "ROLLBACK;");
- PQclear(result);
- }
- bool PostgreSQLInterface::IsResultSuccessful(PGresult *result, bool rollbackOnFailure)
- {
- if (result==0)
- return false;
- bool success=false;
- ExecStatusType execStatus = PQresultStatus(result);
- strcpy(lastError,PQresultErrorMessage(result));
- switch (execStatus)
- {
- case PGRES_COMMAND_OK:
- success=true;
- break;
- case PGRES_EMPTY_QUERY:
- break;
- case PGRES_TUPLES_OK:
- success=true;
- break;
- case PGRES_COPY_OUT:
- break;
- case PGRES_COPY_IN:
- break;
- case PGRES_BAD_RESPONSE:
- break;
- case PGRES_NONFATAL_ERROR:
- break;
- case PGRES_FATAL_ERROR:
- if (rollbackOnFailure)
- Rollback();
- break;
- }
- return success;
- }
- bool PostgreSQLInterface::ExecuteBlockingCommand(const char *command, PGresult **result, bool rollbackOnFailure)
- {
- *result = PQexec(pgConn, command);
- return IsResultSuccessful(*result, rollbackOnFailure);
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(int *output, PGresult *result, unsigned int rowIndex, const char *columnName)
- {
- return PQGetValueFromBinary(output,result,(int) rowIndex,columnName);
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(int *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0)
- return false;
- if (binaryData)
- {
- RakAssert(PQgetlength(result, rowIndex, columnIndex)==sizeof(int));
- memcpy(output, binaryData, sizeof(int));
- EndianSwapInPlace((char*)output, sizeof(int));
- return true;
- }
- return false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(unsigned int *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0 || PQgetlength(result, rowIndex, columnIndex)==0)
- return false;
- if (binaryData)
- {
- RakAssert(PQgetlength(result, rowIndex, columnIndex)==sizeof(unsigned int));
- memcpy(output, binaryData, sizeof(unsigned int));
- EndianSwapInPlace((char*)output, sizeof(unsigned int));
- return true;
- }
- return false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(long long *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0)
- return false;
- if (binaryData)
- {
- RakAssert(PQgetlength(result, rowIndex, columnIndex)==sizeof(long long));
- memcpy(output, binaryData, sizeof(long long));
- EndianSwapInPlace((char*)output, sizeof(long long));
- return true;
- }
- return false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(float *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0)
- return false;
- int len = PQgetlength(result, rowIndex, columnIndex);
- RakAssert(len==sizeof(float));
- RakAssert(binaryData);
- if (binaryData)
- {
- memcpy(output, binaryData, sizeof(float));
- EndianSwapInPlace((char*)output, sizeof(float));
- return true;
- }
- return false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(double *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0)
- return false;
- int len = PQgetlength(result, rowIndex, columnIndex);
- RakAssert(len==sizeof(double));
- RakAssert(binaryData);
- if (binaryData)
- {
- memcpy(output, binaryData, sizeof(double));
- EndianSwapInPlace((char*)output, sizeof(double));
- return true;
- }
- return false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(bool *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *binaryData = PQgetvalue(result, rowIndex, columnIndex);
- if (binaryData==0)
- return false;
- *output = binaryData[0]!=0;
-
- // Seems to return 1 byte only
- /*
- int tempResult=0;
- // int len = PQgetlength(result, rowIndex, columnIndex);
- // RakAssert(len==sizeof(int)); // bug here, returns 0, but is an int
- RakAssert(binaryData);
- if (binaryData)
- {
- memcpy(&tempResult, binaryData, sizeof(int));
- EndianSwapInPlace((char*)&tempResult, sizeof(int));
- *output = tempResult!=0;
- return true;
- }
- */
-
- return true;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(RakNet::RakString *output, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName); if (columnIndex==-1) return false;
- char *gv;
- gv = PQgetvalue(result, rowIndex, columnIndex);
- if (gv && gv[0])
- *output=gv;
- else
- output->Clear();
- return output->IsEmpty()==false;
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(char **output, unsigned int *outputLength, PGresult *result, int rowIndex, const char *columnName)
- {
- return PQGetValueFromBinary(output, (int*) outputLength,result, rowIndex,columnName);
- }
- bool PostgreSQLInterface::PQGetValueFromBinary(char **output, int *outputLength, PGresult *result, int rowIndex, const char *columnName)
- {
- int columnIndex = PQfnumber(result, columnName);
- if (columnIndex!=-1)
- {
- *outputLength=PQgetlength(result, rowIndex, columnIndex);
- if (*outputLength==0)
- {
- *output=0;
- return false;
- }
- else
- {
- *output = (char*) rakMalloc_Ex(*outputLength,_FILE_AND_LINE_);
- memcpy(*output, PQgetvalue(result, rowIndex, columnIndex), *outputLength);
- return true;
- }
- }
- else
- return false;
-
- }
- void PostgreSQLInterface::EndianSwapInPlace(char* data, int dataLength)
- {
- static bool alreadyNetworkOrder=(htonl(12345) == 12345);
- if (alreadyNetworkOrder)
- return;
- int i;
- char tmp;
- for (i=0; i < dataLength/2; i++)
- {
- tmp=data[i];
- data[i]=data[dataLength-1-i];
- data[dataLength-1-i]=tmp;
- }
- }
- char *PostgreSQLInterface::GetLocalTimestamp(void)
- {
- static char strRes[512];
- PGresult *result;
- if (ExecuteBlockingCommand("SELECT LOCALTIMESTAMP", &result, false))
- {
- char *ts=PQgetvalue(result, 0, 0);
- if (ts)
- {
- sprintf(strRes,"Local timestamp is: %s\n", ts);
- }
- else
- {
- sprintf(strRes,"Can't read current time\n");
- }
- PQclear(result);
- }
- else
- sprintf(strRes,"Failed to read LOCALTIMESTAMP\n");
- return (char*)strRes;
- }
- long long PostgreSQLInterface::GetEpoch(void)
- {
- PGresult *result;
- long long out;
- result = QueryVariadic("EXTRACT(EPOCH FROM current_timestamp) as out);");
- PostgreSQLInterface::PQGetValueFromBinary(&out, result, 0, "out");
- PQclear(result);
- return out;
- }
- const char* PostgreSQLInterface::GetLastError(void) const
- {
- return (char*)lastError;
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, unsigned int value, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- valueStr += FormatString("%i", value);
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, unsigned int value, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (valueStr.IsEmpty()==false)
- {
- valueStr += ", ";
- }
- valueStr += colName;
- valueStr += " = ";
- valueStr += FormatString("%i", value);
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, int value, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- valueStr += FormatString("%i", value);
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, bool value, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- if (value)
- valueStr += "true";
- else
- valueStr += "false";
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, int value, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (valueStr.IsEmpty()==false)
- {
- valueStr += ", ";
- }
- valueStr += colName;
- valueStr += " = ";
- valueStr += FormatString("%i", value);
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, float value, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- valueStr += FormatString("%f", value);
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, float value, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- (void)numParams;
- (void)paramData;
- (void)paramLength;
- (void)paramFormat;
- if (valueStr.IsEmpty()==false)
- {
- valueStr += ", ";
- }
- valueStr += colName;
- valueStr += " = ";
- valueStr += FormatString("%f", value);
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, char *binaryData, int binaryDataLength, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat, bool writeEmpty)
- {
- if (writeEmpty==false && (binaryData==0 || binaryDataLength==0))
- return;
- if (binaryData==0)
- binaryDataLength=0;
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- valueStr+=FormatString("$%i::bytea", numParams+1);
- paramData[numParams]=binaryData;
- paramLength[numParams]=binaryDataLength;
- paramFormat[numParams]=PQEXECPARAM_FORMAT_BINARY;
- numParams++;
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, char *binaryData, int binaryDataLength, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat)
- {
- if (binaryData==0 || binaryDataLength==0)
- return;
- if (binaryData==0)
- binaryDataLength=0;
- if (valueStr.IsEmpty()==false)
- {
- valueStr += ", ";
- }
- valueStr += colName;
- valueStr += " = ";
- valueStr+=FormatString("$%i::bytea", numParams+1);
- paramData[numParams]=binaryData;
- paramLength[numParams]=binaryDataLength;
- paramFormat[numParams]=PQEXECPARAM_FORMAT_BINARY;
- numParams++;
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, const char *str, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat, bool writeEmpty, const char *type)
- {
- if (writeEmpty==false && (str==0 || str[0]==0))
- return;
- static char *emptyStr=(char*)"";
- static char *emptyDate=(char*)"01/01/01";
- if (paramTypeStr.IsEmpty()==false)
- {
- paramTypeStr += ", ";
- valueStr += ", ";
- }
- paramTypeStr += colName;
- valueStr+=FormatString("$%i::%s", numParams+1, type);
- if (writeEmpty && (str==0 || str[0]==0))
- {
- if (strcmp(type,"date")==0)
- {
- paramData[numParams]=emptyDate;
- paramLength[numParams]=(int)strlen(emptyDate);
- }
- else
- {
- paramData[numParams]=emptyStr;
- paramLength[numParams]=0;
- }
- }
- else
- {
- paramData[numParams]=(char*) str;
- paramLength[numParams]=(int) strlen(str);
- }
- paramFormat[numParams]=PQEXECPARAM_FORMAT_TEXT;
- numParams++;
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, const char *str, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat, const char *type)
- {
- if (str==0 || str[0]==0)
- return;
- if (valueStr.IsEmpty()==false)
- {
- valueStr += ", ";
- }
- valueStr += colName;
- valueStr+=" = ";
- valueStr+=FormatString("$%i::%s", numParams+1, type);
- paramData[numParams]=(char*) str;
- paramLength[numParams]=(int) strlen(str);
- paramFormat[numParams]=PQEXECPARAM_FORMAT_TEXT;
- numParams++;
- }
- void PostgreSQLInterface::EncodeQueryInput(const char *colName, const RakNet::RakString &str, RakNet::RakString ¶mTypeStr, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat, bool writeEmpty, const char *type)
- {
- EncodeQueryInput(colName, str.C_String(), paramTypeStr, valueStr, numParams, paramData, paramLength, paramFormat, writeEmpty, type);
- }
- void PostgreSQLInterface::EncodeQueryUpdate(const char *colName, const RakNet::RakString &str, RakNet::RakString &valueStr, int &numParams, char **paramData, int *paramLength, int *paramFormat, const char *type)
- {
- EncodeQueryUpdate(colName, str.C_String(), valueStr, numParams, paramData, paramLength, paramFormat, type);
- }
- RakNet::RakString PostgreSQLInterface::GetEscapedString(const char *input) const
- {
- unsigned long len = (unsigned long) strlen(input);
- char *fn = (char*) rakMalloc_Ex(len*2+1,_FILE_AND_LINE_);
- int error;
- PQescapeStringConn(pgConn, fn, input, len, &error);
- RakNet::RakString output;
- // Use assignment so it doesn't parse printf escape strings
- output = fn;
- rakFree_Ex(fn,_FILE_AND_LINE_);
- return output;
- }
- PGresult * PostgreSQLInterface::QueryVariadic( const char * input, ... )
- {
- RakNet::RakString query;
- PGresult *result;
- DataStructures::List<VariadicSQLParser::IndexAndType> indices;
- if ( input==0 || input[0]==0 )
- return 0;
- // Lookup this query in the stored query table. If it doesn't exist, prepare it.
- RakNet::RakString inputStr;
- inputStr=input;
- unsigned int preparedQueryIndex;
- for (preparedQueryIndex=0; preparedQueryIndex < preparedQueries.Size(); preparedQueryIndex++)
- {
- if (preparedQueries[preparedQueryIndex].StrICmp(inputStr)==0)
- break;
- }
- // Find out how many params there are
- // Find out the type of each param (%f, %s)
- indices.Clear(false, _FILE_AND_LINE_);
- GetTypeMappingIndices( input, indices );
- if (preparedQueryIndex==preparedQueries.Size())
- {
- // if (indices.Size()>0)
- // query += " (";
- RakNet::RakString formatCopy;
- RakNet::RakString insertion;
- formatCopy=input;
- unsigned int i;
- unsigned int indexOffset=0;
- for (i=0; i < indices.Size(); i++)
- {
- // if (i!=0)
- // query += ",";
- // query+=typeMappings[indices[i].typeMappingIndex].type;
- formatCopy.SetChar(indices[i].strIndex+indexOffset, '$');
- // if (i < 9)
- // formatCopy.SetChar(indices[i].strIndex+1, i+1+'0');
- // else
- insertion=RakNet::RakString("%i::%s", i+1, VariadicSQLParser::GetTypeMappingAtIndex(indices[i].typeMappingIndex));
- formatCopy.SetChar(indices[i].strIndex+1+indexOffset, insertion);
- indexOffset+=(unsigned int) insertion.GetLength()-1;
- }
- // if (indices.Size()>0)
- // query += ")";
- // query += " AS ";
- query += formatCopy;
- // query += ";\n";
- formatCopy+= ";\n";
- result = PQprepare(pgConn, RakNet::RakString("PGSQL_ExecuteVariadic_%i", preparedQueries.Size()), formatCopy.C_String(), indices.Size(), NULL);
- if (IsResultSuccessful(result, false))
- {
- PQclear(result);
- preparedQueries.Insert(inputStr, _FILE_AND_LINE_);
- }
- else
- {
- printf(formatCopy.C_String());
- printf("\n");
- printf(lastError);
- RakAssert(0);
- PQclear(result);
- return 0;
- }
- }
- // char *paramData[512];
- // int paramLength[512];
- // int paramFormat[512];
- va_list argptr;
- va_start(argptr, input);
- char **paramData;
- int *paramLength;
- int *paramFormat;
- ExtractArguments(argptr, indices, ¶mData, ¶mLength);
- paramFormat=RakNet::OP_NEW_ARRAY<int>(indices.Size(),_FILE_AND_LINE_);
- for (unsigned int i=0; i < indices.Size(); i++)
- paramFormat[i]=PQEXECPARAM_FORMAT_BINARY;
- result = PQexecPrepared(pgConn, RakNet::RakString("PGSQL_ExecuteVariadic_%i", preparedQueryIndex), indices.Size(), paramData, paramLength, paramFormat, PQEXECPARAM_FORMAT_BINARY );
- VariadicSQLParser::FreeArguments(indices, paramData, paramLength);
- RakNet::OP_DELETE_ARRAY(paramFormat,_FILE_AND_LINE_);
- va_end(argptr);
- if (IsResultSuccessful(result, false)==false)
- {
- printf(lastError);
- PQclear(result);
- return 0;
- }
- return result;
- }
- /*
- PGresult * PostgreSQLInterface::QueryVariadic( const char * input, ... )
- {
- RakNet::RakString query;
- PGresult *result;
- unsigned int i;
- DataStructures::List<IndexAndType> indices;
- if ( input==0 || input[0]==0 )
- return 0;
- // Find out how many params there are
- // Find out the type of each param (%f, %s)
- GetTypeMappingIndices( input, indices );
- char *paramData[512];
- int paramLength[512];
- int paramFormat[512];
- va_list argptr;
- int variadicArgIndex;
- va_start(argptr, input);
- for (variadicArgIndex=0, i=0; i < indices.Size(); i++, variadicArgIndex++)
- {
- if (typeMappings[indices[i].typeMappingIndex].inputType=='i' ||
- typeMappings[indices[i].typeMappingIndex].inputType=='d')
- {
- int val = va_arg( argptr, int );
- paramData[i]=(char*) &val;
- paramLength[i]=sizeof(val);
- if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
- }
- else if (typeMappings[indices[i].typeMappingIndex].inputType=='s')
- {
- char* val = va_arg( argptr, char* );
- paramData[i]=val;
- paramLength[i]=(int) strlen(val);
- }
- else if (typeMappings[indices[i].typeMappingIndex].inputType=='b')
- {
- bool val = va_arg( argptr, bool );
- paramData[i]=(char*) &val;
- paramLength[i]=sizeof(bool);
- if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
- }
- else if (typeMappings[indices[i].typeMappingIndex].inputType=='f')
- {
- float val = va_arg( argptr, float );
- paramData[i]=(char*) &val;
- paramLength[i]=sizeof(float);
- if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
- }
- else if (typeMappings[indices[i].typeMappingIndex].inputType=='g')
- {
- double val = va_arg( argptr, double );
- paramData[i]=(char*) &val;
- paramLength[i]=sizeof(double);
- if (RakNet::BitStream::IsNetworkOrder()==false) RakNet::BitStream::ReverseBytesInPlace((unsigned char*) paramData[i], paramLength[i]);
- }
- else if (typeMappings[indices[i].typeMappingIndex].inputType=='a')
- {
- char* val = va_arg( argptr, char* );
- paramData[i]=val;
- variadicArgIndex++;
- paramLength[i]=va_arg( argptr, unsigned int );
- }
- paramFormat[i]=PQEXECPARAM_FORMAT_BINARY;
- }
- // Replace each %whatever with $index::type
- RakNet::RakString inputCopy;
- inputCopy=input;
- unsigned int lastIndex=0;
- for (i=0; i < indices.Size(); i++)
- {
- query+=inputCopy.SubStr(lastIndex, indices[i].strIndex-lastIndex);
- query+=RakNet::RakString("$%i::", i+1);
- query+=typeMappings[indices[i].typeMappingIndex].type;
- lastIndex=indices[i].strIndex+2; // +2 is to skip the %whateverCharacter
- }
- query+=inputCopy.SubStr(lastIndex, (unsigned int)-1);
- result = PQexecParams(pgConn, query.C_String(),indices.Size(),0,paramData,paramLength,paramFormat,PQEXECPARAM_FORMAT_BINARY);
- if (IsResultSuccessful(result, false)==false)
- {
- PQclear(result);
- return 0;
- }
- return result;
- }
- */
- void PostgreSQLInterface::ClearResult(PGresult *result)
- {
- PQclear(result);
- }
|