MeOS version 3.8.1255 Beta
This commit is contained in:
parent
035fec52ec
commit
adb3e81676
File diff suppressed because it is too large
Load Diff
@ -21,15 +21,17 @@
|
||||
|
||||
************************************************************************/
|
||||
|
||||
#pragma warning( disable : 4251)
|
||||
|
||||
#include <mysql++.h>
|
||||
|
||||
#include <string>
|
||||
#include "sqltypes.h"
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "oEvent.h"
|
||||
|
||||
class oRunner;
|
||||
class oEvent;
|
||||
class oCard;
|
||||
class oClub;
|
||||
class oCourse;
|
||||
@ -42,20 +44,29 @@ class oTeam;
|
||||
class oDataContainer;
|
||||
struct SqlUpdated;
|
||||
|
||||
namespace mysqlpp {
|
||||
class Query;
|
||||
namespace sqlwrapper {
|
||||
class ResNSel;
|
||||
class RowWrapper;
|
||||
class QueryWrapper;
|
||||
class ConnectionWrapper;
|
||||
}
|
||||
|
||||
using namespace std;
|
||||
using namespace sqlwrapper;
|
||||
|
||||
enum OpFailStatus {
|
||||
opStatusOKSkipped = 3,
|
||||
opStatusOK = 2,
|
||||
opStatusFail = 0,
|
||||
opStatusWarning = 1,
|
||||
opUnreachable = -1,
|
||||
};
|
||||
|
||||
class MeosSQL
|
||||
{
|
||||
class MeosSQL {
|
||||
protected:
|
||||
bool warnedOldVersion;
|
||||
int monitorId;
|
||||
int buildVersion;
|
||||
mysqlpp::Connection con;
|
||||
shared_ptr<ConnectionWrapper> con;
|
||||
string CmpDataBase;
|
||||
void alert(const string &s);
|
||||
bool writeTime = false;
|
||||
@ -74,8 +85,8 @@ protected:
|
||||
|
||||
OpFailStatus updateTime(const char *oTable, oBase *ob);
|
||||
// Update object in database with fixed query. If useId is false, Id is ignored (used
|
||||
OpFailStatus syncUpdate(mysqlpp::Query &updateqry, const char *oTable, oBase *ob);
|
||||
bool storeData(oDataInterface odi, const mysqlpp::Row &row, unsigned long &revision);
|
||||
OpFailStatus syncUpdate(QueryWrapper &updateqry, const char *oTable, oBase *ob);
|
||||
bool storeData(oDataInterface odi, const RowWrapper &row, unsigned long &revision);
|
||||
|
||||
void importLists(oEvent *oe, const char *bf);
|
||||
void encodeLists(const oEvent *or, string &listEnc) const;
|
||||
@ -84,7 +95,7 @@ protected:
|
||||
void setDefaultDB();
|
||||
|
||||
// Update the courses of a class.
|
||||
OpFailStatus syncReadClassCourses(oClass *c,const set<int> &courses,
|
||||
OpFailStatus syncReadClassCourses(oClass *c, const set<int> &courses,
|
||||
bool readRecursive);
|
||||
OpFailStatus syncRead(bool forceRead, oTeam *t, bool readRecursive);
|
||||
OpFailStatus syncRead(bool forceRead, oRunner *r, bool readClassClub, bool readCourseCard);
|
||||
@ -92,23 +103,23 @@ protected:
|
||||
OpFailStatus syncRead(bool forceRead, oClass *c, bool readCourses);
|
||||
OpFailStatus syncReadControls(oEvent *oe, const set<int> &controlIds);
|
||||
|
||||
void storeClub(const mysqlpp::Row &row, oClub &c);
|
||||
void storeControl(const mysqlpp::Row &row, oControl &c);
|
||||
void storeCard(const mysqlpp::Row &row, oCard &c);
|
||||
void storePunch(const mysqlpp::Row &row, oFreePunch &p, bool rehash);
|
||||
void storeClub(const RowWrapper &row, oClub &c);
|
||||
void storeControl(const RowWrapper &row, oControl &c);
|
||||
void storeCard(const RowWrapper &row, oCard &c);
|
||||
void storePunch(const RowWrapper &row, oFreePunch &p, bool rehash);
|
||||
|
||||
OpFailStatus storeTeam(const mysqlpp::Row &row, oTeam &t,
|
||||
OpFailStatus storeTeam(const RowWrapper &row, oTeam &t,
|
||||
bool readRecursive, bool allowSubRead);
|
||||
|
||||
OpFailStatus storeRunner(const mysqlpp::Row &row, oRunner &r,
|
||||
OpFailStatus storeRunner(const RowWrapper &row, oRunner &r,
|
||||
bool readCourseCard,
|
||||
bool readClassClub,
|
||||
bool readRunners,
|
||||
bool allowSubRead);
|
||||
OpFailStatus storeCourse(const mysqlpp::Row &row, oCourse &c,
|
||||
OpFailStatus storeCourse(const RowWrapper &row, oCourse &c,
|
||||
set<int> &readControls,
|
||||
bool allowSubRead);
|
||||
OpFailStatus storeClass(const mysqlpp::Row &row, oClass &c,
|
||||
OpFailStatus storeClass(const RowWrapper &row, oClass &c,
|
||||
bool readCourses,
|
||||
bool allowSubRead);
|
||||
|
||||
@ -117,13 +128,13 @@ protected:
|
||||
void upgradeDB(const string &db, oDataContainer const *odi);
|
||||
|
||||
void warnOldDB();
|
||||
bool checkOldVersion(oEvent *oe, mysqlpp::Row &row);
|
||||
bool checkOldVersion(oEvent *oe, RowWrapper &row);
|
||||
|
||||
map<pair<int, int>, DWORD> readTimes;
|
||||
void synchronized(const oBase &entity);
|
||||
bool skipSynchronize(const oBase &entity) const;
|
||||
|
||||
mysqlpp::ResNSel updateCounter(const char *oTable, int id, mysqlpp::Query *updateqry);
|
||||
ResNSel updateCounter(const char *oTable, int id, QueryWrapper *updateqry);
|
||||
string selectUpdated(const char *oTable, const SqlUpdated &updated);
|
||||
|
||||
void addedFromDatabase(oBase *object);
|
||||
@ -133,29 +144,10 @@ protected:
|
||||
const string &modified,
|
||||
SqlUpdated &update, int &maxCounter);
|
||||
|
||||
public:
|
||||
void clearReadTimes();
|
||||
void checkAgainstDB(const char *oTable, map<int, oBase *> &existing, vector<pair<int, oBase *>> &idsToUpdate);
|
||||
|
||||
bool dropDatabase(oEvent *oe);
|
||||
bool checkConnection(oEvent *oe);
|
||||
void processMissingObjects();
|
||||
|
||||
bool repairTables(const string &db, vector<string> &output);
|
||||
|
||||
bool getErrorMessage(char *bf);
|
||||
bool reConnect();
|
||||
bool listCompetitions(oEvent *oe, bool keepConnection);
|
||||
bool Remove(oBase *ob);
|
||||
|
||||
// Create database of runners and clubs
|
||||
bool createRunnerDB(oEvent *oe, mysqlpp::Query &query);
|
||||
|
||||
// Upload runner database to server
|
||||
OpFailStatus uploadRunnerDB(oEvent *oe);
|
||||
|
||||
bool openDB(oEvent *oe);
|
||||
|
||||
bool closeDB();
|
||||
template<typename T>
|
||||
bool checkTableCheckSum(const char *oTable, const list<T> &def, int p1, int p2, int p3);
|
||||
|
||||
bool syncListRunner(oEvent *oe);
|
||||
bool syncListClass(oEvent *oe);
|
||||
@ -167,7 +159,6 @@ public:
|
||||
bool syncListTeam(oEvent *oe);
|
||||
|
||||
OpFailStatus SyncEvent(oEvent *oe);
|
||||
|
||||
OpFailStatus SyncUpdate(oEvent *oe);
|
||||
OpFailStatus SyncRead(oEvent *oe);
|
||||
|
||||
@ -195,10 +186,39 @@ public:
|
||||
OpFailStatus syncUpdate(oTeam *t, bool forceWriteAll);
|
||||
OpFailStatus syncRead(bool forceRead, oTeam *t);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
bool synchronizeList(oEvent *oe, oListId lid);
|
||||
OpFailStatus synchronizeUpdate(oBase *obj);
|
||||
|
||||
bool checkConsistency(oEvent *oe, bool force);
|
||||
void clearReadTimes();
|
||||
|
||||
bool dropDatabase(oEvent *oe);
|
||||
bool checkConnection(oEvent *oe);
|
||||
void processMissingObjects();
|
||||
|
||||
bool repairTables(const string &db, vector<string> &output);
|
||||
|
||||
bool getErrorMessage(string &err);
|
||||
bool reConnect();
|
||||
bool listCompetitions(oEvent *oe, bool keepConnection);
|
||||
bool remove(oBase *ob);
|
||||
|
||||
// Create database of runners and clubs
|
||||
bool createRunnerDB(oEvent *oe, QueryWrapper &query);
|
||||
|
||||
// Upload runner database to server
|
||||
OpFailStatus uploadRunnerDB(oEvent *oe);
|
||||
|
||||
bool openDB(oEvent *oe);
|
||||
bool closeDB();
|
||||
string serverVersion() const;
|
||||
|
||||
/** General interface. TypeId lookup */
|
||||
OpFailStatus syncRead(bool forceRead, oBase *c);
|
||||
|
||||
|
||||
int getModifiedMask(oEvent &oe);
|
||||
|
||||
MeosSQL(void);
|
||||
@ -1485,6 +1485,7 @@ pair<int, bool> oDBRunnerEntry::inputData(int id, const wstring &input,
|
||||
break;
|
||||
|
||||
case TID_CLUB:
|
||||
if (inputId != -1)
|
||||
rd.clubNo = inputId;
|
||||
output = input;
|
||||
break;
|
||||
|
||||
@ -64,7 +64,7 @@ SI_StationInfo::SI_StationInfo()
|
||||
localZeroTime=0;
|
||||
}
|
||||
|
||||
SportIdent::SportIdent(HWND hWnd, DWORD Id)
|
||||
SportIdent::SportIdent(HWND hWnd, DWORD Id, bool readVoltage) : readVoltage(readVoltage)
|
||||
{
|
||||
ClassId=Id;
|
||||
hWndNotify=hWnd;
|
||||
@ -1301,6 +1301,7 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
|
||||
BYTE b[128*5];
|
||||
memset(b, 0, 128*5);
|
||||
BYTE c[16];
|
||||
int miliVolt = 0;
|
||||
// STX, 0xE1, 0x01, BN, CRC1,
|
||||
//CRC0, ETX
|
||||
debugLog(L"STARTREAD9 EXT-");
|
||||
@ -1309,7 +1310,7 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
|
||||
int blocks_10_11_SIAC[5]={0,4,5,6,7};
|
||||
int limit = 1;
|
||||
int *blocks = blocks_8_9_p_t;
|
||||
|
||||
bool readBattery = false;
|
||||
DWORD written=0;
|
||||
|
||||
for(int k=0; k < limit; k++){
|
||||
@ -1339,13 +1340,17 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
|
||||
if (bf[0]==STX && bf[1]==0xEf) {
|
||||
if (checkCRC(bf+1, 200)) {
|
||||
memcpy(b+k*128, bf+6, 128);
|
||||
|
||||
if (k == 0) {
|
||||
int series = b[24] & 15;
|
||||
if (series == 15) {
|
||||
int nPunch = min(int(b[22]), 128);
|
||||
blocks = blocks_10_11_SIAC;
|
||||
limit = 1 + (nPunch+31) / 32;
|
||||
|
||||
int cardNo = GetExtCardNumber(b);
|
||||
if (cardNo > 8000000 && cardNo < 9000000) {
|
||||
readBattery = readVoltage;
|
||||
}
|
||||
}
|
||||
else {
|
||||
limit = 2; // Card 8, 9, p, t
|
||||
@ -1365,14 +1370,95 @@ void SportIdent::getSI9DataExt(HANDLE hComm)
|
||||
}
|
||||
}
|
||||
|
||||
if (readBattery) {
|
||||
c[0] = STX;
|
||||
c[1] = 0xEA;
|
||||
c[2] = 0x05;
|
||||
c[3] = 0x7E;
|
||||
c[4] = 0x05;
|
||||
c[5] = 0x05;
|
||||
c[6] = 0x05;
|
||||
c[7] = 0x05;
|
||||
c[10] = ETX;
|
||||
setCRC(c + 1);
|
||||
|
||||
written = 0;
|
||||
WriteFile(hComm, c, 11, &written, NULL); // Measure batt voltage
|
||||
|
||||
if (written == 11) {
|
||||
BYTE bf[256];
|
||||
int read = readBytes(bf, 9, hComm);
|
||||
if (read == 0) {
|
||||
debugLog(L"TIMING");
|
||||
Sleep(300);
|
||||
read = readBytes(bf, 9, hComm);
|
||||
}
|
||||
|
||||
if (read == 9) {
|
||||
/*for (int i = 0; i < read; i++) {
|
||||
char xx[20];
|
||||
sprintf_s(xx, "%02x ", bf[i]);
|
||||
OutputDebugStringA(xx);
|
||||
}
|
||||
OutputDebugStringA("\n\n");*/
|
||||
|
||||
c[0] = STX;
|
||||
c[1] = 0xEF;
|
||||
c[2] = 0x01;
|
||||
c[3] = 3;
|
||||
setCRC(c + 1);
|
||||
c[6] = ETX;
|
||||
|
||||
written = 0;
|
||||
WriteFile(hComm, c, 7, &written, NULL);
|
||||
|
||||
memset(bf, 0, 256);
|
||||
int read = readBytes(bf, 128 + 9, hComm);
|
||||
if (read == 0) {
|
||||
debugLog(L"TIMING");
|
||||
Sleep(300);
|
||||
read = readBytes(bf, 128 + 9, hComm);
|
||||
}
|
||||
|
||||
if (bf[0] == STX && bf[1] == 0xEf) {
|
||||
/*
|
||||
for (int i = 0; i < read; i++) {
|
||||
char xx[20];
|
||||
sprintf_s(xx, "%02x ", bf[i]);
|
||||
OutputDebugStringA(xx);
|
||||
if (i%20==19)
|
||||
OutputDebugStringA("\n");
|
||||
}
|
||||
OutputDebugStringA("\n\n");
|
||||
*/
|
||||
if (checkCRC(bf + 1, 200)) {
|
||||
BYTE battVoltageRow = bf[77];
|
||||
double voltage = 1.9 + (battVoltageRow * 0.09);
|
||||
miliVolt = int(1000 * voltage);
|
||||
|
||||
/*char xx[30];
|
||||
sprintf_s(xx, "V = %f\n\n", voltage);
|
||||
OutputDebugStringA(xx);*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
//02 EA 05 7E 05 05 05 05 B2 31 03
|
||||
|
||||
}
|
||||
|
||||
|
||||
c[0]=ACK;
|
||||
WriteFile(hComm, c, 1, &written, NULL);
|
||||
|
||||
debugLog(L"-ACK-");
|
||||
|
||||
SICard card(ConvertedTimeStatus::Hour24);
|
||||
if (getCard9Data(b, card))
|
||||
if (getCard9Data(b, card)) {
|
||||
card.miliVolt = miliVolt;
|
||||
addCard(card);
|
||||
}
|
||||
}
|
||||
|
||||
bool SportIdent::readSI6Block(HANDLE hComm, BYTE *data)
|
||||
@ -1588,7 +1674,7 @@ bool SportIdent::getCard5Data(BYTE *data, SICard &card)
|
||||
return true;
|
||||
}
|
||||
|
||||
DWORD SportIdent::GetExtCardNumber(BYTE *data) const {
|
||||
DWORD SportIdent::GetExtCardNumber(const BYTE *data) const {
|
||||
DWORD cnr = 0;
|
||||
BYTE *p = (BYTE *)&cnr;
|
||||
p[0] = data[27];
|
||||
@ -2073,7 +2159,7 @@ void checkport_si_thread(void *ptr)
|
||||
int *port=(int *)ptr;
|
||||
wchar_t bf[16];
|
||||
swprintf_s(bf, 16, L"COM%d", *port);
|
||||
SportIdent si(NULL, *port);
|
||||
SportIdent si(NULL, *port, false);
|
||||
|
||||
if (!si.openCom(bf))
|
||||
*port=0; //No SI found here
|
||||
@ -2360,7 +2446,7 @@ vector<string> SICard::logHeader()
|
||||
return log;
|
||||
}
|
||||
|
||||
unsigned SICard::calculateHash() const {
|
||||
unsigned int SICard::calculateHash() const {
|
||||
unsigned h = nPunch * 100000 + FinishPunch.Time;
|
||||
for (unsigned i = 0; i < nPunch; i++) {
|
||||
h = h * 31 + Punch[i].Code;
|
||||
|
||||
@ -91,6 +91,7 @@ struct SICard
|
||||
wchar_t firstName[21];
|
||||
wchar_t lastName[21];
|
||||
wchar_t club[41];
|
||||
int miliVolt; // SIAC voltage
|
||||
char readOutTime[32];
|
||||
bool punchOnly;
|
||||
ConvertedTimeStatus convertedTime;
|
||||
@ -99,11 +100,10 @@ struct SICard
|
||||
int relativeFinishTime;
|
||||
bool statusOK;
|
||||
bool statusDNF;
|
||||
|
||||
vector<string> codeLogData(gdioutput &converter, int row) const;
|
||||
static vector<string> logHeader();
|
||||
|
||||
unsigned calculateHash() const;
|
||||
unsigned int calculateHash() const;
|
||||
bool isManualInput() const {return runnerId != 0;}
|
||||
|
||||
string serializePunches() const;
|
||||
@ -185,7 +185,7 @@ protected:
|
||||
bool getCard6Data(BYTE *data, SICard &card);
|
||||
bool getCard9Data(BYTE *data, SICard &card);
|
||||
|
||||
DWORD GetExtCardNumber(BYTE *data) const;
|
||||
DWORD GetExtCardNumber(const BYTE *data) const;
|
||||
|
||||
void getSI5Data(HANDLE hComm);
|
||||
void getSI5DataExt(HANDLE hComm);
|
||||
@ -204,7 +204,7 @@ protected:
|
||||
DWORD ClassId;
|
||||
|
||||
volatile int tcpPortOpen;
|
||||
volatile unsigned int serverSocket;
|
||||
volatile size_t serverSocket;
|
||||
|
||||
bool MonitorTEST(SI_StationInfo &si);
|
||||
bool MonitorSI(SI_StationInfo &si);
|
||||
@ -225,6 +225,8 @@ protected:
|
||||
|
||||
set<TestCard> testCards;
|
||||
|
||||
bool readVoltage;
|
||||
|
||||
public:
|
||||
SI_StationInfo *findStation(const wstring &com);
|
||||
|
||||
@ -251,7 +253,7 @@ public:
|
||||
|
||||
bool openComListen(const wchar_t *com, DWORD BaudRate);
|
||||
|
||||
SportIdent(HWND hWnd, DWORD Id);
|
||||
SportIdent(HWND hWnd, DWORD Id, bool readVoltage);
|
||||
virtual ~SportIdent();
|
||||
friend void start_si_thread(void *ptr);
|
||||
|
||||
|
||||
@ -218,12 +218,19 @@ int TabClass::multiCB(gdioutput &gdi, int type, void *data)
|
||||
gdi.setInputStatus("CommonStartTime", gdi.isChecked(bi.id));
|
||||
}
|
||||
else if (bi.id == "CoursePool") {
|
||||
int nlegs = 1;
|
||||
if (oe->getClass(ClassId))
|
||||
nlegs = max(1u, oe->getClass(ClassId)->getNumStages());
|
||||
|
||||
string strId = "StageCourses_label";
|
||||
gdi.setTextTranslate(strId, getCourseLabel(gdi.isChecked(bi.id)), true);
|
||||
setLockForkingState(gdi, gdi.isChecked("CoursePool"), gdi.isChecked("LockForking"));
|
||||
setLockForkingState(gdi, gdi.isChecked("CoursePool"), gdi.isChecked("LockForking"), nlegs);
|
||||
}
|
||||
else if (bi.id == "LockForking") {
|
||||
setLockForkingState(gdi, gdi.isChecked("CoursePool"), gdi.isChecked(bi.id));
|
||||
int nlegs = 1;
|
||||
if (oe->getClass(ClassId))
|
||||
nlegs = max(1u, oe->getClass(ClassId)->getNumStages());
|
||||
setLockForkingState(gdi, gdi.isChecked("CoursePool"), gdi.isChecked(bi.id), nlegs);
|
||||
}
|
||||
else if (bi.id == "DefineForking") {
|
||||
if (!checkClassSelected(gdi))
|
||||
@ -2714,7 +2721,7 @@ void TabClass::selectClass(gdioutput &gdi, int cid)
|
||||
|
||||
if (gdi.hasWidget("LockForking")) {
|
||||
gdi.check("LockForking", pc->lockedForking());
|
||||
setLockForkingState(gdi, pc->hasCoursePool(), pc->lockedForking());
|
||||
setLockForkingState(gdi, *pc);
|
||||
}
|
||||
|
||||
if (gdi.hasWidget("MCourses")) {
|
||||
@ -4640,10 +4647,10 @@ void TabClass::writeDrawInfo(gdioutput &gdi, const DrawInfo &drawInfoIn) {
|
||||
}
|
||||
|
||||
void TabClass::setLockForkingState(gdioutput &gdi, const oClass &c) {
|
||||
setLockForkingState(gdi, c.hasCoursePool(), c.lockedForking());
|
||||
setLockForkingState(gdi, c.hasCoursePool(), c.lockedForking(), max(1u, c.getNumStages()));
|
||||
}
|
||||
|
||||
void TabClass::setLockForkingState(gdioutput &gdi, bool poolState, bool lockState) {
|
||||
void TabClass::setLockForkingState(gdioutput &gdi, bool poolState, bool lockState, int nLegs) {
|
||||
if (gdi.hasWidget("DefineForking"))
|
||||
gdi.setInputStatus("DefineForking", !lockState && !poolState);
|
||||
|
||||
@ -4652,7 +4659,7 @@ void TabClass::setLockForkingState(gdioutput &gdi, bool poolState, bool lockStat
|
||||
|
||||
int legno = 0;
|
||||
while (gdi.hasWidget("@Course" + itos(legno))) {
|
||||
gdi.setInputStatus("@Course" + itos(legno++), !lockState || poolState);
|
||||
gdi.setInputStatus("@Course" + itos(legno++), (!lockState || poolState) && legno < nLegs);
|
||||
}
|
||||
|
||||
for (string s : {"MCourses", "StageCourses", "MAdd", "MRemove"}) {
|
||||
@ -5045,14 +5052,15 @@ public:
|
||||
if (ii.id[0] == 'g') {
|
||||
int idNew = _wtoi(ii.text.c_str());
|
||||
if (idNew != id) {
|
||||
if (oe.getStartGroup(idNew).first == -1) {
|
||||
if (oe.getStartGroup(idNew).firstStart == -1) {
|
||||
auto d = oe.getStartGroup(id);
|
||||
oe.setStartGroup(idNew, d.first, d.second);
|
||||
oe.setStartGroup(id, -1, -1);
|
||||
oe.setStartGroup(idNew, d.firstStart, d.lastStart, d.name);
|
||||
oe.setStartGroup(id, -1, -1, L"");
|
||||
string rowIx = ii.id.substr(5);
|
||||
gdi.getBaseInfo("group" + rowIx).setExtra(idNew);
|
||||
gdi.getBaseInfo("first" + rowIx).setExtra(idNew);
|
||||
gdi.getBaseInfo("last" + rowIx).setExtra(idNew);
|
||||
gdi.getBaseInfo("gname" + rowIx).setExtra(idNew);
|
||||
gdi.getBaseInfo("D" + rowIx).setExtra(idNew);
|
||||
ii.setBgColor(colorDefault);
|
||||
}
|
||||
@ -5063,13 +5071,18 @@ public:
|
||||
}
|
||||
else if (ii.id[0] == 'f') {
|
||||
auto d = oe.getStartGroup(id);
|
||||
d.first = oe.getRelativeTime(ii.text);
|
||||
oe.setStartGroup(id, d.first, d.second);
|
||||
d.firstStart = oe.getRelativeTime(ii.text);
|
||||
oe.setStartGroup(id, d.firstStart, d.lastStart, d.name);
|
||||
}
|
||||
else if (ii.id[0] == 'l') {
|
||||
auto d = oe.getStartGroup(id);
|
||||
d.second = oe.getRelativeTime(ii.text);
|
||||
oe.setStartGroup(id, d.first, d.second);
|
||||
d.lastStart = oe.getRelativeTime(ii.text);
|
||||
oe.setStartGroup(id, d.firstStart, d.lastStart, d.name);
|
||||
}
|
||||
else if (ii.id[0] == 'n') {
|
||||
auto d = oe.getStartGroup(id);
|
||||
d.name = ii.text;
|
||||
oe.setStartGroup(id, d.firstStart, d.lastStart, d.name);
|
||||
}
|
||||
}
|
||||
else if (type == GuiEventType::GUI_BUTTON) {
|
||||
@ -5079,16 +5092,16 @@ public:
|
||||
int length = 3600;
|
||||
for (auto &g : oe.getStartGroups(false)) {
|
||||
id = max(id, g.first+1);
|
||||
firstStart = max(firstStart, g.second.second);
|
||||
if (g.second.first < g.second.second)
|
||||
length = min(length, g.second.second - g.second.first);
|
||||
firstStart = max(firstStart, g.second.lastStart);
|
||||
if (g.second.firstStart < g.second.lastStart)
|
||||
length = min(length, g.second.lastStart - g.second.firstStart);
|
||||
}
|
||||
oe.setStartGroup(id, firstStart, firstStart + length);
|
||||
oe.setStartGroup(id, firstStart, firstStart + length, L"");
|
||||
tc->loadStartGroupSettings(gdi, false);
|
||||
}
|
||||
else if (info.id[0] == 'D') {
|
||||
int id = info.getExtraInt();
|
||||
oe.setStartGroup(id, -1, -1);
|
||||
oe.setStartGroup(id, -1, -1, L"");
|
||||
tc->loadStartGroupSettings(gdi, false);
|
||||
}
|
||||
else if (info.id == "Save") {
|
||||
@ -5121,7 +5134,8 @@ void TabClass::loadStartGroupSettings(gdioutput &gdi, bool reload) {
|
||||
int idPos = gdi.getCX();
|
||||
int firstPos = idPos + gdi.scaleLength(120);
|
||||
int lastPos = firstPos + gdi.scaleLength(120);
|
||||
int bPos = lastPos + gdi.scaleLength(120);
|
||||
int namePos = lastPos + gdi.scaleLength(120);
|
||||
int bPos = namePos + gdi.scaleLength(240);
|
||||
bool first = true;
|
||||
|
||||
for (auto &g : sg) {
|
||||
@ -5130,13 +5144,16 @@ void TabClass::loadStartGroupSettings(gdioutput &gdi, bool reload) {
|
||||
gdi.addString("", y, idPos, 0, "Id");
|
||||
gdi.addString("", y, firstPos, 0, "Start");
|
||||
gdi.addString("", y, lastPos, 0, "Slut");
|
||||
gdi.addString("", y, namePos, 0, "Namn");
|
||||
first = false;
|
||||
}
|
||||
int cy = gdi.getCY();
|
||||
string srow = itos(row++);
|
||||
gdi.addInput(idPos, cy, "group" + srow, itow(g.first), 8).setHandler(sgh).setExtra(g.first);
|
||||
gdi.addInput(firstPos, cy, "first" + srow, oe->getAbsTime(g.second.first), 10).setHandler(sgh).setExtra(g.first);
|
||||
gdi.addInput(lastPos, cy, "last" + srow, oe->getAbsTime(g.second.second), 8).setHandler(sgh).setExtra(g.first);
|
||||
gdi.addInput(firstPos, cy, "first" + srow, oe->getAbsTime(g.second.firstStart), 10).setHandler(sgh).setExtra(g.first);
|
||||
gdi.addInput(lastPos, cy, "last" + srow, oe->getAbsTime(g.second.lastStart), 8).setHandler(sgh).setExtra(g.first);
|
||||
gdi.addInput(namePos, cy, "name" + srow, g.second.name, 20).setHandler(sgh).setExtra(g.first);
|
||||
|
||||
gdi.addButton(bPos, cy, "D" + srow, L"Ta bort").setHandler(sgh).setExtra(g.first);
|
||||
}
|
||||
|
||||
|
||||
@ -150,7 +150,7 @@ class TabClass :
|
||||
|
||||
static vector< pair<wstring, size_t> > getPairOptions();
|
||||
|
||||
void setLockForkingState(gdioutput &gdi, bool poolState, bool lockState);
|
||||
void setLockForkingState(gdioutput &gdi, bool poolState, bool lockState, int nLegs);
|
||||
void setLockForkingState(gdioutput &gdi, const oClass &c);
|
||||
|
||||
void loadBasicDrawSetup(gdioutput &gdi, int &bx, int &by, const wstring& firstStart,
|
||||
|
||||
@ -44,7 +44,6 @@
|
||||
#include "RunnerDB.h"
|
||||
#include "gdifonts.h"
|
||||
#include "meosException.h"
|
||||
#include "meosdb/sqltypes.h"
|
||||
#include "socket.h"
|
||||
#include "iof30interface.h"
|
||||
#include "MeOSFeatures.h"
|
||||
@ -54,6 +53,7 @@
|
||||
#include "importformats.h"
|
||||
#include "HTMLWriter.h"
|
||||
#include "metalist.h"
|
||||
#include "MeosSQL.h"
|
||||
|
||||
#include <Shellapi.h>
|
||||
#include <algorithm>
|
||||
@ -255,7 +255,12 @@ void TabCompetition::loadConnectionPage(gdioutput &gdi)
|
||||
gdi.addString("", 1, "Ansluten till:");
|
||||
gdi.addStringUT(1, oe->getServerName()).setColor(colorGreen);
|
||||
gdi.popX();
|
||||
gdi.dropLine(2);
|
||||
gdi.dropLine(1.1);
|
||||
string version = oe->sql().serverVersion();
|
||||
gdi.addString("", 0, "Server version: X#" + version);
|
||||
gdi.dropLine(2.0);
|
||||
gdi.popX();
|
||||
|
||||
gdi.addInput("ClientName", oe->getClientName(), 16, 0, L"Klientnamn:");
|
||||
gdi.dropLine();
|
||||
gdi.addButton("SaveClient", "Ändra", CompetitionCB);
|
||||
@ -291,6 +296,7 @@ void TabCompetition::loadConnectionPage(gdioutput &gdi)
|
||||
}
|
||||
gdi.dropLine(2);
|
||||
gdi.popX();
|
||||
|
||||
if (oe->empty()) {
|
||||
wchar_t bf[260];
|
||||
getUserFile(bf, L"");
|
||||
@ -746,7 +752,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
|
||||
wstring nameId = oe->getNameId(id);
|
||||
vector<string> output;
|
||||
repairTables(gdi.narrow(nameId), output);
|
||||
oe->sql().repairTables(gdi.narrow(nameId), output);
|
||||
gdi.clearPage(true);
|
||||
gdi.addString("", boldLarge, "Reparerar tävlingsdatabasen");
|
||||
gdi.dropLine();
|
||||
@ -895,7 +901,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
allTransfer.clear();
|
||||
transferNoCompet = false;
|
||||
}
|
||||
int id = (int)gdi.getData("PostEvent");
|
||||
int id = gdi.getDataInt("PostEvent");
|
||||
oEvent::ChangedClassMethod method = oEvent::ChangedClassMethod(gdi.getSelectedItem("ChangeClassType").first);
|
||||
lastChangeClassType = method;
|
||||
|
||||
@ -1551,7 +1557,6 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
bool drawn = false;
|
||||
if (createNew && startType>0) {
|
||||
gdi.scrollToBottom();
|
||||
gdi.dropLine();
|
||||
@ -1561,7 +1566,6 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"0",
|
||||
L"0", oEvent::VacantPosition::Mixed,
|
||||
false, false, oEvent::DrawMethod::Random, 1);
|
||||
drawn = true;
|
||||
break;
|
||||
|
||||
case SMDrawn:
|
||||
@ -1588,7 +1592,6 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
oe->automaticDrawAll(gdi, formatTimeHMS(firstStart), L"2:00",
|
||||
L"2", oEvent::VacantPosition::Mixed,
|
||||
true, false, oEvent::DrawMethod::MeOS, 1);
|
||||
drawn = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2147,7 +2150,7 @@ int TabCompetition::competitionCB(gdioutput &gdi, int type, void *data)
|
||||
oe->getRunnerDatabase().clearClubs();
|
||||
oe->saveRunnerDatabase(L"database", true);
|
||||
if (oe->isClient()) {
|
||||
msUploadRunnerDB(oe);
|
||||
oe->sql().uploadRunnerDB(oe);
|
||||
}
|
||||
loadRunnerDB(gdi, 0, false);
|
||||
}
|
||||
|
||||
@ -789,7 +789,7 @@ bool TabCourse::loadPage(gdioutput &gdi) {
|
||||
mlen = max(allCrs[k]->getControlsUI().length()/2+5, mlen);
|
||||
}
|
||||
|
||||
gdi.addInput("Controls", L"", max(48u, mlen), CourseCB, L"Kontroller:");
|
||||
gdi.addInput("Controls", L"", max<int>(48, mlen), CourseCB, L"Kontroller:");
|
||||
gdi.dropLine(0.3);
|
||||
gdi.addString("CourseExpanded", 0, "...").setColor(colorDarkGreen);
|
||||
gdi.dropLine(0.5);
|
||||
|
||||
@ -471,7 +471,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
}
|
||||
}
|
||||
else if (bi.id == "DoRenameSaved") {
|
||||
int ix = int(gdi.getData("ParamIx"));
|
||||
int ix = gdi.getDataInt("ParamIx");
|
||||
oListParam &par = oe->getListContainer().getParam(ix);
|
||||
wstring name = gdi.getText("Name");
|
||||
par.setName(name);
|
||||
@ -501,7 +501,7 @@ int TabList::listCB(gdioutput &gdi, int type, void *data)
|
||||
ListBoxInfo lbi;
|
||||
if (gdi.getSelectedItem("Merge", lbi)) {
|
||||
int mergeWidth = lbi.data;
|
||||
int base = (int)gdi.getData("ParamIx");
|
||||
int base = gdi.getDataInt("ParamIx");
|
||||
oe->synchronize(false);
|
||||
bool showTitle = gdi.isChecked("ShowTitle");
|
||||
oe->getListContainer().mergeParam(mergeWidth, base, showTitle);
|
||||
|
||||
@ -256,8 +256,21 @@ void TabRunner::selectRunner(gdioutput &gdi, pRunner r) {
|
||||
}
|
||||
}
|
||||
oe->fillCourses(gdi, "RCourse", true);
|
||||
wstring crsName = r->getCourse(false) ? r->getCourse(false)->getName() + L" " : L"";
|
||||
gdi.addItem("RCourse", crsName + lang.tl("[Klassens bana]"), 0);
|
||||
wstring crsName;
|
||||
if (r->getCourse(false))
|
||||
crsName = r->getCourse(false)->getName();
|
||||
|
||||
wstring courseType = lang.tl("[Klassens bana]");
|
||||
pClass cClass = r->getClassRef(false);
|
||||
if (cClass && (cClass->hasCoursePool() || r->getClassRef(true)->hasCoursePool())) {
|
||||
if (!crsName.empty())
|
||||
courseType = L", ... ";
|
||||
courseType += L"[" + lang.tl("Banpool") + L"]";
|
||||
}
|
||||
else if (crsName.empty())
|
||||
crsName += L" ";
|
||||
|
||||
gdi.addItem("RCourse", crsName + courseType, 0);
|
||||
gdi.selectItemByData("RCourse", r->getCourseId());
|
||||
updateNumShort(gdi, r->getCourse(false), r);
|
||||
|
||||
@ -2136,7 +2149,7 @@ void TabRunner::listRunners(gdioutput &gdi, const vector<pRunner> &r, bool filte
|
||||
if (filterVacant && r[k]->isVacant())
|
||||
continue;
|
||||
out.clear();
|
||||
sprintf_s(bf, "%d.", k+1);
|
||||
sprintf_s(bf, "%d.", int(k+1));
|
||||
gdi.addStringUT(yp, xp, 0, bf);
|
||||
gdi.addStringUT(yp, xp+gdi.scaleLength(40), 0, r[k]->getNameAndRace(true), gdi.scaleLength(190));
|
||||
gdi.addStringUT(yp, xp+gdi.scaleLength(200), 0, r[k]->getClass(true), gdi.scaleLength(140));
|
||||
|
||||
@ -191,7 +191,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
ListBoxInfo lbi;
|
||||
if (gdi.getSelectedItem("ComPort", lbi)) {
|
||||
|
||||
swprintf_s(bf, 64, L"COM%d", lbi.data);
|
||||
swprintf_s(bf, 64, L"COM%d", lbi.getDataInt());
|
||||
wstring port = bf;
|
||||
|
||||
if (lbi.text.substr(0, 3) == L"TCP")
|
||||
@ -306,7 +306,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
if (lbi.text.substr(0, 3) == L"TCP")
|
||||
swprintf_s(bf, 64, L"TCP");
|
||||
else
|
||||
swprintf_s(bf, 64, L"COM%d", lbi.data);
|
||||
swprintf_s(bf, 64, L"COM%d", lbi.getDataInt());
|
||||
gdi.fillDown();
|
||||
gdi.addStringUT(0, lang.tl(L"Hämtar information om ") + wstring(bf) + L".");
|
||||
printSIInfo(gdi, bf);
|
||||
@ -1214,7 +1214,7 @@ int TabSI::siCB(gdioutput &gdi, int type, void *data)
|
||||
wchar_t bf[64];
|
||||
|
||||
if (bi.text.substr(0,3)!=L"TCP")
|
||||
swprintf_s(bf, 64, L"COM%d", bi.data);
|
||||
swprintf_s(bf, 64, L"COM%d", bi.getDataInt());
|
||||
else
|
||||
wcscpy_s(bf, L"TCP");
|
||||
|
||||
@ -1631,7 +1631,7 @@ void TabSI::showReadPunches(gdioutput &gdi, vector<PunchInfo> &punches, set<stri
|
||||
int xp = gdi.getCX();
|
||||
dates.clear();
|
||||
for (size_t k=0;k<punches.size(); k++) {
|
||||
sprintf_s(bf, "%d.", k+1);
|
||||
sprintf_s(bf, "%d.", int(k+1));
|
||||
gdi.addStringUT(yp, xp, 0, bf);
|
||||
|
||||
pRunner r = oe->getRunnerByCardNo(punches[k].card, punches[k].time, oEvent::CardLookupProperty::Any);
|
||||
@ -1660,7 +1660,7 @@ void TabSI::showReadCards(gdioutput &gdi, vector<SICard> &cards)
|
||||
int yp = gdi.getCY();
|
||||
int xp = gdi.getCX();
|
||||
for (size_t k=0;k<cards.size(); k++) {
|
||||
sprintf_s(bf, "%d.", k+1);
|
||||
sprintf_s(bf, "%d.", int(k+1));
|
||||
gdi.addStringUT(yp, xp, 0, bf);
|
||||
|
||||
pRunner r = oe->getRunnerByCardNo(cards[k].CardNumber, 0, oEvent::CardLookupProperty::Any);
|
||||
@ -1678,7 +1678,7 @@ void TabSI::showReadCards(gdioutput &gdi, vector<SICard> &cards)
|
||||
SportIdent &TabSI::getSI(const gdioutput &gdi) {
|
||||
if (!gSI) {
|
||||
HWND hWnd=gdi.getHWNDMain();
|
||||
gSI = new SportIdent(hWnd, 0);
|
||||
gSI = new SportIdent(hWnd, 0, gEvent->getPropertyInt("ReadVoltageExp", 0) != 0);
|
||||
}
|
||||
return *gSI;
|
||||
}
|
||||
@ -2343,6 +2343,7 @@ void TabSI::processInsertCard(const SICard &sic)
|
||||
pCard card = oe->allocateCard(runner);
|
||||
card->setReadId(sic);
|
||||
card->setCardNo(sic.CardNumber);
|
||||
card->setMeasuredVoltage(sic.miliVolt);
|
||||
|
||||
if (sic.CheckPunch.Code!=-1)
|
||||
card->addPunch(oPunch::PunchCheck, sic.CheckPunch.Time, 0);
|
||||
@ -2372,7 +2373,7 @@ bool TabSI::processUnmatched(gdioutput &gdi, const SICard &csic, bool silent)
|
||||
|
||||
card->setReadId(csic);
|
||||
card->setCardNo(csic.CardNumber);
|
||||
|
||||
card->setMeasuredVoltage(csic.miliVolt);
|
||||
|
||||
wstring info=lang.tl(L"Okänd bricka ") + itow(sic.CardNumber) + L".";
|
||||
wstring warnings;
|
||||
@ -2456,6 +2457,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
||||
|
||||
// Choose course from pool
|
||||
pClass cls = runner->getClassRef(false);
|
||||
pClass pclass = runner->getClassRef(true);
|
||||
if (cls && cls->hasCoursePool()) {
|
||||
unsigned leg=runner->legToRun();
|
||||
|
||||
@ -2465,6 +2467,11 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
||||
runner->setCourseId(c->getId());
|
||||
}
|
||||
}
|
||||
else if (pclass && pclass != cls && pclass->hasCoursePool()) {
|
||||
pCourse c = pclass->selectCourseFromPool(0, csic);
|
||||
if (c)
|
||||
runner->setCourseId(c->getId());
|
||||
}
|
||||
|
||||
if (cls && cls->hasUnorderedLegs()) {
|
||||
pCourse crs = cls->selectParallelCourse(*runner, csic);
|
||||
@ -2474,7 +2481,6 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
||||
}
|
||||
}
|
||||
|
||||
pClass pclass = runner->getClassRef(true);
|
||||
if (!runner->getCourse(false) && !csic.isManualInput() && !oe->getMeOSFeatures().hasFeature(MeOSFeatures::NoCourses)) {
|
||||
|
||||
if (pclass && !pclass->hasMultiCourse() && !pclass->hasDirectResult()) {
|
||||
@ -2522,6 +2528,7 @@ bool TabSI::processCard(gdioutput &gdi, pRunner runner, const SICard &csic, bool
|
||||
|
||||
card->setReadId(csic);
|
||||
card->setCardNo(sic.CardNumber);
|
||||
card->setMeasuredVoltage(sic.miliVolt);
|
||||
|
||||
cardno = itow(sic.CardNumber);
|
||||
|
||||
@ -3738,7 +3745,7 @@ wstring TabSI::getCardInfo(bool param, vector<int> &count) const {
|
||||
|
||||
void TabSI::showRegisterHiredCards(gdioutput &gdi) {
|
||||
gdi.disableInput("Interactive");
|
||||
gdi.disableInput("Database");
|
||||
gdi.disableInput("Database", true);
|
||||
gdi.disableInput("PrintSplits");
|
||||
gdi.disableInput("UseManualInput");
|
||||
|
||||
|
||||
@ -891,7 +891,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
||||
if (r == 0) {
|
||||
throw meosException("Ingen deltagare vald.");
|
||||
}
|
||||
int leg = (int)gdi.getData("Leg");
|
||||
int leg = gdi.getDataInt("Leg");
|
||||
|
||||
pTeam t = oe->getTeam(teamId);
|
||||
processChangeRunner(gdi, t, leg, r);
|
||||
@ -987,7 +987,7 @@ int TabTeam::teamCB(gdioutput &gdi, int type, void *data)
|
||||
else if (type == GUI_LINK) {
|
||||
TextInfo ti = dynamic_cast<TextInfo &>(*(BaseInfo *)data);
|
||||
if (ti.id == "SelectR") {
|
||||
int leg = (int)gdi.getData("Leg");
|
||||
int leg = gdi.getDataInt("Leg");
|
||||
pTeam t = oe->getTeam(teamId);
|
||||
int rid = ti.getExtraInt();
|
||||
pRunner r = oe->getRunner(rid, 0);
|
||||
|
||||
@ -2118,13 +2118,14 @@ void Table::importClipboard(gdioutput &gdi)
|
||||
index = out[i].second;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
if (index != -1) {
|
||||
if (cell.hasOwner())
|
||||
cell.getOwner()->inputData(cell.id, table[k][j], index, output, false);
|
||||
cell.contents = output;
|
||||
}
|
||||
else if (cell.type == cellCombo) {
|
||||
else /*if (cell.type == cellCombo)*/ {
|
||||
if (cell.hasOwner())
|
||||
cell.getOwner()->inputData(cell.id, table[k][j], index, output, false);
|
||||
cell.contents = output;
|
||||
|
||||
@ -387,4 +387,4 @@ TID_RUNNER, TID_CLUB, TID_START, TID_TIME,
|
||||
TID_FINISH, TID_STATUS, TID_RUNNINGTIME, TID_PLACE, TID_POINTS,
|
||||
TID_CARD, TID_TEAM, TID_LEG, TID_CONTROL, TID_CODES, TID_FEE, TID_PAID,
|
||||
TID_INPUTTIME, TID_INPUTSTATUS, TID_INPUTPOINTS, TID_INPUTPLACE,
|
||||
TID_NAME, TID_NATIONAL, TID_SEX, TID_YEAR, TID_INDEX, TID_ENTER, TID_STARTNO};
|
||||
TID_NAME, TID_NATIONAL, TID_SEX, TID_YEAR, TID_INDEX, TID_ENTER, TID_STARTNO, TID_VOLTAGE};
|
||||
|
||||
@ -130,6 +130,15 @@ string TimeStamp::getStampStringN() const
|
||||
SYSTEMTIME st;
|
||||
FileTimeToSystemTime(&ft, &st);
|
||||
|
||||
if (st.wYear > 2021 || st.wYear < 2009) {
|
||||
st.wYear = 2021;
|
||||
st.wDay = 1;
|
||||
st.wMonth = 1;
|
||||
st.wHour = 2;
|
||||
st.wMinute = 0;
|
||||
st.wSecond = 0;
|
||||
}
|
||||
|
||||
char bf[32];
|
||||
sprintf_s(bf, "%d-%02d-%02d %02d:%02d:%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
code/dll64/libharu.dll
Normal file
BIN
code/dll64/libharu.dll
Normal file
Binary file not shown.
BIN
code/dll64/libmysql.dll
Normal file
BIN
code/dll64/libmysql.dll
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2524,3 +2524,26 @@ Startgrupp med id X tilldelad Y finns inte = Starting group with ID X defined fo
|
||||
Använd om möjligt samma dator som användes vid senaste importen = If possible, use the same computer that was used to import the last time
|
||||
Tillåt borttagning av löpare (med mera) som raderats i den importerade tävlingen = Allow removal of competitors (etc) that has was deleted in the imported version.
|
||||
Varning: Kunde inte hitta föregående version av tävlingen (X) = Warning: Could not find the previous version of the competition (X)
|
||||
ClassDefaultResult = Class, Default result
|
||||
RunnerCoursePlace = Competitor's place on course
|
||||
RunnerStagePlace = Competitor's place (on stage)
|
||||
RunnerStagePoints = Competitor's points (on stage)
|
||||
RunnerStageTime = Competitor's time (on stage)
|
||||
RunnerStageStatus = Competitor's status (on stage)
|
||||
RunnerStageTimeStatus = Competitor's time or status (on stage)
|
||||
EFilterIncludeNotParticipating = Include not participating
|
||||
RunnerStageNumber = Stage number earlier stage
|
||||
Begränsa bredd (klipp text) = Limit width (crop text)
|
||||
Håll ihop med = Keep together
|
||||
Justering i sidled = Line adjustment
|
||||
Minsta blockbredd = Least width
|
||||
Relation till föregående = Relation to previous
|
||||
Bantilldelning hänvisar till en löpare (X) som saknas i laget (Y) = Course assignment specifies a competitor (X) that is missing in the team (Y)
|
||||
warn:mysqlbinlog = Performance warning: Could not disable binary logging. Uploading can be slow.\n\nX
|
||||
Server version: X = Server version: X
|
||||
prefsDatabaseEngine = Typ av databastabell för nya tävlingar (MySQL)
|
||||
Startgrupperna X och Y överlappar = Start groups X and Y are overlapping
|
||||
Batteristatus = Battery status
|
||||
Low = Low
|
||||
prefsReadVoltageExp = Read SIAC battery voltage
|
||||
Spänning = Voltage
|
||||
|
||||
@ -1167,12 +1167,12 @@ ButtonInfo &gdioutput::addButton(int x, int y, int w, const string &id,
|
||||
}
|
||||
bi.hWnd=CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP|WS_VISIBLE|WS_CHILD | WS_CLIPSIBLINGS |style|BS_NOTIFY,
|
||||
x-OffsetX, y, w, height, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
}
|
||||
else {
|
||||
bi.hWnd=CreateWindow(L"BUTTON", ttext.c_str(), WS_TABSTOP|WS_VISIBLE|WS_CHILD | WS_CLIPSIBLINGS |style|BS_NOTIFY,
|
||||
x-OffsetX, y-OffsetY-1, w, height, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
}
|
||||
|
||||
SendMessage(bi.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0);
|
||||
@ -1265,12 +1265,6 @@ ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const wstring
|
||||
oy=0;
|
||||
}
|
||||
|
||||
/*
|
||||
bi.hWnd=CreateWindowEx(0,"BUTTON", ttext.c_str(), WS_TABSTOP|WS_VISIBLE|
|
||||
WS_CHILD|BS_AUTOCHECKBOX|BS_NOTIFY,
|
||||
x-ox, y-oy, size.cx+30, size.cy+5, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
*/
|
||||
int h = size.cy;
|
||||
SelectObject(hDC, getGUIFont());
|
||||
GetTextExtentPoint32(hDC, ttext.c_str(), ttext.length(), &size);
|
||||
@ -1279,7 +1273,7 @@ ButtonInfo &gdioutput::addCheckbox(int x, int y, const string &id, const wstring
|
||||
bi.hWnd=CreateWindowEx(0,L"BUTTON", L"", WS_TABSTOP|WS_VISIBLE|
|
||||
WS_CHILD | WS_CLIPSIBLINGS |BS_AUTOCHECKBOX|BS_NOTIFY,
|
||||
x-ox, y-oy + (size.cy-h)/2, h, h, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
TextInfo &desc = addStringUT(y , x + (3*h)/2, 0, ttext, 0, checkBoxCallback);
|
||||
desc.id = "T" + id;
|
||||
@ -1384,7 +1378,7 @@ InputInfo &gdioutput::addInput(int x, int y, const string &id, const wstring &te
|
||||
ii.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", text.c_str(),
|
||||
WS_TABSTOP|WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS | ES_AUTOHSCROLL | WS_BORDER,
|
||||
x-ox, y-oy, dim.first, dim.second,
|
||||
hWndTarget, NULL, (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
hWndTarget, NULL, (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
int mrg = scaleLength(4);
|
||||
updatePos(x, y, dim.first+mrg, dim.second+mrg);
|
||||
|
||||
@ -1438,7 +1432,7 @@ InputInfo &gdioutput::addInputBox(const string &id, int x, int y, int width, int
|
||||
ii.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"EDIT", text.c_str(), WS_HSCROLL|WS_VSCROLL|
|
||||
WS_TABSTOP|WS_VISIBLE|WS_CHILD | WS_CLIPSIBLINGS |ES_AUTOHSCROLL|ES_MULTILINE|ES_AUTOVSCROLL|WS_BORDER,
|
||||
x-ox, y-oy, width, height, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
updatePos(x, y, width, height);
|
||||
|
||||
@ -1470,7 +1464,7 @@ ListBoxInfo &gdioutput::addListBox(const string &id, int width, int height, GUIC
|
||||
}
|
||||
|
||||
LRESULT CALLBACK GetMsgProc(HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {
|
||||
ListBoxInfo *lbi = (ListBoxInfo *)(GetWindowLongPtr(hWnd, GWL_USERDATA));
|
||||
ListBoxInfo *lbi = (ListBoxInfo *)(GetWindowLongPtr(hWnd, GWLP_USERDATA));
|
||||
if (!lbi) {
|
||||
throw std::exception("Internal GDI error");
|
||||
}
|
||||
@ -1501,14 +1495,14 @@ void gdioutput::synchronizeListScroll(const string &id1, const string &id2)
|
||||
|
||||
a->lbiSync = b;
|
||||
b->lbiSync = a;
|
||||
SetWindowLongPtr(a->hWnd, GWL_USERDATA, LONG_PTR(a));
|
||||
SetWindowLongPtr(b->hWnd, GWL_USERDATA, LONG_PTR(b));
|
||||
SetWindowLongPtr(a->hWnd, GWLP_USERDATA, LONG_PTR(a));
|
||||
SetWindowLongPtr(b->hWnd, GWLP_USERDATA, LONG_PTR(b));
|
||||
|
||||
a->originalProc = WNDPROC(GetWindowLongPtr(a->hWnd, GWL_WNDPROC));
|
||||
b->originalProc = WNDPROC(GetWindowLongPtr(b->hWnd, GWL_WNDPROC));
|
||||
a->originalProc = WNDPROC(GetWindowLongPtr(a->hWnd, GWLP_WNDPROC));
|
||||
b->originalProc = WNDPROC(GetWindowLongPtr(b->hWnd, GWLP_WNDPROC));
|
||||
|
||||
SetWindowLongPtr(a->hWnd, GWL_WNDPROC, LONG_PTR(GetMsgProc));
|
||||
SetWindowLongPtr(b->hWnd, GWL_WNDPROC, LONG_PTR(GetMsgProc));
|
||||
SetWindowLongPtr(a->hWnd, GWLP_WNDPROC, LONG_PTR(GetMsgProc));
|
||||
SetWindowLongPtr(b->hWnd, GWLP_WNDPROC, LONG_PTR(GetMsgProc));
|
||||
}
|
||||
|
||||
ListBoxInfo &gdioutput::addListBox(int x, int y, const string &id, int width, int height, GUICALLBACK cb,
|
||||
@ -1528,7 +1522,7 @@ ListBoxInfo &gdioutput::addListBox(int x, int y, const string &id, int width, in
|
||||
|
||||
lbi.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"LISTBOX", L"", style,
|
||||
x-ox, y-oy, int(width*scale), int(height*scale), hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
updatePos(x, y, int(scale*(width+5)), int(scale * (height+2)));
|
||||
SendMessage(lbi.hWnd, WM_SETFONT, (WPARAM) getGUIFont(), 0);
|
||||
@ -1617,7 +1611,7 @@ ListBoxInfo &gdioutput::addSelection(int x, int y, const string &id, int width,
|
||||
|
||||
lbi.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"COMBOBOX", L"", WS_TABSTOP|WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS |WS_BORDER|CBS_DROPDOWNLIST|WS_VSCROLL ,
|
||||
x-ox, y-oy, int(scale*width), int(scale*height), hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
updatePos(x, y, int(scale*(width+5)), int(scale*30));
|
||||
|
||||
@ -1659,7 +1653,7 @@ ListBoxInfo &gdioutput::addCombo(int x, int y, const string &id, int width, int
|
||||
|
||||
lbi.hWnd=CreateWindowEx(WS_EX_CLIENTEDGE, L"COMBOBOX", L"", WS_TABSTOP|WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS |WS_BORDER|CBS_DROPDOWN |CBS_AUTOHSCROLL,
|
||||
x-ox, y-oy, int(scale*width), int(scale*height), hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
updatePos(x, y, int(scale * (width+5)), getButtonHeight()+scaleLength(5));
|
||||
|
||||
@ -1791,7 +1785,7 @@ bool gdioutput::getSelectedItem(const string &id, ListBoxInfo &lbi) {
|
||||
pair<int, bool> gdioutput::getSelectedItem(const string &id) {
|
||||
ListBoxInfo lbi;
|
||||
bool ret = getSelectedItem(id, lbi);
|
||||
return make_pair(lbi.data, ret);
|
||||
return make_pair(lbi.getDataInt(), ret);
|
||||
}
|
||||
|
||||
pair<int, bool> gdioutput::getSelectedItem(const char *id) {
|
||||
@ -2116,7 +2110,7 @@ LRESULT gdioutput::ProcessMsg(UINT iMessage, LPARAM lParam, WPARAM wParam)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gdioutput::processButtonMessage(ButtonInfo &bi, DWORD wParam)
|
||||
void gdioutput::processButtonMessage(ButtonInfo &bi, WPARAM wParam)
|
||||
{
|
||||
WORD hwParam = HIWORD(wParam);
|
||||
|
||||
@ -2164,7 +2158,7 @@ void gdioutput::processButtonMessage(ButtonInfo &bi, DWORD wParam)
|
||||
}
|
||||
}
|
||||
|
||||
void gdioutput::processEditMessage(InputInfo &bi, DWORD wParam)
|
||||
void gdioutput::processEditMessage(InputInfo &bi, WPARAM wParam)
|
||||
{
|
||||
WORD hwParam = HIWORD(wParam);
|
||||
|
||||
@ -2208,7 +2202,7 @@ void gdioutput::processEditMessage(InputInfo &bi, DWORD wParam)
|
||||
}
|
||||
}
|
||||
|
||||
void gdioutput::processComboMessage(ListBoxInfo &bi, DWORD wParam)
|
||||
void gdioutput::processComboMessage(ListBoxInfo &bi, WPARAM wParam)
|
||||
{
|
||||
WORD hwParam = HIWORD(wParam);
|
||||
int index;
|
||||
@ -2325,7 +2319,7 @@ void gdioutput::keyCommand(KeyCommandCode code) {
|
||||
|
||||
#endif
|
||||
|
||||
void gdioutput::processListMessage(ListBoxInfo &bi, DWORD wParam)
|
||||
void gdioutput::processListMessage(ListBoxInfo &bi, WPARAM wParam)
|
||||
{
|
||||
WORD hwParam = HIWORD(wParam);
|
||||
int index;
|
||||
@ -5415,7 +5409,7 @@ wstring gdioutput::browseForSave(const vector< pair<wstring, wstring> > &filter,
|
||||
|
||||
of.lStructSize = sizeof(of);
|
||||
of.hwndOwner = hWndTarget;
|
||||
of.hInstance = (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE);
|
||||
of.hInstance = (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE);
|
||||
of.lpstrFilter = sFilter.c_str();
|
||||
of.lpstrCustomFilter = NULL;
|
||||
of.nMaxCustFilter = 0;
|
||||
@ -5477,7 +5471,7 @@ wstring gdioutput::browseForOpen(const vector< pair<wstring, wstring> > &filter,
|
||||
|
||||
of.lStructSize = sizeof(of);
|
||||
of.hwndOwner = hWndTarget;
|
||||
of.hInstance = (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE);
|
||||
of.hInstance = (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE);
|
||||
of.lpstrFilter = sFilter.c_str();
|
||||
of.lpstrCustomFilter = NULL;
|
||||
of.nMaxCustFilter = 0;
|
||||
@ -5587,7 +5581,7 @@ void gdioutput::init(HWND hWnd, HWND hMain, HWND hTab)
|
||||
|
||||
hWndToolTip = CreateWindow(TOOLTIPS_CLASS, (LPWSTR) NULL, TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
NULL, (HMENU) NULL, (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
NULL, (HMENU) NULL, (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
}
|
||||
|
||||
ToolInfo &gdioutput::addToolTip(const string &tipId, const wstring &tip, HWND hWnd, RECT *rc) {
|
||||
@ -5615,7 +5609,7 @@ ToolInfo &gdioutput::addToolTip(const string &tipId, const wstring &tip, HWND hW
|
||||
}
|
||||
|
||||
ti.hwnd = hWndTarget;
|
||||
ti.hinst = (HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE);
|
||||
ti.hinst = (HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE);
|
||||
info.name = tipId;
|
||||
ti.lpszText = (LPWSTR)toolTips.back().tip.c_str();
|
||||
|
||||
@ -7094,7 +7088,7 @@ AutoCompleteInfo &gdioutput::addAutoComplete(const string &key) {
|
||||
|
||||
HWND hWnd = CreateWindowEx(WS_EX_CLIENTEDGE, L"AUTOCOMPLETE", L"", WS_VISIBLE | WS_CHILD | WS_CLIPSIBLINGS| WS_BORDER ,
|
||||
pt.x, pt.y, scaleLength(350), height, hWndTarget, NULL,
|
||||
(HINSTANCE)GetWindowLong(hWndTarget, GWL_HINSTANCE), NULL);
|
||||
(HINSTANCE)GetWindowLongPtr(hWndTarget, GWLP_HINSTANCE), NULL);
|
||||
|
||||
autoCompleteInfo.reset(new AutoCompleteInfo(hWnd, key, *this));
|
||||
|
||||
|
||||
@ -225,10 +225,10 @@ protected:
|
||||
|
||||
void initCommon(double scale, const wstring &font);
|
||||
|
||||
void processButtonMessage(ButtonInfo &bi, DWORD wParam);
|
||||
void processEditMessage(InputInfo &bi, DWORD wParam);
|
||||
void processComboMessage(ListBoxInfo &bi, DWORD wParam);
|
||||
void processListMessage(ListBoxInfo &bi, DWORD wParam);
|
||||
void processButtonMessage(ButtonInfo &bi, WPARAM wParam);
|
||||
void processEditMessage(InputInfo &bi, WPARAM wParam);
|
||||
void processComboMessage(ListBoxInfo &bi, WPARAM wParam);
|
||||
void processListMessage(ListBoxInfo &bi, WPARAM wParam);
|
||||
|
||||
void doEnter();
|
||||
void doEscape();
|
||||
@ -543,6 +543,8 @@ public:
|
||||
void setData(const string &id, const string &data);
|
||||
|
||||
void *getData(const string &id) const;
|
||||
int getDataInt(const string &id) const { return int(size_t(getData(id))); }
|
||||
|
||||
bool getData(const string &id, string &out) const;
|
||||
|
||||
|
||||
|
||||
@ -59,12 +59,15 @@ public:
|
||||
|
||||
BaseInfo &setExtra(const wchar_t *e) {extra=(void *)e; dataString = true; return *this;}
|
||||
|
||||
BaseInfo &setExtra(int e) {extra = (void *)(e); return *this;}
|
||||
BaseInfo &setExtra(int e) {extra = (void *)size_t(e); return *this;}
|
||||
BaseInfo &setExtra(size_t e) {extra = (void *)(e); return *this;}
|
||||
#ifdef _M_X64
|
||||
BaseInfo &setExtra(unsigned int e) { extra = (void *)size_t(e); return *this; }
|
||||
#endif
|
||||
|
||||
bool isExtraString() const {return dataString;}
|
||||
wchar_t *getExtra() const {assert(extra == 0 || dataString); return (wchar_t *)extra;}
|
||||
int getExtraInt() const {return int(extra);}
|
||||
int getExtraInt() const {return (int)size_t(extra);}
|
||||
size_t getExtraSize() const {return size_t(extra);}
|
||||
|
||||
GuiHandler &getHandler() const;
|
||||
@ -293,6 +296,8 @@ public:
|
||||
updateLastData(0) {}
|
||||
wstring text;
|
||||
size_t data;
|
||||
int getDataInt() const { return (int)data; }
|
||||
|
||||
int index;
|
||||
bool changed() const {return text!=original;}
|
||||
void ignore(bool ig) {ignoreCheck=ig;}
|
||||
|
||||
@ -38,6 +38,22 @@
|
||||
wstring &getFirst(wstring &inout, int maxNames);
|
||||
wstring getMeosCompectVersion();
|
||||
|
||||
vector<int> parseSGTimes(const oEvent &oe, const wstring &name) {
|
||||
vector<wstring> parts;
|
||||
vector<int> times;
|
||||
split(name, L" -‒–—‐", parts);
|
||||
for (auto &p : parts) {
|
||||
for (auto &c : p) {
|
||||
if (c == '.')
|
||||
c = ':';
|
||||
}
|
||||
int t = oe.getRelativeTime(p);
|
||||
if (t > 0)
|
||||
times.push_back(t);
|
||||
}
|
||||
return times;
|
||||
}
|
||||
|
||||
IOF30Interface::IOF30Interface(oEvent *oe, bool forceSplitFee) : oe(*oe), useGMT(false), teamsAsIndividual(false),
|
||||
entrySourceId(1), unrollLoops(true),
|
||||
includeStageRaceInfo(true) {
|
||||
@ -136,6 +152,116 @@ void IOF30Interface::readCourseData(gdioutput &gdi, const xmlobject &xo, bool up
|
||||
classAssignmentObsolete(gdi, xAssignment, courses, coursesFamilies);
|
||||
}
|
||||
|
||||
auto matchCoursePattern = [](const vector<int> &p1, const vector<int> &p2) {
|
||||
for (int j = 0; j < p1.size(); j++) {
|
||||
if (p1[j] != p2[j] && p1[j] != -1 && p2[j] != -1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
// Try to reconstruct
|
||||
for (auto &bibLegCourse : classToBibLegCourse) {
|
||||
pClass pc = oe.getClass(bibLegCourse.first);
|
||||
if (!pc || bibLegCourse.second.empty())
|
||||
continue;
|
||||
|
||||
// Get collection of courses
|
||||
set<int> classCourses;
|
||||
for (auto &blc : bibLegCourse.second)
|
||||
classCourses.insert(get<pCourse>(blc)->getId());
|
||||
|
||||
vector<pCourse> presentCrs;
|
||||
pc->getCourses(-1, presentCrs);
|
||||
|
||||
// Check if we have the same set of courses
|
||||
bool sameSet = presentCrs.size() == classCourses.size();
|
||||
for (pCourse crs : presentCrs) {
|
||||
if (!classCourses.count(crs->getId())) {
|
||||
sameSet = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sameSet)
|
||||
continue; // Do not touch forking if same set
|
||||
|
||||
int fallBackCrs = *classCourses.begin();
|
||||
map<int, vector<pair<int, int>>> bibToLegCourseId;
|
||||
for (auto &blc : bibLegCourse.second) {
|
||||
int bib = get<0>(blc);
|
||||
int leg = get<1>(blc);
|
||||
int crsId = get<2>(blc)->getId();
|
||||
bibToLegCourseId[bib].emplace_back(leg, crsId);
|
||||
}
|
||||
|
||||
int width = 0;
|
||||
for (auto &blcid : bibToLegCourseId) {
|
||||
sort(blcid.second.begin(), blcid.second.end());
|
||||
width = max(width, blcid.second.back().first);
|
||||
}
|
||||
|
||||
vector<vector<int>> coursePattern;
|
||||
int offset = bibToLegCourseId.begin()->first;
|
||||
for (auto &blcid : bibToLegCourseId) {
|
||||
int bib = blcid.first;
|
||||
while (coursePattern.size() <= bib - offset)
|
||||
coursePattern.emplace_back(width + 1, -1);
|
||||
for (auto &legCrsId : blcid.second) {
|
||||
coursePattern.back()[legCrsId.first] = legCrsId.second;
|
||||
}
|
||||
}
|
||||
|
||||
int period = 1;
|
||||
while (period < coursePattern.size()) {
|
||||
if (matchCoursePattern(coursePattern[0], coursePattern[period])) {
|
||||
// Check if pattern is OK
|
||||
bool ok = true;
|
||||
for (int off = 0; off < period; off++) {
|
||||
for (int c = off + period; c < coursePattern.size(); c++) {
|
||||
if (!matchCoursePattern(coursePattern[off], coursePattern[c])) {
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ok) // Found OK pattern
|
||||
break;
|
||||
}
|
||||
period++;
|
||||
}
|
||||
|
||||
// Add any missing courses for incomplete patterns. Need not result in a fair forking
|
||||
for (int leg = 0; leg < coursePattern[0].size(); leg++) {
|
||||
vector<int> crsLeg;
|
||||
for (int i = 0; i < period; i++) {
|
||||
int crs = coursePattern[i][leg];
|
||||
if (crs != -1)
|
||||
crsLeg.push_back(crs);
|
||||
}
|
||||
if (crsLeg.empty())
|
||||
crsLeg.push_back(fallBackCrs);
|
||||
int rot = 0;
|
||||
for (int i = 0; i < period; i++) {
|
||||
if (coursePattern[i][leg] == -1)
|
||||
coursePattern[i][leg] = crsLeg[(rot++) % crsLeg.size()]; // Take courses from this leg
|
||||
}
|
||||
}
|
||||
|
||||
int patternStart = (offset - 1) % period;
|
||||
|
||||
if (pc->getNumStages() == 0) {
|
||||
pc->setNumStages(coursePattern[0].size());
|
||||
}
|
||||
for (int leg = 0; leg < pc->getNumStages() && leg < coursePattern[0].size(); leg++) {
|
||||
pc->clearStageCourses(leg);
|
||||
for (int m = 0; m < period; m++)
|
||||
pc->addStageCourse(leg, coursePattern[(patternStart + m)%period][leg], -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IOF30Interface::classCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||
@ -386,6 +512,8 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||
vector<pTeam> allT;
|
||||
oe.getTeams(0, allT, false);
|
||||
|
||||
map<int, int> firstBib2Class;
|
||||
|
||||
map<wstring, pTeam> bib2Team;
|
||||
map<pair<wstring, wstring>, pTeam> nameClass2Team;
|
||||
for (size_t k = 0; k < allT.size(); k++) {
|
||||
@ -401,18 +529,22 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||
pTeam t = 0;
|
||||
wstring teamText;
|
||||
wstring bib;
|
||||
int iBib = -1;
|
||||
int iClass = -1;
|
||||
xTAssignment.getObjectString("BibNumber", bib);
|
||||
|
||||
if (!bib.empty()) {
|
||||
teamText = bib;
|
||||
iBib = _wtoi(bib.c_str());
|
||||
t = bib2Team[bib];
|
||||
if (t == nullptr) {
|
||||
int ibib = _wtoi(bib.c_str());
|
||||
if (ibib > 0) {
|
||||
wstring bib2 = itow(ibib);
|
||||
if (iBib > 0) {
|
||||
wstring bib2 = itow(iBib);
|
||||
t = bib2Team[bib2];
|
||||
}
|
||||
}
|
||||
if (t != nullptr)
|
||||
iClass = t->getClassId(false);
|
||||
}
|
||||
|
||||
if (t == 0) {
|
||||
@ -421,27 +553,74 @@ void IOF30Interface::teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||
if (!team.empty()) {
|
||||
wstring cls;
|
||||
xTAssignment.getObjectString("ClassName", cls);
|
||||
auto pcls = oe.getClass(cls);
|
||||
if (pcls)
|
||||
iClass = pcls->getId();
|
||||
|
||||
t = nameClass2Team[make_pair(team, cls)];
|
||||
teamText = team + L" / " + cls;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == 0) {
|
||||
if (iBib > 0 && iClass <= 0) {
|
||||
if (firstBib2Class.empty()) {
|
||||
map<int, int> classId2FirstBib;
|
||||
|
||||
auto insertClsBib = [&](int cls, int b) {
|
||||
auto res = classId2FirstBib.find(cls);
|
||||
if (res == classId2FirstBib.end())
|
||||
classId2FirstBib.emplace(cls, b);
|
||||
else
|
||||
res->second = min(res->second, b);
|
||||
};
|
||||
|
||||
for (pTeam t : allT) {
|
||||
int b = _wtoi(t->getBib().c_str());
|
||||
if (b <= 0)
|
||||
continue;
|
||||
int cls = t->getClassId(false);
|
||||
if (cls > 0)
|
||||
insertClsBib(cls, b);
|
||||
}
|
||||
vector<pClass> allC;
|
||||
oe.getClasses(allC, false);
|
||||
for (pClass c : allC) {
|
||||
int b = _wtoi(c->getDCI().getString("Bib").c_str());
|
||||
if (b > 0)
|
||||
insertClsBib(c->getId(), b);
|
||||
}
|
||||
|
||||
// No check for overlapping classes
|
||||
for (auto cfb : classId2FirstBib) {
|
||||
firstBib2Class[cfb.second] = cfb.first;
|
||||
}
|
||||
}
|
||||
|
||||
auto res = firstBib2Class.upper_bound(iBib);
|
||||
if (res != firstBib2Class.begin()) {
|
||||
--res;
|
||||
iClass = res->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (t == 0 && (iBib<=0 || iClass<=0)) {
|
||||
gdi.addString("", 0, L"Varning: Laget 'X' finns inte.#" + teamText).setColor(colorRed);
|
||||
continue;
|
||||
}
|
||||
|
||||
xmlList teamMemberAssignment;
|
||||
xTAssignment.getObjects("TeamMemberCourseAssignment", teamMemberAssignment);
|
||||
assignTeamCourse(gdi, *t, teamMemberAssignment, courses);
|
||||
assignTeamCourse(gdi, t, iClass, iBib, teamMemberAssignment, courses);
|
||||
}
|
||||
}
|
||||
|
||||
void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAssignment,
|
||||
void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam *team, int iClass, int iBib, xmlList &xAssignment,
|
||||
const map<wstring, pCourse> &courses) {
|
||||
|
||||
if (!team.getClassRef(false))
|
||||
pClass cls = oe.getClass(iClass);
|
||||
if (!cls)
|
||||
return;
|
||||
|
||||
for (size_t k = 0; k <xAssignment.size(); k++) {
|
||||
|
||||
// Extract courses / families
|
||||
@ -457,38 +636,51 @@ void IOF30Interface::assignTeamCourse(gdioutput &gdi, oTeam &team, xmlList &xAss
|
||||
if (xLegOrder)
|
||||
legorder = xLegOrder.getInt() - 1;
|
||||
|
||||
int legId = team.getClassRef(false)->getLegNumberLinear(leg, legorder);
|
||||
int legId = cls->getLegNumberLinear(leg, legorder);
|
||||
if (legId>=0) {
|
||||
pRunner r = team.getRunner(legId);
|
||||
|
||||
classToBibLegCourse[iClass].emplace_back(iBib, legId, c);
|
||||
|
||||
if (team) {
|
||||
pRunner r = team->getRunner(legId);
|
||||
if (r == 0) {
|
||||
r = oe.addRunner(lang.tl(L"N.N."), team.getClubId(), team.getClassId(false), 0, 0, false);
|
||||
r = oe.addRunner(lang.tl(L"N.N."), team->getClubId(), team->getClassId(false), 0, 0, false);
|
||||
if (r) {
|
||||
r->setEntrySource(entrySourceId);
|
||||
r->flagEntryTouched(true);
|
||||
}
|
||||
team.setRunner(legId, r, false);
|
||||
r = team.getRunner(legId);
|
||||
team->setRunner(legId, r, false);
|
||||
r = team->getRunner(legId);
|
||||
}
|
||||
if (r) {
|
||||
r->setCourseId(c->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
gdi.addString("", 0, L"Bantilldelning för 'X' hänvisar till en sträcka som inte finns#" + team.getClass(false)).setColor(colorRed);
|
||||
gdi.addString("", 0, L"Bantilldelning för 'X' hänvisar till en sträcka som inte finns#" + cls->getName()).setColor(colorRed);
|
||||
}
|
||||
else {
|
||||
wstring name;
|
||||
xAssignment[k].getObjectString("TeamMemberName", name);
|
||||
bool done = false;
|
||||
if (team) {
|
||||
if (!name.empty()) {
|
||||
for (int j = 0; j < team.getNumRunners(); j++) {
|
||||
pRunner r = team.getRunner(j);
|
||||
for (int j = 0; j < team->getNumRunners(); j++) {
|
||||
pRunner r = team->getRunner(j);
|
||||
if (r && r->getName() == name) {
|
||||
r->setCourseId(c->getId());
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!done) {
|
||||
gdi.addString("", 0, L"Bantilldelning hänvisar till en löpare (X) som saknas i laget (Y)#" +
|
||||
name + L"#" + team->getName()).setColor(colorRed);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -787,6 +979,8 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
|
||||
vector<pRunner> allR;
|
||||
vector<pTeam> allT;
|
||||
oe.getRunners(0, 0, allR, false);
|
||||
oe.getStartGroups(true); // Setup transient data for start groups
|
||||
|
||||
for (size_t k = 0; k < allR.size(); k++) {
|
||||
if (allR[k]->getEntrySource() == entrySourceId)
|
||||
allR[k]->flagEntryTouched(false);
|
||||
@ -849,6 +1043,8 @@ void IOF30Interface::readEntryList(gdioutput &gdi, xmlobject &xo, bool removeNon
|
||||
entFail++;
|
||||
}
|
||||
|
||||
oe.updateStartGroups(); // Store any updated start groups
|
||||
|
||||
bool hasMulti = false;
|
||||
for (map<int, vector< pair<int, int> > >::iterator it = personId2TeamLeg.begin();
|
||||
it != personId2TeamLeg.end(); ++it) {
|
||||
@ -1416,21 +1612,10 @@ void IOF30Interface::readEvent(gdioutput &gdi, const xmlobject &xo,
|
||||
bool anySG = false;
|
||||
// This is a "hack" to interpret services of the from "XXXX 14:00 - 15:00 XXXX" as a start group.
|
||||
for (auto &srv : services) {
|
||||
vector<wstring> parts;
|
||||
split(srv.name, L" -‒–—‐", parts);
|
||||
vector<int> times;
|
||||
for (auto &p : parts) {
|
||||
for (auto &c : p) {
|
||||
if (c == '.')
|
||||
c = ':';
|
||||
}
|
||||
int t = oe.getRelativeTime(p);
|
||||
if (t > 0)
|
||||
times.push_back(t);
|
||||
}
|
||||
vector<int> times = parseSGTimes(oe, srv.name);
|
||||
int ts = times.size();
|
||||
if (ts >= 2 && times[ts - 2] < times[ts - 1]) {
|
||||
oe.setStartGroup(srv.id, times[ts - 2], times[ts - 1]);
|
||||
oe.setStartGroup(srv.id, times[ts - 2], times[ts - 1], L"");
|
||||
anySG = true;
|
||||
}
|
||||
}
|
||||
@ -1844,6 +2029,22 @@ pRunner IOF30Interface::readPersonEntry(gdioutput &gdi, xmlobject &xo, pTeam tea
|
||||
if (xx.is("TimePresentation")) {
|
||||
hasTime = xx.getObjectBool(nullptr);
|
||||
}
|
||||
else if (xx.is("StartGroup")) {
|
||||
int groupId = xx.getObjectInt("Id");
|
||||
if (groupId > 0) {
|
||||
wstring groupName;
|
||||
xx.getObjectString("Name", groupName);
|
||||
if (oe.getStartGroup(groupId).firstStart == -1) {
|
||||
vector<int> times = parseSGTimes(oe, groupName);
|
||||
int ts = times.size();
|
||||
if (ts >= 2 && times[ts - 2] < times[ts - 1])
|
||||
oe.setStartGroup(groupId, times[ts - 2], times[ts - 1], groupName);
|
||||
else
|
||||
oe.setStartGroup(groupId, 3600, 3600 * 2, groupName);
|
||||
}
|
||||
r->setStartGroup(groupId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!hasTime)
|
||||
@ -3970,7 +4171,7 @@ void IOF30Interface::bindClassCourse(oClass &pc, const vector< vector<pCourse> >
|
||||
pc.setCourse(crs[0][0]);
|
||||
else {
|
||||
unsigned ns = pc.getNumStages();
|
||||
ns = max(ns, crs.size());
|
||||
ns = max<unsigned>(ns, crs.size());
|
||||
pc.setNumStages(ns);
|
||||
for (size_t k = 0; k < crs.size(); k++) {
|
||||
pc.clearStageCourses(k);
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
|
||||
class oEvent;
|
||||
class xmlobject;
|
||||
@ -141,6 +142,8 @@ class IOF30Interface {
|
||||
|
||||
vector<FeeStatistics> feeStatistics;
|
||||
|
||||
map<int, vector<tuple<int, int, pCourse>>> classToBibLegCourse;
|
||||
|
||||
static void getAgeLevels(const vector<FeeInfo> &fees, const vector<int> &ix,
|
||||
int &normalIx, int &redIx, wstring &youthLimit, wstring &seniorLimit);
|
||||
|
||||
@ -266,7 +269,7 @@ class IOF30Interface {
|
||||
void teamCourseAssignment(gdioutput &gdi, xmlList &xAssignment,
|
||||
const map<wstring, pCourse> &courses);
|
||||
|
||||
void assignTeamCourse(gdioutput &gdi, oTeam &t, xmlList &xAssignment,
|
||||
void assignTeamCourse(gdioutput &gdi, oTeam *t, int iClass, int iBib, xmlList &xAssignment,
|
||||
const map<wstring, pCourse> &courses);
|
||||
|
||||
pCourse findCourse(gdioutput &gdi, const map<wstring, pCourse> &courses,
|
||||
|
||||
BIN
code/lib/libmysql.lib
Normal file
BIN
code/lib/libmysql.lib
Normal file
Binary file not shown.
BIN
code/lib64/RestBed.lib
Normal file
BIN
code/lib64/RestBed.lib
Normal file
Binary file not shown.
BIN
code/lib64/libharu.lib
Normal file
BIN
code/lib64/libharu.lib
Normal file
Binary file not shown.
BIN
code/lib64/libmysql.lib
Normal file
BIN
code/lib64/libmysql.lib
Normal file
Binary file not shown.
BIN
code/lib64/libpng.lib
Normal file
BIN
code/lib64/libpng.lib
Normal file
Binary file not shown.
BIN
code/lib64/zlibstat.lib
Normal file
BIN
code/lib64/zlibstat.lib
Normal file
Binary file not shown.
BIN
code/lib_db/libmysql.lib
Normal file
BIN
code/lib_db/libmysql.lib
Normal file
Binary file not shown.
@ -35,6 +35,8 @@
|
||||
#include "tabbase.h"
|
||||
#include "CommDlg.h"
|
||||
#include "generalresult.h"
|
||||
#include "gdiconstants.h"
|
||||
#include "autocomplete.h"
|
||||
|
||||
ListEditor::ListEditor(oEvent *oe_) {
|
||||
oe = oe_;
|
||||
@ -46,6 +48,12 @@ ListEditor::ListEditor(oEvent *oe_) {
|
||||
oe->loadGeneralResults(false, true);
|
||||
}
|
||||
|
||||
namespace {
|
||||
const wstring &getSearchString() {
|
||||
return lang.tl(L"Sök (X)#Ctrl+F");
|
||||
}
|
||||
}
|
||||
|
||||
ListEditor::~ListEditor() {
|
||||
setCurrentList(0);
|
||||
}
|
||||
@ -301,7 +309,42 @@ static void getPosFromId(int id, int &groupIx, int &lineIx, int &ix) {
|
||||
|
||||
int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
int lineIx, groupIx, ix;
|
||||
if (type == GUI_BUTTON) {
|
||||
|
||||
if (type == GUI_EVENT) {
|
||||
EventInfo &ev = *(EventInfo *)(&data);
|
||||
if (ev.getKeyCommand() == KC_FIND) {
|
||||
gdi.setInputFocus("SearchText", true);
|
||||
}
|
||||
else if (ev.getKeyCommand() == KC_FINDBACK) {
|
||||
gdi.setInputFocus("SearchText", false);
|
||||
}
|
||||
}
|
||||
else if (type == GUI_FOCUS) {
|
||||
InputInfo &ii = *(InputInfo *)(&data);
|
||||
|
||||
if (ii.text == getSearchString()) {
|
||||
((InputInfo *)gdi.setText("SearchText", L""))->setFgColor(colorDefault);
|
||||
}
|
||||
}
|
||||
else if (type == GUI_INPUTCHANGE) {
|
||||
InputInfo &ii = *(InputInfo *)(&data);
|
||||
bool show = false;
|
||||
if (ii.text.length() > 1) {
|
||||
vector<AutoCompleteRecord> rec;
|
||||
MetaList::getAutoComplete(ii.text, rec);
|
||||
if (!rec.empty()) {
|
||||
auto &ac = gdi.addAutoComplete(ii.id);
|
||||
ac.setAutoCompleteHandler(this);
|
||||
ac.setData(rec);
|
||||
ac.show();
|
||||
show = true;
|
||||
}
|
||||
}
|
||||
if (!show) {
|
||||
gdi.clearAutoComplete(ii.id);
|
||||
}
|
||||
}
|
||||
else if (type == GUI_BUTTON) {
|
||||
ButtonInfo bi = dynamic_cast<ButtonInfo &>(data);
|
||||
ButtonInfo &biSrc = dynamic_cast<ButtonInfo &>(data);
|
||||
|
||||
@ -434,9 +477,14 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
mlp.setText(str);
|
||||
|
||||
gdi.getSelectedItem("AlignType", lbi);
|
||||
mlp.align(EPostType(lbi.data), gdi.isChecked("BlockAlign"));
|
||||
mlp.align(EPostType(lbi.data));
|
||||
|
||||
mlp.limitBlockWidth(gdi.isChecked("LimitBlockWidth"));
|
||||
mlp.alignText(gdi.getText("AlignText"));
|
||||
mlp.mergePrevious(gdi.isChecked("MergeText"));
|
||||
|
||||
auto relPrev = gdi.getSelectedItem("RelPrevious");
|
||||
mlp.packWithPrevious(relPrev.first == 2);
|
||||
mlp.mergePrevious(relPrev.first == 1);
|
||||
|
||||
gdi.getSelectedItem("TextAdjust", lbi);
|
||||
mlp.setTextAdjust(lbi.data);
|
||||
@ -466,15 +514,19 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
mlp.setResultModule("");
|
||||
|
||||
mlp.setBlock(gdi.getTextNo("BlockSize"));
|
||||
mlp.indent(gdi.getTextNo("MinIndeent"));
|
||||
mlp.indent(gdi.getTextNo("MinIndent"));
|
||||
|
||||
gdi.getSelectedItem("Fonts", lbi);
|
||||
mlp.setFont(gdiFonts(lbi.data));
|
||||
makeDirty(gdi, MakeDirty, MakeDirty);
|
||||
|
||||
if (!gdi.hasData("NoRedraw") || force) {
|
||||
gdi.restore("BeginListEdit", false);
|
||||
show(gdi);
|
||||
}
|
||||
|
||||
if (bi.id != "Apply")
|
||||
editListPost(gdi, mlp, bi.getExtraInt());
|
||||
}
|
||||
else if (bi.id == "ApplyListProp") {
|
||||
wstring name = gdi.getText("Name");
|
||||
@ -628,7 +680,6 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
gdi.pushX();
|
||||
vector< pair<wstring, size_t> > lists;
|
||||
oe->getListContainer().getLists(lists, true, false, false);
|
||||
reverse(lists.begin(), lists.end());
|
||||
|
||||
gdi.fillRight();
|
||||
gdi.addSelection("OpenList", 250, 400, editListCB, L"Välj lista:");
|
||||
@ -728,8 +779,10 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
}
|
||||
else if (type == GUI_LISTBOX) {
|
||||
ListBoxInfo &lbi = dynamic_cast<ListBoxInfo &>(data);
|
||||
|
||||
if (lbi.id == "AlignType") {
|
||||
if (lbi.id == "RelPrevious") {
|
||||
updateAlign(gdi, lbi.data);
|
||||
}
|
||||
else if (lbi.id == "AlignType") {
|
||||
gdi.setInputStatus("AlignText", lbi.data == lString);
|
||||
if (lbi.data == lString) {
|
||||
int ix = lbi.text.find_first_of(L":");
|
||||
@ -740,31 +793,7 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
gdi.setText("AlignText", L"");
|
||||
}
|
||||
else if (lbi.id == "Type") {
|
||||
EPostType type = EPostType(lbi.data);
|
||||
gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true);
|
||||
if (type == lResultModuleNumber || type == lResultModuleTime ||
|
||||
type == lResultModuleNumberTeam || type == lResultModuleTimeTeam) {
|
||||
gdi.check("UseLeg", true);
|
||||
gdi.disableInput("UseLeg");
|
||||
|
||||
if (gdi.hasWidget("UseResultModule")) {
|
||||
gdi.check("UseResultModule", true);
|
||||
gdi.disableInput("UseResultModule");
|
||||
}
|
||||
gdi.enableInput("Leg");
|
||||
if (gdi.getText("Leg").empty())
|
||||
gdi.setText("Leg", L"0");
|
||||
}
|
||||
else {
|
||||
gdi.enableInput("UseLeg");
|
||||
if (gdi.getTextNo("Leg") == 0) {
|
||||
gdi.setText("Leg", L"");
|
||||
gdi.enableInput("UseLeg");
|
||||
gdi.enableInput("UseResultModule", true);
|
||||
gdi.check("UseLeg", false);
|
||||
gdi.disableInput("Leg");
|
||||
}
|
||||
}
|
||||
updateType(lbi.data, gdi);
|
||||
}
|
||||
else if (lbi.id == "SubType") {
|
||||
oListInfo::EBaseType subType = oListInfo::EBaseType(lbi.data);
|
||||
@ -797,6 +826,39 @@ int ListEditor::editList(gdioutput &gdi, int type, BaseInfo &data) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ListEditor::updateType(int iType, gdioutput & gdi) {
|
||||
EPostType type = EPostType(iType);
|
||||
gdi.setTextTranslate("TUseLeg", getIndexDescription(type), true);
|
||||
if (type == lResultModuleNumber || type == lResultModuleTime ||
|
||||
type == lResultModuleNumberTeam || type == lResultModuleTimeTeam) {
|
||||
gdi.check("UseLeg", true);
|
||||
gdi.disableInput("UseLeg");
|
||||
|
||||
if (gdi.hasWidget("UseResultModule")) {
|
||||
gdi.check("UseResultModule", true);
|
||||
gdi.disableInput("UseResultModule");
|
||||
}
|
||||
gdi.enableInput("Leg");
|
||||
if (gdi.getText("Leg").empty())
|
||||
gdi.setText("Leg", L"0");
|
||||
}
|
||||
else {
|
||||
gdi.enableInput("UseLeg");
|
||||
if (gdi.getTextNo("Leg") == 0) {
|
||||
gdi.setText("Leg", L"");
|
||||
gdi.enableInput("UseLeg");
|
||||
gdi.enableInput("UseResultModule", true);
|
||||
gdi.check("UseLeg", false);
|
||||
gdi.disableInput("Leg");
|
||||
}
|
||||
}
|
||||
|
||||
gdi.restore("Example", false);
|
||||
int margin = gdi.scaleLength(10);
|
||||
showExample(gdi, margin, type);
|
||||
gdi.refreshFast();
|
||||
}
|
||||
|
||||
void ListEditor::checkUnsaved(gdioutput &gdi) {
|
||||
if (gdi.hasData("IsEditing")) {
|
||||
if (gdi.isInputChanged("")) {
|
||||
@ -812,6 +874,22 @@ void ListEditor::checkUnsaved(gdioutput &gdi) {
|
||||
}
|
||||
}
|
||||
|
||||
void ListEditor::updateAlign(gdioutput &gdi, int val) {
|
||||
gdi.setInputStatus("AlignType", val != 1);
|
||||
gdi.setInputStatus("AlignText", val != 1);
|
||||
|
||||
gdi.setInputStatus("BlockSize", val != 1);
|
||||
gdi.setInputStatus("LimitBlockWidth", val != 1);
|
||||
|
||||
gdi.setInputStatus("TextAdjust", val != 1);
|
||||
gdi.setInputStatus("MinIndent", val != 1);
|
||||
|
||||
gdi.setInputStatus("Color", val != 1);
|
||||
gdi.setInputStatus("Fonts", val != 1);
|
||||
|
||||
|
||||
|
||||
}
|
||||
void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
checkUnsaved(gdi);
|
||||
gdi.restore("EditList", false);
|
||||
@ -832,8 +910,13 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
gdi.addString("", boldLarge, "Listpost").setColor(colorDarkGrey);
|
||||
gdi.setCX(gdi.getCX() + gdi.scaleLength(20));
|
||||
|
||||
gdi.addButton("MoveLeft", "<< Flytta vänster", editListCB);
|
||||
gdi.addButton("MoveRight", "Flytta höger >>", editListCB);
|
||||
gdi.addButton("MoveLeft", "<< Flytta vänster", editListCB).setExtra(id-1);
|
||||
if (ix == 0)
|
||||
gdi.setInputStatus("MoveLeft", false);
|
||||
|
||||
gdi.addButton("MoveRight", "Flytta höger >>", editListCB).setExtra(id+1);
|
||||
if (ix + 1 == currentList->getNumPostsOnLine(groupIx, lineIx))
|
||||
gdi.setInputStatus("MoveRight", false);
|
||||
|
||||
gdi.dropLine(3);
|
||||
gdi.popX();
|
||||
@ -857,34 +940,31 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
|
||||
sort(types.begin(), types.end());
|
||||
gdi.pushX();
|
||||
gdi.fillRight();
|
||||
int boxY = gdi.getCY();
|
||||
gdi.addSelection("Type", 290, 500, editListCB, L"Typ:");
|
||||
gdi.fillRight();
|
||||
gdi.addString("", 0, L"Typ:");
|
||||
gdi.fillDown();
|
||||
gdi.registerEvent("SearchRunner", editListCB).setKeyCommand(KC_FIND);
|
||||
gdi.registerEvent("SearchRunnerBack", editListCB).setKeyCommand(KC_FINDBACK);
|
||||
|
||||
gdi.addInput("SearchText", getSearchString(), 26, editListCB, L"",
|
||||
L"Sök symbol.").isEdit(false)
|
||||
.setBgColor(colorLightCyan).ignore(true);
|
||||
|
||||
gdi.dropLine(-0.1);
|
||||
gdi.popX();
|
||||
gdi.fillRight();
|
||||
gdi.addSelection("Type", 290, 500, editListCB);
|
||||
gdi.dropLine(-1);
|
||||
gdi.addItem("Type", types);
|
||||
gdi.selectItemByData("Type", currentType);
|
||||
gdi.addInput("Text", mlp.getText(), 16, 0, L"Egen text:", L"Använd symbolen X där MeOS ska fylla i typens data.");
|
||||
gdi.setInputFocus("Text", true);
|
||||
((InputInfo *)gdi.setText("SearchText", getSearchString()))->setFgColor(colorGreyBlue);
|
||||
int boxX = gdi.getCX();
|
||||
gdi.popX();
|
||||
gdi.fillRight();
|
||||
gdi.dropLine(3);
|
||||
currentList->getAlignTypes(mlp, types, currentType);
|
||||
sort(types.begin(), types.end());
|
||||
gdi.addSelection("AlignType", 290, 500, editListCB, L"Justera mot:");
|
||||
gdi.addItem("AlignType", types);
|
||||
gdi.selectItemByData("AlignType", currentType);
|
||||
|
||||
gdi.addInput("AlignText", mlp.getAlignText(), 16, 0, L"Text:");
|
||||
if (currentType != lString)
|
||||
gdi.disableInput("AlignText");
|
||||
gdi.popX();
|
||||
gdi.dropLine(3);
|
||||
gdi.fillRight();
|
||||
gdi.addCheckbox("BlockAlign", "Justera blockvis:", 0, mlp.getAlignBlock());
|
||||
gdi.dropLine(-0.2);
|
||||
gdi.addInput("BlockSize", itow(mlp.getBlockWidth()), 5, 0, L"", L"Blockbredd");
|
||||
gdi.dropLine(2.1);
|
||||
gdi.popX();
|
||||
gdi.fillRight();
|
||||
|
||||
if (hasResultModule) {
|
||||
gdi.addCheckbox("UseResultModule", "Data from result module (X)#" + currentList->getResultModule(), 0, !mlp.getResultModule().empty());
|
||||
@ -897,11 +977,14 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
gdi.dropLine(-0.2);
|
||||
gdi.setCX(gdi.getCX() + gdi.getLineHeight() * 5);
|
||||
if (storedType == lResultModuleNumber || storedType == lResultModuleTime || storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam)
|
||||
gdi.addInput("Leg", leg>=0 ? itow(leg) : L"0", 4);
|
||||
gdi.addInput("Leg", leg >= 0 ? itow(leg) : L"0", 4);
|
||||
else
|
||||
gdi.addInput("Leg", leg>=0 ? itow(leg + 1) : L"", 4);
|
||||
gdi.addInput("Leg", leg >= 0 ? itow(leg + 1) : L"", 4);
|
||||
|
||||
if (storedType == lResultModuleNumber || storedType == lResultModuleTime || storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam) {
|
||||
gdi.enableInput("Leg", leg != -1);
|
||||
|
||||
if (storedType == lResultModuleNumber || storedType == lResultModuleTime ||
|
||||
storedType == lResultModuleTimeTeam || storedType == lResultModuleNumberTeam) {
|
||||
gdi.check("UseLeg", true);
|
||||
gdi.disableInput("UseLeg");
|
||||
if (gdi.hasWidget("UseResultModule")) {
|
||||
@ -910,12 +993,33 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
}
|
||||
}
|
||||
|
||||
gdi.dropLine(2);
|
||||
if (ix>0) {
|
||||
gdi.popX();
|
||||
gdi.addCheckbox("MergeText", "Slå ihop text med föregående", 0, mlp.isMergePrevious());
|
||||
gdi.dropLine(2.5);
|
||||
currentList->getAlignTypes(mlp, types, currentType);
|
||||
sort(types.begin(), types.end());
|
||||
gdi.addSelection("AlignType", 290, 500, editListCB, L"Justera mot:");
|
||||
gdi.addItem("AlignType", types);
|
||||
gdi.selectItemByData("AlignType", currentType);
|
||||
|
||||
gdi.addInput("AlignText", mlp.getAlignText(), 16, 0, L"Text:");
|
||||
if (currentType != lString)
|
||||
gdi.disableInput("AlignText");
|
||||
gdi.popX();
|
||||
gdi.dropLine(3);
|
||||
gdi.fillRight();
|
||||
gdi.addString("", 0, "Minsta blockbredd:");
|
||||
gdi.dropLine(-0.2);
|
||||
gdi.addInput("BlockSize", itow(mlp.getBlockWidth()), 5, 0, L"", L"Blockbredd");
|
||||
gdi.dropLine(0.2);
|
||||
gdi.addCheckbox("LimitBlockWidth", "Begränsa bredd (klipp text)", 0, mlp.getLimitBlockWidth());
|
||||
gdi.dropLine(1.9);
|
||||
gdi.popX();
|
||||
gdi.fillRight();
|
||||
|
||||
|
||||
|
||||
gdi.dropLine(2);
|
||||
}
|
||||
|
||||
int maxY = gdi.getCY();
|
||||
gdi.popX();
|
||||
gdi.fillDown();
|
||||
@ -925,13 +1029,28 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
gdi.addString("", 1, "Formateringsregler");
|
||||
gdi.dropLine(0.5);
|
||||
gdi.fillRight();
|
||||
gdi.addInput("MinIndeent", itow(mlp.getMinimalIndent()), 7, 0, L"Minsta intabbning:");
|
||||
int val = 0;
|
||||
if (ix>0) {
|
||||
gdi.popX();
|
||||
gdi.addSelection("RelPrevious", 100, 100, editListCB, L"Relation till föregående:");
|
||||
gdi.addItem("RelPrevious", lang.tl("Ingen"), 0);
|
||||
gdi.addItem("RelPrevious", lang.tl("Slå ihop text"), 1);
|
||||
gdi.addItem("RelPrevious", lang.tl("Håll ihop med"), 2);
|
||||
gdi.autoGrow("RelPrevious");
|
||||
|
||||
val = mlp.isMergePrevious() ? 1 : (mlp.getPackWithPrevious() ? 2 : 0);
|
||||
gdi.selectItemByData("RelPrevious", val);
|
||||
}
|
||||
|
||||
|
||||
gdi.addInput("MinIndent", itow(mlp.getMinimalIndent()), 7, 0, L"Justering i sidled:");
|
||||
gdi.popX();
|
||||
gdi.dropLine(3);
|
||||
vector< pair<wstring, size_t> > fonts;
|
||||
int currentFont;
|
||||
mlp.getFonts(fonts, currentFont);
|
||||
|
||||
gdi.addSelection("Fonts", 150, 500, 0, L"Format:");
|
||||
gdi.addSelection("Fonts", 200, 500, 0, L"Format:");
|
||||
gdi.addItem("Fonts", fonts);
|
||||
gdi.selectItemByData("Fonts", currentFont);
|
||||
int maxX = gdi.getCX();
|
||||
@ -939,7 +1058,7 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
gdi.popX();
|
||||
gdi.dropLine(3);
|
||||
|
||||
gdi.addSelection("TextAdjust", 150, 100, 0, L"Textjustering:");
|
||||
gdi.addSelection("TextAdjust", 130, 100, 0, L"Textjustering:");
|
||||
gdi.addItem("TextAdjust", lang.tl("Vänster"), 0);
|
||||
gdi.addItem("TextAdjust", lang.tl("Höger"), textRight);
|
||||
gdi.addItem("TextAdjust", lang.tl("Centrera"), textCenter);
|
||||
@ -966,22 +1085,66 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
|
||||
maxY = max(maxY, gdi.getCY());
|
||||
maxX = max(gdi.getCX(), maxX);
|
||||
|
||||
gdi.fillDown();
|
||||
gdi.popX();
|
||||
gdi.setData("IsEditing", 1);
|
||||
|
||||
RECT rc;
|
||||
rc.top = y1;
|
||||
rc.left = x1;
|
||||
rc.right = maxX + gdi.scaleLength(6);
|
||||
rc.bottom = maxY + gdi.scaleLength(6);
|
||||
rc.bottom = maxY + gdi.scaleLength(6) + gdi.getLineHeight()*4;
|
||||
|
||||
gdi.addRectangle(rc, colorLightBlue, true);
|
||||
gdi.setData("IsEditing", 1);
|
||||
gdi.setCX(x1);
|
||||
gdi.setCY(maxY);
|
||||
|
||||
showExample(gdi, margin, mlp);
|
||||
|
||||
updateAlign(gdi, val);
|
||||
gdi.scrollToBottom();
|
||||
gdi.refresh();
|
||||
}
|
||||
|
||||
void ListEditor::showExample(gdioutput &gdi, int margin, const MetaListPost &mlp) {
|
||||
int x1 = gdi.getCX();
|
||||
|
||||
RECT rrInner;
|
||||
rrInner.left = x1 + margin;
|
||||
rrInner.top = gdi.getCY();
|
||||
|
||||
gdi.setRestorePoint("Example");
|
||||
gdi.fillDown();
|
||||
gdi.setCX(x1 + margin * 2);
|
||||
gdi.dropLine(0.5);
|
||||
gdi.addString("", 0, "Exempel:");
|
||||
gdi.fillRight();
|
||||
int maxX = gdi.getWidth();
|
||||
gdi.dropLine(0.5);
|
||||
|
||||
vector<pRunner> rr;
|
||||
oe->getRunners(0, 0, rr, false);
|
||||
set<wstring> used;
|
||||
for (size_t i = 0; i < rr.size(); i++) {
|
||||
int ix = (997 * i) % rr.size();
|
||||
wstring s = oe->formatListString(mlp.getTypeRaw(), rr[i]);
|
||||
if (used.insert(s).second) {
|
||||
int xb = gdi.getCX();
|
||||
gdi.addStringUT(italicText, s + L" ");
|
||||
int xa = gdi.getCX();
|
||||
int delta = xa - xb;
|
||||
|
||||
int dist = maxX - xa;
|
||||
if (dist < delta * 3 || used.size() == 5)
|
||||
break; // Enough examples
|
||||
}
|
||||
}
|
||||
gdi.dropLine(1.5);
|
||||
rrInner.right = max(gdi.getCX(), gdi.scaleLength(120)) + margin;
|
||||
rrInner.bottom = gdi.getCY();
|
||||
gdi.fillDown();
|
||||
gdi.popX();
|
||||
|
||||
gdi.addRectangle(rrInner, colorLightGreen, true);
|
||||
}
|
||||
|
||||
const wchar_t *ListEditor::getIndexDescription(EPostType type) {
|
||||
if (type == lResultModuleTime || type == lResultModuleTimeTeam)
|
||||
return L"Index in X[index]#OutputTimes";
|
||||
@ -1230,3 +1393,10 @@ void ListEditor::enableOpen(gdioutput &gdi) {
|
||||
gdi.setInputStatus("DoOpen", enabled);
|
||||
}
|
||||
|
||||
void ListEditor::handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) {
|
||||
gdi.selectItemByData("Type", info.getCurrentInt());
|
||||
updateType(info.getCurrentInt(), gdi);
|
||||
gdi.clearAutoComplete("");
|
||||
gdi.setText("SearchText", getSearchString());
|
||||
gdi.TabFocus(1);
|
||||
}
|
||||
|
||||
@ -33,8 +33,9 @@ enum EPostType;
|
||||
class TabBase;
|
||||
|
||||
#include <vector>
|
||||
#include "autocompletehandler.h"
|
||||
|
||||
class ListEditor {
|
||||
class ListEditor : public AutoCompleteHandler {
|
||||
private:
|
||||
enum SaveType {NotSaved, SavedInside, SavedFile};
|
||||
oEvent *oe;
|
||||
@ -49,10 +50,14 @@ private:
|
||||
|
||||
void showLine(gdioutput &gdi, const vector<MetaListPost> &line, int ix) const;
|
||||
int editList(gdioutput &gdi, int type, BaseInfo &data);
|
||||
void updateType(int iType, gdioutput &gdi);
|
||||
|
||||
ButtonInfo &addButton(gdioutput &gdi, const MetaListPost &mlp, int x, int y,
|
||||
int lineIx, int ix) const;
|
||||
|
||||
void editListPost(gdioutput &gdi, const MetaListPost &mlp, int id);
|
||||
void showExample(gdioutput &gdi, int margin, const MetaListPost &mlp);
|
||||
|
||||
void editListProp(gdioutput &gdi, bool newList);
|
||||
|
||||
enum DirtyFlag {MakeDirty, ClearDirty, NoTouch};
|
||||
@ -68,6 +73,8 @@ private:
|
||||
|
||||
void makeDirty(gdioutput &gdi, DirtyFlag inside, DirtyFlag outside);
|
||||
|
||||
void updateAlign(gdioutput &gdi, int val);
|
||||
|
||||
TabBase *origin = nullptr;
|
||||
void show(gdioutput &gdi);
|
||||
|
||||
@ -75,16 +82,11 @@ public:
|
||||
ListEditor(oEvent *oe);
|
||||
virtual ~ListEditor();
|
||||
|
||||
//void load(MetaList *list);
|
||||
void load(const MetaListContainer &mlc, int index);
|
||||
|
||||
void show(TabBase *dst, gdioutput &gdi);
|
||||
|
||||
bool isShown(TabBase *tab) const { return origin == tab; }
|
||||
|
||||
MetaList *getCurrentList() const {return currentList;};
|
||||
|
||||
void handleAutoComplete(gdioutput &gdi, AutoCompleteInfo &info) final;
|
||||
|
||||
friend int editListCB(gdioutput*, int, void *);
|
||||
|
||||
};
|
||||
|
||||
@ -303,6 +303,7 @@ int APIENTRY WinMain(HINSTANCE hInstance,
|
||||
getUserFile(oldSettings, L"meospref.xml");
|
||||
gEvent->loadProperties(oldSettings);
|
||||
}
|
||||
gEvent->clear();
|
||||
|
||||
lang.get().addLangResource(L"English", L"104");
|
||||
lang.get().addLangResource(L"Svenska", L"103");
|
||||
@ -922,7 +923,7 @@ gdioutput *createExtraWindow(const string &tag, const wstring &title, int max_x,
|
||||
else {
|
||||
gdi->initRecorder(&gdi_main->getRecorder());
|
||||
}
|
||||
SetWindowLong(hWnd, GWL_USERDATA, gdi_extra.size());
|
||||
SetWindowLongPtr(hWnd, GWLP_USERDATA, gdi_extra.size());
|
||||
currentFocusIx = gdi_extra.size();
|
||||
gdi_extra.push_back(gdi);
|
||||
|
||||
@ -1413,9 +1414,9 @@ LRESULT CALLBACK WorkSpaceWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc;
|
||||
|
||||
LONG ix = GetWindowLong(hWnd, GWL_USERDATA);
|
||||
LONG_PTR ix = GetWindowLongPtr(hWnd, GWLP_USERDATA);
|
||||
gdioutput *gdi = 0;
|
||||
if (ix < LONG(gdi_extra.size()))
|
||||
if (ix < LONG_PTR(gdi_extra.size()))
|
||||
gdi = gdi_extra[ix];
|
||||
|
||||
if (gdi) {
|
||||
|
||||
10
code/meos.h
10
code/meos.h
@ -1,11 +1,3 @@
|
||||
#if !defined(AFX_MEOS_H__7F8E5F23_ADD4_45AB_9626_7378FEA38D49__INCLUDED_)
|
||||
#define AFX_MEOS_H__7F8E5F23_ADD4_45AB_9626_7378FEA38D49__INCLUDED_
|
||||
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
#pragma once
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
#endif // !defined(AFX_MEOS_H__7F8E5F23_ADD4_45AB_9626_7378FEA38D49__INCLUDED_)
|
||||
|
||||
@ -745,19 +745,26 @@ const wstring &itow(int i) {
|
||||
return res;
|
||||
}
|
||||
|
||||
wstring itow(unsigned int i) {
|
||||
wchar_t bf[32];
|
||||
_ultow_s(i, bf, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
wstring itow(unsigned long i) {
|
||||
wchar_t bf[32];
|
||||
_ultow_s(i, bf, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
wstring itow(__int64 i) {
|
||||
|
||||
wstring itow(unsigned int i) {
|
||||
wchar_t bf[32];
|
||||
_ultow_s(i, bf, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
wstring itow(int64_t i) {
|
||||
wchar_t bf[32];
|
||||
_i64tow_s(i, bf, 32, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
wstring itow(uint64_t i) {
|
||||
wchar_t bf[32];
|
||||
_i64tow_s(i, bf, 32, 10);
|
||||
return bf;
|
||||
@ -786,13 +793,21 @@ string itos(unsigned long i)
|
||||
return bf;
|
||||
}
|
||||
|
||||
string itos(__int64 i)
|
||||
string itos(int64_t i)
|
||||
{
|
||||
char bf[32];
|
||||
_i64toa_s(i, bf, 32, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
string itos(uint64_t i)
|
||||
{
|
||||
char bf[32];
|
||||
_ui64toa_s(i, bf, 32, 10);
|
||||
return bf;
|
||||
}
|
||||
|
||||
|
||||
bool filterMatchString(const string &c, const char *filt_lc)
|
||||
{
|
||||
if (filt_lc[0] == 0)
|
||||
@ -1818,6 +1833,60 @@ wstring makeValidFileName(const wstring &input, bool strict) {
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
string makeValidFileName(const string& input, bool strict) {
|
||||
string out;
|
||||
out.reserve(input.size());
|
||||
|
||||
if (strict) {
|
||||
for (size_t k = 0; k < input.length(); k++) {
|
||||
char b = input[k];
|
||||
if ((b >= '0' && b <= '9') || (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') || b == '_' || b == '.')
|
||||
out.push_back(b);
|
||||
else if (b == ' ' || b == ',')
|
||||
out.push_back('_');
|
||||
else {
|
||||
b = toLowerStripped(b);
|
||||
|
||||
if (b >= 'a' && b <= 'z')
|
||||
b = b;
|
||||
else if (b == 'ö')
|
||||
b = 'o';
|
||||
else if (b == 'ä' || b == 'å' || b == 'à' || b == 'á' || b == 'â' || b == 'ã' || b == 'æ')
|
||||
b = 'a';
|
||||
else if (b == 'ç')
|
||||
b = 'c';
|
||||
else if (b == 'è' || b == 'é' || b == 'ê' || b == 'ë')
|
||||
b = 'e';
|
||||
else if (b == 'ð')
|
||||
b = 't';
|
||||
else if (b == 'ï' || b == 'ì' || b == 'ï' || b == 'î' || b == 'í')
|
||||
b = 'i';
|
||||
else if (b == 'ò' || b == 'ó' || b == 'ô' || b == 'õ' || b == 'ø')
|
||||
b = 'o';
|
||||
else if (b == 'ù' || b == 'ú' || b == 'û' || b == 'ü')
|
||||
b = 'u';
|
||||
else if (b == 'ý')
|
||||
b = 'y';
|
||||
else
|
||||
b = '-';
|
||||
|
||||
out.push_back(b);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (size_t k = 0; k < input.length(); k++) {
|
||||
char b = input[k];
|
||||
if (b < 32 || b == '*' || b == '?' || b == ':' || b == '/' || b == '\\')
|
||||
b = '_';
|
||||
out.push_back(b);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
void capitalize(wstring &str) {
|
||||
if (str.length() > 0) {
|
||||
auto bf = str.c_str();
|
||||
|
||||
@ -40,14 +40,14 @@ public:
|
||||
std::string &get() {
|
||||
if ( (++ix) >= cache.size() )
|
||||
ix = 0;
|
||||
int lx = ix;
|
||||
size_t lx = ix;
|
||||
return cache[lx];
|
||||
}
|
||||
|
||||
std::wstring &wget() {
|
||||
if ( (++wix) >= wcache.size() )
|
||||
wix = 0;
|
||||
int lx = wix;
|
||||
size_t lx = wix;
|
||||
return wcache[lx];
|
||||
}
|
||||
};
|
||||
@ -127,14 +127,16 @@ const wstring &makeDash(const wchar_t *t);
|
||||
|
||||
wstring formatRank(int rank);
|
||||
const string &itos(int i);
|
||||
string itos(unsigned long i);
|
||||
string itos(unsigned int i);
|
||||
string itos(__int64 i);
|
||||
string itos(unsigned long i);
|
||||
string itos(int64_t i);
|
||||
string itos(uint64_t i);
|
||||
|
||||
const wstring &itow(int i);
|
||||
wstring itow(unsigned long i);
|
||||
wstring itow(unsigned int i);
|
||||
wstring itow(__int64 i);
|
||||
wstring itow(unsigned long i);
|
||||
wstring itow(int64_t i);
|
||||
wstring itow(uint64_t i);
|
||||
|
||||
|
||||
///Lower case match (filt_lc must be lc)
|
||||
@ -237,6 +239,7 @@ PersonSex interpretSex(const wstring &sex);
|
||||
wstring encodeSex(PersonSex sex);
|
||||
|
||||
wstring makeValidFileName(const wstring &input, bool strict);
|
||||
string makeValidFileName(const string& input, bool strict);
|
||||
|
||||
/** Initial capital letter. */
|
||||
void capitalize(wstring &str);
|
||||
|
||||
@ -3,19 +3,28 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 14
|
||||
VisualStudioVersion = 14.0.25420.1
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "meos", "meosvc15.vcxproj", "{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}"
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "meosvc15", "meosvc15.vcxproj", "{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
Debug|x86 = Debug|x86
|
||||
Release|x64 = Release|x64
|
||||
Release|x86 = Release|x86
|
||||
test|x64 = test|x64
|
||||
test|x86 = test|x86
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Debug|x64.Build.0 = Debug|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Debug|x86.Build.0 = Debug|Win32
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Release|x64.ActiveCfg = Release|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Release|x64.Build.0 = Release|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Release|x86.ActiveCfg = Release|Win32
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.Release|x86.Build.0 = Release|Win32
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.test|x64.ActiveCfg = test|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.test|x64.Build.0 = test|x64
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.test|x86.ActiveCfg = test|Win32
|
||||
{B854EF2A-2BB7-4D62-B08B-96BD64B347E8}.test|x86.Build.0 = test|Win32
|
||||
EndGlobalSection
|
||||
|
||||
@ -1,248 +0,0 @@
|
||||
/************************************************************************
|
||||
MeOS - Orienteering Software
|
||||
Copyright (C) 2009-2020 Melin Software HB
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Melin Software HB - software@melin.nu - www.melin.nu
|
||||
Eksoppsvägen 16, SE-75646 UPPSALA, Sweden
|
||||
|
||||
************************************************************************/
|
||||
|
||||
|
||||
// meosdb.cpp : Defines the exported functions for the DLL application.
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef c
|
||||
#include "meosdb.h"
|
||||
#else
|
||||
#define MEOSDB_API
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <fstream>
|
||||
|
||||
#include "MeosSQL.h"
|
||||
#include "../meos_util.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "../oRunner.h"
|
||||
#include "../oEvent.h"
|
||||
#include "../Localizer.h"
|
||||
|
||||
#ifdef BUILD_DB_DLL
|
||||
HINSTANCE hInst=0;
|
||||
Localizer lang;
|
||||
#endif
|
||||
|
||||
|
||||
int MEOSDB_API getMeosVersion()
|
||||
{
|
||||
return getMeosBuild();
|
||||
}
|
||||
|
||||
MeosSQL msql;
|
||||
static int nSynchList = 0;
|
||||
static int nSynchEnt = 0;
|
||||
|
||||
int getListMask(oEvent &oe) {
|
||||
return msql.getModifiedMask(oe);
|
||||
}
|
||||
|
||||
void resetSynchTimes() {
|
||||
msql.clearReadTimes();
|
||||
}
|
||||
|
||||
bool MEOSDB_API msSynchronizeList(oEvent *oe, oListId lid)
|
||||
{
|
||||
nSynchList++;
|
||||
if (nSynchList % 100 == 99)
|
||||
OutputDebugString(L"Synchronized 100 lists\n");
|
||||
bool ret = false;
|
||||
switch (lid) {
|
||||
case oListId::oLRunnerId:
|
||||
ret = msql.syncListRunner(oe);
|
||||
break;
|
||||
case oListId::oLClassId:
|
||||
ret = msql.syncListClass(oe);
|
||||
break;
|
||||
case oListId::oLCourseId:
|
||||
ret = msql.syncListCourse(oe);
|
||||
break;
|
||||
case oListId::oLControlId:
|
||||
ret = msql.syncListControl(oe);
|
||||
break;
|
||||
case oListId::oLClubId:
|
||||
ret = msql.syncListClub(oe);
|
||||
break;
|
||||
case oListId::oLCardId:
|
||||
ret = msql.syncListCard(oe);
|
||||
break;
|
||||
case oListId::oLPunchId:
|
||||
ret = msql.syncListPunch(oe);
|
||||
break;
|
||||
case oListId::oLTeamId:
|
||||
ret = msql.syncListTeam(oe);
|
||||
break;
|
||||
}
|
||||
|
||||
msql.processMissingObjects();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int MEOSDB_API msSynchronizeUpdate(oBase *obj)
|
||||
{
|
||||
if (typeid(*obj)==typeid(oRunner)){
|
||||
return msql.syncUpdate((oRunner *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oClass)){
|
||||
return msql.syncUpdate((oClass *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oCourse)){
|
||||
return msql.syncUpdate((oCourse *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oControl)){
|
||||
return msql.syncUpdate((oControl *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oClub)){
|
||||
return msql.syncUpdate((oClub *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oCard)){
|
||||
return msql.syncUpdate((oCard *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oFreePunch)){
|
||||
return msql.syncUpdate((oFreePunch *) obj, false);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oEvent)){
|
||||
|
||||
return msql.SyncUpdate((oEvent *) obj);
|
||||
}
|
||||
else if (typeid(*obj)==typeid(oTeam)){
|
||||
return msql.syncUpdate((oTeam *) obj, false);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int MEOSDB_API msSynchronizeRead(oBase *obj)
|
||||
{
|
||||
nSynchEnt++;
|
||||
if (nSynchEnt % 100 == 99)
|
||||
OutputDebugString(L"Synchronized 100 entities\n");
|
||||
|
||||
return msql.syncRead(false, obj);
|
||||
}
|
||||
|
||||
// Removes (marks it as removed) an entry from the database.
|
||||
int MEOSDB_API msRemove(oBase *obj)
|
||||
{
|
||||
return msql.Remove(obj);
|
||||
}
|
||||
|
||||
// Checks the database connection, lists other connected components
|
||||
// and register ourself in the database. The value oe=0 unregister us.
|
||||
int MEOSDB_API msMonitor(oEvent *oe)
|
||||
{
|
||||
return msql.checkConnection(oe);
|
||||
}
|
||||
|
||||
// Tries to open the database defined by oe.
|
||||
int MEOSDB_API msUploadRunnerDB(oEvent *oe)
|
||||
{
|
||||
return msql.uploadRunnerDB(oe);
|
||||
}
|
||||
|
||||
// Tries to open the database defined by oe.
|
||||
int MEOSDB_API msOpenDatabase(oEvent *oe)
|
||||
{
|
||||
return msql.openDB(oe);
|
||||
}
|
||||
|
||||
// Tries to remove the database defined by oe.
|
||||
int MEOSDB_API msDropDatabase(oEvent *oe)
|
||||
{
|
||||
return msql.dropDatabase(oe);
|
||||
}
|
||||
|
||||
// Tries to connect to the server defined by oe.
|
||||
int MEOSDB_API msConnectToServer(oEvent *oe)
|
||||
{
|
||||
return msql.listCompetitions(oe, false);
|
||||
}
|
||||
|
||||
// Reloads competitions. Assumes a connection.
|
||||
int MEOSDB_API msListCompetitions(oEvent *oe)
|
||||
{
|
||||
return msql.listCompetitions(oe, true);
|
||||
}
|
||||
|
||||
// Fills string msgBuff with the current error stage
|
||||
bool MEOSDB_API msGetErrorState(char *msgBuff)
|
||||
{
|
||||
return msql.getErrorMessage(msgBuff);
|
||||
}
|
||||
|
||||
// Close database connection.
|
||||
bool MEOSDB_API msResetConnection()
|
||||
{
|
||||
return msql.closeDB();
|
||||
}
|
||||
|
||||
// Try to reconnect to the database. Returns true if successful.
|
||||
bool MEOSDB_API msReConnect()
|
||||
{
|
||||
return msql.reConnect();
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool repairTables(const string &db, vector<string> &output) {
|
||||
return msql.repairTables(db, output);
|
||||
}
|
||||
|
||||
|
||||
#ifdef BUILD_DB_DLL
|
||||
|
||||
bool getUserFile(char *file, const char *in)
|
||||
{
|
||||
throw 0;
|
||||
strcpy_s(file, 256, in);
|
||||
return true;
|
||||
}
|
||||
|
||||
string MakeDash(string)
|
||||
{
|
||||
throw 0;
|
||||
return "";
|
||||
}
|
||||
|
||||
bool __cdecl GetRandomBit()
|
||||
{
|
||||
throw 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int __cdecl GetRandomNumber(int)
|
||||
{
|
||||
throw 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,391 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="9,00"
|
||||
Name="meosdb"
|
||||
ProjectGUID="{13A51976-5F88-471F-A1E9-259102710806}"
|
||||
RootNamespace="meosdb"
|
||||
Keyword="Win32Proj"
|
||||
TargetFrameworkVersion="196613"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="0"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""mysql++";"mysql50""
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MEOSDB_EXPORTS;MEOSDB"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="mysqlpp.lib Msimg32.lib comctl32.lib winmm.lib"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="..\lib_db"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="$(SolutionDir)$(ConfigurationName)"
|
||||
IntermediateDirectory="$(ConfigurationName)"
|
||||
ConfigurationType="2"
|
||||
CharacterSet="2"
|
||||
WholeProgramOptimization="1"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="2"
|
||||
InlineFunctionExpansion="2"
|
||||
EnableIntrinsicFunctions="true"
|
||||
FavorSizeOrSpeed="1"
|
||||
AdditionalIncludeDirectories=""mysql++";"mysql50""
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MEOSDB_EXPORTS;MEOSDB"
|
||||
RuntimeLibrary="2"
|
||||
EnableFunctionLevelLinking="true"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
DebugInformationFormat="0"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="Msimg32.lib comctl32.lib mysqlpp.lib winmm.lib"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories="..\lib"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="2"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath="..\csvparser.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\dllmain.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="0"
|
||||
CompileAsManaged="0"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\gdioutput.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\intkeymapimpl.hpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\localizer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meos_util.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meosdb.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MeosSQL.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\meosversion.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\metalist.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\mysqldaemon.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oBase.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oCard.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oClass.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oClub.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oControl.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oCourse.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oDataContainer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oEvent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oEventSpeaker.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oEventSQL.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oFreeImport.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oFreePunch.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oPunch.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oRunner.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oTeam.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\oTeamEvent.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\printer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\progress.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\RunnerDB.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TabAuto.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\Table.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\TimeStamp.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\xmlparser.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\meosdb.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MeosSQL.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\targetver.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@ -1,158 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{13A51976-5F88-471F-A1E9-259102710806}</ProjectGuid>
|
||||
<RootNamespace>meosdb</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>NotSet</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)$(Configuration)\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Configuration)\</IntDir>
|
||||
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
|
||||
<CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
|
||||
<CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
<CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>mysql++\;C:\Program Files\MySQL\MySQL Server 5.5\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;MEOSDB_EXPORTS;MEOSDB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>mysqlpp.lib;Msimg32.lib;comctl32.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\lib_db;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>F:\Dev\meos\code\meosdb\mysql++;F:\Dev\meos\code\meosdb\mysql50;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;MEOSDB_EXPORTS;MEOSDB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>
|
||||
</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>Msimg32.lib;comctl32.lib;mysqlpp.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalLibraryDirectories>..\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\csvparser.cpp" />
|
||||
<ClCompile Include="..\metalist.cpp" />
|
||||
<ClCompile Include="..\Table.cpp" />
|
||||
<ClCompile Include="dllmain.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</CompileAsManaged>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
</PrecompiledHeader>
|
||||
<CompileAsManaged Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</CompileAsManaged>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\gdioutput.cpp" />
|
||||
<ClCompile Include="..\localizer.cpp" />
|
||||
<ClCompile Include="..\meos_util.cpp" />
|
||||
<ClCompile Include="meosdb.cpp" />
|
||||
<ClCompile Include="MeosSQL.cpp" />
|
||||
<ClCompile Include="..\meosversion.cpp" />
|
||||
<ClCompile Include="..\mysqldaemon.cpp" />
|
||||
<ClCompile Include="..\oBase.cpp" />
|
||||
<ClCompile Include="..\oCard.cpp" />
|
||||
<ClCompile Include="..\oClass.cpp" />
|
||||
<ClCompile Include="..\oClub.cpp" />
|
||||
<ClCompile Include="..\oControl.cpp" />
|
||||
<ClCompile Include="..\oCourse.cpp" />
|
||||
<ClCompile Include="..\oDataContainer.cpp" />
|
||||
<ClCompile Include="..\oEvent.cpp" />
|
||||
<ClCompile Include="..\oEventSpeaker.cpp" />
|
||||
<ClCompile Include="..\oEventSQL.cpp" />
|
||||
<ClCompile Include="..\oFreeImport.cpp" />
|
||||
<ClCompile Include="..\oFreePunch.cpp" />
|
||||
<ClCompile Include="..\oPunch.cpp" />
|
||||
<ClCompile Include="..\oRunner.cpp" />
|
||||
<ClCompile Include="..\oTeam.cpp" />
|
||||
<ClCompile Include="..\oTeamEvent.cpp" />
|
||||
<ClCompile Include="..\printer.cpp" />
|
||||
<ClCompile Include="..\progress.cpp" />
|
||||
<ClCompile Include="..\RunnerDB.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\TabAuto.cpp" />
|
||||
<ClCompile Include="..\TimeStamp.cpp" />
|
||||
<ClCompile Include="..\xmlparser.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\intkeymapimpl.hpp" />
|
||||
<ClInclude Include="meosdb.h" />
|
||||
<ClInclude Include="MeosSQL.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,57 +0,0 @@
|
||||
/// \file autoflag.h
|
||||
/// \brief Defines a template for setting a flag within a given variable
|
||||
/// scope, and resetting it when exiting that scope.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 2007 by Educational Technology Resources, Inc. Others
|
||||
may also hold copyrights on code in this file. See the CREDITS file in
|
||||
the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#if !defined(MYSQLPP_AUTOFLAG_H)
|
||||
#define MYSQLPP_AUTOFLAG_H
|
||||
|
||||
/// \brief A template for setting a flag on a variable as long as the
|
||||
/// object that set it is in scope. Flag resets when object goes
|
||||
/// out of scope. Works on anything that looks like bool.
|
||||
|
||||
template <class T = bool>
|
||||
class AutoFlag
|
||||
{
|
||||
public:
|
||||
/// \brief Constructor: sets ref to true.
|
||||
AutoFlag(T& ref) :
|
||||
referent_(ref)
|
||||
{
|
||||
referent_ = true;
|
||||
}
|
||||
|
||||
/// \brief Destructor: sets referent passed to ctor to false.
|
||||
~AutoFlag()
|
||||
{
|
||||
referent_ = false;
|
||||
}
|
||||
|
||||
private:
|
||||
T& referent_;
|
||||
};
|
||||
|
||||
#endif // !defined(MYSQLPP_AUTOFLAG_H)
|
||||
|
||||
@ -1,37 +0,0 @@
|
||||
/***********************************************************************
|
||||
coldata.cpp - Implements the ColData_Tmpl template.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "coldata.h"
|
||||
#include "const_string.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
template class ColData_Tmpl<std::string>;
|
||||
template class ColData_Tmpl<const_string>;
|
||||
|
||||
} // end namespace mysqlpp
|
||||
@ -1,386 +0,0 @@
|
||||
/// \file coldata.h
|
||||
/// \brief Declares classes for converting string data to any of
|
||||
/// the basic C types.
|
||||
///
|
||||
/// Roughly speaking, this defines classes that are the inverse of
|
||||
/// mysqlpp::SQLString.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_COLDATA_H
|
||||
#define MYSQLPP_COLDATA_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "const_string.h"
|
||||
#include "convert.h"
|
||||
#include "exceptions.h"
|
||||
#include "null.h"
|
||||
#include "string_util.h"
|
||||
#include "type_info.h"
|
||||
|
||||
#include <typeinfo>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Template for string data that can convert itself to any
|
||||
/// standard C data type.
|
||||
///
|
||||
/// Do not use this class directly. Use the typedef ColData or
|
||||
/// MutableColData instead. ColData is a \c ColData_Tmpl<const
|
||||
/// \c std::string> and MutableColData is a
|
||||
/// \c ColData_Tmpl<std::string>.
|
||||
///
|
||||
/// The ColData types add to the C++ string type the ability to
|
||||
/// automatically convert the string data to any of the basic C types.
|
||||
/// This is important with SQL, because all data coming from the
|
||||
/// database is in string form. MySQL++ uses this class internally
|
||||
/// to hold the data it receives from the server, so you can use it
|
||||
/// naturally, because it does the conversions implicitly:
|
||||
///
|
||||
/// \code ColData("12.86") + 2.0 \endcode
|
||||
///
|
||||
/// That works fine, but be careful. If you had said this instead:
|
||||
///
|
||||
/// \code ColData("12.86") + 2 \endcode
|
||||
///
|
||||
/// the result would be 14 because 2 is an integer, and C++'s type
|
||||
/// conversion rules put the ColData object in an integer context.
|
||||
///
|
||||
/// If these automatic conversions scare you, define the macro
|
||||
/// NO_BINARY_OPERS to disable this behavior.
|
||||
///
|
||||
/// This class also has some basic information about the type of data
|
||||
/// stored in it, to allow it to do the conversions more intelligently
|
||||
/// than a trivial implementation would allow.
|
||||
|
||||
template <class Str>
|
||||
class MYSQLPP_EXPORT ColData_Tmpl : public Str
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Null flag is set to false, type data is not set, and string
|
||||
/// data is left empty.
|
||||
///
|
||||
/// It's probably a bad idea to use this ctor, becuase there's no
|
||||
/// way to set the type data once the object's constructed.
|
||||
ColData_Tmpl() :
|
||||
null_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Copy ctor
|
||||
///
|
||||
/// \param cd the other ColData_Tmpl object
|
||||
ColData_Tmpl(const ColData_Tmpl<Str>& cd) :
|
||||
Str(cd.data(), cd.length()),
|
||||
type_(cd.type_),
|
||||
null_(cd.null_)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Constructor allowing you to set the null flag and the
|
||||
/// type data.
|
||||
///
|
||||
/// \param n if true, data is a SQL null
|
||||
/// \param t MySQL type information for data being stored
|
||||
explicit ColData_Tmpl(bool n,
|
||||
mysql_type_info t = mysql_type_info::string_type) :
|
||||
type_(t),
|
||||
null_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief C++ string version of full ctor
|
||||
///
|
||||
/// \param str the string this object represents
|
||||
/// \param t MySQL type information for data within str
|
||||
/// \param n if true, str is a SQL null
|
||||
explicit ColData_Tmpl(const std::string& str,
|
||||
mysql_type_info t = mysql_type_info::string_type,
|
||||
bool n = false) :
|
||||
Str(str),
|
||||
type_(t),
|
||||
null_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Null-terminated C string version of full ctor
|
||||
///
|
||||
/// \param str the string this object represents
|
||||
/// \param t MySQL type information for data within str
|
||||
/// \param n if true, str is a SQL null
|
||||
explicit ColData_Tmpl(const char* str,
|
||||
mysql_type_info t = mysql_type_info::string_type,
|
||||
bool n = false) :
|
||||
Str(str),
|
||||
type_(t),
|
||||
null_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Full constructor.
|
||||
///
|
||||
/// \param str the string this object represents
|
||||
/// \param len the length of the string; embedded nulls are legal
|
||||
/// \param t MySQL type information for data within str
|
||||
/// \param n if true, str is a SQL null
|
||||
explicit ColData_Tmpl(const char* str, typename Str::size_type len,
|
||||
mysql_type_info t = mysql_type_info::string_type,
|
||||
bool n = false) :
|
||||
Str(str, len),
|
||||
type_(t),
|
||||
null_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Get this object's current MySQL type.
|
||||
mysql_type_info type() const { return type_; }
|
||||
|
||||
/// \brief Returns true if data of this type should be quoted, false
|
||||
/// otherwise.
|
||||
bool quote_q() const { return type_.quote_q(); }
|
||||
|
||||
/// \brief Returns true if data of this type should be escaped, false
|
||||
/// otherwise.
|
||||
bool escape_q() const { return type_.escape_q(); }
|
||||
|
||||
/// \brief Template for converting data from one type to another.
|
||||
template <class Type> Type conv(Type dummy) const;
|
||||
|
||||
/// \brief Set a flag indicating that this object is a SQL null.
|
||||
void it_is_null() { null_ = true; }
|
||||
|
||||
/// \brief Returns true if this object is a SQL null.
|
||||
inline const bool is_null() const { return null_; }
|
||||
|
||||
/// \brief Returns this object's data in C++ string form.
|
||||
///
|
||||
/// This method is inefficient, and not recommended. It makes a
|
||||
/// duplicate copy of the string that lives as long as the
|
||||
/// \c ColData object itself.
|
||||
///
|
||||
/// If you are using the \c MutableColData typedef for this
|
||||
/// template, you can avoid the duplicate copy entirely. You can
|
||||
/// pass a \c MutableColData object to anything expecting a
|
||||
/// \c std::string and get the right result. (This didn't work
|
||||
/// reliably prior to v2.3.)
|
||||
///
|
||||
/// This method is arguably useful with plain \c ColData objects,
|
||||
/// but there are more efficient alternatives. If you know your
|
||||
/// data is a null-terminated C string, just cast this object to
|
||||
/// a \c const \c char* or call the \c data() method. This gives
|
||||
/// you a pointer to our internal buffer, so the copy isn't needed.
|
||||
/// If the \c ColData can contain embedded null characters, you do
|
||||
/// need to make a copy, but it's better to make your own copy of
|
||||
/// the string, instead of calling get_string(), so you can better
|
||||
/// control its lifetime:
|
||||
///
|
||||
/// \code
|
||||
/// ColData cd = ...;
|
||||
/// std::string s(cd.data(), cd.length());
|
||||
/// \endcode
|
||||
inline const std::string& get_string() const
|
||||
{
|
||||
temp_buf_.assign(Str::data(), Str::length());
|
||||
return temp_buf_;
|
||||
}
|
||||
|
||||
/// \brief Returns a const char pointer to the object's raw data
|
||||
operator cchar*() const { return Str::data(); }
|
||||
|
||||
/// \brief Converts this object's string data to a signed char
|
||||
operator signed char() const
|
||||
{ return conv(static_cast<signed char>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to an unsigned char
|
||||
operator unsigned char() const
|
||||
{ return conv(static_cast<unsigned char>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to an int
|
||||
operator int() const
|
||||
{ return conv(static_cast<int>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to an unsigned int
|
||||
operator unsigned int() const
|
||||
{ return conv(static_cast<unsigned int>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to a short int
|
||||
operator short int() const
|
||||
{ return conv(static_cast<short int>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to an unsigned short
|
||||
/// int
|
||||
operator unsigned short int() const
|
||||
{ return conv(static_cast<unsigned short int>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to a long int
|
||||
operator long int() const
|
||||
{ return conv(static_cast<long int>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to an unsigned long
|
||||
/// int
|
||||
operator unsigned long int() const
|
||||
{ return conv(static_cast<unsigned long int>(0)); }
|
||||
|
||||
#if !defined(NO_LONG_LONGS)
|
||||
/// \brief Converts this object's string data to the platform-
|
||||
/// specific 'longlong' type, usually a 64-bit integer.
|
||||
operator longlong() const
|
||||
{ return conv(static_cast<longlong>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to the platform-
|
||||
/// specific 'ulonglong' type, usually a 64-bit unsigned integer.
|
||||
operator ulonglong() const
|
||||
{ return conv(static_cast<ulonglong>(0)); }
|
||||
#endif
|
||||
|
||||
/// \brief Converts this object's string data to a float
|
||||
operator float() const
|
||||
{ return conv(static_cast<float>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to a double
|
||||
operator double() const
|
||||
{ return conv(static_cast<double>(0)); }
|
||||
|
||||
/// \brief Converts this object's string data to a bool
|
||||
operator bool() const { return conv(0); }
|
||||
|
||||
template <class T, class B> operator Null<T, B>() const;
|
||||
|
||||
private:
|
||||
mysql_type_info type_;
|
||||
mutable std::string temp_buf_;
|
||||
bool null_;
|
||||
};
|
||||
|
||||
/// \typedef ColData_Tmpl<const_string> ColData
|
||||
/// \brief The type that is returned by constant rows
|
||||
typedef ColData_Tmpl<const_string> ColData;
|
||||
|
||||
/// \typedef ColData_Tmpl<std::string> MutableColData
|
||||
/// \brief The type that is returned by mutable rows
|
||||
typedef ColData_Tmpl<std::string> MutableColData;
|
||||
|
||||
|
||||
#if !defined(NO_BINARY_OPERS) && !defined(DOXYGEN_IGNORE)
|
||||
// Ignore this section is NO_BINARY_OPERS is defined, or if this section
|
||||
// is being parsed by Doxygen. In the latter case, it's ignored because
|
||||
// Doxygen doesn't understand it correctly, and we can't be bothered to
|
||||
// explain it to Doxygen.
|
||||
|
||||
#define oprsw(opr, other, conv) \
|
||||
template<class Str> \
|
||||
inline other operator opr (ColData_Tmpl<Str> x, other y) \
|
||||
{return static_cast<conv>(x) opr y;} \
|
||||
template<class Str> \
|
||||
inline other operator opr (other x, ColData_Tmpl<Str> y) \
|
||||
{return x opr static_cast<conv>(y);}
|
||||
|
||||
#define operator_binary(other, conv) \
|
||||
oprsw(+, other, conv) \
|
||||
oprsw(-, other, conv) \
|
||||
oprsw(*, other, conv) \
|
||||
oprsw(/, other, conv)
|
||||
|
||||
#define operator_binary_int(other, conv) \
|
||||
operator_binary(other, conv) \
|
||||
oprsw(%, other, conv) \
|
||||
oprsw(&, other, conv) \
|
||||
oprsw(^, other, conv) \
|
||||
oprsw(|, other, conv) \
|
||||
oprsw(<<, other, conv) \
|
||||
oprsw(>>, other, conv)
|
||||
|
||||
operator_binary(float, double)
|
||||
operator_binary(double, double)
|
||||
|
||||
operator_binary_int(char, long int)
|
||||
operator_binary_int(int, long int)
|
||||
operator_binary_int(short int, long int)
|
||||
operator_binary_int(long int, long int)
|
||||
|
||||
operator_binary_int(unsigned char, unsigned long int)
|
||||
operator_binary_int(unsigned int, unsigned long int)
|
||||
operator_binary_int(unsigned short int, unsigned long int)
|
||||
operator_binary_int(unsigned long int, unsigned long int)
|
||||
|
||||
#if !defined(NO_LONG_LONGS)
|
||||
operator_binary_int(longlong, longlong)
|
||||
operator_binary_int(ulonglong, ulonglong)
|
||||
#endif
|
||||
#endif // NO_BINARY_OPERS
|
||||
|
||||
/// \brief Converts this object to a SQL null
|
||||
///
|
||||
/// Returns a copy of the global null object if the string data held by
|
||||
/// the object is exactly equal to "NULL". Else, it constructs an empty
|
||||
/// object of type T and tries to convert it to Null<T, B>.
|
||||
template <class Str> template<class T, class B>
|
||||
ColData_Tmpl<Str>::operator Null<T, B>() const
|
||||
{
|
||||
if ((Str::size() == 4) &&
|
||||
(*this)[0] == 'N' &&
|
||||
(*this)[1] == 'U' &&
|
||||
(*this)[2] == 'L' &&
|
||||
(*this)[3] == 'L') {
|
||||
return Null<T, B>(null);
|
||||
}
|
||||
else {
|
||||
return Null<T, B>(conv(T()));
|
||||
}
|
||||
}
|
||||
|
||||
template <class Str> template <class Type>
|
||||
Type ColData_Tmpl<Str>::conv(Type /* dummy */) const
|
||||
{
|
||||
std::string strbuf(Str::data(), Str::length());
|
||||
strip_all_blanks(strbuf);
|
||||
std::string::size_type len = strbuf.size();
|
||||
const char* str = strbuf.c_str();
|
||||
const char* end = str;
|
||||
Type num = mysql_convert<Type>(str, end);
|
||||
|
||||
if (*end == '.') {
|
||||
++end;
|
||||
for (; *end == '0'; ++end) ;
|
||||
}
|
||||
|
||||
if (*end != '\0' && end != 0) {
|
||||
throw BadConversion(typeid(Type).name(), Str::c_str(),
|
||||
end - str, len);
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,161 +0,0 @@
|
||||
/// \file common.h
|
||||
/// \brief This file includes top-level definitions for use both
|
||||
/// internal to the library, and outside it. Contrast mysql++.h
|
||||
///
|
||||
/// This file mostly takes care of platform differences.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#if !defined(MYSQLPP_COMMON_H)
|
||||
#define MYSQLPP_COMMON_H
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for the following stuff.
|
||||
|
||||
// Work out major platform-specific stuff here.
|
||||
#if defined(__WIN32__) || defined(_WIN32)
|
||||
# define MYSQLPP_PLATFORM_WINDOWS
|
||||
|
||||
// Windows compiler support. Tested with Microsoft Visual C++,
|
||||
// Borland C++ Builder, and MinGW GCC.
|
||||
# include <winsock.h>
|
||||
|
||||
// Stuff for Visual C++ only
|
||||
# if defined(_MSC_VER)
|
||||
// Disable whining about using 'this' as a member initializer on VC++.
|
||||
# pragma warning(disable: 4355)
|
||||
// Disable whining about implicit conversions to bool
|
||||
# pragma warning(disable: 4800)
|
||||
// Disable nagging about new "secure" functions like strncpy_s()
|
||||
# pragma warning(disable: 4996)
|
||||
// Disable complaints about STL data members: VC++ believes
|
||||
// these need to be __declspec(dllexport) for some reason.
|
||||
//# pragma warning(disable: 4251)
|
||||
// Call _snprintf() for VC++ version of snprintf() function
|
||||
//# define snprintf _snprintf
|
||||
# endif
|
||||
|
||||
// Define DLL import/export tags for Windows compilers, where we build
|
||||
// the library into a DLL, for LGPL license compatibility reasons.
|
||||
// (This is based on a similar mechanism in wxWindows.)
|
||||
|
||||
#ifdef MYSQLPP_MAKING_DLL
|
||||
// When making the DLL, export tagged symbols, so they appear
|
||||
// in the import library.
|
||||
#define MYSQLPP_EXPORT __declspec(dllexport)
|
||||
#elif !defined(MYSQLPP_NO_DLL)
|
||||
// We must be _using_ the DLL, so import symbols instead.
|
||||
#define MYSQLPP_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
// Not making a DLL at all, so no-op these declspecs
|
||||
#define MYSQLPP_EXPORT
|
||||
#endif
|
||||
#else
|
||||
// If not Windows, we assume some sort of Unixy build environment,
|
||||
// where autotools is used. (This includes Cygwin!) #include the
|
||||
// config.h file only if this file was included from a non-header
|
||||
// file, because headers must not be dependent on config.h.
|
||||
# if defined(MYSQLPP_NOT_HEADER)
|
||||
# include "config.h"
|
||||
# endif
|
||||
|
||||
// Make DLL stuff a no-op on this platform.
|
||||
#define MYSQLPP_EXPORT
|
||||
#endif
|
||||
|
||||
#if defined(MYSQLPP_MYSQL_HEADERS_BURIED)
|
||||
# include <mysql/mysql_version.h>
|
||||
#else
|
||||
# include <mysql_version.h>
|
||||
#endif
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Alias for 'true', to make code requesting exceptions more
|
||||
/// readable.
|
||||
const bool use_exceptions = true;
|
||||
|
||||
/// \brief Used to disambiguate overloads of equal_list() in SSQLSes.
|
||||
enum sql_cmp_type { sql_use_compare };
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Figure out how to get large integer support on this system. Suppress
|
||||
// refman documentation for these typedefs, as they're system-dependent.
|
||||
#if defined(NO_LONG_LONGS)
|
||||
// Alias "longlong" and "ulonglong" to the regular "long" counterparts
|
||||
typedef unsigned long ulonglong;
|
||||
typedef long longlong;
|
||||
#elif defined(_MSC_VER)
|
||||
// It's VC++, so we'll use Microsoft's 64-bit integer types
|
||||
typedef unsigned __int64 ulonglong;
|
||||
typedef __int64 longlong;
|
||||
#else
|
||||
// No better idea, so assume the C99 convention. If your compiler
|
||||
// doesn't support this, please provide a patch to extend this ifdef, or
|
||||
// define NO_LONG_LONGS.
|
||||
typedef unsigned long long ulonglong;
|
||||
typedef long long longlong;
|
||||
#endif
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
/// \brief Contraction for 'const char*'
|
||||
typedef const char cchar;
|
||||
|
||||
#if !defined(MYSQLPP_NO_UNSIGNED_INT_TYPES)
|
||||
/// \brief Contraction for 'unsigned int'
|
||||
typedef unsigned int uint;
|
||||
/// \brief Contraction for 'unsigned long'
|
||||
typedef unsigned long ulong;
|
||||
#endif
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
// The MySQL headers define these macros, which is completely wrong in a
|
||||
// C++ project. Undo the damage.
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
// Now that we've defined all the stuff above, we can pull in the full
|
||||
// MySQL header. Basically, the above largely replaces MySQL's my_global.h
|
||||
// while actually working with C++. This is why we disobey the MySQL
|
||||
// developer docs, which recommend including my_global.h before mysql.h.
|
||||
#if defined(MYSQLPP_MYSQL_HEADERS_BURIED)
|
||||
# include <mysql/mysql.h>
|
||||
#else
|
||||
# include <mysql.h>
|
||||
#endif
|
||||
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Alias for MYSQL_FIELD
|
||||
typedef MYSQL_FIELD Field;
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_COMMON_H)
|
||||
@ -1,725 +0,0 @@
|
||||
/***********************************************************************
|
||||
connection.cpp - Implements the Connection class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#define MYSQLPP_NOT_HEADER
|
||||
#include "common.h"
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
#include "query.h"
|
||||
#include "result.h"
|
||||
|
||||
// An argument was added to mysql_shutdown() in MySQL 4.1.3 and 5.0.1.
|
||||
#if ((MYSQL_VERSION_ID >= 40103) && (MYSQL_VERSION_ID <= 49999)) || (MYSQL_VERSION_ID >= 50001)
|
||||
# define SHUTDOWN_ARG ,SHUTDOWN_DEFAULT
|
||||
#else
|
||||
# define SHUTDOWN_ARG
|
||||
#endif
|
||||
|
||||
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Sets a variable to a given value temporarily.
|
||||
///
|
||||
/// Saves existing value, sets new value, and restores old value when
|
||||
/// the object is destroyed. Used to set a flag in an exception-safe
|
||||
/// manner.
|
||||
template <class T>
|
||||
class scoped_var_set
|
||||
{
|
||||
public:
|
||||
/// \brief Create object, saving old value, setting new value
|
||||
scoped_var_set(T& var, T new_value) :
|
||||
var_(var)
|
||||
{
|
||||
old_value_ = var_;
|
||||
var_ = new_value;
|
||||
}
|
||||
|
||||
/// \brief Destroy object, restoring old value
|
||||
~scoped_var_set()
|
||||
{
|
||||
var_ = old_value_;
|
||||
}
|
||||
|
||||
private:
|
||||
T& var_;
|
||||
T old_value_;
|
||||
};
|
||||
|
||||
|
||||
// Initialize table of legal option argument types.
|
||||
Connection::OptionArgType
|
||||
Connection::legal_opt_arg_types_[Connection::opt_COUNT] = {
|
||||
Connection::opt_type_integer, // opt_connect_timeout
|
||||
Connection::opt_type_none, // opt_compress
|
||||
Connection::opt_type_none, // opt_named_pipe
|
||||
Connection::opt_type_string, // opt_init_command
|
||||
Connection::opt_type_string, // opt_read_default_file
|
||||
Connection::opt_type_string, // opt_read_default_group
|
||||
Connection::opt_type_string, // opt_set_charset_dir
|
||||
Connection::opt_type_string, // opt_set_charset_name
|
||||
Connection::opt_type_integer, // opt_local_infile
|
||||
Connection::opt_type_integer, // opt_protocol
|
||||
Connection::opt_type_string, // opt_shared_memory_base_name
|
||||
Connection::opt_type_integer, // opt_read_timeout
|
||||
Connection::opt_type_integer, // opt_write_timeout
|
||||
Connection::opt_type_none, // opt_use_result
|
||||
Connection::opt_type_none, // opt_use_remote_connection
|
||||
Connection::opt_type_none, // opt_use_embedded_connection
|
||||
Connection::opt_type_none, // opt_guess_connection
|
||||
Connection::opt_type_string, // opt_set_client_ip
|
||||
Connection::opt_type_boolean, // opt_secure_auth
|
||||
Connection::opt_type_boolean, // opt_multi_statements
|
||||
Connection::opt_type_boolean, // opt_report_data_truncation
|
||||
Connection::opt_type_boolean, // opt_reconnect
|
||||
};
|
||||
|
||||
|
||||
Connection::Connection(bool te) :
|
||||
OptionalExceptions(te),
|
||||
Lockable(false),
|
||||
is_connected_(false),
|
||||
connecting_(false),
|
||||
success_(false)
|
||||
{
|
||||
mysql_init(&mysql_);
|
||||
}
|
||||
|
||||
|
||||
Connection::Connection(const char* db, const char* host,
|
||||
const char* user, const char* passwd, uint port,
|
||||
my_bool compress, unsigned int connect_timeout,
|
||||
cchar* socket_name, unsigned int client_flag) :
|
||||
OptionalExceptions(),
|
||||
Lockable(false),
|
||||
connecting_(false)
|
||||
{
|
||||
mysql_init(&mysql_);
|
||||
if (connect(db, host, user, passwd, port, compress,
|
||||
connect_timeout, socket_name, client_flag)) {
|
||||
unlock();
|
||||
success_ = is_connected_ = true;
|
||||
}
|
||||
else {
|
||||
unlock();
|
||||
success_ = is_connected_ = false;
|
||||
if (throw_exceptions()) {
|
||||
throw ConnectionFailed(error());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connection::Connection(const Connection& other) :
|
||||
OptionalExceptions(),
|
||||
Lockable(false),
|
||||
is_connected_(false)
|
||||
{
|
||||
copy(other);
|
||||
}
|
||||
|
||||
|
||||
Connection::~Connection()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
|
||||
|
||||
Connection&
|
||||
Connection::operator=(const Connection& rhs)
|
||||
{
|
||||
copy(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::connect(cchar* db, cchar* host, cchar* user,
|
||||
cchar* passwd, uint port, my_bool compress,
|
||||
unsigned int connect_timeout, cchar* socket_name,
|
||||
unsigned int client_flag)
|
||||
{
|
||||
lock();
|
||||
|
||||
// Drop previous connection, if any
|
||||
if (connected()) {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
// Set defaults for certain connection options. User can override
|
||||
// these by calling set_option() before connect().
|
||||
set_option_default(opt_read_default_file, "my");
|
||||
set_option_default(opt_connect_timeout, connect_timeout);
|
||||
if (compress) {
|
||||
set_option_default(opt_compress);
|
||||
}
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
// Check to see if user turned on multi-statements before
|
||||
// establishing the connection. This one we handle specially, by
|
||||
// setting a flag during connection establishment.
|
||||
if (option_set(opt_multi_statements)) {
|
||||
client_flag |= CLIENT_MULTI_STATEMENTS;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Establish connection
|
||||
scoped_var_set<bool> sb(connecting_, true);
|
||||
if (mysql_real_connect(&mysql_, host, user, passwd, db, port,
|
||||
socket_name, client_flag)) {
|
||||
unlock();
|
||||
success_ = is_connected_ = true;
|
||||
|
||||
if (db && db[0]) {
|
||||
// Also attach to given database
|
||||
success_ = select_db(db);
|
||||
}
|
||||
}
|
||||
else {
|
||||
unlock();
|
||||
success_ = is_connected_ = false;
|
||||
if (throw_exceptions()) {
|
||||
throw ConnectionFailed(error());
|
||||
}
|
||||
}
|
||||
|
||||
return success_;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::connect(const MYSQL& mysql)
|
||||
{
|
||||
return connect(mysql.db, mysql.host, mysql.user, mysql.passwd,
|
||||
mysql.port, mysql.options.compress,
|
||||
mysql.options.connect_timeout, mysql.unix_socket,
|
||||
mysql.client_flag);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Connection::copy(const Connection& other)
|
||||
{
|
||||
if (connected()) {
|
||||
disconnect();
|
||||
}
|
||||
|
||||
mysql_init(&mysql_);
|
||||
set_exceptions(other.throw_exceptions());
|
||||
|
||||
if (other.connected()) {
|
||||
// Try to reconnect to server using same parameters
|
||||
connect(other.mysql_);
|
||||
}
|
||||
else {
|
||||
is_connected_ = false;
|
||||
connecting_ = false;
|
||||
success_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Connection::disconnect()
|
||||
{
|
||||
mysql_close(&mysql_);
|
||||
is_connected_ = false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::create_db(const std::string& db)
|
||||
{
|
||||
Query q(this, throw_exceptions());
|
||||
return q.exec("CREATE DATABASE " + db);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::drop_db(const std::string& db)
|
||||
{
|
||||
Query q(this, throw_exceptions());
|
||||
return q.exec("DROP DATABASE " + db);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::select_db(const char *db)
|
||||
{
|
||||
if (connected()) {
|
||||
bool suc = !(mysql_select_db(&mysql_, db));
|
||||
if (throw_exceptions() && !suc) {
|
||||
throw DBSelectionFailed(error());
|
||||
}
|
||||
else {
|
||||
return suc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throw_exceptions()) {
|
||||
throw DBSelectionFailed("MySQL++ connection not established");
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::reload()
|
||||
{
|
||||
if (connected()) {
|
||||
bool suc = !mysql_reload(&mysql_);
|
||||
if (throw_exceptions() && !suc) {
|
||||
// Reloading grant tables through this API isn't precisely a
|
||||
// query, but it's acceptable to signal errors with BadQuery
|
||||
// because the new mechanism is the FLUSH PRIVILEGES query.
|
||||
// A program won't have to change when doing it the new way.
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return suc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throw_exceptions()) {
|
||||
throw BadQuery("MySQL++ connection not established");
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::shutdown()
|
||||
{
|
||||
if (connected()) {
|
||||
bool suc = !(mysql_shutdown(&mysql_ SHUTDOWN_ARG));
|
||||
if (throw_exceptions() && !suc) {
|
||||
throw ConnectionFailed(error());
|
||||
}
|
||||
else {
|
||||
return suc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (throw_exceptions()) {
|
||||
throw ConnectionFailed("MySQL++ connection not established");
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
string
|
||||
Connection::info()
|
||||
{
|
||||
const char* i = mysql_info(&mysql_);
|
||||
if (!i) {
|
||||
return string();
|
||||
}
|
||||
else {
|
||||
return string(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Query
|
||||
Connection::query()
|
||||
{
|
||||
return Query(this, throw_exceptions());
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option(Option option)
|
||||
{
|
||||
if (connected()) {
|
||||
// None of the argument-less options can be set once the
|
||||
// connection is up.
|
||||
return bad_option(option, opt_err_conn);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (option) {
|
||||
case opt_compress:
|
||||
success = set_option_impl(MYSQL_OPT_COMPRESS);
|
||||
break;
|
||||
|
||||
case opt_named_pipe:
|
||||
success = set_option_impl(MYSQL_OPT_NAMED_PIPE);
|
||||
break;
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
case opt_use_result:
|
||||
success = set_option_impl(MYSQL_OPT_USE_RESULT);
|
||||
break;
|
||||
|
||||
case opt_use_remote_connection:
|
||||
success = set_option_impl(MYSQL_OPT_USE_REMOTE_CONNECTION);
|
||||
break;
|
||||
|
||||
case opt_use_embedded_connection:
|
||||
success = set_option_impl(MYSQL_OPT_USE_EMBEDDED_CONNECTION);
|
||||
break;
|
||||
|
||||
case opt_guess_connection:
|
||||
success = set_option_impl(MYSQL_OPT_GUESS_CONNECTION);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return bad_option(option, opt_err_type);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
applied_options_.push_back(OptionInfo(option));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return bad_option(option, opt_err_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option(Option option, const char* arg)
|
||||
{
|
||||
if (connected()) {
|
||||
// None of the options taking a char* argument can be set once
|
||||
// the connection is up.
|
||||
return bad_option(option, opt_err_conn);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (option) {
|
||||
case opt_init_command:
|
||||
success = set_option_impl(MYSQL_INIT_COMMAND, arg);
|
||||
break;
|
||||
|
||||
case opt_read_default_file:
|
||||
success = set_option_impl(MYSQL_READ_DEFAULT_FILE, arg);
|
||||
break;
|
||||
|
||||
case opt_read_default_group:
|
||||
success = set_option_impl(MYSQL_READ_DEFAULT_GROUP, arg);
|
||||
break;
|
||||
|
||||
case opt_set_charset_dir:
|
||||
success = set_option_impl(MYSQL_SET_CHARSET_DIR, arg);
|
||||
break;
|
||||
|
||||
case opt_set_charset_name:
|
||||
success = set_option_impl(MYSQL_SET_CHARSET_NAME, arg);
|
||||
break;
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40100
|
||||
case opt_shared_memory_base_name:
|
||||
success = set_option_impl(MYSQL_SHARED_MEMORY_BASE_NAME, arg);
|
||||
break;
|
||||
#endif
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
case opt_set_client_ip:
|
||||
success = set_option_impl(MYSQL_SET_CLIENT_IP, arg);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return bad_option(option, opt_err_type);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
applied_options_.push_back(OptionInfo(option, arg));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return bad_option(option, opt_err_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option(Option option, unsigned int arg)
|
||||
{
|
||||
if (connected()) {
|
||||
// None of the options taking an int argument can be set once
|
||||
// the connection is up.
|
||||
return bad_option(option, opt_err_conn);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (option) {
|
||||
case opt_connect_timeout:
|
||||
success = set_option_impl(MYSQL_OPT_CONNECT_TIMEOUT, &arg);
|
||||
break;
|
||||
|
||||
case opt_local_infile:
|
||||
success = set_option_impl(MYSQL_OPT_LOCAL_INFILE, &arg);
|
||||
break;
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40100
|
||||
case opt_protocol:
|
||||
success = set_option_impl(MYSQL_OPT_PROTOCOL, &arg);
|
||||
break;
|
||||
#endif
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
case opt_read_timeout:
|
||||
success = set_option_impl(MYSQL_OPT_READ_TIMEOUT, &arg);
|
||||
break;
|
||||
|
||||
case opt_write_timeout:
|
||||
success = set_option_impl(MYSQL_OPT_WRITE_TIMEOUT, &arg);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return bad_option(option, opt_err_type);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
applied_options_.push_back(OptionInfo(option, arg));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return bad_option(option, opt_err_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option(Option option, bool arg)
|
||||
{
|
||||
if (connected() && (option != opt_multi_statements)) {
|
||||
// We're connected and it isn't an option that can be set
|
||||
// after connection is up, so complain to user.
|
||||
return bad_option(option, opt_err_conn);
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
switch (option) {
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
case opt_secure_auth:
|
||||
success = set_option_impl(MYSQL_SECURE_AUTH, &arg);
|
||||
break;
|
||||
|
||||
case opt_multi_statements:
|
||||
// If connection is up, set the flag immediately. If not,
|
||||
// and caller wants this turned on, pretend success so that
|
||||
// we store the info we need to turn this flag on when
|
||||
// bringing the connection up. (If the caller is turning it
|
||||
// off before conn comes up, we effectively ignore this,
|
||||
// because that's the default.)
|
||||
if (connected()) {
|
||||
success = set_option_impl(arg ?
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_ON :
|
||||
MYSQL_OPTION_MULTI_STATEMENTS_OFF);
|
||||
}
|
||||
else {
|
||||
success = arg;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#if MYSQL_VERSION_ID >= 50003
|
||||
case opt_report_data_truncation:
|
||||
success = set_option_impl(MYSQL_REPORT_DATA_TRUNCATION, &arg);
|
||||
break;
|
||||
#endif
|
||||
#if MYSQL_VERSION_ID >= 50013
|
||||
case opt_reconnect:
|
||||
success = set_option_impl(MYSQL_OPT_RECONNECT, &arg);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
return bad_option(option, opt_err_type);
|
||||
}
|
||||
|
||||
if (success) {
|
||||
applied_options_.push_back(OptionInfo(option, arg));
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return bad_option(option, opt_err_value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option_default(Option option)
|
||||
{
|
||||
if (option_set(option)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return set_option(option);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
Connection::set_option_default(Option option, T arg)
|
||||
{
|
||||
if (option_set(option)) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return set_option(option, arg);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::set_option_impl(mysql_option moption, const void* arg)
|
||||
{
|
||||
return !mysql_options(&mysql_, moption,
|
||||
static_cast<const char*>(arg));
|
||||
}
|
||||
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
bool
|
||||
Connection::set_option_impl(enum_mysql_set_option msoption)
|
||||
{
|
||||
return !mysql_set_server_option(&mysql_, msoption);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool
|
||||
Connection::bad_option(Option option, OptionError error)
|
||||
{
|
||||
if (throw_exceptions()) {
|
||||
ostringstream os;
|
||||
|
||||
switch (error) {
|
||||
case opt_err_type: {
|
||||
// Option was set using wrong argument type
|
||||
OptionArgType type = option_arg_type(option);
|
||||
os << "option " << option;
|
||||
if (type == opt_type_none) {
|
||||
os << " does not take an argument";
|
||||
}
|
||||
else {
|
||||
os << " requires an argument of type " << type;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case opt_err_value:
|
||||
// C API rejected option, which probably indicates that
|
||||
// you passed a option that it doesn't understand.
|
||||
os << "option " << option << " not supported in MySQL "
|
||||
"C API v";
|
||||
api_version(os);
|
||||
break;
|
||||
|
||||
case opt_err_conn:
|
||||
os << "option " << option << " can only be set "
|
||||
"before connection is established";
|
||||
break;
|
||||
}
|
||||
|
||||
throw BadOption(os.str(), option);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Connection::OptionArgType
|
||||
Connection::option_arg_type(Option option)
|
||||
{
|
||||
if ((option > opt_FIRST) && (option < opt_COUNT)) {
|
||||
return legal_opt_arg_types_[option];
|
||||
}
|
||||
else {
|
||||
// Non-optional exception. Something is wrong with the library
|
||||
// internals if this one is thrown.
|
||||
throw BadOption("bad value given to option_arg_type()", option);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Connection::option_set(Option option)
|
||||
{
|
||||
for (OptionListIt it = applied_options_.begin();
|
||||
it != applied_options_.end();
|
||||
++it) {
|
||||
if (it->option == option) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Connection::enable_ssl(const char* key, const char* cert,
|
||||
const char* ca, const char* capath, const char* cipher)
|
||||
{
|
||||
#if defined(HAVE_MYSQL_SSL_SET)
|
||||
mysql_ssl_set(&mysql_, key, cert, ca, capath, cipher);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
ostream&
|
||||
Connection::api_version(ostream& os)
|
||||
{
|
||||
const int major = MYSQL_VERSION_ID / 10000;
|
||||
const int minor = (MYSQL_VERSION_ID - (major * 10000)) / 100;
|
||||
const int bug = MYSQL_VERSION_ID - (major * 10000) - (minor * 100);
|
||||
|
||||
os << major << '.' << minor << '.' << bug;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
Connection::ping()
|
||||
{
|
||||
if (connected()) {
|
||||
return mysql_ping(&mysql_);
|
||||
}
|
||||
else {
|
||||
// Not connected, and we've forgotten everything we need in
|
||||
// order to re-connect, if we once were connected.
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,579 +0,0 @@
|
||||
/// \file connection.h
|
||||
/// \brief Declares the Connection class.
|
||||
///
|
||||
/// Every program using MySQL++ must create a Connection object, which
|
||||
/// manages information about the connection to the MySQL database, and
|
||||
/// performs connection-related operations once the connection is up.
|
||||
/// Subordinate classes, such as Query and Row take their defaults as
|
||||
/// to whether exceptions are thrown when errors are encountered from
|
||||
/// the Connection object that created them, directly or indirectly.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_CONNECTION_H
|
||||
#define MYSQLPP_CONNECTION_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "lockable.h"
|
||||
#include "noexceptions.h"
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT Query;
|
||||
#endif
|
||||
|
||||
/// \brief Manages the connection to the MySQL database.
|
||||
|
||||
class MYSQLPP_EXPORT Connection : public OptionalExceptions, public Lockable
|
||||
{
|
||||
public:
|
||||
/// \brief Legal types of option arguments
|
||||
enum OptionArgType {
|
||||
opt_type_none,
|
||||
opt_type_string,
|
||||
opt_type_integer,
|
||||
opt_type_boolean
|
||||
};
|
||||
|
||||
/// \brief Per-connection options you can set with set_option()
|
||||
///
|
||||
/// This is currently a combination of the MySQL C API
|
||||
/// \c mysql_option and \c enum_mysql_set_option enums. It may
|
||||
/// be extended in the future.
|
||||
enum Option
|
||||
{
|
||||
// Symbolic "first" option, before real options. Never send
|
||||
// this to set_option()!
|
||||
opt_FIRST = -1,
|
||||
|
||||
opt_connect_timeout = 0,
|
||||
opt_compress,
|
||||
opt_named_pipe,
|
||||
opt_init_command,
|
||||
opt_read_default_file,
|
||||
opt_read_default_group,
|
||||
opt_set_charset_dir,
|
||||
opt_set_charset_name,
|
||||
opt_local_infile,
|
||||
opt_protocol,
|
||||
opt_shared_memory_base_name,
|
||||
opt_read_timeout,
|
||||
opt_write_timeout,
|
||||
opt_use_result,
|
||||
opt_use_remote_connection,
|
||||
opt_use_embedded_connection,
|
||||
opt_guess_connection,
|
||||
opt_set_client_ip,
|
||||
opt_secure_auth,
|
||||
|
||||
// Set multi-query statement support; no argument
|
||||
opt_multi_statements,
|
||||
|
||||
// Set reporting of data truncation errors
|
||||
opt_report_data_truncation,
|
||||
|
||||
// Enable or disable automatic reconnection to the server if
|
||||
// the connection is found to have been lost.
|
||||
opt_reconnect,
|
||||
|
||||
// Number of options supported. Never send this to
|
||||
// set_option()!
|
||||
opt_COUNT
|
||||
};
|
||||
|
||||
/// \brief Create object without connecting it to the MySQL server.
|
||||
///
|
||||
/// \param te if true, exceptions are thrown on errors
|
||||
Connection(bool te = true);
|
||||
|
||||
/// \brief Create object and connect to database server in one step.
|
||||
///
|
||||
/// This constructor allows you to most fully specify the options
|
||||
/// used when connecting to the MySQL database. It is the thinnest
|
||||
/// layer in MySQL++ over the MySQL C API function
|
||||
/// \c mysql_real_connect(). The correspondence isn't exact as
|
||||
/// we have some additional parameters you'd have to set with
|
||||
/// \c mysql_option() when using the C API.
|
||||
///
|
||||
/// \param db name of database to use
|
||||
/// \param host host name or IP address of MySQL server, or 0
|
||||
/// if server is running on the same host as your program
|
||||
/// \param user user name to log in under, or 0 to use the user
|
||||
/// name this program is running under
|
||||
/// \param passwd password to use when logging in
|
||||
/// \param port TCP port number MySQL server is listening on, or 0
|
||||
/// to use default value
|
||||
/// \param compress if true, compress data passing through
|
||||
/// connection, to save bandwidth at the expense of CPU time
|
||||
/// \param connect_timeout max seconds to wait for server to
|
||||
/// respond to our connection attempt
|
||||
/// \param socket_name Unix domain socket server is using, if
|
||||
/// connecting to MySQL server on the same host as this program
|
||||
/// running on, or 0 to use default name
|
||||
/// \param client_flag special connection flags. See MySQL C API
|
||||
/// documentation for \c mysql_real_connect() for details.
|
||||
Connection(const char* db, const char* host = "",
|
||||
const char* user = "", const char* passwd = "",
|
||||
uint port = 0, my_bool compress = 0,
|
||||
unsigned int connect_timeout = 60, cchar* socket_name = 0,
|
||||
unsigned int client_flag = 0);
|
||||
|
||||
/// \brief Establish a new connection using the same parameters as
|
||||
/// an existing C API connection.
|
||||
///
|
||||
/// \param other existing Connection object
|
||||
Connection(const Connection& other);
|
||||
|
||||
/// \brief Establish a new connection using the same parameters as
|
||||
/// an existing C API connection.
|
||||
///
|
||||
/// \param mysql existing MySQL C API connection object
|
||||
bool connect(const MYSQL& mysql);
|
||||
|
||||
/// \brief Destroy connection object
|
||||
~Connection();
|
||||
|
||||
/// \brief Connect to database after object is created.
|
||||
///
|
||||
/// It's better to use the connect-on-create constructor if you can.
|
||||
/// See its documentation for the meaning of these parameters.
|
||||
///
|
||||
/// If you call this method on an object that is already connected
|
||||
/// to a database server, the previous connection is dropped and a
|
||||
/// new connection is established.
|
||||
bool connect(cchar* db = "", cchar* host = "",
|
||||
cchar* user = "", cchar* passwd = "", uint port = 0,
|
||||
my_bool compress = 0, unsigned int connect_timeout = 60,
|
||||
cchar* socket_name = 0, unsigned int client_flag = 0);
|
||||
|
||||
/// \brief Close connection to MySQL server.
|
||||
///
|
||||
/// Closes the connection to the MySQL server.
|
||||
void close()
|
||||
{
|
||||
mysql_close(&mysql_);
|
||||
is_connected_ = false;
|
||||
}
|
||||
|
||||
/// \brief Calls MySQL C API function \c mysql_info() and returns
|
||||
/// result as a C++ string.
|
||||
std::string info();
|
||||
|
||||
/// \brief return true if connection was established successfully
|
||||
///
|
||||
/// \return true if connection was established successfully
|
||||
bool connected() const
|
||||
{
|
||||
return is_connected_;
|
||||
}
|
||||
|
||||
/// \brief Return true if the last query was successful
|
||||
bool success() const
|
||||
{
|
||||
return success_;
|
||||
}
|
||||
|
||||
/// \brief Alias for close()
|
||||
void purge() { close(); }
|
||||
|
||||
/// \brief Return a new query object.
|
||||
///
|
||||
/// The returned query object is tied to this MySQL connection,
|
||||
/// so when you call a method like
|
||||
/// \link mysqlpp::Query::execute() execute() \endlink
|
||||
/// on that object, the query is sent to the server this object
|
||||
/// is connected to.
|
||||
Query query();
|
||||
|
||||
/// \brief Alias for success()
|
||||
///
|
||||
/// Alias for success() member function. Allows you to have code
|
||||
/// constructs like this:
|
||||
///
|
||||
/// \code
|
||||
/// Connection conn;
|
||||
/// .... use conn
|
||||
/// if (conn) {
|
||||
/// ... last SQL query was successful
|
||||
/// }
|
||||
/// else {
|
||||
/// ... error occurred in SQL query
|
||||
/// }
|
||||
/// \endcode
|
||||
operator bool() { return success(); }
|
||||
|
||||
/// \brief Copy an existing Connection object's state into this
|
||||
/// object.
|
||||
Connection& operator=(const Connection& rhs);
|
||||
|
||||
/// \brief Return error message for last MySQL error associated with
|
||||
/// this connection.
|
||||
///
|
||||
/// Simply wraps \c mysql_error() in the C API.
|
||||
const char* error()
|
||||
{
|
||||
return mysql_error(&mysql_);
|
||||
}
|
||||
|
||||
/// \brief Return last MySQL error number associated with this
|
||||
/// connection
|
||||
///
|
||||
/// Simply wraps \c mysql_errno() in the C API.
|
||||
int errnum() { return mysql_errno(&mysql_); }
|
||||
|
||||
/// \brief Wraps MySQL C API function \c mysql_refresh()
|
||||
///
|
||||
/// The corresponding C API function is undocumented. All I know
|
||||
/// is that it's used by \c mysqldump and \c mysqladmin, according
|
||||
/// to MySQL bug database entry http://bugs.mysql.com/bug.php?id=9816
|
||||
/// If that entry changes to say that the function is now documented,
|
||||
/// reevaluate whether we need to wrap it. It may be that it's not
|
||||
/// supposed to be used by regular end-user programs.
|
||||
int refresh(unsigned int refresh_options)
|
||||
{
|
||||
return mysql_refresh(&mysql_, refresh_options);
|
||||
}
|
||||
|
||||
/// \brief "Pings" the MySQL database
|
||||
///
|
||||
/// Wraps \c mysql_ping() in the C API. As a result, this function
|
||||
/// will try to reconnect to the server if the connection has been
|
||||
/// dropped.
|
||||
///
|
||||
/// \retval 0 if server is responding, regardless of whether we had
|
||||
/// to reconnect or not
|
||||
/// \retval nonzero if either we already know the connection is down
|
||||
/// and cannot re-establish it, or if the server did not respond to
|
||||
/// the ping and we could not re-establish the connection.
|
||||
int ping();
|
||||
|
||||
/// \brief Kill a MySQL server thread
|
||||
///
|
||||
/// \param pid ID of thread to kill
|
||||
///
|
||||
/// Simply wraps \c mysql_kill() in the C API.
|
||||
int kill(unsigned long pid)
|
||||
{
|
||||
return mysql_kill(&mysql_, pid);
|
||||
}
|
||||
|
||||
/// \brief Get MySQL client library version
|
||||
///
|
||||
/// Simply wraps \c mysql_get_client_info() in the C API.
|
||||
std::string client_info()
|
||||
{
|
||||
return std::string(mysql_get_client_info());
|
||||
}
|
||||
|
||||
/// \brief Get information about the network connection
|
||||
///
|
||||
/// String contains info about type of connection and the server
|
||||
/// hostname.
|
||||
///
|
||||
/// Simply wraps \c mysql_get_host_info() in the C API.
|
||||
std::string host_info()
|
||||
{
|
||||
return std::string(mysql_get_host_info(&mysql_));
|
||||
}
|
||||
|
||||
/// \brief Returns version number of MySQL protocol this connection
|
||||
/// is using
|
||||
///
|
||||
/// Simply wraps \c mysql_get_proto_info() in the C API.
|
||||
int proto_info()
|
||||
{
|
||||
return mysql_get_proto_info(&mysql_);
|
||||
}
|
||||
|
||||
/// \brief Get the MySQL server's version number
|
||||
///
|
||||
/// Simply wraps \c mysql_get_server_info() in the C API.
|
||||
std::string server_info()
|
||||
{
|
||||
return std::string(mysql_get_server_info(&mysql_));
|
||||
}
|
||||
|
||||
/// \brief Returns information about MySQL server status
|
||||
///
|
||||
/// String is similar to that returned by the \c mysqladmin
|
||||
/// \c status command. Among other things, it contains uptime
|
||||
/// in seconds, and the number of running threads, questions
|
||||
/// and open tables.
|
||||
std::string stat()
|
||||
{
|
||||
return std::string(mysql_stat(&mysql_));
|
||||
}
|
||||
|
||||
/// \brief Create a database
|
||||
///
|
||||
/// \param db name of database to create
|
||||
///
|
||||
/// \return true if database was created successfully
|
||||
bool create_db(const std::string& db);
|
||||
|
||||
/// \brief Drop a database
|
||||
///
|
||||
/// \param db name of database to destroy
|
||||
///
|
||||
/// \return true if database was created successfully
|
||||
bool drop_db(const std::string& db);
|
||||
|
||||
/// \brief Change to a different database
|
||||
bool select_db(const std::string& db)
|
||||
{
|
||||
return select_db(db.c_str());
|
||||
}
|
||||
|
||||
/// \brief Change to a different database
|
||||
bool select_db(const char* db);
|
||||
|
||||
/// \brief Ask MySQL server to reload the grant tables
|
||||
///
|
||||
/// User must have the "reload" privilege.
|
||||
///
|
||||
/// Simply wraps \c mysql_reload() in the C API. Since that
|
||||
/// function is deprecated, this one is, too. The MySQL++
|
||||
/// replacement is execute("FLUSH PRIVILEGES").
|
||||
bool reload();
|
||||
|
||||
/// \brief Ask MySQL server to shut down.
|
||||
///
|
||||
/// User must have the "shutdown" privilege.
|
||||
///
|
||||
/// Simply wraps \c mysql_shutdown() in the C API.
|
||||
bool shutdown();
|
||||
|
||||
/// \brief Return the connection options object
|
||||
st_mysql_options get_options() const
|
||||
{
|
||||
return mysql_.options;
|
||||
}
|
||||
|
||||
/// \brief Sets a connection option, with no argument
|
||||
///
|
||||
/// \param option any of the Option enum constants
|
||||
///
|
||||
/// Based on the option you give, this function calls either
|
||||
/// \c mysql_options() or \c mysql_set_server_option() in the C API.
|
||||
///
|
||||
/// There are several overloaded versions of this function. The
|
||||
/// others take an additional argument for the option and differ
|
||||
/// only by the type of the option. Unlike with the underlying C
|
||||
/// API, it does matter which of these overloads you call: if you
|
||||
/// use the wrong argument type or pass an argument where one is
|
||||
/// not expected (or vice versa), the call will either throw an
|
||||
/// exception or return false, depending on the object's "throw
|
||||
/// exceptions" flag.
|
||||
///
|
||||
/// This mechanism parallels the underlying C API structure fairly
|
||||
/// closely, but do not expect this to continue in the future.
|
||||
/// Its very purpose is to 'paper over' the differences among the
|
||||
/// C API's option setting mechanisms, so it may become further
|
||||
/// abstracted from these mechanisms.
|
||||
///
|
||||
/// \retval true if option was successfully set, or at least queued
|
||||
/// for setting during connection establishment sequence
|
||||
///
|
||||
/// If exceptions are enabled, a false return means the C API
|
||||
/// rejected the option, or the connection is not established and
|
||||
/// so the option was queued for later processing. If exceptions
|
||||
/// are disabled, false can also mean that the argument was of the
|
||||
/// wrong type (wrong overload was called), the option value was out
|
||||
/// of range, or the option is not supported by the C API, most
|
||||
/// because it isn't a high enough version. These latter cases will
|
||||
/// cause BadOption exceptions otherwise.
|
||||
bool set_option(Option option);
|
||||
|
||||
/// \brief Sets a connection option, with string argument
|
||||
bool set_option(Option option, const char* arg);
|
||||
|
||||
/// \brief Sets a connection option, with integer argument
|
||||
bool set_option(Option option, unsigned int arg);
|
||||
|
||||
/// \brief Sets a connection option, with Boolean argument
|
||||
bool set_option(Option option, bool arg);
|
||||
|
||||
/// \brief Same as set_option(), except that it won't override
|
||||
/// a previously-set option.
|
||||
bool set_option_default(Option option);
|
||||
|
||||
/// \brief Same as set_option(), except that it won't override
|
||||
/// a previously-set option.
|
||||
template <typename T>
|
||||
bool set_option_default(Option option, T arg);
|
||||
|
||||
/// \brief Returns true if the given option has been set already
|
||||
bool option_set(Option option);
|
||||
|
||||
/// \brief Enable SSL-encrypted connection.
|
||||
///
|
||||
/// \param key the pathname to the key file
|
||||
/// \param cert the pathname to the certificate file
|
||||
/// \param ca the pathname to the certificate authority file
|
||||
/// \param capath directory that contains trusted SSL CA
|
||||
/// certificates in pem format.
|
||||
/// \param cipher list of allowable ciphers to use
|
||||
///
|
||||
/// Must be called before connection is established.
|
||||
///
|
||||
/// Wraps \c mysql_ssl_set() in MySQL C API.
|
||||
void enable_ssl(const char* key = 0,
|
||||
const char* cert = 0, const char* ca = 0,
|
||||
const char* capath = 0, const char* cipher = 0);
|
||||
|
||||
/// \brief Return the number of rows affected by the last query
|
||||
///
|
||||
/// Simply wraps \c mysql_affected_rows() in the C API.
|
||||
my_ulonglong affected_rows()
|
||||
{
|
||||
return mysql_affected_rows(&mysql_);
|
||||
}
|
||||
|
||||
/// \brief Get ID generated for an AUTO_INCREMENT column in the
|
||||
/// previous INSERT query.
|
||||
///
|
||||
/// \retval 0 if the previous query did not generate an ID. Use
|
||||
/// the SQL function LAST_INSERT_ID() if you need the last ID
|
||||
/// generated by any query, not just the previous one.
|
||||
my_ulonglong insert_id()
|
||||
{
|
||||
return mysql_insert_id(&mysql_);
|
||||
}
|
||||
|
||||
/// \brief Insert C API version we're linked against into C++ stream
|
||||
///
|
||||
/// Version will be of the form X.Y.Z, where X is the major version
|
||||
/// number, Y the minor version, and Z the bug fix number.
|
||||
std::ostream& api_version(std::ostream& os);
|
||||
|
||||
protected:
|
||||
/// \brief Types of option setting errors we can diagnose
|
||||
enum OptionError {
|
||||
opt_err_type,
|
||||
opt_err_value,
|
||||
opt_err_conn
|
||||
};
|
||||
|
||||
/// \brief Drop the connection to the database server
|
||||
///
|
||||
/// This method is protected because it should only be used within
|
||||
/// the library. Unless you use the default constructor, this
|
||||
/// object should always be connected.
|
||||
void disconnect();
|
||||
|
||||
/// \brief Error handling routine for set_option()
|
||||
bool bad_option(Option option, OptionError error);
|
||||
|
||||
/// \brief Given option value, return its proper argument type
|
||||
OptionArgType option_arg_type(Option option);
|
||||
|
||||
/// \brief Set MySQL C API connection option
|
||||
///
|
||||
/// Wraps \c mysql_options() in C API. This is an internal
|
||||
/// implementation detail, to be used only by the public overloads
|
||||
/// above.
|
||||
bool set_option_impl(mysql_option moption, const void* arg = 0);
|
||||
|
||||
#if MYSQL_VERSION_ID >= 40101
|
||||
/// \brief Set MySQL C API connection option
|
||||
///
|
||||
/// Wraps \c mysql_set_server_option() in C API. This is an
|
||||
/// internal implementation detail, to be used only by the public
|
||||
/// overloads above.
|
||||
bool set_option_impl(enum_mysql_set_option msoption);
|
||||
#endif
|
||||
|
||||
/// \brief Establish a new connection as a copy of an existing one
|
||||
///
|
||||
/// \param other the connection to copy
|
||||
void copy(const Connection& other);
|
||||
|
||||
private:
|
||||
friend class ResNSel;
|
||||
friend class ResUse;
|
||||
friend class Query;
|
||||
|
||||
struct OptionInfo {
|
||||
Option option;
|
||||
OptionArgType arg_type;
|
||||
std::string str_arg;
|
||||
unsigned int int_arg;
|
||||
bool bool_arg;
|
||||
|
||||
OptionInfo(Option o) :
|
||||
option(o),
|
||||
arg_type(opt_type_none),
|
||||
int_arg(0),
|
||||
bool_arg(false)
|
||||
{
|
||||
}
|
||||
|
||||
OptionInfo(Option o, const char* a) :
|
||||
option(o),
|
||||
arg_type(opt_type_string),
|
||||
str_arg(a),
|
||||
int_arg(0),
|
||||
bool_arg(false)
|
||||
{
|
||||
}
|
||||
|
||||
OptionInfo(Option o, unsigned int a) :
|
||||
option(o),
|
||||
arg_type(opt_type_integer),
|
||||
int_arg(a),
|
||||
bool_arg(false)
|
||||
{
|
||||
}
|
||||
|
||||
OptionInfo(Option o, bool a) :
|
||||
option(o),
|
||||
arg_type(opt_type_boolean),
|
||||
int_arg(0),
|
||||
bool_arg(a)
|
||||
{
|
||||
}
|
||||
};
|
||||
typedef std::deque<OptionInfo> OptionList;
|
||||
typedef OptionList::const_iterator OptionListIt;
|
||||
|
||||
MYSQL mysql_;
|
||||
bool is_connected_;
|
||||
bool connecting_;
|
||||
bool success_;
|
||||
OptionList applied_options_;
|
||||
static OptionArgType legal_opt_arg_types_[];
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,258 +0,0 @@
|
||||
/// \file const_string.h
|
||||
/// \brief Declares a wrapper for <tt>const char*</tt> which behaves
|
||||
/// in a way more useful to MySQL++.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_CONST_STRING_H
|
||||
#define MYSQLPP_CONST_STRING_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Wrapper for <tt>const char*</tt> to make it behave in a
|
||||
/// way more useful to MySQL++.
|
||||
///
|
||||
/// This class implements a small subset of the standard string class.
|
||||
///
|
||||
/// As of MySQL++ 2.3, it makes a copy of the string we are initialized
|
||||
/// with, instead of just copying the pointer. This is required to
|
||||
/// avoid problems with the new SSQLS + BLOB support.
|
||||
class MYSQLPP_EXPORT const_string
|
||||
{
|
||||
public:
|
||||
/// \brief Type of the data stored in this object, when it is not
|
||||
/// equal to SQL null.
|
||||
typedef const char value_type;
|
||||
|
||||
/// \brief Type of "size" integers
|
||||
typedef unsigned int size_type;
|
||||
|
||||
/// \brief Type used when returning a reference to a character in
|
||||
/// the string.
|
||||
typedef const char& const_reference;
|
||||
|
||||
/// \brief Type of iterators
|
||||
typedef const char* const_iterator;
|
||||
|
||||
/// \brief Same as const_iterator because the data cannot be
|
||||
/// changed.
|
||||
typedef const_iterator iterator;
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
typedef int difference_type;
|
||||
typedef const_reference reference;
|
||||
typedef const char* const_pointer;
|
||||
typedef const_pointer pointer;
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
/// \brief Create empty string
|
||||
const_string() :
|
||||
str_data_(0),
|
||||
length_(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize string from existing C++ string
|
||||
const_string(const std::string& str) :
|
||||
str_data_(0),
|
||||
length_(str.length())
|
||||
{
|
||||
str_data_ = new char[length_ + 1];
|
||||
memcpy(str_data_, str.data(), length_);
|
||||
str_data_[length_] = '\0';
|
||||
}
|
||||
|
||||
/// \brief Initialize string from existing C string
|
||||
const_string(const char* str) :
|
||||
str_data_(0),
|
||||
length_(size_type(strlen(str)))
|
||||
{
|
||||
str_data_ = new char[length_ + 1];
|
||||
memcpy(str_data_, str, length_);
|
||||
str_data_[length_] = '\0';
|
||||
}
|
||||
|
||||
/// \brief Initialize string from existing C string of known length
|
||||
const_string(const char* str, size_type len) :
|
||||
str_data_(0),
|
||||
length_(size_type(len))
|
||||
{
|
||||
str_data_ = new char[length_ + 1];
|
||||
memcpy(str_data_, str, length_);
|
||||
str_data_[length_] = '\0';
|
||||
}
|
||||
|
||||
/// \brief Destroy string
|
||||
~const_string()
|
||||
{
|
||||
delete[] str_data_;
|
||||
}
|
||||
|
||||
/// \brief Assignment operator, from C string
|
||||
const_string& operator=(const char* str)
|
||||
{
|
||||
delete[] str_data_;
|
||||
length_ = size_type(strlen(str));
|
||||
str_data_ = new char[length_];
|
||||
memcpy(str_data_, str, length_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assignment operator, from other const_string
|
||||
const_string& operator=(const const_string& cs)
|
||||
{
|
||||
delete[] str_data_;
|
||||
length_ = cs.length_;
|
||||
str_data_ = new char[length_];
|
||||
memcpy(str_data_, cs.str_data_, length_);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return number of characters in the string
|
||||
size_type length() const { return length_; }
|
||||
|
||||
/// \brief Return number of characters in string
|
||||
size_type size() const { return length_; }
|
||||
|
||||
/// \brief Return iterator pointing to the first character of
|
||||
/// the string
|
||||
const_iterator begin() const { return str_data_; }
|
||||
|
||||
/// \brief Return iterator pointing to one past the last character
|
||||
/// of the string.
|
||||
const_iterator end() const { return str_data_ + size(); }
|
||||
|
||||
/// \brief Return the maximum number of characters in the string.
|
||||
///
|
||||
/// Because this is a \c const string, this is just an alias for
|
||||
/// size(); its size is always equal to the amount of data currently
|
||||
/// stored.
|
||||
size_type max_size() const { return size(); }
|
||||
|
||||
/// \brief Return a reference to a character within the string.
|
||||
const_reference operator [](size_type pos) const
|
||||
{ return str_data_[pos]; }
|
||||
|
||||
/// \brief Return a reference to a character within the string.
|
||||
///
|
||||
/// Unlike \c operator[](), this function throws an
|
||||
/// \c std::out_of_range exception if the index isn't within range.
|
||||
const_reference at(size_type pos) const
|
||||
{
|
||||
if (pos >= size())
|
||||
throw std::out_of_range("");
|
||||
else
|
||||
return str_data_[pos];
|
||||
}
|
||||
|
||||
/// \brief Return a const pointer to the string data. Not
|
||||
/// necessarily null-terminated!
|
||||
const char* c_str() const { return str_data_; }
|
||||
|
||||
/// \brief Alias for \c c_str()
|
||||
const char* data() const { return str_data_; }
|
||||
|
||||
/// \brief Lexically compare this string to another.
|
||||
///
|
||||
/// \param str string to compare against this one
|
||||
///
|
||||
/// \retval <0 if str1 is lexically "less than" str2
|
||||
/// \retval 0 if str1 is equal to str2
|
||||
/// \retval >0 if str1 is lexically "greater than" str2
|
||||
int compare(const const_string& str) const
|
||||
{
|
||||
size_type i = 0, short_len = std::min(length(), str.length());
|
||||
while ((i < short_len) && (str_data_[i] != str.str_data_[i])) {
|
||||
++i;
|
||||
}
|
||||
return str_data_[i] - str.str_data_[i];
|
||||
}
|
||||
|
||||
private:
|
||||
char* str_data_;
|
||||
size_type length_;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Inserts a const_string into a C++ stream
|
||||
inline std::ostream& operator <<(std::ostream& o,
|
||||
const const_string& str)
|
||||
{
|
||||
return o << str.c_str();
|
||||
}
|
||||
|
||||
/// \brief Calls lhs.compare(), passing rhs
|
||||
inline int compare(const const_string& lhs, const const_string& rhs)
|
||||
{
|
||||
return lhs.compare(rhs);
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is the same as rhs
|
||||
inline bool operator ==(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) == 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is not the same as rhs
|
||||
inline bool operator !=(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) != 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is lexically less than rhs
|
||||
inline bool operator <(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) < 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is lexically less or equal to rhs
|
||||
inline bool operator <=(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) <= 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is lexically greater than rhs
|
||||
inline bool operator >(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) > 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if lhs is lexically greater than or equal to rhs
|
||||
inline bool operator >=(const_string& lhs, const_string& rhs)
|
||||
{
|
||||
return compare(lhs, rhs) >= 0;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,117 +0,0 @@
|
||||
/// \file convert.h
|
||||
/// \brief Declares various string-to-integer type conversion templates.
|
||||
///
|
||||
/// These templates are the mechanism used within mysqlpp::ColData_Tmpl
|
||||
/// for its string-to-\e something conversions.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_CONVERT_H
|
||||
#define MYSQLPP_CONVERT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
template <class Type> class mysql_convert;
|
||||
|
||||
#define mysql__convert(TYPE, FUNC) \
|
||||
template <> \
|
||||
class mysql_convert<TYPE> {\
|
||||
public:\
|
||||
mysql_convert(const char* str, const char *& end) { \
|
||||
num_ = FUNC(str, const_cast<char **>(&end));}\
|
||||
operator TYPE () {return num_;}\
|
||||
private:\
|
||||
TYPE num_;\
|
||||
};\
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4244)
|
||||
#endif
|
||||
|
||||
mysql__convert(float, strtod)
|
||||
mysql__convert(double, strtod)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(default: 4244)
|
||||
#endif
|
||||
|
||||
#undef mysql__convert
|
||||
#define mysql__convert(TYPE, FUNC) \
|
||||
template <> \
|
||||
class mysql_convert<TYPE> {\
|
||||
public:\
|
||||
mysql_convert(const char* str, const char *& end) { \
|
||||
num_ = FUNC(str, const_cast<char **>(&end),10);}\
|
||||
operator TYPE () {return num_;}\
|
||||
private:\
|
||||
TYPE num_;\
|
||||
};\
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(disable: 4244)
|
||||
#endif
|
||||
|
||||
mysql__convert(char, strtol)
|
||||
mysql__convert(signed char, strtol)
|
||||
mysql__convert(int, strtol)
|
||||
mysql__convert(short int, strtol)
|
||||
mysql__convert(long int, strtol)
|
||||
|
||||
mysql__convert(unsigned char, strtoul)
|
||||
mysql__convert(unsigned int, strtoul)
|
||||
mysql__convert(unsigned short int, strtoul)
|
||||
mysql__convert(unsigned long int, strtoul)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# pragma warning(default: 4244)
|
||||
#endif
|
||||
|
||||
#if !defined(NO_LONG_LONGS)
|
||||
#if defined(_MSC_VER)
|
||||
// Handle 64-bit ints the VC++ way
|
||||
mysql__convert(longlong, _strtoi64)
|
||||
mysql__convert(ulonglong, _strtoui64)
|
||||
#else
|
||||
// No better idea, so assume the C99 way. If your compiler doesn't
|
||||
// support this, please provide a patch to extend this ifdef, or define
|
||||
// NO_LONG_LONGS.
|
||||
mysql__convert(longlong, strtoll)
|
||||
mysql__convert(ulonglong, strtoull)
|
||||
#endif
|
||||
#endif // !defined(NO_LONG_LONGS)
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,98 +0,0 @@
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// This file is generated by the Perl script custom.pl. Please do
|
||||
// not modify this file directly. Change the script instead.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
#ifndef MYSQLPP_CUSTOM_H
|
||||
#define MYSQLPP_CUSTOM_H
|
||||
|
||||
#include "common.h"
|
||||
#include "tiny_int.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
# error Please run the MySQL++ script lib/custom.pl with the -v compatibility flag.
|
||||
#endif
|
||||
|
||||
#ifdef MYSQLPP_SSQLS_NO_STATICS
|
||||
# define MYSQLPP_SSQLS_EXPAND(...)
|
||||
#else
|
||||
# define MYSQLPP_SSQLS_EXPAND(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
enum sql_dummy_type {sql_dummy};
|
||||
|
||||
inline int sql_cmp(const std::string &a, const std::string &b) {
|
||||
return a.compare(b);
|
||||
}
|
||||
|
||||
inline int sql_cmp(char a,char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(unsigned char a,unsigned char b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(tiny_int a,tiny_int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(int a,int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(unsigned int a,unsigned int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(short int a,short int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(unsigned short int a,unsigned short int b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(unsigned long a,unsigned long b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(long a,long b) {
|
||||
return a-b;
|
||||
}
|
||||
|
||||
inline int sql_cmp(double a,double b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int sql_cmp(float a,float b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int sql_cmp(longlong a,longlong b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int sql_cmp(ulonglong a,ulonglong b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
#include "custom-macros.h"
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,924 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
########################################################################
|
||||
# custom.pl - Generates custom.h and custom-macros.h, as these files
|
||||
# contain many near-duplicate classes, varying only in the number of
|
||||
# SQL table columns they support.
|
||||
#
|
||||
# Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
# MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
# Others may also hold copyrights on code in this file. See the CREDITS
|
||||
# file in the top directory of the distribution for details.
|
||||
#
|
||||
# This file is part of MySQL++.
|
||||
#
|
||||
# MySQL++ is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with MySQL++; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
# USA
|
||||
########################################################################
|
||||
|
||||
|
||||
# This is the limit on the number of SSQLS data members. Higher values
|
||||
# will make custom-macros.h exponentially larger, increase compile
|
||||
# times, and possibly even expose limits in your compiler. Increase it
|
||||
# only if you must.
|
||||
my $max_data_members = 25;
|
||||
|
||||
|
||||
# No user-serviceable parts below.
|
||||
|
||||
use strict;
|
||||
use Getopt::Std;
|
||||
|
||||
our ($opt_v);
|
||||
getopts('v') or die "usage: custom.pl [-v]\n";
|
||||
|
||||
open (OUT0, ">custom.h");
|
||||
open (OUT, ">custom-macros.h");
|
||||
|
||||
print OUT0 << "---";
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// This file is generated by the Perl script custom.pl. Please do
|
||||
// not modify this file directly. Change the script instead.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
#ifndef MYSQLPP_CUSTOM_H
|
||||
#define MYSQLPP_CUSTOM_H
|
||||
|
||||
#include "common.h"
|
||||
#include "tiny_int.h"
|
||||
|
||||
#include <string>
|
||||
---
|
||||
|
||||
my ($suppress_statics_start, $suppress_statics_end) = ('', '');
|
||||
unless ($opt_v) {
|
||||
print OUT0 << "---";
|
||||
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
# error Please run the MySQL++ script lib/custom.pl with the -v compatibility flag.
|
||||
#endif
|
||||
|
||||
#ifdef MYSQLPP_SSQLS_NO_STATICS
|
||||
# define MYSQLPP_SSQLS_EXPAND(...)
|
||||
#else
|
||||
# define MYSQLPP_SSQLS_EXPAND(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
---
|
||||
$suppress_statics_start = 'MYSQLPP_SSQLS_EXPAND(';
|
||||
$suppress_statics_end = ')';
|
||||
}
|
||||
|
||||
print OUT0 << "---";
|
||||
namespace mysqlpp {
|
||||
|
||||
enum sql_dummy_type {sql_dummy};
|
||||
|
||||
inline int sql_cmp(const std::string &a, const std::string &b) {
|
||||
return a.compare(b);
|
||||
}
|
||||
---
|
||||
|
||||
my @types = ("char", "unsigned char", "tiny_int", "int", "unsigned int",
|
||||
"short int", "unsigned short int", "unsigned long", "long");
|
||||
foreach my $type (@types) {
|
||||
print OUT0 << "---";
|
||||
|
||||
inline int sql_cmp($type a,$type b) {
|
||||
return a-b;
|
||||
}
|
||||
---
|
||||
}
|
||||
|
||||
@types = ("double", "float");
|
||||
foreach my $type (@types) {
|
||||
print OUT0 << "---";
|
||||
|
||||
inline int sql_cmp($type a,$type b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
---
|
||||
}
|
||||
|
||||
@types = ("longlong", "ulonglong");
|
||||
foreach my $type (@types) {
|
||||
print OUT0 << "---";
|
||||
|
||||
inline int sql_cmp($type a,$type b) {
|
||||
if (a == b) return 0;
|
||||
if (a < b) return -1;
|
||||
return 1;
|
||||
}
|
||||
---
|
||||
}
|
||||
|
||||
print OUT0 << "---";
|
||||
|
||||
#include "custom-macros.h"
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
---
|
||||
|
||||
print OUT << "---";
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// This file is generated by the Perl script custom.pl. Please do
|
||||
// not modify this file directly. Change the script instead.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Begin Mandatory Compare
|
||||
// ---------------------------------------------------
|
||||
|
||||
#define sql_compare_define(NAME) \\
|
||||
bool operator == (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) == 0;} \\
|
||||
bool operator != (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) != 0;} \\
|
||||
bool operator > (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) > 0;} \\
|
||||
bool operator < (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) < 0;} \\
|
||||
bool operator >= (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) >= 0;} \\
|
||||
bool operator <= (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other) <= 0;} \\
|
||||
int cmp (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other);} \\
|
||||
int compare (const NAME &other) const \\
|
||||
{return sql_compare_##NAME<mysqlpp::sql_dummy>(*this,other);}
|
||||
---
|
||||
|
||||
my ($parm0, $parm1);
|
||||
|
||||
foreach my $j (1..$max_data_members) {
|
||||
$parm0 .= "T$j, C$j";
|
||||
$parm0 .= ", " unless $j == $max_data_members;
|
||||
$parm1 .= "C$j";
|
||||
$parm1 .= ", " unless $j == $max_data_members;
|
||||
}
|
||||
|
||||
print OUT << "---";
|
||||
|
||||
#define sql_compare_define_0(NAME, $parm0)
|
||||
|
||||
#define sql_construct_define_0(NAME, $parm0)
|
||||
|
||||
#define sql_COMPARE__0(NAME, $parm1)
|
||||
|
||||
#define sql_compare_type_def_0(NAME, WHAT, NUM) \\
|
||||
sql_compare_type_def_##NUM (NAME, WHAT, NUM)
|
||||
|
||||
#define sql_compare_type_defe_0(NAME, WHAT, NUM) \\
|
||||
sql_compare_type_defe_##NUM (NAME, WHAT, NUM)
|
||||
|
||||
// ---------------------------------------------------
|
||||
// End Mandatory Compare
|
||||
// ---------------------------------------------------
|
||||
---
|
||||
|
||||
|
||||
foreach my $i (1..$max_data_members) {
|
||||
my ($compr, $define, $compp, $set, $parm2);
|
||||
$compr = ""; $parm2 = ""; $define = "";
|
||||
$compr = " int cmp; \\\n" unless $i == 1;
|
||||
$compp = "";
|
||||
$set = "";
|
||||
foreach my $j (1..$i) {
|
||||
if ($j != $i) {
|
||||
$compr .= " cmp = mysqlpp::sql_cmp(x.C$j , y.C$j ); \\\n";
|
||||
$compr .= " if (cmp) return cmp; \\\n";
|
||||
}
|
||||
|
||||
$compr .= " return mysqlpp::sql_cmp(x.C$j , y.C$j );" if $j == $i;
|
||||
$parm2 .= "const T$j &p$j";
|
||||
$parm2 .= ", " unless $j == $i;
|
||||
$define.= "C$j (p$j)";
|
||||
$define.= ", " unless $j == $i;
|
||||
$set .= " C$j = p$j;\\\n";
|
||||
$compp .= "true";
|
||||
$compp .= ", " unless $j == $i;
|
||||
}
|
||||
print OUT << "---";
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Begin Compare $i
|
||||
// ---------------------------------------------------
|
||||
|
||||
#define sql_compare_define_$i(NAME, $parm0) \\
|
||||
NAME ($parm2) : $define {} \\
|
||||
void set ($parm2) { \\
|
||||
$set \\
|
||||
} \\
|
||||
sql_compare_define(NAME)
|
||||
|
||||
#define sql_construct_define_$i(NAME, $parm0) \\
|
||||
void set ($parm2) { \\
|
||||
$set \\
|
||||
} \\
|
||||
NAME ($parm2) : $define {}
|
||||
|
||||
#define sql_compare_type_def_$i(NAME, WHAT, NUM) \\
|
||||
return WHAT##_list(d, m, $compp)
|
||||
|
||||
#define sql_compare_type_defe_$i(NAME, WHAT, NUM) \\
|
||||
return WHAT##_list(d, c, m, $compp)
|
||||
|
||||
#define sql_COMPARE__$i(NAME, $parm1) \\
|
||||
template <mysqlpp::sql_dummy_type dummy> \\
|
||||
int sql_compare_##NAME (const NAME &x, const NAME &y) { \\
|
||||
$compr \\
|
||||
} \\
|
||||
template <mysqlpp::sql_dummy_type dummy> \\
|
||||
int compare (const NAME &x, const NAME &y) { \\
|
||||
$compr \\
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// End Compare $i
|
||||
// ---------------------------------------------------
|
||||
|
||||
---
|
||||
}
|
||||
|
||||
print OUT << "---";
|
||||
---
|
||||
|
||||
|
||||
foreach my $i (1..$max_data_members) {
|
||||
my $parm_complete = "";
|
||||
my $parm_order = ""; my $parm_order2c = "";
|
||||
my $parm_simple = ""; my $parm_simple2c = "";
|
||||
my $parm_simple_b = ""; my $parm_simple2c_b = "";
|
||||
my $parm_names = ""; my $parm_names2c = "";
|
||||
my $defs = ""; my $popul = ""; my $parmc = ""; my $parmC = "";
|
||||
my $value_list = ""; my $field_list = ""; my $equal_list = "";
|
||||
my $value_list_cus = ""; my $cus_field_list = ""; my $cus_equal_list = "";
|
||||
my $create_bool = ""; my $create_list = "";
|
||||
my $cusparms1 = ""; my $cusparms2 = ""; my $cusparmsv = "";
|
||||
my $cusparms11 = ""; my $cusparms22 = "";
|
||||
my $names = "";my $enums = "";
|
||||
foreach my $j (1 .. $i) {
|
||||
$parm_complete .= "T$j, I$j, N$j, O$j";
|
||||
$parm_complete .= ", " unless $j == $i;
|
||||
$parm_order .= "T$j, I$j, O$j";
|
||||
$parm_order .= ", " unless $j == $i;
|
||||
$parm_order2c .= "T$j, I$j, #I$j, O$j";
|
||||
$parm_order2c .= ", " unless $j == $i;
|
||||
$parm_names .= "T$j, I$j, N$j";
|
||||
$parm_names .= ", " unless $j == $i;
|
||||
$parm_names2c .= "T$j, I$j, N$j, ". ($j-1);
|
||||
$parm_names2c .= ", " unless $j == $i;
|
||||
$parm_simple .= "T$j, I$j";
|
||||
$parm_simple .= ", " unless $j == $i;
|
||||
$parm_simple2c .= "T$j, I$j, #I$j, ". ($j-1);
|
||||
$parm_simple2c .= ", " unless $j == $i;
|
||||
$parm_simple_b .= "T$j, I$j";
|
||||
$parm_simple_b .= ", " unless $j == $i;
|
||||
$parm_simple2c_b .= "T$j, I$j, ". ($j-1);
|
||||
$parm_simple2c_b .= ", " unless $j == $i;
|
||||
$defs .= " T$j I$j;";
|
||||
$defs .= "\n" unless $j == $i;
|
||||
$popul .= " s->I$j = static_cast<T$j>(row.at(O$j));";
|
||||
$popul .= "\n" unless $j == $i;
|
||||
$names .= " N$j ";
|
||||
$names .= ",\n" unless $j == $i;
|
||||
$enums .= " NAME##_##I$j";
|
||||
$enums .= ",\n" unless $j == $i;
|
||||
$field_list .= " s << obj.manip << obj.obj->names[".($j-1)."]";
|
||||
$field_list .= " << obj.delem;\n" unless $j == $i;
|
||||
$value_list .= " s << obj.manip << obj.obj->I$j";
|
||||
$value_list .= " << obj.delem;\n" unless $j == $i;
|
||||
$create_bool .= " if (i$j) (*include)[".($j-1)."]=true;\n";
|
||||
$create_list .= " if (i$j == NAME##_NULL) return;\n" unless $i == 1;
|
||||
$create_list .= " (*include)[i$j]=true;\n";
|
||||
|
||||
$value_list_cus .= " if ((*obj.include)[".($j-1)."]) { \n";
|
||||
$value_list_cus .= " if (before) s << obj.delem;\n" unless $j == 1;
|
||||
$value_list_cus .= " s << obj.manip << obj.obj->I$j;\n";
|
||||
$value_list_cus .= " before = true; \n" unless $j == $i;
|
||||
$value_list_cus .= " } \n";
|
||||
|
||||
$cus_field_list .= " if ((*obj.include)[".($j-1)."]) { \n";
|
||||
$cus_field_list .= " if (before) s << obj.delem;\n" unless $j == 1;
|
||||
$cus_field_list .= " s << obj.manip << obj.obj->names[".($j-1)."];\n";
|
||||
$cus_field_list .= " before = true; \n" unless $j == $i;
|
||||
$cus_field_list .= " } \n";
|
||||
|
||||
$cus_equal_list .= " if ((*obj.include)[".($j-1)."]) { \n";
|
||||
$cus_equal_list .= " if (before) s << obj.delem;\n" unless $j == 1;
|
||||
$cus_equal_list .= " s << obj.obj->names[".($j-1)."] << obj.comp";
|
||||
$cus_equal_list .= " << obj.manip << obj.obj->I$j;\n";
|
||||
$cus_equal_list .= " before = true; \n" unless $j == $i;
|
||||
$cus_equal_list .= " } \n";
|
||||
|
||||
$equal_list .= " s << obj.obj->names[".($j-1)."] << obj.comp";
|
||||
$equal_list .= " << obj.manip << obj.obj->I$j";
|
||||
$equal_list .= " << obj.delem;\n" unless $j == $i;
|
||||
$cusparms1 .= "bool i$j" if $j == 1;
|
||||
$cusparms1 .= "bool i$j = false" unless $j == 1;
|
||||
$cusparms1 .= ", " unless $j == $i;
|
||||
$cusparms11 .= "bool i$j" ;
|
||||
$cusparms11 .= ", " unless $j == $i;
|
||||
$cusparms2 .= "NAME##_enum i$j" if $j == 1;
|
||||
$cusparms2 .= "NAME##_enum i$j = NAME##_NULL" unless $j == 1;
|
||||
$cusparms2 .= ", " unless $j == $i;
|
||||
$cusparms22 .= "NAME##_enum i$j";
|
||||
$cusparms22 .= ", " unless $j == $i;
|
||||
$cusparmsv .= "i$j";
|
||||
$cusparmsv .= ", " unless $j == $i;
|
||||
$parmC .= "T$j, I$j";
|
||||
$parmC .= ", " unless $j == $max_data_members;
|
||||
$parmc .= "I$j";
|
||||
$parmc .= ", " unless $j == $max_data_members;
|
||||
}
|
||||
foreach my $j ($i+1 .. $max_data_members) {
|
||||
$parmC .= "0, 0";
|
||||
$parmC .= ", " unless $j == $max_data_members;
|
||||
$parmc .= "0";
|
||||
$parmc .= ", " unless $j == $max_data_members;
|
||||
}
|
||||
|
||||
print OUT << "---";
|
||||
// ---------------------------------------------------
|
||||
// Begin Create $i
|
||||
// ---------------------------------------------------
|
||||
---
|
||||
my $out = <<"---";
|
||||
#define sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_order)
|
||||
|
||||
struct NAME;
|
||||
|
||||
template <mysqlpp::sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);
|
||||
|
||||
struct NAME {
|
||||
$defs
|
||||
NAME () {}
|
||||
NAME (const mysqlpp::Row &row);
|
||||
sql_compare_define_##CMP(NAME, $parmC)
|
||||
};
|
||||
|
||||
template <mysqlpp::sql_dummy_type dummy>
|
||||
void populate_##NAME (NAME *s, const mysqlpp::Row &row) {
|
||||
$popul
|
||||
}
|
||||
|
||||
inline NAME::NAME (const mysqlpp::Row &row)
|
||||
{populate_##NAME<mysqlpp::sql_dummy>(this, row);}
|
||||
|
||||
sql_COMPARE__##CMP(NAME, $parmc )
|
||||
---
|
||||
print OUT &prepare($out);
|
||||
|
||||
$out = <<"---";
|
||||
#define sql_create_complete_$i(NAME, CMP, CONTR, $parm_complete)
|
||||
struct NAME;
|
||||
|
||||
enum NAME##_enum {
|
||||
$enums
|
||||
,NAME##_NULL
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_value_list {
|
||||
/*friend std::ostream& operator << <> (std::ostream&, const NAME##_value_list&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
mysqlpp::cchar *delem;
|
||||
Manip manip;
|
||||
public:
|
||||
NAME##_value_list (const NAME *o, mysqlpp::cchar *d, Manip m)
|
||||
: obj(o), delem(d), manip(m) {}
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_##field_list {
|
||||
/* friend std::ostream& operator << <> (std::ostream&, const NAME##_field_list&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
mysqlpp::cchar *delem;
|
||||
Manip manip;
|
||||
public:
|
||||
NAME##_field_list (const NAME *o, mysqlpp::cchar *d, Manip m)
|
||||
: obj(o), delem(d), manip(m) {}
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_equal_list {
|
||||
/* friend std::ostream& operator << <> (std::ostream&, const NAME##_equal_list&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
mysqlpp::cchar *delem;
|
||||
mysqlpp::cchar *comp;
|
||||
Manip manip;
|
||||
public:
|
||||
NAME##_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m)
|
||||
: obj(o), delem(d), comp(c), manip(m) {}
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_cus_value_list {
|
||||
/* friend std::ostream& operator << <> (std::ostream&,
|
||||
const NAME##_cus_value_list<Manip>&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
std::vector<bool> *include;
|
||||
bool del_vector;
|
||||
mysqlpp::cchar *delem;
|
||||
Manip manip;
|
||||
public:
|
||||
~NAME##_cus_value_list () {if (del_vector) delete include;}
|
||||
NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11);
|
||||
NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22);
|
||||
NAME##_cus_value_list (const NAME *o, mysqlpp::cchar *d, Manip m ,std::vector<bool>* i)
|
||||
: obj(o), include(i), del_vector(false), delem(d), manip(m) {}
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_cus_field_list {
|
||||
/* friend std::ostream& operator << <> (std::ostream&,
|
||||
const NAME##_cus_field_list<Manip>&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
std::vector<bool> *include;
|
||||
bool del_vector;
|
||||
mysqlpp::cchar *delem;
|
||||
Manip manip;
|
||||
public:
|
||||
~NAME##_cus_field_list () {if (del_vector) delete include;}
|
||||
NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11);
|
||||
NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22);
|
||||
NAME##_cus_field_list (const NAME *o, mysqlpp::cchar *d, Manip m, std::vector<bool> *i)
|
||||
: obj(o), include(i), del_vector(false), delem(d), manip(m) {}
|
||||
};
|
||||
|
||||
template <class Manip>
|
||||
class NAME##_cus_equal_list {
|
||||
/* friend std::ostream& operator << <> (std::ostream&,
|
||||
const NAME##_cus_equal_list<Manip>&); */
|
||||
public:
|
||||
const NAME *obj;
|
||||
std::vector<bool> *include;
|
||||
bool del_vector;
|
||||
mysqlpp::cchar *delem;
|
||||
mysqlpp::cchar *comp;
|
||||
Manip manip;
|
||||
public:
|
||||
~NAME##_##cus_equal_list () {if (del_vector) delete include;}
|
||||
NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms11);
|
||||
NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms22);
|
||||
NAME##_##cus_equal_list (const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, std::vector<bool> *i)
|
||||
: obj(o), include(i), del_vector(false), delem(d), comp(c), manip(m) {}
|
||||
};
|
||||
|
||||
template <mysqlpp::sql_dummy_type dummy> int sql_compare_##NAME (const NAME &, const NAME &);
|
||||
|
||||
struct NAME {
|
||||
$defs
|
||||
NAME () {}
|
||||
NAME (const mysqlpp::Row &row);
|
||||
void set (const mysqlpp::Row &row);
|
||||
sql_compare_define_##CMP(NAME, $parmC)
|
||||
sql_construct_define_##CONTR(NAME, $parmC)
|
||||
static const char *names[];
|
||||
static const char *_table;
|
||||
static const char *& table() {return _table;}
|
||||
|
||||
NAME##_value_list<mysqlpp::quote_type0> value_list() const {
|
||||
return value_list(",", mysqlpp::quote);}
|
||||
NAME##_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d) const {
|
||||
return value_list(d, mysqlpp::quote);}
|
||||
template <class Manip>
|
||||
NAME##_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m) const;
|
||||
|
||||
NAME##_field_list<mysqlpp::do_nothing_type0> field_list() const {
|
||||
return field_list(",", mysqlpp::do_nothing);}
|
||||
NAME##_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d) const {
|
||||
return field_list(d, mysqlpp::do_nothing);}
|
||||
template <class Manip>
|
||||
NAME##_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m) const;
|
||||
|
||||
NAME##_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d = ",",
|
||||
mysqlpp::cchar *c = " = ") const{
|
||||
return equal_list(d, c, mysqlpp::quote);}
|
||||
template <class Manip>
|
||||
NAME##_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m) const;
|
||||
|
||||
/* cus_data */
|
||||
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list($cusparms1) const {
|
||||
return value_list(",", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list($cusparms2) const {
|
||||
return value_list(",", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(std::vector<bool> *i) const {
|
||||
return value_list(",", mysqlpp::quote, i);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::sql_cmp_type sc) const {
|
||||
return value_list(",", mysqlpp::quote, sc);
|
||||
}
|
||||
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, $cusparms1) const {
|
||||
return value_list(d, mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d, $cusparms2) const {
|
||||
return value_list(d, mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d,
|
||||
std::vector<bool> *i) const {
|
||||
return value_list(d, mysqlpp::quote, i);
|
||||
}
|
||||
NAME##_cus_value_list<mysqlpp::quote_type0> value_list(mysqlpp::cchar *d,
|
||||
mysqlpp::sql_cmp_type sc) const {
|
||||
return value_list(d, mysqlpp::quote, sc);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms1) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms2) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
|
||||
std::vector<bool> *i) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip> value_list(mysqlpp::cchar *d, Manip m,
|
||||
mysqlpp::sql_cmp_type sc) const;
|
||||
/* cus field */
|
||||
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list($cusparms1) const {
|
||||
return field_list(",", mysqlpp::do_nothing, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list($cusparms2) const {
|
||||
return field_list(",", mysqlpp::do_nothing, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(std::vector<bool> *i) const {
|
||||
return field_list(",", mysqlpp::do_nothing, i);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::sql_cmp_type sc) const
|
||||
{
|
||||
return field_list(",", mysqlpp::do_nothing, sc);
|
||||
}
|
||||
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d,
|
||||
$cusparms1) const {
|
||||
return field_list(d, mysqlpp::do_nothing, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d,
|
||||
$cusparms2) const {
|
||||
return field_list(d, mysqlpp::do_nothing, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d,
|
||||
std::vector<bool> *i) const {
|
||||
return field_list(d, mysqlpp::do_nothing, i);
|
||||
}
|
||||
NAME##_cus_field_list<mysqlpp::do_nothing_type0> field_list(mysqlpp::cchar *d,
|
||||
mysqlpp::sql_cmp_type sc) const {
|
||||
return field_list(d, mysqlpp::do_nothing, sc);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms1) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms2) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
|
||||
std::vector<bool> *i) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip> field_list(mysqlpp::cchar *d, Manip m,
|
||||
mysqlpp::sql_cmp_type sc) const;
|
||||
|
||||
/* cus equal */
|
||||
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list($cusparms1) const {
|
||||
return equal_list(",", " = ", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list($cusparms2) const {
|
||||
return equal_list(",", " = ", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(std::vector<bool> *i) const {
|
||||
return equal_list(",", " = ", mysqlpp::quote, i);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::sql_cmp_type sc) const {
|
||||
return equal_list(",", " = ", mysqlpp::quote, sc);
|
||||
}
|
||||
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, $cusparms1) const {
|
||||
return equal_list(d, " = ", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, $cusparms2) const {
|
||||
return equal_list(d, " = ", mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d,
|
||||
std::vector<bool> *i) const {
|
||||
return equal_list(d, " = ", mysqlpp::quote, i);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d,
|
||||
mysqlpp::sql_cmp_type sc) const {
|
||||
return equal_list(d, " = ", mysqlpp::quote, sc);
|
||||
}
|
||||
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
|
||||
$cusparms1) const {
|
||||
return equal_list(d, c, mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
|
||||
$cusparms2) const {
|
||||
return equal_list(d, c, mysqlpp::quote, $cusparmsv);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
|
||||
std::vector<bool> *i) const {
|
||||
return equal_list(d, c, mysqlpp::quote, i);
|
||||
}
|
||||
NAME##_cus_equal_list<mysqlpp::quote_type0> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c,
|
||||
mysqlpp::sql_cmp_type sc) const {
|
||||
return equal_list(d, c, mysqlpp::quote, sc);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
$cusparms1) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
$cusparms2) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
std::vector<bool> *i) const;
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip> equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
mysqlpp::sql_cmp_type sc) const;
|
||||
};
|
||||
$suppress_statics_start
|
||||
const char *NAME::names[] = {
|
||||
$names
|
||||
};
|
||||
const char *NAME::_table = #NAME ;
|
||||
$suppress_statics_end
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip>::NAME##_cus_value_list
|
||||
(const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11)
|
||||
{
|
||||
delem = d;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_bool
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_value_list<Manip>::NAME##_cus_value_list
|
||||
(const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22) {
|
||||
delem = d;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_list
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip>::NAME##_cus_field_list
|
||||
(const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms11) {
|
||||
delem = d;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_bool
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_field_list<Manip>::NAME##_cus_field_list
|
||||
(const NAME *o, mysqlpp::cchar *d, Manip m, $cusparms22) {
|
||||
delem = d;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_list
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
|
||||
(const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms11) {
|
||||
delem = d;
|
||||
comp = c;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_bool
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
NAME##_cus_equal_list<Manip>::NAME##_cus_equal_list
|
||||
(const NAME *o, mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, $cusparms22) {
|
||||
delem = d;
|
||||
comp = c;
|
||||
manip = m;
|
||||
del_vector = true;
|
||||
obj = o;
|
||||
include = new std::vector<bool>($i, false);
|
||||
$create_list
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_value_list<Manip>& obj) {
|
||||
$value_list;
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_field_list<Manip>& obj) {
|
||||
$field_list;
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_equal_list<Manip>& obj) {
|
||||
$equal_list;
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_cus_value_list<Manip>& obj) {
|
||||
bool before = false;
|
||||
$value_list_cus
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_cus_field_list<Manip>& obj) {
|
||||
bool before = false;
|
||||
$cus_field_list
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
std::ostream& operator << (std::ostream& s, const NAME##_cus_equal_list<Manip>& obj) {
|
||||
bool before = false;
|
||||
$cus_equal_list
|
||||
return s;
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m) const {
|
||||
return NAME##_value_list<Manip> (this, d, m);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m) const {
|
||||
return NAME##_field_list<Manip> (this, d, m);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m) const {
|
||||
return NAME##_equal_list<Manip> (this, d, c, m);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms11) const {
|
||||
return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms11) const {
|
||||
return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
$cusparms11) const {
|
||||
return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms22) const {
|
||||
return NAME##_cus_value_list<Manip> (this, d, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
|
||||
$cusparms22) const {
|
||||
return NAME##_cus_field_list<Manip> (this, d, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
$cusparms22) const {
|
||||
return NAME##_cus_equal_list<Manip> (this, d, c, m, $cusparmsv);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_value_list<Manip> NAME::value_list(mysqlpp::cchar *d, Manip m,
|
||||
std::vector<bool> *i) const {
|
||||
return NAME##_cus_value_list<Manip> (this, d, m, i);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_field_list<Manip> NAME::field_list(mysqlpp::cchar *d, Manip m,
|
||||
std::vector<bool> *i) const {
|
||||
return NAME##_cus_field_list<Manip> (this, d, m, i);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_equal_list<Manip> NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m,
|
||||
std::vector<bool> *i) const {
|
||||
return NAME##_cus_equal_list<Manip> (this, d, c, m, i);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_value_list<Manip>
|
||||
NAME::value_list(mysqlpp::cchar *d, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
|
||||
sql_compare_type_def_##CMP (NAME, value, NUM);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_field_list<Manip>
|
||||
NAME::field_list(mysqlpp::cchar *d, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
|
||||
sql_compare_type_def_##CMP (NAME, field, NUM);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
inline NAME##_cus_equal_list<Manip>
|
||||
NAME::equal_list(mysqlpp::cchar *d, mysqlpp::cchar *c, Manip m, mysqlpp::sql_cmp_type /*sc*/) const {
|
||||
sql_compare_type_defe_##CMP (NAME, equal, NUM);
|
||||
}
|
||||
|
||||
template <mysqlpp::sql_dummy_type dummy>
|
||||
void populate_##NAME (NAME *s, const mysqlpp::Row &row) {
|
||||
$popul
|
||||
}
|
||||
|
||||
inline NAME::NAME (const mysqlpp::Row &row)
|
||||
{populate_##NAME<mysqlpp::sql_dummy>(this, row);}
|
||||
inline void NAME::set (const mysqlpp::Row &row)
|
||||
{populate_##NAME<mysqlpp::sql_dummy>(this, row);}
|
||||
|
||||
sql_COMPARE__##CMP(NAME, $parmc )
|
||||
|
||||
---
|
||||
print OUT &prepare($out);
|
||||
|
||||
#
|
||||
# short cut defs
|
||||
#
|
||||
|
||||
print OUT << "---";
|
||||
#define sql_create_basic_$i(NAME, CMP, CONTR, $parm_simple_b) \\
|
||||
sql_create_basic_c_order_$i(NAME, CMP, CONTR, $parm_simple2c_b)
|
||||
|
||||
#define sql_create_$i(NAME, CMP, CONTR, $parm_simple) \\
|
||||
sql_create_complete_$i(NAME, CMP, CONTR, $parm_simple2c) \\
|
||||
|
||||
#define sql_create_c_order_$i(NAME, CMP, CONTR, $parm_order) \\
|
||||
sql_create_complete_$i(NAME, CMP, CONTR, $parm_order2c)
|
||||
|
||||
#define sql_create_c_names_$i(NAME, CMP, CONTR, $parm_names) \\
|
||||
sql_create_complete_$i(NAME, CMP, CONTR, $parm_names2c)
|
||||
|
||||
// ---------------------------------------------------
|
||||
// End Create $i
|
||||
// ---------------------------------------------------
|
||||
|
||||
---
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub prepare {
|
||||
local $_ = $_[0];
|
||||
s/\n+$//;
|
||||
s/\n[\n ]*\n/\n/g;
|
||||
s/\n+/\\\n/g;
|
||||
$_ .= "\n\n";
|
||||
return $_;
|
||||
}
|
||||
|
||||
@ -1,219 +0,0 @@
|
||||
/***********************************************************************
|
||||
datetime.cpp - Implements date and time classes compatible with MySQL's
|
||||
various date and time column types.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#define MYSQLPP_NOT_HEADER
|
||||
#include "common.h"
|
||||
|
||||
#include "datetime.h"
|
||||
|
||||
#include <iomanip>
|
||||
|
||||
#include <time.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const Date& d)
|
||||
{
|
||||
char fill = os.fill('0');
|
||||
ios::fmtflags flags = os.setf(ios::right);
|
||||
os << setw(4) << d.year << '-'
|
||||
<< setw(2) << d.month << '-'
|
||||
<< setw(2) << d.day;
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const Time& t)
|
||||
{
|
||||
char fill = os.fill('0');
|
||||
ios::fmtflags flags = os.setf(ios::right);
|
||||
os << setw(2) << t.hour << ':'
|
||||
<< setw(2) << t.minute << ':'
|
||||
<< setw(2) << t.second;
|
||||
os.flags(flags);
|
||||
os.fill(fill);
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
std::ostream& operator <<(std::ostream& os, const DateTime& dt)
|
||||
{
|
||||
operator <<(os, Date(dt));
|
||||
os << ' ';
|
||||
return operator <<(os, Time(dt));
|
||||
}
|
||||
|
||||
|
||||
cchar* Date::convert(cchar* str)
|
||||
{
|
||||
char num[5];
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = *str++;
|
||||
num[3] = *str++;
|
||||
num[4] = 0;
|
||||
year = short(strtol(num, 0, 10));
|
||||
if (*str == '-') str++;
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = 0;
|
||||
month = short(strtol(num, 0, 10));
|
||||
if (*str == '-') str++;
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = 0;
|
||||
day = short(strtol(num, 0, 10));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
cchar* Time::convert(cchar* str)
|
||||
{
|
||||
char num[5];
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = 0;
|
||||
hour = short(strtol(num,0,10));
|
||||
if (*str == ':') str++;
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = 0;
|
||||
minute = short(strtol(num,0,10));
|
||||
if (*str == ':') str++;
|
||||
|
||||
num[0] = *str++;
|
||||
num[1] = *str++;
|
||||
num[2] = 0;
|
||||
second = short(strtol(num,0,10));
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
cchar* DateTime::convert(cchar* str)
|
||||
{
|
||||
Date d;
|
||||
str = d.convert(str);
|
||||
year = d.year;
|
||||
month = d.month;
|
||||
day = d.day;
|
||||
|
||||
if (*str == ' ') ++str;
|
||||
|
||||
Time t;
|
||||
str = t.convert(str);
|
||||
hour = t.hour;
|
||||
minute = t.minute;
|
||||
second = t.second;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
short int Date::compare(const Date& other) const
|
||||
{
|
||||
if (year != other.year) return year - other.year;
|
||||
if (month != other.month) return month - other.month;
|
||||
return day - other.day;
|
||||
}
|
||||
|
||||
|
||||
short int Time::compare(const Time& other) const
|
||||
{
|
||||
if (hour != other.hour) return hour - other.hour;
|
||||
if (minute != other.minute) return minute - other.minute;
|
||||
return second - other.second;
|
||||
}
|
||||
|
||||
|
||||
short int DateTime::compare(const DateTime& other) const
|
||||
{
|
||||
Date d(*this), od(other);
|
||||
Time t(*this), ot(other);
|
||||
|
||||
if (int x = d.compare(od)) {
|
||||
return x;
|
||||
}
|
||||
else {
|
||||
return t.compare(ot);
|
||||
}
|
||||
}
|
||||
|
||||
DateTime::operator time_t() const
|
||||
{
|
||||
struct tm tm;
|
||||
tm.tm_sec = second;
|
||||
tm.tm_min = minute;
|
||||
tm.tm_hour = hour;
|
||||
tm.tm_mday = day;
|
||||
tm.tm_mon = month - (tiny_int)1;
|
||||
tm.tm_year = year - 1900;
|
||||
tm.tm_isdst = -1;
|
||||
|
||||
return mktime(&tm);
|
||||
};
|
||||
|
||||
DateTime::DateTime(time_t t)
|
||||
{
|
||||
struct tm tm;
|
||||
#if defined(_MSC_VER) && _MSC_VER >= 1400 && !defined(_STLP_VERSION) && \
|
||||
!defined(_STLP_VERSION_STR)
|
||||
// Use thread-safe localtime() replacement included with VS2005 and
|
||||
// up, but only when using native RTL, not STLport.
|
||||
localtime_s(&tm, &t);
|
||||
#elif defined(HAVE_LOCALTIME_R)
|
||||
// Detected POSIX thread-safe localtime() replacement.
|
||||
localtime_r(&t, &tm);
|
||||
#else
|
||||
// No explicitly thread-safe localtime() replacement found. This
|
||||
// may still be thread-safe, as some C libraries take special steps
|
||||
// within localtime() to get thread safety. For example, thread-
|
||||
// local storage (TLS) in some Windows compilers.
|
||||
memcpy(&tm, localtime(&t), sizeof(tm));
|
||||
#endif
|
||||
|
||||
year = tm.tm_year + 1900;
|
||||
month = tm.tm_mon + 1;
|
||||
day = tm.tm_mday;
|
||||
hour = tm.tm_hour;
|
||||
minute = tm.tm_min;
|
||||
second = tm.tm_sec;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
|
||||
@ -1,384 +0,0 @@
|
||||
/// \file datetime.h
|
||||
/// \brief Declares classes to add MySQL-compatible date and time
|
||||
/// types to C++'s type system.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_DATETIME_H
|
||||
#define MYSQLPP_DATETIME_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "coldata.h"
|
||||
#include "stream2string.h"
|
||||
#include "tiny_int.h"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Base class template for MySQL++ date and time classes.
|
||||
///
|
||||
/// This template primarily defines the comparison operators, which are
|
||||
/// all implemented in terms of compare(). Each subclass implements that
|
||||
/// as a protected method, because these operators are the only
|
||||
/// supported comparison method.
|
||||
///
|
||||
/// This template also defines interfaces for converting the object to
|
||||
/// a string form, which a subclass must define.
|
||||
template <class T> struct DTbase
|
||||
{
|
||||
/// \brief Destroy object
|
||||
virtual ~DTbase() { }
|
||||
|
||||
/// \brief Return a copy of the item in C++ string form
|
||||
operator std::string() const
|
||||
{
|
||||
return stream2string<std::string>(*this);
|
||||
}
|
||||
|
||||
/// \brief Compare this object to another of the same type
|
||||
///
|
||||
/// Returns < 0 if this object is "before" the other, 0 of they are
|
||||
/// equal, and > 0 if this object is "after" the other.
|
||||
MYSQLPP_EXPORT virtual short compare(const T& other) const = 0;
|
||||
|
||||
/// \brief Returns true if "other" is equal to this object
|
||||
bool operator ==(const T& other) const
|
||||
{
|
||||
return !compare(other);
|
||||
}
|
||||
|
||||
/// \brief Returns true if "other" is not equal to this object
|
||||
bool operator !=(const T& other) const
|
||||
{
|
||||
return compare(other);
|
||||
}
|
||||
|
||||
/// \brief Returns true if "other" is less than this object
|
||||
bool operator <(const T& other) const
|
||||
{
|
||||
return compare(other) < 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if "other" is less than or equal to this object
|
||||
bool operator <=(const T& other) const
|
||||
{
|
||||
return compare(other) <= 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if "other" is greater than this object
|
||||
bool operator >(const T& other) const
|
||||
{
|
||||
return compare(other) > 0;
|
||||
}
|
||||
|
||||
/// \brief Returns true if "other" is greater than or equal to this object
|
||||
bool operator >=(const T& other) const
|
||||
{
|
||||
return compare(other) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief C++ form of MySQL's DATETIME type.
|
||||
///
|
||||
/// Objects of this class can be inserted into streams, and
|
||||
/// initialized from MySQL DATETIME strings.
|
||||
struct DateTime : public DTbase<DateTime>
|
||||
{
|
||||
/// \brief the year
|
||||
///
|
||||
/// No surprises; the year 2005 is stored as the integer 2005.
|
||||
short int year;
|
||||
|
||||
/// \brief the month, 1-12
|
||||
tiny_int month;
|
||||
|
||||
/// \brief the day, 1-31
|
||||
tiny_int day;
|
||||
|
||||
/// \brief hour, 0-23
|
||||
tiny_int hour;
|
||||
|
||||
/// \brief minute, 0-59
|
||||
tiny_int minute;
|
||||
|
||||
/// \brief second, 0-59
|
||||
tiny_int second;
|
||||
|
||||
/// \brief Default constructor
|
||||
DateTime() :
|
||||
DTbase<DateTime>(),
|
||||
year(0),
|
||||
month(0),
|
||||
day(0),
|
||||
hour(0),
|
||||
minute(0),
|
||||
second(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object as a copy of another Date
|
||||
DateTime(const DateTime& other) :
|
||||
DTbase<DateTime>(),
|
||||
year(other.year),
|
||||
month(other.month),
|
||||
day(other.day),
|
||||
hour(other.hour),
|
||||
minute(other.minute),
|
||||
second(other.second)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object from a MySQL date-and-time string
|
||||
///
|
||||
/// String must be in the HH:MM:SS format. It doesn't have to be
|
||||
/// zero-padded.
|
||||
DateTime(cchar* str) { convert(str); }
|
||||
|
||||
/// \brief Initialize object from a MySQL date-and-time string
|
||||
///
|
||||
/// \sa DateTime(cchar*)
|
||||
DateTime(const ColData& str)
|
||||
{
|
||||
convert(str.c_str());
|
||||
}
|
||||
|
||||
/// \brief Initialize object from a MySQL date-and-time string
|
||||
///
|
||||
/// \sa DateTime(cchar*)
|
||||
DateTime(const std::string& str)
|
||||
{
|
||||
convert(str.c_str());
|
||||
}
|
||||
|
||||
/// \brief Initialize object from a time_t
|
||||
DateTime(time_t t);
|
||||
|
||||
/// \brief Compare this datetime to another.
|
||||
///
|
||||
/// Returns < 0 if this datetime is before the other, 0 of they are
|
||||
/// equal, and > 0 if this datetime is after the other.
|
||||
///
|
||||
/// This method is protected because it is merely the engine used
|
||||
/// by the various operators in DTbase.
|
||||
MYSQLPP_EXPORT short compare(const DateTime& other) const;
|
||||
|
||||
/// \brief Parse a MySQL date and time string into this object.
|
||||
MYSQLPP_EXPORT cchar* convert(cchar*);
|
||||
|
||||
/// Convert to time_t
|
||||
operator time_t() const;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Inserts a DateTime object into a C++ stream in a
|
||||
/// MySQL-compatible format.
|
||||
///
|
||||
/// The date and time are inserted into the stream, in that order,
|
||||
/// with a space between them.
|
||||
///
|
||||
/// \param os stream to insert date and time into
|
||||
/// \param dt date/time object to insert into stream
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
|
||||
const DateTime& dt);
|
||||
|
||||
|
||||
/// \brief C++ form of MySQL's DATE type.
|
||||
///
|
||||
/// Objects of this class can be inserted into streams, and
|
||||
/// initialized from MySQL DATE strings.
|
||||
struct Date : public DTbase<Date>
|
||||
{
|
||||
/// \brief the year
|
||||
///
|
||||
/// No surprises; the year 2005 is stored as the integer 2005.
|
||||
short int year;
|
||||
|
||||
/// \brief the month, 1-12
|
||||
tiny_int month;
|
||||
|
||||
/// \brief the day, 1-31
|
||||
tiny_int day;
|
||||
|
||||
/// \brief Default constructor
|
||||
Date() : year(0), month(0), day(0) { }
|
||||
|
||||
/// \brief Initialize object
|
||||
Date(short int y, tiny_int m, tiny_int d) :
|
||||
DTbase<Date>(),
|
||||
year(y),
|
||||
month(m),
|
||||
day(d)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object as a copy of another Date
|
||||
Date(const Date& other) :
|
||||
DTbase<Date>(),
|
||||
year(other.year),
|
||||
month(other.month),
|
||||
day(other.day)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object from date part of date/time object
|
||||
Date(const DateTime& other) :
|
||||
DTbase<Date>(),
|
||||
year(other.year),
|
||||
month(other.month),
|
||||
day(other.day)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object from a MySQL date string
|
||||
///
|
||||
/// String must be in the YYYY-MM-DD format. It doesn't have to be
|
||||
/// zero-padded.
|
||||
Date(cchar* str) { convert(str); }
|
||||
|
||||
/// \brief Initialize object from a MySQL date string
|
||||
///
|
||||
/// \sa Date(cchar*)
|
||||
Date(const ColData& str) { convert(str.c_str()); }
|
||||
|
||||
/// \brief Initialize object from a MySQL date string
|
||||
///
|
||||
/// \sa Date(cchar*)
|
||||
Date(const std::string& str)
|
||||
{
|
||||
convert(str.c_str());
|
||||
}
|
||||
|
||||
/// \brief Compare this date to another.
|
||||
///
|
||||
/// Returns < 0 if this date is before the other, 0 of they are
|
||||
/// equal, and > 0 if this date is after the other.
|
||||
MYSQLPP_EXPORT short int compare(const Date& other) const;
|
||||
|
||||
/// \brief Parse a MySQL date string into this object.
|
||||
MYSQLPP_EXPORT cchar* convert(cchar*);
|
||||
};
|
||||
|
||||
/// \brief Inserts a Date object into a C++ stream
|
||||
///
|
||||
/// The format is YYYY-MM-DD, zero-padded.
|
||||
///
|
||||
/// \param os stream to insert date into
|
||||
/// \param d date to insert into stream
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
|
||||
const Date& d);
|
||||
|
||||
|
||||
/// \brief C++ form of MySQL's TIME type.
|
||||
///
|
||||
/// Objects of this class can be inserted into streams, and
|
||||
/// initialized from MySQL TIME strings.
|
||||
struct Time : public DTbase<Time>
|
||||
{
|
||||
/// \brief hour, 0-23
|
||||
tiny_int hour;
|
||||
|
||||
/// \brief minute, 0-59
|
||||
tiny_int minute;
|
||||
|
||||
/// \brief second, 0-59
|
||||
tiny_int second;
|
||||
|
||||
/// \brief Default constructor
|
||||
Time() : hour(0), minute(0), second(0) { }
|
||||
|
||||
/// \brief Initialize object
|
||||
Time(tiny_int h, tiny_int m, tiny_int s) :
|
||||
hour(h),
|
||||
minute(m),
|
||||
second(s)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object as a copy of another Time
|
||||
Time(const Time& other) :
|
||||
DTbase<Time>(),
|
||||
hour(other.hour),
|
||||
minute(other.minute),
|
||||
second(other.second)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object from time part of date/time object
|
||||
Time(const DateTime& other) :
|
||||
DTbase<Time>(),
|
||||
hour(other.hour),
|
||||
minute(other.minute),
|
||||
second(other.second)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object from a MySQL time string
|
||||
///
|
||||
/// String must be in the HH:MM:SS format. It doesn't have to be
|
||||
/// zero-padded.
|
||||
Time(cchar* str) { convert(str); }
|
||||
|
||||
/// \brief Initialize object from a MySQL time string
|
||||
///
|
||||
/// \sa Time(cchar*)
|
||||
Time(const ColData& str) { convert(str.c_str()); }
|
||||
|
||||
/// \brief Initialize object from a MySQL time string
|
||||
///
|
||||
/// \sa Time(cchar*)
|
||||
Time(const std::string& str)
|
||||
{
|
||||
convert(str.c_str());
|
||||
}
|
||||
|
||||
/// \brief Parse a MySQL time string into this object.
|
||||
MYSQLPP_EXPORT cchar* convert(cchar*);
|
||||
|
||||
/// \brief Compare this time to another.
|
||||
///
|
||||
/// Returns < 0 if this time is before the other, 0 of they are
|
||||
/// equal, and > 0 if this time is after the other.
|
||||
MYSQLPP_EXPORT short int compare(const Time& other) const;
|
||||
};
|
||||
|
||||
/// \brief Inserts a Time object into a C++ stream in a MySQL-compatible
|
||||
/// format.
|
||||
///
|
||||
/// The format is HH:MM:SS, zero-padded.
|
||||
///
|
||||
/// \param os stream to insert time into
|
||||
/// \param t time to insert into stream
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& os,
|
||||
const Time& t);
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_DATETIME_H)
|
||||
@ -1,352 +0,0 @@
|
||||
/// \file exceptions.h
|
||||
/// \brief Declares the MySQL++-specific exception classes.
|
||||
///
|
||||
/// When exceptions are enabled for a given mysqlpp::OptionalExceptions
|
||||
/// derivative, any of these exceptions can be thrown on error.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_EXCEPTIONS_H
|
||||
#define MYSQLPP_EXCEPTIONS_H
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Base class for all MySQL++ custom exceptions
|
||||
|
||||
class Exception : public std::exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object as copy of another
|
||||
Exception(const Exception& e) throw() :
|
||||
std::exception(e),
|
||||
what_(e.what_)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Assign another exception object's contents to this one
|
||||
Exception& operator=(const Exception& rhs) throw()
|
||||
{
|
||||
what_ = rhs.what_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Destroy exception object
|
||||
~Exception() throw() { }
|
||||
|
||||
/// \brief Returns explanation of why exception was thrown
|
||||
virtual const char* what() const throw()
|
||||
{
|
||||
return what_.c_str();
|
||||
}
|
||||
|
||||
protected:
|
||||
/// \brief Create exception object
|
||||
Exception(const char* w = "") throw() :
|
||||
what_(w)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create exception object
|
||||
Exception(const std::string& w) throw() :
|
||||
what_(w)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief explanation of why exception was thrown
|
||||
std::string what_;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when a bad type conversion is attempted.
|
||||
|
||||
class BadConversion : public Exception
|
||||
{
|
||||
public:
|
||||
const char* type_name; ///< name of type we tried to convert to
|
||||
std::string data; ///< string form of data we tried to convert
|
||||
size_t retrieved; ///< documentation needed!
|
||||
size_t actual_size; ///< documentation needed!
|
||||
|
||||
/// \brief Create exception object, building error string
|
||||
/// dynamically
|
||||
///
|
||||
/// \param tn type name we tried to convert to
|
||||
/// \param d string form of data we tried to convert
|
||||
/// \param r ??
|
||||
/// \param a ??
|
||||
BadConversion(const char* tn, const char* d,
|
||||
size_t r, size_t a) :
|
||||
Exception("Bad type conversion: \""),
|
||||
type_name(tn),
|
||||
data(d),
|
||||
retrieved(r),
|
||||
actual_size(a)
|
||||
{
|
||||
what_ += d ? d : "<NULL>";
|
||||
what_ += "\" incompatible with \"";
|
||||
what_ += tn;
|
||||
what_ += "\" type";
|
||||
}
|
||||
|
||||
/// \brief Create exception object, given completed error string
|
||||
///
|
||||
/// \param w the "what" error string
|
||||
/// \param tn type name we tried to convert to
|
||||
/// \param d string form of data we tried to convert
|
||||
/// \param r ??
|
||||
/// \param a ??
|
||||
BadConversion(const std::string& w, const char* tn,
|
||||
const char* d, size_t r, size_t a) :
|
||||
Exception(w),
|
||||
type_name(tn),
|
||||
data(d),
|
||||
retrieved(r),
|
||||
actual_size(a)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create exception object, with error string only
|
||||
///
|
||||
/// \param w the "what" error string
|
||||
///
|
||||
/// All other data members are initialize to default values
|
||||
explicit BadConversion(const char* w = "") :
|
||||
Exception(w),
|
||||
type_name("unknown"),
|
||||
data(""),
|
||||
retrieved(0),
|
||||
actual_size(0)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy exception
|
||||
~BadConversion() throw() { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when a requested named field doesn't exist.
|
||||
///
|
||||
/// Thrown by Row::lookup_by_name() when you pass a field name that
|
||||
/// isn't in the result set.
|
||||
|
||||
class BadFieldName : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
///
|
||||
/// \param bad_field name of field the MySQL server didn't like
|
||||
explicit BadFieldName(const char* bad_field) :
|
||||
Exception(std::string("Unknown field name: ") + bad_field)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy exception
|
||||
~BadFieldName() throw() { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when you attempt to convert a SQL null
|
||||
/// to an incompatible type.
|
||||
|
||||
class BadNullConversion : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit BadNullConversion(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when you pass an unrecognized option to
|
||||
/// Connection::set_option().
|
||||
|
||||
class BadOption : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object, taking C string
|
||||
explicit BadOption(const char* w,
|
||||
Connection::Option o) :
|
||||
Exception(w),
|
||||
option_(o)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create exception object, taking C++ string
|
||||
explicit BadOption(const std::string& w,
|
||||
Connection::Option o) :
|
||||
Exception(w),
|
||||
option_(o)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Return the option that failed
|
||||
Connection::Option what_option() const { return option_; }
|
||||
|
||||
private:
|
||||
Connection::Option option_;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when not enough query parameters are
|
||||
/// provided.
|
||||
///
|
||||
/// This is used in handling template queries.
|
||||
|
||||
class BadParamCount : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit BadParamCount(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy exception
|
||||
~BadParamCount() throw() { }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when MySQL encounters a problem while
|
||||
/// processing your query.
|
||||
///
|
||||
/// This exception is typically only thrown when the server rejects a
|
||||
/// SQL query. In v1.7, it was used as a more generic exception type,
|
||||
/// for no particularly good reason.
|
||||
|
||||
class BadQuery : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object, taking C string
|
||||
explicit BadQuery(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create exception object, taking C++ string
|
||||
explicit BadQuery(const std::string& w) :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when there is a problem establishing the
|
||||
/// database server connection. It's also thrown if
|
||||
/// Connection::shutdown() fails.
|
||||
|
||||
class ConnectionFailed : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit ConnectionFailed(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when the program tries to select a new
|
||||
/// database and the server refuses for some reason.
|
||||
|
||||
class DBSelectionFailed : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit DBSelectionFailed(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when ResUse::fetch_row() walks off the end
|
||||
/// of a use-query's result set.
|
||||
|
||||
class EndOfResults : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit EndOfResults(const char* w = "end of results") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when Query::store_next() walks off the end
|
||||
/// of a use-query's multi result sets.
|
||||
|
||||
class EndOfResultSets : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit EndOfResultSets(const char* w = "end of result sets") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when a Lockable object fails.
|
||||
///
|
||||
/// Currently, "failure" means that the object is already locked when
|
||||
/// you make a call that tries to lock it again. In the future, that
|
||||
/// case will probably result in the second thread blocking, but the
|
||||
/// thread library could assert other errors that would keep this
|
||||
/// exception relevant.
|
||||
|
||||
class LockFailed : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit LockFailed(const char* w = "lock failed") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Exception thrown when you try to use an object that isn't
|
||||
/// completely initialized.
|
||||
|
||||
class ObjectNotInitialized : public Exception
|
||||
{
|
||||
public:
|
||||
/// \brief Create exception object
|
||||
explicit ObjectNotInitialized(const char* w = "") :
|
||||
Exception(w)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,48 +0,0 @@
|
||||
/***********************************************************************
|
||||
field_names.cpp - Implements the FieldNames class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#define MYSQLPP_NOT_HEADER
|
||||
#include "common.h"
|
||||
|
||||
#include "field_names.h"
|
||||
|
||||
#include "result.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
void FieldNames::init(const ResUse * res)
|
||||
{
|
||||
int num = res->num_fields();
|
||||
reserve(num);
|
||||
|
||||
for (int i = 0; i < num; i++) {
|
||||
std::string p(res->fields().at(i).name);
|
||||
str_to_lwr(p);
|
||||
push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
@ -1,105 +0,0 @@
|
||||
/// \file field_names.h
|
||||
/// \brief Declares a class to hold a list of field names.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_FIELD_NAMES_H
|
||||
#define MYSQLPP_FIELD_NAMES_H
|
||||
|
||||
#include "coldata.h"
|
||||
#include "string_util.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT ResUse;
|
||||
#endif
|
||||
|
||||
/// \brief Holds a list of SQL field names
|
||||
class FieldNames : public std::vector<std::string>
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
FieldNames() { }
|
||||
|
||||
/// \brief Create field name list from a result set
|
||||
FieldNames(const ResUse* res)
|
||||
{
|
||||
init(res);
|
||||
}
|
||||
|
||||
/// \brief Create empty field name list, reserving space for
|
||||
/// a fixed number of field names.
|
||||
FieldNames(int i) :
|
||||
std::vector<std::string>(i)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initializes the field list from a result set
|
||||
FieldNames& operator =(const ResUse* res)
|
||||
{
|
||||
init(res);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Insert \c i empty field names at beginning of list
|
||||
FieldNames& operator =(int i)
|
||||
{
|
||||
insert(begin(), i, "");
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Get the name of a field given its index.
|
||||
std::string& operator [](int i)
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
/// \brief Get the name of a field given its index, in const
|
||||
/// context.
|
||||
const std::string& operator [](int i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
/// \brief Get the index number of a field given its name
|
||||
uint operator [](std::string i) const
|
||||
{
|
||||
std::string temp(i);
|
||||
str_to_lwr(temp);
|
||||
return uint(std::find(begin(), end(), temp) - begin());
|
||||
}
|
||||
|
||||
private:
|
||||
void init(const ResUse* res);
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,45 +0,0 @@
|
||||
/***********************************************************************
|
||||
field_types.cpp - Implements the FieldTypes class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#define MYSQLPP_NOT_HEADER
|
||||
#include "common.h"
|
||||
|
||||
#include "field_types.h"
|
||||
|
||||
#include "result.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
void FieldTypes::init(const ResUse * res)
|
||||
{
|
||||
int num = res->num_fields();
|
||||
reserve(num);
|
||||
for (int i = 0; i < num; i++) {
|
||||
push_back(res->fields(i));
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
@ -1,97 +0,0 @@
|
||||
/// \file field_types.h
|
||||
/// \brief Declares a class to hold a list of SQL field type info.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_FIELD_TYPES_H
|
||||
#define MYSQLPP_FIELD_TYPES_H
|
||||
|
||||
#include "type_info.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT ResUse;
|
||||
#endif
|
||||
|
||||
/// \brief A vector of SQL field types.
|
||||
class FieldTypes : public std::vector<mysql_type_info>
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
FieldTypes() { }
|
||||
|
||||
/// \brief Create list of field types from a result set
|
||||
FieldTypes(const ResUse* res)
|
||||
{
|
||||
init(res);
|
||||
}
|
||||
|
||||
/// \brief Create fixed-size list of uninitialized field types
|
||||
FieldTypes(int i) :
|
||||
std::vector<mysql_type_info>(i)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize field list based on a result set
|
||||
FieldTypes& operator =(const ResUse* res)
|
||||
{
|
||||
init(res);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Insert a given number of uninitialized field type
|
||||
/// objects at the beginning of the list
|
||||
///
|
||||
/// \param i number of field type objects to insert
|
||||
FieldTypes& operator =(int i)
|
||||
{
|
||||
insert(begin(), i, mysql_type_info());
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Returns a field type within the list given its index.
|
||||
mysql_type_info& operator [](int i)
|
||||
{
|
||||
return std::vector<mysql_type_info>::operator [](i);
|
||||
}
|
||||
|
||||
/// \brief Returns a field type within the list given its index,
|
||||
/// in const context.
|
||||
const mysql_type_info& operator [](int i) const
|
||||
{
|
||||
return std::vector<mysql_type_info>::operator [](i);
|
||||
}
|
||||
|
||||
private:
|
||||
void init(const ResUse* res);
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,44 +0,0 @@
|
||||
/***********************************************************************
|
||||
fields.cpp - Implements the Fields class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "fields.h"
|
||||
|
||||
#include "result.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
Fields::size_type Fields::size() const
|
||||
{
|
||||
return res_->num_fields();
|
||||
}
|
||||
|
||||
const Field& Fields::at(Fields::size_type i) const
|
||||
{
|
||||
res_->field_seek(i);
|
||||
return res_->fetch_field();
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
@ -1,73 +0,0 @@
|
||||
/// \file fields.h
|
||||
/// \brief Declares a class for holding information about a set of
|
||||
/// fields.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_FIELDS_H
|
||||
#define MYSQLPP_FIELDS_H
|
||||
|
||||
#include "resiter.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT ResUse;
|
||||
#endif
|
||||
|
||||
/// \brief A container similar to \c std::vector for holding
|
||||
/// mysqlpp::Field records.
|
||||
|
||||
class MYSQLPP_EXPORT Fields : public const_subscript_container<Fields, Field>
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
Fields() { }
|
||||
|
||||
/// \brief Create a field list from a result set
|
||||
Fields(ResUse* r) :
|
||||
res_(r)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Returns a field given its index.
|
||||
const Field& at(Fields::size_type i) const;
|
||||
|
||||
/// \brief Returns a field given its index.
|
||||
const Field& at(int i) const
|
||||
{
|
||||
return at(static_cast<size_type>(i));
|
||||
}
|
||||
|
||||
size_type size() const; ///< get the number of fields
|
||||
|
||||
private:
|
||||
mutable ResUse* res_;
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,163 +0,0 @@
|
||||
/// \file lockable.h
|
||||
/// \brief Declares interface that allows a class to declare itself as
|
||||
/// "lockable".
|
||||
///
|
||||
/// The meaning of a class being lockable is very much per-class
|
||||
/// specific in this version of MySQL++. In a future version, it will
|
||||
/// imply that operations that aren't normally thread-safe will use
|
||||
/// platform mutexes if MySQL++ is configured to support them. This is
|
||||
/// planned for a version beyond v2.0. (See the Wishlist for the plan.)
|
||||
/// In the meantime, do not depend on this mechanism for thread safety;
|
||||
/// you will have to serialize access to some resources yourself.
|
||||
///
|
||||
/// To effect this variability in what it means for an object to be
|
||||
/// "locked", Lockable is only an interface. It delegates the actual
|
||||
/// implementation to a subclass of the Lock interface, using the
|
||||
/// Bridge pattern. (See Gamma et al.)
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_LOCKABLE_H
|
||||
#define MYSQLPP_LOCKABLE_H
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Abstract base class for lock implementation, used by
|
||||
/// Lockable.
|
||||
|
||||
class MYSQLPP_EXPORT Lock
|
||||
{
|
||||
public:
|
||||
/// \brief Destroy object
|
||||
virtual ~Lock() { }
|
||||
|
||||
/// \brief Lock the object
|
||||
///
|
||||
/// \return true if object was already locked
|
||||
virtual bool lock() = 0;
|
||||
|
||||
/// \brief Unlock the object
|
||||
virtual void unlock() = 0;
|
||||
|
||||
/// \brief Returns true if object is locked
|
||||
virtual bool locked() const = 0;
|
||||
|
||||
/// \brief Set the lock state.
|
||||
virtual void set(bool b) = 0;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Trivial Lock subclass, using a boolean variable as the
|
||||
/// lock flag.
|
||||
///
|
||||
/// This is the only Lock implementation available in this version of
|
||||
/// MySQL++. It will be supplemented with a better implementation for
|
||||
/// use with threads at a later date.
|
||||
|
||||
class MYSQLPP_EXPORT BasicLock : public Lock
|
||||
{
|
||||
public:
|
||||
/// \brief Create object
|
||||
BasicLock(bool is_locked = false) :
|
||||
locked_(is_locked)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy object
|
||||
~BasicLock() { }
|
||||
|
||||
/// \brief Lock the object
|
||||
///
|
||||
/// \return true if object was already locked
|
||||
bool lock()
|
||||
{
|
||||
if (locked_) {
|
||||
return true;
|
||||
}
|
||||
locked_ = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// \brief Unlock the object
|
||||
void unlock() { locked_ = false; }
|
||||
|
||||
/// \brief Returns true if object is locked
|
||||
bool locked() const { return locked_; }
|
||||
|
||||
/// \brief Set the lock state.
|
||||
void set(bool b) { locked_ = b; }
|
||||
|
||||
private:
|
||||
bool locked_;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Interface allowing a class to declare itself as "lockable".
|
||||
///
|
||||
/// A class derives from this one to acquire a standard interface for
|
||||
/// serializing operations that may not be thread-safe.
|
||||
|
||||
class MYSQLPP_EXPORT Lockable
|
||||
{
|
||||
protected:
|
||||
/// \brief Default constructor
|
||||
Lockable(bool is_locked) :
|
||||
pimpl_(new BasicLock(is_locked))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy object
|
||||
virtual ~Lockable()
|
||||
{
|
||||
delete pimpl_;
|
||||
}
|
||||
|
||||
/// \brief Lock the object
|
||||
///
|
||||
/// \return true if object was already locked
|
||||
virtual bool lock() { return pimpl_->lock(); }
|
||||
|
||||
/// \brief Unlock the object
|
||||
virtual void unlock() { pimpl_->unlock(); }
|
||||
|
||||
/// \brief Returns true if object is locked
|
||||
bool locked() const { return pimpl_->locked(); }
|
||||
|
||||
protected:
|
||||
/// \brief Set the lock state. Protected, because this method is
|
||||
/// only for use by subclass assignment operators and the like.
|
||||
void set_lock(bool b) { pimpl_->set(b); }
|
||||
|
||||
private:
|
||||
// Don't allow default construction
|
||||
Lockable();
|
||||
|
||||
// Pointer to implementation object
|
||||
Lock* pimpl_;
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // MYSQLPP_LOCKABLE_H
|
||||
|
||||
@ -1,546 +0,0 @@
|
||||
/***********************************************************************
|
||||
manip.cpp - Implements MySQL++'s various quoting/escaping stream
|
||||
manipulators.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "manip.h"
|
||||
|
||||
#include "query.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Manipulator stuff is _always_ in namespace mysqlpp.
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Set to true if you want to suppress automatic quoting
|
||||
///
|
||||
/// Works only for ColData inserted into C++ streams.
|
||||
|
||||
bool dont_quote_auto = false;
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, quoted and escaped.
|
||||
///
|
||||
/// If in.is_string is set and in.dont_escape is \e not set, the string
|
||||
/// is quoted and escaped.
|
||||
///
|
||||
/// If both in.is_string and in.dont_escape are set, the string is
|
||||
/// quoted but not escaped.
|
||||
///
|
||||
/// If in.is_string is not set, the data is inserted as-is. This is
|
||||
/// the case when you initialize SQLString with one of the constructors
|
||||
/// taking an integral type, for instance.
|
||||
|
||||
SQLQueryParms& operator <<(quote_type2 p, SQLString& in)
|
||||
{
|
||||
if (in.is_string) {
|
||||
SQLString in2('\'');
|
||||
if (in.dont_escape) {
|
||||
in2 += in;
|
||||
in2 += '\'';
|
||||
in2.processed = true;
|
||||
return *p.qparms << in2;
|
||||
}
|
||||
else {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
in2.append(s, len);
|
||||
in2 += '\'';
|
||||
in2.processed = true;
|
||||
*p.qparms << in2;
|
||||
delete[] s;
|
||||
return *p.qparms;
|
||||
}
|
||||
}
|
||||
else {
|
||||
in.processed = true;
|
||||
return *p.qparms << in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a C++ string into a stream, quoted and escaped
|
||||
///
|
||||
/// Because std::string lacks the type information we need, the string
|
||||
/// is both quoted and escaped, always.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_type1 o, const string& in)
|
||||
{
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
o.ostr->write("'", 1);
|
||||
o.ostr->write(s, len);
|
||||
o.ostr->write("'", 1);
|
||||
|
||||
delete[] s;
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a C string into a stream, quoted and escaped
|
||||
///
|
||||
/// Because C strings lack the type information we need, the string
|
||||
/// is both quoted and escaped, always.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_type1 o, const char* const& in)
|
||||
{
|
||||
size_t len = strlen(in);
|
||||
char* s = new char[len * 2 + 1];
|
||||
len = mysql_escape_string(s, in, len);
|
||||
|
||||
o.ostr->write("'", 1);
|
||||
o.ostr->write(s, len);
|
||||
o.ostr->write("'", 1);
|
||||
|
||||
delete[] s;
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Utility function used by operator<<(quote_type1, ColData)
|
||||
|
||||
template<class Str>
|
||||
inline ostream& _manip(quote_type1 o, const ColData_Tmpl<Str>& in)
|
||||
{
|
||||
if (in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
o.ostr->write(s, len);
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
o.ostr->write(in.data(), in.length());
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
}
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData into a stream, quoted and escaped
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote or escape the data, if it is not
|
||||
/// needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_type1 o, const ColData_Tmpl<string>& in)
|
||||
{
|
||||
return _manip(o, in);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData with const string into a stream, quoted and
|
||||
/// escaped
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote or escape the data, if it is not
|
||||
/// needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_type1 o, const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
return _manip(o, in);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData into a stream.
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, this
|
||||
/// operator has the information needed to choose to quote and/or escape
|
||||
/// the data as it is inserted into the stream, even if you don't use
|
||||
/// any of the quoting or escaping manipulators.
|
||||
|
||||
ostream& operator <<(ostream& o, const ColData_Tmpl<string>& in)
|
||||
{
|
||||
// Decide if we're allowed to escape or quote the data.
|
||||
bool transform_ok =
|
||||
!dont_quote_auto &&
|
||||
(o.rdbuf() != cout.rdbuf()) &&
|
||||
(o.rdbuf() != cerr.rdbuf());
|
||||
|
||||
if (transform_ok && in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
if (in.quote_q()) o << '\'';
|
||||
o.write(s, len);
|
||||
if (in.quote_q()) o << '\'';
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
bool add_quote = transform_ok && in.quote_q();
|
||||
|
||||
if (add_quote) o << '\'';
|
||||
o.write(in.data(), in.length());
|
||||
if (add_quote) o << '\'';
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData with const string into a stream.
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, this
|
||||
/// operator has the information needed to choose to quote and/or escape
|
||||
/// the data as it is inserted into the stream, even if you don't use
|
||||
/// any of the quoting or escaping manipulators.
|
||||
|
||||
ostream& operator <<(ostream& o, const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
// Decide if we're allowed to escape or quote the data.
|
||||
bool transform_ok =
|
||||
!dont_quote_auto &&
|
||||
(o.rdbuf() != cout.rdbuf()) &&
|
||||
(o.rdbuf() != cerr.rdbuf());
|
||||
|
||||
if (transform_ok && in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
if (in.quote_q()) o << '\'';
|
||||
o.write(s, len);
|
||||
if (in.quote_q()) o << '\'';
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
bool add_quote = transform_ok && in.quote_q();
|
||||
|
||||
if (add_quote) o << '\'';
|
||||
o.write(in.data(), in.length());
|
||||
if (add_quote) o << '\'';
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Insert a ColData into a SQLQuery
|
||||
///
|
||||
/// This operator appears to be a workaround for a weakness in one
|
||||
/// compiler's implementation of the C++ type system. See Wishlist for
|
||||
/// current plan on what to do about this.
|
||||
|
||||
Query& operator <<(Query& o, const ColData_Tmpl<string>& in)
|
||||
{
|
||||
if (dont_quote_auto) {
|
||||
o.write(in.data(), in.length());
|
||||
}
|
||||
else if (in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
o.write(s, len);
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
o.write(in.data(), in.length());
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Insert a ColData with const string into a SQLQuery
|
||||
///
|
||||
/// This operator appears to be a workaround for a weakness in one
|
||||
/// compiler's implementation of the C++ type system. See Wishlist for
|
||||
/// current plan on what to do about this.
|
||||
|
||||
Query& operator <<(Query& o, const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
if (dont_quote_auto) {
|
||||
o.write(in.data(), in.length());
|
||||
}
|
||||
else if (in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
o.write(s, len);
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
o.write(in.data(), in.length());
|
||||
if (in.quote_q()) o.write("'", 1);
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, quoting it unless it's
|
||||
/// data that needs no quoting.
|
||||
///
|
||||
/// We make the decision to quote the data based on the in.is_string
|
||||
/// flag. You can set it yourself, but SQLString's ctors should set
|
||||
/// it correctly for you.
|
||||
|
||||
SQLQueryParms& operator <<(quote_only_type2 p, SQLString& in)
|
||||
{
|
||||
if (in.is_string) {
|
||||
SQLString in2;
|
||||
in2 = '\'' + in + '\'';
|
||||
in2.processed = true;
|
||||
return *p.qparms << in2;
|
||||
}
|
||||
else {
|
||||
in.processed = true;
|
||||
return *p.qparms << in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData into a stream, quoted
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_only_type1 o, const ColData_Tmpl<string>& in)
|
||||
{
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
o.ostr->write(in.data(), in.length());
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData with const string into a stream, quoted
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_only_type1 o,
|
||||
const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
o.ostr->write(in.data(), in.length());
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, double-quoting it (")
|
||||
/// unless it's data that needs no quoting.
|
||||
///
|
||||
/// We make the decision to quote the data based on the in.is_string
|
||||
/// flag. You can set it yourself, but SQLString's ctors should set
|
||||
/// it correctly for you.
|
||||
|
||||
SQLQueryParms& operator <<(quote_double_only_type2 p, SQLString& in)
|
||||
{
|
||||
if (in.is_string) {
|
||||
SQLString in2;
|
||||
in2 = "\"" + in + "\"";
|
||||
in2.processed = true;
|
||||
return *p.qparms << in2;
|
||||
}
|
||||
else {
|
||||
in.processed = true;
|
||||
return *p.qparms << in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData into a stream, double-quoted (")
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_double_only_type1 o,
|
||||
const ColData_Tmpl<string>& in)
|
||||
{
|
||||
if (in.quote_q()) o.ostr->write("\"", 1);
|
||||
o.ostr->write(in.data(), in.length());
|
||||
if (in.quote_q()) o.ostr->write("\"", 1);
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData with const string into a stream,
|
||||
/// double-quoted (")
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to actually quote the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(quote_double_only_type1 o,
|
||||
const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
o.ostr->write(in.data(), in.length());
|
||||
if (in.quote_q()) o.ostr->write("'", 1);
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
SQLQueryParms& operator <<(escape_type2 p, SQLString& in)
|
||||
{
|
||||
if (in.is_string && !in.dont_escape) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
|
||||
SQLString in2(s, len);
|
||||
in2.processed = true;
|
||||
*p.qparms << in2;
|
||||
|
||||
delete[] s;
|
||||
return *p.qparms;
|
||||
}
|
||||
else {
|
||||
in.processed = true;
|
||||
return *p.qparms << in;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a C++ string into a stream, escaping special SQL
|
||||
/// characters
|
||||
///
|
||||
/// Because std::string lacks the type information we need, the string
|
||||
/// is always escaped, even if it doesn't need it.
|
||||
|
||||
template <>
|
||||
std::ostream& operator <<(escape_type1 o, const std::string& in)
|
||||
{
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
o.ostr->write(s, len);
|
||||
delete[] s;
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a C string into a stream, escaping special SQL
|
||||
/// characters
|
||||
///
|
||||
/// Because C's type system lacks the information we need to second-
|
||||
/// guess this manipulator, we always run the escaping algorithm on
|
||||
/// the data, even if it's not needed.
|
||||
|
||||
template <>
|
||||
ostream& operator <<(escape_type1 o, const char* const& in)
|
||||
{
|
||||
size_t len = strlen(in);
|
||||
char* s = new char[len * 2 + 1];
|
||||
len = mysql_escape_string(s, in, len);
|
||||
o.ostr->write(s, len);
|
||||
delete[] s;
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Utility function used by operator<<(escape_type1, ColData)
|
||||
|
||||
template <class Str>
|
||||
inline ostream& _manip(escape_type1 o, const ColData_Tmpl<Str>& in)
|
||||
{
|
||||
if (in.escape_q()) {
|
||||
char* s = new char[in.length() * 2 + 1];
|
||||
size_t len = mysql_escape_string(s, in.data(), in.length());
|
||||
o.ostr->write(s, len);
|
||||
delete[] s;
|
||||
}
|
||||
else {
|
||||
o.ostr->write(in.data(), in.length());
|
||||
}
|
||||
|
||||
return *o.ostr;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData into a stream, escaping special SQL
|
||||
/// characters
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to escape the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
std::ostream& operator <<(escape_type1 o,
|
||||
const ColData_Tmpl<std::string>& in)
|
||||
{
|
||||
return _manip(o, in);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a ColData with const string into a stream, escaping
|
||||
/// special SQL characters
|
||||
///
|
||||
/// Because ColData was designed to contain MySQL type data, we may
|
||||
/// choose not to escape the data, if it is not needed.
|
||||
|
||||
template <>
|
||||
std::ostream& operator <<(escape_type1 o, const ColData_Tmpl<const_string>& in)
|
||||
{
|
||||
return _manip(o, in);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, with no escaping or
|
||||
/// quoting.
|
||||
|
||||
SQLQueryParms& operator <<(do_nothing_type2 p, SQLString& in)
|
||||
{
|
||||
in.processed = true;
|
||||
return *p.qparms << in;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, with no escaping or
|
||||
/// quoting, and without marking the string as having been "processed".
|
||||
|
||||
SQLQueryParms& operator <<(ignore_type2 p, SQLString& in)
|
||||
{
|
||||
return *p.qparms << in;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,680 +0,0 @@
|
||||
/// \file manip.h
|
||||
/// \brief Declares \c std::ostream manipulators useful with SQL syntax.
|
||||
///
|
||||
/// These manipulators let you automatically quote elements or escape
|
||||
/// characters that are special in SQL when inserting them into an
|
||||
/// \c std::ostream. Since mysqlpp::Query is an ostream, these
|
||||
/// manipulators make it easier to build syntactically-correct SQL
|
||||
/// queries.
|
||||
///
|
||||
/// This file also includes \c operator<< definitions for ColData_Tmpl,
|
||||
/// one of the MySQL++ string-like classes. When inserting such items
|
||||
/// into a stream, they are automatically quoted and escaped as
|
||||
/// necessary unless the global variable dont_quote_auto is set to true.
|
||||
/// These operators are smart enough to turn this behavior off when
|
||||
/// the stream is \c cout or \c cerr, however, since quoting and
|
||||
/// escaping are surely not required in that instance.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_MANIP_H
|
||||
#define MYSQLPP_MANIP_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "datetime.h"
|
||||
#include "myset.h"
|
||||
#include "sql_string.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
/// All global symbols in MySQL++ are in namespace mysqlpp. This is
|
||||
/// needed because many symbols are rather generic (e.g. Row, Query...),
|
||||
/// so there is a serious danger of conflicts.
|
||||
namespace mysqlpp {
|
||||
|
||||
class Query;
|
||||
|
||||
extern bool dont_quote_auto;
|
||||
|
||||
|
||||
/// \enum quote_type0
|
||||
/// \anchor quote_manip
|
||||
///
|
||||
/// The standard 'quote' manipulator.
|
||||
///
|
||||
/// Insert this into a stream to put single quotes around the next item
|
||||
/// in the stream, and escape characters within it that are 'special'
|
||||
/// in SQL. This is the most generally useful of the manipulators.
|
||||
|
||||
|
||||
enum quote_type0
|
||||
{
|
||||
quote ///< insert into a std::ostream to single-quote and escape next item
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct quote_type1
|
||||
{
|
||||
std::ostream * ostr;
|
||||
quote_type1(std::ostream * o) :
|
||||
ostr(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_type1 operator <<(std::ostream& o,
|
||||
quote_type0 /*esc */)
|
||||
{
|
||||
return quote_type1(&o);
|
||||
}
|
||||
|
||||
|
||||
class SQLQueryParms;
|
||||
struct quote_type2
|
||||
{
|
||||
SQLQueryParms *qparms;
|
||||
quote_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_type2 operator <<(SQLQueryParms& p,
|
||||
quote_type0 /*esc */)
|
||||
{
|
||||
return quote_type2(&p);
|
||||
}
|
||||
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator <<(quote_type1 o, const T & in)
|
||||
{
|
||||
return *o.ostr << in;
|
||||
}
|
||||
|
||||
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(std::ostream& o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
MYSQLPP_EXPORT Query& operator <<(Query& o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
MYSQLPP_EXPORT Query& operator <<(Query& o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
|
||||
const std::string& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
|
||||
const char* const& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_type1 o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
char* const& in)
|
||||
{
|
||||
return operator <<(o, const_cast<const char* const&>(in));
|
||||
}
|
||||
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
char in[])
|
||||
{
|
||||
return operator <<(o, static_cast<const char* const&>(in));
|
||||
}
|
||||
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
const char in[])
|
||||
{
|
||||
return operator <<(o, const_cast<char* const&>(in));
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
const Date& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
const Time& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_type1 o,
|
||||
const DateTime& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <class ST>
|
||||
inline std::ostream& operator <<(quote_type1 o, const Set<ST>& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \enum quote_only_type0
|
||||
/// \anchor quote_only_manip
|
||||
///
|
||||
/// The 'quote_only' manipulator.
|
||||
///
|
||||
/// Similar to <a href="#quote_manip">quote manipulator</a>, except that
|
||||
/// it doesn't escape special SQL characters.
|
||||
|
||||
enum quote_only_type0
|
||||
{
|
||||
quote_only ///< insert into a std::ostream to single-quote next item
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct quote_only_type1
|
||||
{
|
||||
std::ostream* ostr;
|
||||
quote_only_type1(std::ostream* o) :
|
||||
ostr(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_only_type1 operator <<(std::ostream& o,
|
||||
quote_only_type0 /* esc */)
|
||||
{
|
||||
return quote_only_type1(&o);
|
||||
}
|
||||
|
||||
|
||||
struct quote_only_type2
|
||||
{
|
||||
SQLQueryParms* qparms;
|
||||
quote_only_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_only_type2 operator <<(SQLQueryParms& p,
|
||||
quote_only_type0 /* esc */)
|
||||
{
|
||||
return quote_only_type2(&p);
|
||||
}
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_only_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator <<(quote_only_type1 o, const T& in)
|
||||
{
|
||||
return *o.ostr << in;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_only_type1 o,
|
||||
const std::string& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_only_type1 o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_only_type1 o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_only_type1 o,
|
||||
const Date& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_only_type1 o,
|
||||
const Time& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(quote_only_type1 o,
|
||||
const DateTime& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
|
||||
template <class ST>
|
||||
inline std::ostream& operator <<(quote_only_type1 o, const Set<ST>& in)
|
||||
{
|
||||
return *o.ostr << '\'' << in << '\'';
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \enum quote_double_only_type0
|
||||
/// \anchor quote_double_manip
|
||||
///
|
||||
/// The 'double_quote_only' manipulator.
|
||||
///
|
||||
/// Similar to <a href="#quote_only_manip">quote_only manipulator</a>,
|
||||
/// except that it uses double quotes instead of single quotes.
|
||||
|
||||
enum quote_double_only_type0
|
||||
{
|
||||
quote_double_only ///< insert into a std::ostream to double-quote next item
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct quote_double_only_type1
|
||||
{
|
||||
std::ostream* ostr;
|
||||
quote_double_only_type1(std::ostream* o) :
|
||||
ostr(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_double_only_type1 operator <<(
|
||||
std::ostream& o, quote_double_only_type0 /* esc */)
|
||||
{
|
||||
return quote_double_only_type1(&o);
|
||||
}
|
||||
|
||||
|
||||
struct quote_double_only_type2
|
||||
{
|
||||
SQLQueryParms *qparms;
|
||||
quote_double_only_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline quote_double_only_type2 operator <<(
|
||||
SQLQueryParms& p, quote_double_only_type0 /* esc */)
|
||||
{
|
||||
return quote_double_only_type2(&p);
|
||||
}
|
||||
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(quote_double_only_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator <<(quote_double_only_type1 o, const T& in)
|
||||
{
|
||||
return *o.ostr << in;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(
|
||||
quote_double_only_type1 o, const std::string& in)
|
||||
{
|
||||
return *o.ostr << '"' << in << '"';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(quote_double_only_type1 o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream & operator <<(quote_double_only_type1 o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(
|
||||
quote_double_only_type1 o, const Date& in)
|
||||
{
|
||||
return *o.ostr << '"' << in << '"';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(
|
||||
quote_double_only_type1 o, const Time& in)
|
||||
{
|
||||
return *o.ostr << '"' << in << '"';
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(
|
||||
quote_double_only_type1 o, const DateTime& in)
|
||||
{
|
||||
return *o.ostr << '"' << in << '"';
|
||||
}
|
||||
|
||||
|
||||
template <class ST>
|
||||
inline std::ostream& operator <<(quote_double_only_type1 o,
|
||||
const Set<ST>& in)
|
||||
{
|
||||
return *o.ostr << '"' << in << '"';
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \enum escape_type0
|
||||
/// The 'escape' manipulator.
|
||||
///
|
||||
/// Calls mysql_escape_string() in the MySQL C API on the following
|
||||
/// argument to prevent any special SQL characters from being
|
||||
/// interpreted.
|
||||
|
||||
enum escape_type0 { escape };
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct escape_type1
|
||||
{
|
||||
std::ostream* ostr;
|
||||
escape_type1(std::ostream* o) :
|
||||
ostr(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline escape_type1 operator <<(std::ostream& o,
|
||||
escape_type0 /*esc */)
|
||||
{
|
||||
return escape_type1(&o);
|
||||
}
|
||||
|
||||
|
||||
struct escape_type2
|
||||
{
|
||||
SQLQueryParms *qparms;
|
||||
escape_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline escape_type2 operator <<(SQLQueryParms& p,
|
||||
escape_type0 /*esc */)
|
||||
{
|
||||
return escape_type2(&p);
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \brief Inserts a SQLString into a stream, escaping special SQL
|
||||
/// characters
|
||||
///
|
||||
/// We actually only do the escaping if in.is_string is set but
|
||||
/// in.dont_escape is not. If that is not the case, we insert the
|
||||
/// string data directly.
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(escape_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
|
||||
/// \brief Inserts any type T into a stream that has an operator<<
|
||||
/// defined for it.
|
||||
///
|
||||
/// Does not actually escape that data! Use one of the other forms of
|
||||
/// operator<< for the escape manipulator if you need escaping. This
|
||||
/// template exists to catch cases like inserting an \c int after the
|
||||
/// escape manipulator: you don't actually want escaping in this
|
||||
/// instance.
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator <<(escape_type1 o, const T& in)
|
||||
{
|
||||
return *o.ostr << in;
|
||||
}
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
|
||||
const std::string& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
|
||||
const char* const& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
|
||||
const ColData_Tmpl<std::string>& in);
|
||||
|
||||
|
||||
template <>
|
||||
MYSQLPP_EXPORT std::ostream& operator <<(escape_type1 o,
|
||||
const ColData_Tmpl<const_string>& in);
|
||||
|
||||
|
||||
/// \brief Inserts a C string into a stream, escaping special SQL
|
||||
/// characters.
|
||||
///
|
||||
/// This version exists solely to handle constness problems. We force
|
||||
/// everything to the completely-const version: operator<<(escape_type1,
|
||||
/// const char* const&).
|
||||
|
||||
template <>
|
||||
inline std::ostream& operator <<(escape_type1 o,
|
||||
char* const& in)
|
||||
{
|
||||
return operator <<(o, const_cast<const char* const&>(in));
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts an array of char into a stream, escaping special SQL
|
||||
/// characters.
|
||||
|
||||
inline std::ostream& operator <<(escape_type1 o,
|
||||
char in[])
|
||||
{
|
||||
return operator <<(o, static_cast<const char* const&>(in));
|
||||
}
|
||||
|
||||
inline std::ostream& operator <<(escape_type1 o,
|
||||
const char in[])
|
||||
{
|
||||
return operator <<(o, const_cast<char* const&>(in));
|
||||
}
|
||||
|
||||
|
||||
/// \enum do_nothing_type0
|
||||
/// \anchor do_nothing_manip
|
||||
///
|
||||
/// The 'do_nothing' manipulator.
|
||||
///
|
||||
/// Does exactly what it says: nothing. Used as a dummy manipulator when
|
||||
/// you are required to use some manipulator but don't want anything to
|
||||
/// be done to the following item. When used with SQLQueryParms it will
|
||||
/// make sure that it does not get formatted in any way, overriding any
|
||||
/// setting set by the template query.
|
||||
|
||||
enum do_nothing_type0
|
||||
{
|
||||
do_nothing ///< insert into a std::ostream to override manipulation of next item
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct do_nothing_type1
|
||||
{
|
||||
std::ostream* ostr;
|
||||
do_nothing_type1(std::ostream* o) :
|
||||
ostr(o)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline do_nothing_type1 operator <<(std::ostream& o,
|
||||
do_nothing_type0 /*esc */)
|
||||
{
|
||||
return do_nothing_type1(&o);
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline std::ostream& operator <<(do_nothing_type1 o, const T& in)
|
||||
{
|
||||
return *o.ostr << in;
|
||||
}
|
||||
|
||||
|
||||
struct do_nothing_type2
|
||||
{
|
||||
SQLQueryParms *qparms;
|
||||
do_nothing_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline do_nothing_type2 operator <<(SQLQueryParms& p,
|
||||
do_nothing_type0 /* esc */)
|
||||
{
|
||||
return do_nothing_type2(&p);
|
||||
}
|
||||
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(do_nothing_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \enum ignore_type0
|
||||
/// \anchor ignore_manip
|
||||
///
|
||||
/// The 'ignore' manipulator.
|
||||
///
|
||||
/// Only valid when used with SQLQueryParms. It's a dummy manipulator
|
||||
/// like the <a href="#do_nothing_manip">do_nothing manipulator</a>,
|
||||
/// except that it will not override formatting set by the template
|
||||
/// query. It is simply ignored.
|
||||
|
||||
enum ignore_type0
|
||||
{
|
||||
ignore ///< insert into a std::ostream as a dummy manipulator
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
struct ignore_type2
|
||||
{
|
||||
SQLQueryParms* qparms;
|
||||
ignore_type2(SQLQueryParms* p) :
|
||||
qparms(p)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline ignore_type2 operator <<(SQLQueryParms& p,
|
||||
ignore_type0 /* esc*/)
|
||||
{
|
||||
return ignore_type2(&p);
|
||||
}
|
||||
|
||||
|
||||
MYSQLPP_EXPORT SQLQueryParms& operator <<(ignore_type2 p,
|
||||
SQLString& in);
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,35 +0,0 @@
|
||||
/***********************************************************************
|
||||
myset.cpp - Implements the Set template. (Not to be confused with
|
||||
std::set, which this template wraps.)
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "myset.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
template class Set<std::set<std::string> >;
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,157 +0,0 @@
|
||||
/// \file myset.h
|
||||
/// \brief Declares templates for generating custom containers used
|
||||
/// elsewhere in the library.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_MYSET_H
|
||||
#define MYSQLPP_MYSET_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "coldata.h"
|
||||
#include "stream2string.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
template <class T, class key_type = typename T::key_type>
|
||||
class MYSQLPP_EXPORT SetInsert
|
||||
{
|
||||
public:
|
||||
SetInsert(T* o) : object_(o) { }
|
||||
void operator ()(const key_type& data) { object_->insert(data); }
|
||||
|
||||
private:
|
||||
T* object_;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline SetInsert< std::set<T> > set_insert(std::set<T>* o)
|
||||
{
|
||||
return SetInsert< std::set<T> >(o);
|
||||
}
|
||||
|
||||
template <class Insert>
|
||||
void set2container(const char* str, Insert insert);
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \brief A special std::set derivative for holding MySQL data sets.
|
||||
|
||||
template <class Container = std::set<std::string> >
|
||||
class MYSQLPP_EXPORT Set : public Container
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
Set() {};
|
||||
|
||||
/// \brief Create object from a comma-separated list of values
|
||||
Set(const char* str)
|
||||
{
|
||||
set2container(str, set_insert(this));
|
||||
}
|
||||
|
||||
/// \brief Create object from a comma-separated list of values
|
||||
Set(const std::string& str)
|
||||
{
|
||||
set2container(str.c_str(), set_insert(this));
|
||||
}
|
||||
|
||||
/// \brief Create object from a comma-separated list of values
|
||||
Set(const ColData& str)
|
||||
{
|
||||
set2container(str.c_str(), set_insert(this));
|
||||
}
|
||||
|
||||
/// \brief Insert this set's data into a C++ stream in
|
||||
/// comma-separated format.
|
||||
std::ostream& out_stream(std::ostream& s) const
|
||||
{
|
||||
typename Container::const_iterator i = Container::begin();
|
||||
typename Container::const_iterator e = Container::end();
|
||||
|
||||
while (true) {
|
||||
s << *i;
|
||||
if (++i == e) {
|
||||
break;
|
||||
}
|
||||
s << ",";
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// \brief Convert this set's data to a string containing
|
||||
/// comma-separated items.
|
||||
operator std::string() { return stream2string<std::string>(*this); }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Inserts a Set object into a C++ stream
|
||||
template <class Container>
|
||||
inline std::ostream& operator <<(std::ostream& s,
|
||||
const Set<Container>& d)
|
||||
{
|
||||
return d.out_stream(s);
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
template <class Insert>
|
||||
void set2container(const char* str, Insert insert)
|
||||
{
|
||||
while (1) {
|
||||
MutableColData s("");
|
||||
while (*str != ',' && *str) {
|
||||
s += *str;
|
||||
str++;
|
||||
}
|
||||
|
||||
insert(s);
|
||||
|
||||
if (!*str) {
|
||||
break;
|
||||
}
|
||||
|
||||
str++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,38 +0,0 @@
|
||||
/***********************************************************************
|
||||
mysql++.cpp - Implements functions dealing with the library itself,
|
||||
as opposed to individual features of the library.
|
||||
|
||||
Copyright (c) 2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "mysql++.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
unsigned int
|
||||
get_library_version()
|
||||
{
|
||||
return MYSQLPP_HEADER_VERSION;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,140 +0,0 @@
|
||||
/// \file mysql++.h
|
||||
/// \brief The main MySQL++ header file.
|
||||
///
|
||||
/// This file brings in all MySQL++ headers except for custom.h and
|
||||
/// custom-macros.h which are a strictly optional feature of MySQL++.
|
||||
///
|
||||
/// There is no point in trying to optimize which headers you include,
|
||||
/// because the MySQL++ headers are so intertwined. You can only get
|
||||
/// trivial compile time benefits, at the expense of clarity.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_MYSQLPP_H
|
||||
#define MYSQLPP_MYSQLPP_H
|
||||
|
||||
/// \brief Encode MySQL++ library version number.
|
||||
///
|
||||
/// This macro takes major, minor and bugfix numbers (e.g. 1, 2, and 3)
|
||||
/// and encodes them like 0x010203.
|
||||
#define MYSQLPP_VERSION(major, minor, bugfix) \
|
||||
(((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
|
||||
/// \brief Get the library version number that mysql++.h comes from
|
||||
///
|
||||
/// MySQL++ Version number that the mysql++.h header file comes from,
|
||||
/// encoded by MYSQLPP_VERSION macro. Compare this value to what
|
||||
/// mysqlpp_lib_version() returns in order to ensure that your program
|
||||
/// is using header files from the same version of MySQL++ as the
|
||||
/// actual library you're linking to.
|
||||
#define MYSQLPP_HEADER_VERSION MYSQLPP_VERSION(2, 3, 2)
|
||||
|
||||
// This #include order gives the fewest redundancies in the #include
|
||||
// dependency chain.
|
||||
#include "connection.h"
|
||||
#include "query.h"
|
||||
#include "sql_types.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Get the current MySQL++ library version number
|
||||
///
|
||||
/// MySQL++ version number that the program is actually linked to,
|
||||
/// encoded by MYSQLPP_VERSION macro. Compare this value to the
|
||||
/// MYSQLPP_HEADER_VERSION constant in order to ensure that your
|
||||
/// program is using header files from the same version of MySQL++ as
|
||||
/// the actual library you're linking to.
|
||||
MYSQLPP_EXPORT unsigned int get_library_version();
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_MYSQLPP_H)
|
||||
|
||||
|
||||
/**
|
||||
\mainpage MySQL++ Reference Manual
|
||||
|
||||
\section getting_started Getting Started
|
||||
|
||||
The best place to get started is the
|
||||
<a href="../userman/index.html">user manual</a>. It provides
|
||||
a guide to the example programs and more.
|
||||
|
||||
|
||||
\section classes Major Classes
|
||||
|
||||
In MySQL++, the main user-facing classes are mysqlpp::Connection,
|
||||
mysqlpp::Query, mysqlpp::Result, and mysqlpp::Row.
|
||||
|
||||
In addition, MySQL++ has a mechanism called Specialized SQL
|
||||
Structures (SSQLS), which allow you to create C++ structures
|
||||
that parallel the definition of the tables in your database
|
||||
schema. These let you manipulate the data in your database using
|
||||
native C++ data structures. Programs using this feature often
|
||||
include very little SQL code, because MySQL++ can generate most
|
||||
of what you need automatically when using SSQLSes. There is a
|
||||
whole chapter in the user manual on how to use this feature of
|
||||
the library, plus a section in the user manual's tutorial chapter
|
||||
to introduce it. It's possible to use MySQL++ effectively without
|
||||
using SSQLS, but it sure makes some things a lot easier.
|
||||
|
||||
|
||||
\section files Major Files
|
||||
|
||||
The only two header files your program ever needs to include
|
||||
are mysql++.h, and optionally custom.h. (The latter implements
|
||||
the SSQLS mechanism.) All of the other files are used within
|
||||
the library only.
|
||||
|
||||
|
||||
\section user_questions If You Have Questions...
|
||||
|
||||
If you want to email someone to ask questions about this library,
|
||||
we greatly prefer that you send mail to the MySQL++ mailing list,
|
||||
which you can subscribe to here: http://lists.mysql.com/plusplus
|
||||
|
||||
That mailing list is archived, so if you have questions, do a
|
||||
search to see if the question has been asked before.
|
||||
|
||||
You may find people's individual email addresses in various
|
||||
files within the MySQL++ distribution. Please do not send mail
|
||||
to them unless you are sending something that is inherently
|
||||
personal. Questions that are about MySQL++ usage may well be
|
||||
ignored if you send them to our personal email accounts. Those of
|
||||
us still active in MySQL++ development monitor the mailing list,
|
||||
so you aren't getting any extra "coverage" by sending messages
|
||||
to those addresses in addition to the mailing list.
|
||||
|
||||
|
||||
\section licensing Licensing
|
||||
|
||||
MySQL++ is licensed under the GNU Lesser General Public License,
|
||||
which you should have received with the distribution package in
|
||||
a file called "LGPL" or "LICENSE". You can also view it here:
|
||||
http://www.gnu.org/licenses/lgpl.html or receive a copy by
|
||||
writing to Free Software Foundation, Inc., 51 Franklin Street,
|
||||
Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
@ -1,140 +0,0 @@
|
||||
/// \file mysql++.h
|
||||
/// \brief The main MySQL++ header file.
|
||||
///
|
||||
/// This file brings in all MySQL++ headers except for custom.h and
|
||||
/// custom-macros.h which are a strictly optional feature of MySQL++.
|
||||
///
|
||||
/// There is no point in trying to optimize which headers you include,
|
||||
/// because the MySQL++ headers are so intertwined. You can only get
|
||||
/// trivial compile time benefits, at the expense of clarity.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_MYSQLPP_H
|
||||
#define MYSQLPP_MYSQLPP_H
|
||||
|
||||
/// \brief Encode MySQL++ library version number.
|
||||
///
|
||||
/// This macro takes major, minor and bugfix numbers (e.g. 1, 2, and 3)
|
||||
/// and encodes them like 0x010203.
|
||||
#define MYSQLPP_VERSION(major, minor, bugfix) \
|
||||
(((major) << 16) | ((minor) << 8) | (bugfix))
|
||||
|
||||
/// \brief Get the library version number that mysql++.h comes from
|
||||
///
|
||||
/// MySQL++ Version number that the mysql++.h header file comes from,
|
||||
/// encoded by MYSQLPP_VERSION macro. Compare this value to what
|
||||
/// mysqlpp_lib_version() returns in order to ensure that your program
|
||||
/// is using header files from the same version of MySQL++ as the
|
||||
/// actual library you're linking to.
|
||||
#define MYSQLPP_HEADER_VERSION MYSQLPP_VERSION(@MYSQLPP_VERSION_MAJOR@, @MYSQLPP_VERSION_MINOR@, @MYSQLPP_VERSION_BUGFIX@)
|
||||
|
||||
// This #include order gives the fewest redundancies in the #include
|
||||
// dependency chain.
|
||||
#include "connection.h"
|
||||
#include "query.h"
|
||||
#include "sql_types.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Get the current MySQL++ library version number
|
||||
///
|
||||
/// MySQL++ version number that the program is actually linked to,
|
||||
/// encoded by MYSQLPP_VERSION macro. Compare this value to the
|
||||
/// MYSQLPP_HEADER_VERSION constant in order to ensure that your
|
||||
/// program is using header files from the same version of MySQL++ as
|
||||
/// the actual library you're linking to.
|
||||
MYSQLPP_EXPORT unsigned int get_library_version();
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_MYSQLPP_H)
|
||||
|
||||
|
||||
/**
|
||||
\mainpage MySQL++ Reference Manual
|
||||
|
||||
\section getting_started Getting Started
|
||||
|
||||
The best place to get started is the
|
||||
<a href="../userman/index.html">user manual</a>. It provides
|
||||
a guide to the example programs and more.
|
||||
|
||||
|
||||
\section classes Major Classes
|
||||
|
||||
In MySQL++, the main user-facing classes are mysqlpp::Connection,
|
||||
mysqlpp::Query, mysqlpp::Result, and mysqlpp::Row.
|
||||
|
||||
In addition, MySQL++ has a mechanism called Specialized SQL
|
||||
Structures (SSQLS), which allow you to create C++ structures
|
||||
that parallel the definition of the tables in your database
|
||||
schema. These let you manipulate the data in your database using
|
||||
native C++ data structures. Programs using this feature often
|
||||
include very little SQL code, because MySQL++ can generate most
|
||||
of what you need automatically when using SSQLSes. There is a
|
||||
whole chapter in the user manual on how to use this feature of
|
||||
the library, plus a section in the user manual's tutorial chapter
|
||||
to introduce it. It's possible to use MySQL++ effectively without
|
||||
using SSQLS, but it sure makes some things a lot easier.
|
||||
|
||||
|
||||
\section files Major Files
|
||||
|
||||
The only two header files your program ever needs to include
|
||||
are mysql++.h, and optionally custom.h. (The latter implements
|
||||
the SSQLS mechanism.) All of the other files are used within
|
||||
the library only.
|
||||
|
||||
|
||||
\section user_questions If You Have Questions...
|
||||
|
||||
If you want to email someone to ask questions about this library,
|
||||
we greatly prefer that you send mail to the MySQL++ mailing list,
|
||||
which you can subscribe to here: http://lists.mysql.com/plusplus
|
||||
|
||||
That mailing list is archived, so if you have questions, do a
|
||||
search to see if the question has been asked before.
|
||||
|
||||
You may find people's individual email addresses in various
|
||||
files within the MySQL++ distribution. Please do not send mail
|
||||
to them unless you are sending something that is inherently
|
||||
personal. Questions that are about MySQL++ usage may well be
|
||||
ignored if you send them to our personal email accounts. Those of
|
||||
us still active in MySQL++ development monitor the mailing list,
|
||||
so you aren't getting any extra "coverage" by sending messages
|
||||
to those addresses in addition to the mailing list.
|
||||
|
||||
|
||||
\section licensing Licensing
|
||||
|
||||
MySQL++ is licensed under the GNU Lesser General Public License,
|
||||
which you should have received with the distribution package in
|
||||
a file called "LGPL" or "LICENSE". You can also view it here:
|
||||
http://www.gnu.org/licenses/lgpl.html or receive a copy by
|
||||
writing to Free Software Foundation, Inc., 51 Franklin Street,
|
||||
Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
@ -1,138 +0,0 @@
|
||||
/// \file noexceptions.h
|
||||
/// \brief Declares interface that allows exceptions to be optional
|
||||
///
|
||||
/// A class may inherit from OptionalExceptions, which will add to it
|
||||
/// a mechanism by which a user can tell objects of that class to
|
||||
/// suppress exceptions. (They are enabled by default.) This module
|
||||
/// also declares a NoExceptions class, objects of which take a
|
||||
/// reference to any class derived from OptionalExceptions. The
|
||||
/// NoExceptions constructor calls the method that disables exceptions,
|
||||
/// and the destructor reverts them to the previous state. One uses
|
||||
/// the NoExceptions object within a scope to suppress exceptions in
|
||||
/// that block, without having to worry about reverting the setting when
|
||||
/// the block exits.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_NOEXCEPTIONS_H
|
||||
#define MYSQLPP_NOEXCEPTIONS_H
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT NoExceptions;
|
||||
#endif
|
||||
|
||||
/// \brief Interface allowing a class to have optional exceptions.
|
||||
///
|
||||
/// A class derives from this one to acquire a standard interface for
|
||||
/// disabling exceptions, possibly only temporarily. By default,
|
||||
/// exceptions are enabled.
|
||||
|
||||
class MYSQLPP_EXPORT OptionalExceptions
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// \param e if true, exceptions are enabled (this is the default)
|
||||
OptionalExceptions(bool e = true) :
|
||||
exceptions_(e)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Destroy object
|
||||
virtual ~OptionalExceptions() { }
|
||||
|
||||
/// \brief Enable exceptions from the object
|
||||
void enable_exceptions() { exceptions_ = true; }
|
||||
|
||||
/// \brief Disable exceptions from the object
|
||||
void disable_exceptions() { exceptions_ = false; }
|
||||
|
||||
/// \brief Returns true if exceptions are enabled
|
||||
bool throw_exceptions() const { return exceptions_; }
|
||||
|
||||
protected:
|
||||
/// \brief Sets the exception state to a particular value
|
||||
///
|
||||
/// This method is protected because it is only intended for use by
|
||||
/// subclasses' copy constructors and the like.
|
||||
void set_exceptions(bool e) { exceptions_ = e; }
|
||||
|
||||
/// \brief Declare NoExceptions to be our friend so it can access
|
||||
/// our protected functions.
|
||||
friend class NoExceptions;
|
||||
|
||||
private:
|
||||
bool exceptions_;
|
||||
};
|
||||
|
||||
|
||||
/// \brief Disable exceptions in an object derived from
|
||||
/// OptionalExceptions.
|
||||
///
|
||||
/// This class was designed to be created on the stack, taking a
|
||||
/// reference to a subclass of OptionalExceptions. (We call that our
|
||||
/// "associate" object.) On creation, we save that object's current
|
||||
/// exception state, and disable exceptions. On destruction, we restore
|
||||
/// our associate's previous state.
|
||||
|
||||
class MYSQLPP_EXPORT NoExceptions
|
||||
{
|
||||
public:
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// Takes a reference to an OptionalExceptions derivative,
|
||||
/// saves that object's current exception state, and disables
|
||||
/// exceptions.
|
||||
NoExceptions(OptionalExceptions& a) :
|
||||
assoc_(a),
|
||||
exceptions_were_enabled_(a.throw_exceptions())
|
||||
{
|
||||
assoc_.disable_exceptions();
|
||||
}
|
||||
|
||||
/// \brief Destructor
|
||||
///
|
||||
/// Restores our associate object's previous exception state.
|
||||
~NoExceptions()
|
||||
{
|
||||
assoc_.set_exceptions(exceptions_were_enabled_);
|
||||
}
|
||||
|
||||
private:
|
||||
OptionalExceptions& assoc_;
|
||||
bool exceptions_were_enabled_;
|
||||
|
||||
// Hidden assignment operator and copy ctor, because we should not
|
||||
// be copied.
|
||||
NoExceptions(const NoExceptions&);
|
||||
NoExceptions& operator=(const NoExceptions&);
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // MYSQLPP_NOEXCEPTIONS_H
|
||||
|
||||
@ -1,278 +0,0 @@
|
||||
/// \file null.h
|
||||
/// \brief Declares classes that implement SQL "null" semantics within
|
||||
/// C++'s type system.
|
||||
///
|
||||
/// This is required because C++'s own NULL type is not semantically
|
||||
/// the same as SQL nulls.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_NULL_H
|
||||
#define MYSQLPP_NULL_H
|
||||
|
||||
#include "exceptions.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
|
||||
/// \brief The type of the global mysqlpp::null object.
|
||||
///
|
||||
/// This class is for internal use only. Normal code should use
|
||||
/// Null instead.
|
||||
class MYSQLPP_EXPORT null_type
|
||||
{
|
||||
public:
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
template <class Type> operator Type()
|
||||
{
|
||||
throw BadNullConversion();
|
||||
return Type();
|
||||
}
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
};
|
||||
|
||||
/// \brief Global 'null' instance. Use wherever you need a SQL null.
|
||||
/// (As opposed to a C++ language null pointer or null character.)
|
||||
const null_type null = null_type();
|
||||
|
||||
|
||||
/// \brief Class for objects that define SQL null in terms of
|
||||
/// MySQL++'s null_type.
|
||||
///
|
||||
/// Returns a null_type instance when you ask what null is, and is
|
||||
/// "(NULL)" when you insert it into a C++ stream.
|
||||
///
|
||||
/// Used for the behavior parameter for template Null
|
||||
struct NullisNull
|
||||
{
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
static null_type null_is() { return null_type(); }
|
||||
|
||||
static std::ostream& null_ostr(std::ostream& o)
|
||||
{
|
||||
o << "(NULL)";
|
||||
return o;
|
||||
}
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
};
|
||||
|
||||
|
||||
/// \brief Class for objects that define SQL null as 0.
|
||||
///
|
||||
/// Returns 0 when you ask what null is, and is zero when you insert it
|
||||
/// into a C++ stream.
|
||||
///
|
||||
/// Used for the behavior parameter for template Null
|
||||
struct NullisZero
|
||||
{
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
static int null_is() { return 0; }
|
||||
|
||||
static std::ostream& null_ostr(std::ostream& o)
|
||||
{
|
||||
o << 0;
|
||||
return o;
|
||||
}
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
};
|
||||
|
||||
/// \brief Class for objects that define SQL null as a blank C string.
|
||||
///
|
||||
/// Returns "" when you ask what null is, and is empty when you insert
|
||||
/// it into a C++ stream.
|
||||
///
|
||||
/// Used for the behavior parameter for template Null
|
||||
struct NullisBlank
|
||||
{
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
static const char *null_is() { return ""; }
|
||||
|
||||
static std::ostream& null_ostr(std::ostream& o)
|
||||
{
|
||||
o << "";
|
||||
return o;
|
||||
}
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
};
|
||||
|
||||
|
||||
/// \brief Class for holding data from a SQL column with the NULL
|
||||
/// attribute.
|
||||
///
|
||||
/// This template is necessary because there is nothing in the C++ type
|
||||
/// system with the same semantics as SQL's null. In SQL, a column can
|
||||
/// have the optional 'NULL' attribute, so there is a difference in
|
||||
/// type between, say an \c int column that can be null and one that
|
||||
/// cannot be. C++'s NULL constant does not have these features.
|
||||
///
|
||||
/// It's important to realize that this class doesn't hold nulls,
|
||||
/// it holds data that \e can \e be null. It can hold a non-null
|
||||
/// value, you can then assign null to it (using MySQL++'s global
|
||||
/// \c null object), and then assign a regular value to it again; the
|
||||
/// object will behave as you expect throughout this process.
|
||||
///
|
||||
/// Because one of the template parameters is a C++ type, the typeid()
|
||||
/// for a null \c int is different than for a null \c string, to pick
|
||||
/// two random examples. See type_info.cpp for the table SQL types that
|
||||
/// can be null.
|
||||
template <class Type, class Behavior = NullisNull> class Null
|
||||
{
|
||||
public:
|
||||
/// \brief The object's value, when it is not SQL null
|
||||
Type data;
|
||||
|
||||
/// \brief If set, this object is considered equal to SQL null.
|
||||
///
|
||||
/// This flag affects how the Type() and << operators work.
|
||||
bool is_null;
|
||||
|
||||
/// \brief Type of the data stored in this object, when it is not
|
||||
/// equal to SQL null.
|
||||
typedef Type value_type;
|
||||
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// "data" member is left uninitialized by this ctor, because we
|
||||
/// don't know what to initialize it to.
|
||||
Null() :
|
||||
is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize the object with a particular value.
|
||||
///
|
||||
/// The object is marked as "not null" if you use this ctor. This
|
||||
/// behavior exists because the class doesn't encode nulls, but
|
||||
/// rather data which \e can \e be null. The distinction is
|
||||
/// necessary because 'NULL' is an optional attribute of SQL
|
||||
/// columns.
|
||||
Null(const Type& x) :
|
||||
data(x),
|
||||
is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Construct a Null equal to SQL null
|
||||
///
|
||||
/// This is typically used with the global \c null object. (Not to
|
||||
/// be confused with C's NULL type.) You can say something like...
|
||||
/// \code
|
||||
/// Null<int> foo = null;
|
||||
/// \endcode
|
||||
/// ...to get a null \c int.
|
||||
Null(const null_type& n) :
|
||||
is_null(true)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Converts this object to Type
|
||||
///
|
||||
/// If is_null is set, returns whatever we consider that null "is",
|
||||
/// according to the Behavior parameter you used when instantiating
|
||||
/// this template. See NullisNull, NullisZero and NullisBlank.
|
||||
///
|
||||
/// Otherwise, just returns the 'data' member.
|
||||
operator Type&()
|
||||
{
|
||||
if (is_null)
|
||||
return data = Behavior::null_is();
|
||||
else
|
||||
return data;
|
||||
}
|
||||
|
||||
/// \brief Assign a value to the object.
|
||||
///
|
||||
/// This marks the object as "not null" as a side effect.
|
||||
Null& operator =(const Type& x)
|
||||
{
|
||||
data = x;
|
||||
is_null = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign SQL null to this object.
|
||||
///
|
||||
/// This just sets the is_null flag; the data member is not
|
||||
/// affected until you call the Type() operator on it.
|
||||
Null& operator =(const null_type& n)
|
||||
{
|
||||
is_null = true;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
// Specialization the Null template for \c void
|
||||
template <> class Null<void>
|
||||
{
|
||||
public:
|
||||
bool is_null;
|
||||
typedef void value_type;
|
||||
|
||||
Null() :
|
||||
is_null(false)
|
||||
{
|
||||
}
|
||||
|
||||
Null(const null_type&) :
|
||||
is_null(true)
|
||||
{
|
||||
}
|
||||
|
||||
Null& operator =(const null_type&)
|
||||
{
|
||||
is_null = true;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \brief Inserts null-able data into a C++ stream if it is not
|
||||
/// actually null. Otherwise, insert something appropriate for null
|
||||
/// data.
|
||||
template <class Type, class Behavior>
|
||||
inline std::ostream& operator <<(std::ostream& o,
|
||||
const Null<Type, Behavior>& n)
|
||||
{
|
||||
if (n.is_null)
|
||||
return Behavior::null_ostr(o);
|
||||
else
|
||||
return o << n.data;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,69 +0,0 @@
|
||||
/***********************************************************************
|
||||
qparms.cpp - Implements the SQLQuery class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "qparms.h"
|
||||
|
||||
#include "query.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
SQLString&
|
||||
SQLQueryParms::operator [](const char* str)
|
||||
{
|
||||
if (parent_) {
|
||||
return operator [](parent_->parsed_nums_[str]);
|
||||
}
|
||||
throw ObjectNotInitialized("SQLQueryParms object has no parent!");
|
||||
}
|
||||
|
||||
const SQLString&
|
||||
SQLQueryParms::operator[] (const char* str) const
|
||||
{
|
||||
if (parent_) {
|
||||
return operator [](parent_->parsed_nums_[str]);
|
||||
}
|
||||
throw ObjectNotInitialized("SQLQueryParms object has no parent!");
|
||||
}
|
||||
|
||||
SQLQueryParms
|
||||
SQLQueryParms::operator +(const SQLQueryParms& other) const
|
||||
{
|
||||
if (other.size() <= size()) {
|
||||
return *this;
|
||||
}
|
||||
SQLQueryParms New = *this;
|
||||
size_t i;
|
||||
for (i = size(); i < other.size(); i++) {
|
||||
New.push_back(other[i]);
|
||||
}
|
||||
|
||||
return New;
|
||||
}
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
@ -1,255 +0,0 @@
|
||||
/// \file qparms.h
|
||||
/// \brief Declares the template query parameter-related stuff.
|
||||
///
|
||||
/// The classes defined in this file are used by class Query when it
|
||||
/// parses a template query: they hold information that it finds in the
|
||||
/// template, so it can assemble a SQL statement later on demand.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_QPARMS_H
|
||||
#define MYSQLPP_QPARMS_H
|
||||
|
||||
#include "sql_string.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT Query;
|
||||
#endif
|
||||
|
||||
/// \brief This class holds the parameter values for filling
|
||||
/// template queries.
|
||||
class MYSQLPP_EXPORT SQLQueryParms : public std::vector<SQLString>
|
||||
{
|
||||
public:
|
||||
/// \brief Abbreviation so some of the declarations below don't
|
||||
/// span many lines.
|
||||
typedef const SQLString& ss;
|
||||
|
||||
/// \brief Default constructor
|
||||
SQLQueryParms() :
|
||||
parent_(0),
|
||||
processing_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param p pointer to the query object these parameters are tied
|
||||
/// to
|
||||
SQLQueryParms(Query* p) :
|
||||
parent_(p),
|
||||
processing_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Returns true if we are bound to a query object.
|
||||
///
|
||||
/// Basically, this tells you which of the two ctors were called.
|
||||
bool bound()
|
||||
{
|
||||
return parent_ != 0;
|
||||
}
|
||||
|
||||
/// \brief Clears the list
|
||||
void clear()
|
||||
{
|
||||
erase(begin(), end());
|
||||
}
|
||||
|
||||
/// \brief Access element number n
|
||||
SQLString& operator [](size_type n)
|
||||
{
|
||||
if (n >= size())
|
||||
insert(end(), (n + 1) - size(), "");
|
||||
return std::vector<SQLString>::operator [](n);
|
||||
}
|
||||
|
||||
/// \brief Access element number n
|
||||
const SQLString& operator [](size_type n) const
|
||||
{
|
||||
return std::vector<SQLString>::operator [](n);
|
||||
}
|
||||
|
||||
/// \brief Access the value of the element with a key of str.
|
||||
SQLString& operator [](const char *str);
|
||||
|
||||
/// \brief Access the value of the element with a key of str.
|
||||
const SQLString& operator [](const char *str) const;
|
||||
|
||||
/// \brief Adds an element to the list
|
||||
SQLQueryParms& operator <<(const SQLString& str)
|
||||
{
|
||||
push_back(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Adds an element to the list
|
||||
SQLQueryParms& operator +=(const SQLString& str)
|
||||
{
|
||||
push_back(str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Build a composite of two parameter lists
|
||||
///
|
||||
/// If this list is (a, b) and \c other is (c, d, e, f, g), then
|
||||
/// the returned list will be (a, b, e, f, g). That is, all of this
|
||||
/// list's parameters are in the returned list, plus any from the
|
||||
/// other list that are in positions beyond what exist in this list.
|
||||
///
|
||||
/// If the two lists are the same length or this list is longer than
|
||||
/// the \c other list, a copy of this list is returned.
|
||||
SQLQueryParms operator +(
|
||||
const SQLQueryParms& other) const;
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
void set(ss a)
|
||||
{
|
||||
clear();
|
||||
*this << a;
|
||||
}
|
||||
void set(ss a, ss b)
|
||||
{
|
||||
clear();
|
||||
*this << a << b;
|
||||
}
|
||||
void set(ss a, ss b, ss c)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g << h;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g << h << i;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i, ss j)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g << h << i << j;
|
||||
}
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g, ss h, ss i, ss j, ss k)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g << h << i << j << k;
|
||||
}
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
/// \brief Set the template query parameters.
|
||||
///
|
||||
/// Sets parameter 0 to a, parameter 1 to b, etc. There are
|
||||
/// overloaded versions of this function that take anywhere from
|
||||
/// one to a dozen parameters.
|
||||
void set(ss a, ss b, ss c, ss d, ss e, ss f, ss g,
|
||||
ss h, ss i, ss j, ss k, ss l)
|
||||
{
|
||||
clear();
|
||||
*this << a << b << c << d << e << f << g << h << i << j << k << l;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Query;
|
||||
|
||||
Query* parent_;
|
||||
bool processing_; ///< true if we're building a query string
|
||||
};
|
||||
|
||||
|
||||
/// \brief Used within Query to hold elements for parameterized
|
||||
/// queries.
|
||||
///
|
||||
/// Each element has three parts:
|
||||
///
|
||||
/// The concept behind the \c before variable needs a little explaining.
|
||||
/// When a template query is parsed, each parameter is parsed into one
|
||||
/// of these SQLParseElement objects, but the non-parameter parts of the
|
||||
/// template also have to be stored somewhere. MySQL++ chooses to
|
||||
/// attach the text leading up to a parameter to that parameter. So,
|
||||
/// the \c before string is simply the text copied literally into the
|
||||
/// finished query before we insert a value for the parameter.
|
||||
///
|
||||
/// The \c option character is currently one of 'q', 'Q', 'r', 'R' or
|
||||
/// ' '. See the "Template Queries" chapter in the user manual for
|
||||
/// details.
|
||||
///
|
||||
/// The position value (\c num) allows a template query to have its
|
||||
/// parameters in a different order than in the Query method call.
|
||||
/// An example of how this can be helpful is in the "Template Queries"
|
||||
/// chapter of the user manual.
|
||||
|
||||
struct SQLParseElement
|
||||
{
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param b the 'before' value
|
||||
/// \param o the 'option' value
|
||||
/// \param n the 'num' value
|
||||
SQLParseElement(std::string b, char o, signed char n) :
|
||||
before(b),
|
||||
option(o),
|
||||
num(n)
|
||||
{
|
||||
}
|
||||
|
||||
std::string before; ///< string inserted before the parameter
|
||||
char option; ///< the parameter option, or blank if none
|
||||
signed char num; ///< the parameter position to use
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_QPARMS_H)
|
||||
|
||||
@ -1,656 +0,0 @@
|
||||
/***********************************************************************
|
||||
query.cpp - Implements the Query class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "query.h"
|
||||
|
||||
#include "autoflag.h"
|
||||
#include "connection.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
Query::Query(Connection* c, bool te) :
|
||||
#if defined(_MSC_VER) && !defined(_STLP_VERSION) && !defined(_STLP_VERSION_STR)
|
||||
// prevents a double-init memory leak in native VC++ RTL (not STLport!)
|
||||
std::ostream(std::_Noinit),
|
||||
#else
|
||||
std::ostream(0),
|
||||
#endif
|
||||
OptionalExceptions(te),
|
||||
Lockable(false),
|
||||
def(this),
|
||||
conn_(c),
|
||||
success_(false)
|
||||
{
|
||||
init(&sbuffer_);
|
||||
success_ = true;
|
||||
}
|
||||
|
||||
Query::Query(const Query& q) :
|
||||
#if defined(_MSC_VER) && !defined(_STLP_VERSION) && !defined(_STLP_VERSION_STR)
|
||||
// ditto above
|
||||
std::ostream(std::_Noinit),
|
||||
#else
|
||||
std::ostream(0),
|
||||
#endif
|
||||
OptionalExceptions(q.throw_exceptions()),
|
||||
Lockable(q.locked()),
|
||||
def(q.def),
|
||||
conn_(q.conn_),
|
||||
success_(q.success_)
|
||||
{
|
||||
init(&sbuffer_);
|
||||
}
|
||||
|
||||
|
||||
Query&
|
||||
Query::operator=(const Query& rhs)
|
||||
{
|
||||
set_exceptions(rhs.throw_exceptions());
|
||||
set_lock(rhs.locked());
|
||||
def = rhs.def;
|
||||
conn_ = rhs.conn_;
|
||||
success_ = rhs.success_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
my_ulonglong
|
||||
Query::affected_rows() const
|
||||
{
|
||||
return conn_->affected_rows();
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Query::error()
|
||||
{
|
||||
return conn_->error();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Query::exec(const std::string& str)
|
||||
{
|
||||
success_ = !mysql_real_query(&conn_->mysql_, str.data(),
|
||||
static_cast<unsigned long>(str.length()));
|
||||
if (!success_ && throw_exceptions()) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return success_;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ResNSel
|
||||
Query::execute(const SQLString& str)
|
||||
{
|
||||
if ((parse_elems_.size() == 2) && !def.processing_) {
|
||||
// We're a template query and we haven't gone through this path
|
||||
// before, so take str to be a lone parameter for the query.
|
||||
// We will come back through this function with a completed
|
||||
// query, but the processing_ flag will be reset, allowing us to
|
||||
// take the 'else' path, avoiding an infinite loop.
|
||||
AutoFlag<> af(def.processing_);
|
||||
return execute(SQLQueryParms() << str);
|
||||
}
|
||||
else {
|
||||
// Take str to be the entire query string
|
||||
return execute(str.data(), str.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ResNSel
|
||||
Query::execute(const char* str)
|
||||
{
|
||||
return execute(SQLString(str));
|
||||
}
|
||||
|
||||
|
||||
ResNSel
|
||||
Query::execute(const char* str, size_t len)
|
||||
{
|
||||
if (lock()) {
|
||||
success_ = false;
|
||||
if (throw_exceptions()) {
|
||||
throw LockFailed();
|
||||
}
|
||||
else {
|
||||
return ResNSel();
|
||||
}
|
||||
}
|
||||
|
||||
success_ = !mysql_real_query(&conn_->mysql_, str, len);
|
||||
|
||||
unlock();
|
||||
if (success_) {
|
||||
return ResNSel(conn_);
|
||||
}
|
||||
else if (throw_exceptions()) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return ResNSel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
ResNSel
|
||||
Query::execute(SQLQueryParms& p)
|
||||
{
|
||||
return execute(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
std::string
|
||||
Query::info()
|
||||
{
|
||||
return conn_->info();
|
||||
}
|
||||
|
||||
|
||||
my_ulonglong
|
||||
Query::insert_id()
|
||||
{
|
||||
return conn_->insert_id();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Query::lock()
|
||||
{
|
||||
return conn_->lock();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Query::more_results()
|
||||
{
|
||||
#if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 +
|
||||
return mysql_more_results(&conn_->mysql_);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::parse()
|
||||
{
|
||||
std::string str = "";
|
||||
char num[4];
|
||||
std::string name;
|
||||
char *s, *s0;
|
||||
s0 = s = preview_char();
|
||||
while (*s) {
|
||||
if (*s == '%') {
|
||||
// Following might be a template parameter declaration...
|
||||
s++;
|
||||
if (*s == '%') {
|
||||
// Doubled percent sign, so insert literal percent sign.
|
||||
str += *s++;
|
||||
}
|
||||
else if (isdigit(*s)) {
|
||||
// Number following percent sign, so it signifies a
|
||||
// positional parameter. First step: find position
|
||||
// value, up to 3 digits long.
|
||||
num[0] = *s;
|
||||
s++;
|
||||
if (isdigit(*s)) {
|
||||
num[1] = *s;
|
||||
num[2] = 0;
|
||||
s++;
|
||||
if (isdigit(*s)) {
|
||||
num[2] = *s;
|
||||
num[3] = 0;
|
||||
s++;
|
||||
}
|
||||
else {
|
||||
num[2] = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
num[1] = 0;
|
||||
}
|
||||
signed char n = atoi(num);
|
||||
|
||||
// Look for option character following position value.
|
||||
char option = ' ';
|
||||
if (*s == 'q' || *s == 'Q' || *s == 'r' || *s == 'R') {
|
||||
option = *s++;
|
||||
}
|
||||
|
||||
// Is it a named parameter?
|
||||
if (*s == ':') {
|
||||
// Save all alphanumeric and underscore characters
|
||||
// following colon as parameter name.
|
||||
s++;
|
||||
for (/* */; isalnum(*s) || *s == '_'; ++s) {
|
||||
name += *s;
|
||||
}
|
||||
|
||||
// Eat trailing colon, if it's present.
|
||||
if (*s == ':') {
|
||||
s++;
|
||||
}
|
||||
|
||||
// Update maps that translate parameter name to
|
||||
// number and vice versa.
|
||||
if (n >= static_cast<short>(parsed_names_.size())) {
|
||||
parsed_names_.insert(parsed_names_.end(),
|
||||
static_cast<std::vector<std::string>::size_type>(
|
||||
n + 1) - parsed_names_.size(),
|
||||
std::string());
|
||||
}
|
||||
parsed_names_[n] = name;
|
||||
parsed_nums_[name] = n;
|
||||
}
|
||||
|
||||
// Finished parsing parameter; save it.
|
||||
parse_elems_.push_back(SQLParseElement(str, option, n));
|
||||
str = "";
|
||||
name = "";
|
||||
}
|
||||
else {
|
||||
// Insert literal percent sign, because sign didn't
|
||||
// precede a valid parameter string; this allows users
|
||||
// to play a little fast and loose with the rules,
|
||||
// avoiding a double percent sign here.
|
||||
str += '%';
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Regular character, so just copy it.
|
||||
str += *s++;
|
||||
}
|
||||
}
|
||||
|
||||
parse_elems_.push_back(SQLParseElement(str, ' ', -1));
|
||||
delete[] s0;
|
||||
}
|
||||
|
||||
|
||||
SQLString*
|
||||
Query::pprepare(char option, SQLString& S, bool replace)
|
||||
{
|
||||
if (S.processed) {
|
||||
return &S;
|
||||
}
|
||||
|
||||
if (option == 'r' || (option == 'q' && S.is_string)) {
|
||||
char *s = new char[S.size() * 2 + 1];
|
||||
mysql_real_escape_string(&conn_->mysql_, s, S.data(),
|
||||
static_cast<unsigned long>(S.size()));
|
||||
SQLString *ss = new SQLString("'");
|
||||
*ss += s;
|
||||
*ss += "'";
|
||||
delete[] s;
|
||||
|
||||
if (replace) {
|
||||
S = *ss;
|
||||
S.processed = true;
|
||||
delete ss;
|
||||
return &S;
|
||||
}
|
||||
else {
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
else if (option == 'R' || (option == 'Q' && S.is_string)) {
|
||||
SQLString *ss = new SQLString("'" + S + "'");
|
||||
|
||||
if (replace) {
|
||||
S = *ss;
|
||||
S.processed = true;
|
||||
delete ss;
|
||||
return &S;
|
||||
}
|
||||
else {
|
||||
return ss;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (replace) {
|
||||
S.processed = true;
|
||||
}
|
||||
return &S;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
Query::preview_char()
|
||||
{
|
||||
const std::string& str(sbuffer_.str());
|
||||
char* s = new char[str.size() + 1];
|
||||
memcpy(s, str.data(), str.size());
|
||||
s[str.size()] = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::proc(SQLQueryParms& p)
|
||||
{
|
||||
sbuffer_.str("");
|
||||
|
||||
for (std::vector<SQLParseElement>::iterator i = parse_elems_.begin();
|
||||
i != parse_elems_.end(); ++i) {
|
||||
MYSQLPP_QUERY_THISPTR << i->before;
|
||||
int num = i->num;
|
||||
if (num >= 0) {
|
||||
SQLQueryParms* c;
|
||||
if (size_t(num) < p.size()) {
|
||||
c = &p;
|
||||
}
|
||||
else if (size_t(num) < def.size()) {
|
||||
c = &def;
|
||||
}
|
||||
else {
|
||||
*this << " ERROR";
|
||||
throw BadParamCount(
|
||||
"Not enough parameters to fill the template.");
|
||||
}
|
||||
|
||||
SQLString& param = (*c)[num];
|
||||
SQLString* ss = pprepare(i->option, param, c->bound());
|
||||
MYSQLPP_QUERY_THISPTR << *ss;
|
||||
if (ss != ¶m) {
|
||||
// pprepare() returned a new string object instead of
|
||||
// updating param in place, so we need to delete it.
|
||||
delete ss;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Query::reset()
|
||||
{
|
||||
seekp(0);
|
||||
clear();
|
||||
sbuffer_.str("");
|
||||
|
||||
parse_elems_.clear();
|
||||
def.clear();
|
||||
}
|
||||
|
||||
|
||||
Result
|
||||
Query::store(const SQLString& str)
|
||||
{
|
||||
if ((parse_elems_.size() == 2) && !def.processing_) {
|
||||
// We're a template query and we haven't gone through this path
|
||||
// before, so take str to be a lone parameter for the query.
|
||||
// We will come back through this function with a completed
|
||||
// query, but the processing_ flag will be reset, allowing us to
|
||||
// take the 'else' path, avoiding an infinite loop.
|
||||
AutoFlag<> af(def.processing_);
|
||||
return store(SQLQueryParms() << str);
|
||||
}
|
||||
else {
|
||||
// Take str to be the entire query string
|
||||
return store(str.data(), str.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Result
|
||||
Query::store(const char* str)
|
||||
{
|
||||
return store(SQLString(str));
|
||||
}
|
||||
|
||||
|
||||
Result
|
||||
Query::store(const char* str, size_t len)
|
||||
{
|
||||
if (lock()) {
|
||||
success_ = false;
|
||||
if (throw_exceptions()) {
|
||||
throw LockFailed();
|
||||
}
|
||||
else {
|
||||
return Result();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (success_ = !mysql_real_query(&conn_->mysql_, str, len)) {
|
||||
MYSQL_RES* res = mysql_store_result(&conn_->mysql_);
|
||||
if (res) {
|
||||
unlock();
|
||||
return Result(res, throw_exceptions());
|
||||
}
|
||||
else {
|
||||
success_ = false;
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
||||
// One of the MySQL API calls failed, but it's not an error if we
|
||||
// just get an empty result set. It happens when store()ing a query
|
||||
// that doesn't always return results. While it's better to use
|
||||
// exec*() in that situation, it's legal to call store() instead,
|
||||
// and sometimes you have no choice. For example, if the SQL comes
|
||||
// from outside the program so you can't predict whether there will
|
||||
// be results.
|
||||
if (conn_->errnum() && throw_exceptions()) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return Result();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
Result
|
||||
Query::store(SQLQueryParms& p)
|
||||
{
|
||||
return store(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
Result
|
||||
Query::store_next()
|
||||
{
|
||||
#if MYSQL_VERSION_ID > 41000 // only in MySQL v4.1 +
|
||||
if (lock()) {
|
||||
if (throw_exceptions()) {
|
||||
throw LockFailed();
|
||||
}
|
||||
else {
|
||||
return Result();
|
||||
}
|
||||
}
|
||||
|
||||
int ret;
|
||||
if ((ret = mysql_next_result(&conn_->mysql_)) == 0) {
|
||||
// There are more results, so return next result set.
|
||||
MYSQL_RES* res = mysql_store_result(&conn_->mysql_);
|
||||
unlock();
|
||||
if (res) {
|
||||
return Result(res, throw_exceptions());
|
||||
}
|
||||
else {
|
||||
// Result set is null, but throw an exception only i it is
|
||||
// null because of some error. If not, it's just an empty
|
||||
// result set, which is harmless. We return an empty result
|
||||
// set if exceptions are disabled, as well.
|
||||
if (conn_->errnum() && throw_exceptions()) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return Result();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No more results, or some other error occurred.
|
||||
unlock();
|
||||
if (throw_exceptions()) {
|
||||
if (ret > 0) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
throw EndOfResultSets();
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Result();
|
||||
}
|
||||
}
|
||||
#else
|
||||
return store();
|
||||
#endif // MySQL v4.1+
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Query::str(SQLQueryParms& p)
|
||||
{
|
||||
if (!parse_elems_.empty()) {
|
||||
proc(p);
|
||||
}
|
||||
|
||||
return sbuffer_.str();
|
||||
}
|
||||
|
||||
|
||||
std::string
|
||||
Query::str(SQLQueryParms& p, query_reset r)
|
||||
{
|
||||
std::string tmp = str(p);
|
||||
if (r == RESET_QUERY) {
|
||||
reset();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Query::success()
|
||||
{
|
||||
return success_ && conn_->success();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::unlock()
|
||||
{
|
||||
conn_->unlock();
|
||||
}
|
||||
|
||||
|
||||
ResUse
|
||||
Query::use(const SQLString& str)
|
||||
{
|
||||
if ((parse_elems_.size() == 2) && !def.processing_) {
|
||||
// We're a template query and we haven't gone through this path
|
||||
// before, so take str to be a lone parameter for the query.
|
||||
// We will come back through this function with a completed
|
||||
// query, but the processing_ flag will be reset, allowing us to
|
||||
// take the 'else' path, avoiding an infinite loop.
|
||||
AutoFlag<> af(def.processing_);
|
||||
return use(SQLQueryParms() << str);
|
||||
}
|
||||
else {
|
||||
// Take str to be the entire query string
|
||||
return use(str.data(), str.length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ResUse
|
||||
Query::use(const char* str)
|
||||
{
|
||||
return use(SQLString(str));
|
||||
}
|
||||
|
||||
|
||||
ResUse
|
||||
Query::use(const char* str, size_t len)
|
||||
{
|
||||
if (lock()) {
|
||||
success_ = false;
|
||||
if (throw_exceptions()) {
|
||||
throw LockFailed();
|
||||
}
|
||||
else {
|
||||
return ResUse();
|
||||
}
|
||||
}
|
||||
|
||||
if (success_ = !mysql_real_query(&conn_->mysql_, str, len)) {
|
||||
MYSQL_RES* res = mysql_use_result(&conn_->mysql_);
|
||||
if (res) {
|
||||
unlock();
|
||||
return ResUse(res, conn_, throw_exceptions());
|
||||
}
|
||||
}
|
||||
unlock();
|
||||
|
||||
// One of the MySQL API calls failed, but it's not an error if we
|
||||
// just get an empty result set. It happens when use()ing a query
|
||||
// that doesn't always return results. While it's better to use
|
||||
// exec*() in that situation, it's legal to call use() instead, and
|
||||
// sometimes you have no choice. For example, if the SQL comes
|
||||
// from outside the program so you can't predict whether there will
|
||||
// be results.
|
||||
if (conn_->errnum() && throw_exceptions()) {
|
||||
throw BadQuery(error());
|
||||
}
|
||||
else {
|
||||
return ResUse();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
ResUse
|
||||
Query::use(SQLQueryParms& p)
|
||||
{
|
||||
return use(str(p, parse_elems_.size() ? DONT_RESET : RESET_QUERY));
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,930 +0,0 @@
|
||||
/// \file query.h
|
||||
/// \brief Defines a class for building and executing SQL queries.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_QUERY_H
|
||||
#define MYSQLPP_QUERY_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "lockable.h"
|
||||
#include "noexceptions.h"
|
||||
#include "qparms.h"
|
||||
#include "querydef.h"
|
||||
#include "result.h"
|
||||
#include "row.h"
|
||||
#include "sql_string.h"
|
||||
|
||||
#include <deque>
|
||||
#include <iomanip>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
|
||||
#ifdef HAVE_EXT_SLIST
|
||||
# include <ext/slist>
|
||||
#else
|
||||
# if defined(HAVE_STD_SLIST) || defined(HAVE_GLOBAL_SLIST)
|
||||
# include <slist>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/// \def MYSQLPP_QUERY_THISPTR
|
||||
/// \brief Helper macro used inside MySQL++ to work around a VC++ 2003 bug
|
||||
///
|
||||
/// This macro returns '*this', either directly or upcast to Query's
|
||||
/// base class to work around an error in the overloaded operator
|
||||
/// lookup logic in VC++ 2003. For an explanation of the problem, see:
|
||||
/// http://groups.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
|
||||
#if defined(_MSC_VER) && (_MSC_VER < 1400)
|
||||
# define MYSQLPP_QUERY_THISPTR dynamic_cast<std::ostream&>(*this)
|
||||
#else
|
||||
# define MYSQLPP_QUERY_THISPTR *this
|
||||
#endif
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT Connection;
|
||||
#endif
|
||||
|
||||
/// \brief Used for indicating whether a query object should auto-reset
|
||||
enum query_reset { DONT_RESET, RESET_QUERY };
|
||||
|
||||
/// \brief A class for building and executing SQL queries.
|
||||
///
|
||||
/// This class is derived from SQLQuery. It adds to that a tie between
|
||||
/// the query object and a MySQL++
|
||||
/// \link mysqlpp::Connection Connection \endlink object, so that
|
||||
/// the query can be sent to the MySQL server we're connected to.
|
||||
///
|
||||
/// One does not generally create Query objects directly. Instead, call
|
||||
/// mysqlpp::Connection::query() to get one tied to that connection.
|
||||
///
|
||||
/// There are several ways to build and execute SQL queries with this
|
||||
/// class.
|
||||
///
|
||||
/// The way most like other database libraries is to pass a SQL
|
||||
/// statement to one of the
|
||||
/// \link mysqlpp::Query::execute() exec*(), \endlink
|
||||
/// \link mysqlpp::Query::store() store*(), \endlink or use() methods
|
||||
/// taking a C or C++ string. The query is executed immediately, and
|
||||
/// any results returned.
|
||||
///
|
||||
/// For more complicated queries, you can use Query's stream interface.
|
||||
/// You simply build up a query using the Query instance as you would
|
||||
/// any other C++ stream object. When the query string is complete, you
|
||||
/// call the overloaded version of \c exec*(), \c store*() or \c use()
|
||||
/// that takes no parameters, which executes the built query and returns
|
||||
/// any results.
|
||||
///
|
||||
/// If you are using the library's Specialized SQL Structures feature,
|
||||
/// Query has several special functions for generating common SQL
|
||||
/// queries from those structures. For instance, it offers the
|
||||
/// \link mysqlpp::Query::insert() insert() \endlink method, which
|
||||
/// builds an INSERT query to add the contents of the SSQLS to the
|
||||
/// database. As with the stream interface, these methods only build
|
||||
/// the query string; call one of the parameterless methods mentioned
|
||||
/// previously to actually execute the query.
|
||||
///
|
||||
/// Finally, you can build "template queries". This is something like
|
||||
/// C's \c printf() function, in that you insert a specially-formatted
|
||||
/// query string into the object which contains placeholders for data.
|
||||
/// You call the parse() method to tell the Query object that the query
|
||||
/// string contains placeholders. Once that's done, you can call any of
|
||||
/// the many overloaded methods that take a number of SQLStrings (up to
|
||||
/// 25 by default) or any type that can be converted to SQLString, and
|
||||
/// those parameters will be inserted into the placeholders. When you
|
||||
/// call one of the parameterless functions the execute the query, the
|
||||
/// final query string is assembled and sent to the server.
|
||||
///
|
||||
/// See the user manual for more details about these options.
|
||||
|
||||
class MYSQLPP_EXPORT Query : public std::ostream,
|
||||
public OptionalExceptions, public Lockable
|
||||
{
|
||||
public:
|
||||
/// \brief Create a new query object attached to a connection.
|
||||
///
|
||||
/// This is the constructor used by mysqlpp::Connection::query().
|
||||
///
|
||||
/// \param c connection the finished query should be sent out on
|
||||
/// \param te if true, throw exceptions on errors
|
||||
Query(Connection* c, bool te = true);
|
||||
|
||||
/// \brief Create a new query object as a copy of another.
|
||||
///
|
||||
/// This is \b not a traditional copy ctor! Its only purpose is to
|
||||
/// make it possible to assign the return of Connection::query()
|
||||
/// to an empty Query object. In particular, the stream buffer and
|
||||
/// template query stuff will be empty in the copy, regardless of
|
||||
/// what values they have in the original.
|
||||
Query(const Query& q);
|
||||
|
||||
/// \brief Assign another query's state to this object
|
||||
///
|
||||
/// The same caveats apply to this operator as apply to the copy
|
||||
/// ctor.
|
||||
Query& operator=(const Query& rhs);
|
||||
|
||||
/// \brief Get the last error message that was set.
|
||||
///
|
||||
/// This class has an internal error message string, but if it
|
||||
/// isn't set, we return the last error message that happened
|
||||
/// on the connection we're bound to instead.
|
||||
std::string error();
|
||||
|
||||
/// \brief Returns true if the last operation succeeded
|
||||
///
|
||||
/// Returns true if the last query succeeded, and the associated
|
||||
/// Connection object's success() method also returns true. If
|
||||
/// either object is unhappy, this method returns false.
|
||||
bool success();
|
||||
|
||||
/// \brief Treat the contents of the query string as a template
|
||||
/// query.
|
||||
///
|
||||
/// This method sets up the internal structures used by all of the
|
||||
/// other members that accept template query parameters. See the
|
||||
/// "Template Queries" chapter in the user manual for more
|
||||
/// information.
|
||||
void parse();
|
||||
|
||||
/// \brief Reset the query object so that it can be reused.
|
||||
///
|
||||
/// This erases the query string and the contents of the parameterized
|
||||
/// query element list.
|
||||
void reset();
|
||||
|
||||
/// \brief Return the query string currently in the buffer.
|
||||
std::string preview() { return str(def); }
|
||||
|
||||
/// \brief Return the query string currently in the buffer with
|
||||
/// template query parameter substitution.
|
||||
///
|
||||
/// \param arg0 the value to substitute for the first template query
|
||||
/// parameter
|
||||
std::string preview(const SQLString& arg0)
|
||||
{ return preview(SQLQueryParms() << arg0); }
|
||||
|
||||
/// \brief Return the query string currently in the buffer.
|
||||
std::string preview(SQLQueryParms& p) { return str(p); }
|
||||
|
||||
/// \brief Get built query as a null-terminated C++ string
|
||||
std::string str() { return str(def); }
|
||||
|
||||
/// \brief Get built query as a null-terminated C++ string with
|
||||
/// template query parameter substitution.
|
||||
///
|
||||
/// \param arg0 the value to substitute for the first template query
|
||||
/// parameter
|
||||
std::string str(const SQLString& arg0)
|
||||
{ return preview(SQLQueryParms() << arg0); }
|
||||
|
||||
/// \brief Get built query as a null-terminated C++ string
|
||||
///
|
||||
/// \param r if equal to \c RESET_QUERY, query object is cleared
|
||||
/// after this call
|
||||
std::string str(query_reset r) { return str(def, r); }
|
||||
|
||||
/// \brief Get built query as a null-terminated C++ string
|
||||
///
|
||||
/// \param p template query parameters to use, overriding the ones
|
||||
/// this object holds, if any
|
||||
std::string str(SQLQueryParms& p);
|
||||
|
||||
/// \brief Get built query as a null-terminated C++ string
|
||||
///
|
||||
/// \param p template query parameters to use, overriding the ones
|
||||
/// this object holds, if any
|
||||
/// \param r if equal to \c RESET_QUERY, query object is cleared
|
||||
/// after this call
|
||||
std::string str(SQLQueryParms& p, query_reset r);
|
||||
|
||||
/// \brief Execute a query
|
||||
///
|
||||
/// Same as execute(), except that it only returns a flag indicating
|
||||
/// whether the query succeeded or not. It is basically a thin
|
||||
/// wrapper around the C API function \c mysql_real_query().
|
||||
///
|
||||
/// \param str the query to execute
|
||||
///
|
||||
/// \return true if query was executed successfully
|
||||
///
|
||||
/// \sa execute(), store(), storein(), and use()
|
||||
bool exec(const std::string& str);
|
||||
|
||||
/// \brief Execute built-up query
|
||||
///
|
||||
/// Use one of the execute() overloads if you don't expect the
|
||||
/// server to return a result set. For instance, a DELETE query.
|
||||
/// The returned ResNSel object contains status information from
|
||||
/// the server, such as whether the query succeeded, and if so how
|
||||
/// many rows were affected.
|
||||
///
|
||||
/// This overloaded version of execute() simply executes the query
|
||||
/// that you have built up in the object in some way. (For instance,
|
||||
/// via the insert() method, or by using the object's stream
|
||||
/// interface.)
|
||||
///
|
||||
/// \return ResNSel status information about the query
|
||||
///
|
||||
/// \sa exec(), store(), storein(), and use()
|
||||
ResNSel execute() { return execute(def); }
|
||||
|
||||
/// \brief Execute query in a C++ string, or substitute string into
|
||||
/// a template query and execute it.
|
||||
///
|
||||
/// \param str If the object represents a compiled template query,
|
||||
/// substitutes this string in for the first parameter. Otherwise,
|
||||
/// takes the string as a complete SQL query and executes it.
|
||||
ResNSel execute(const SQLString& str);
|
||||
|
||||
/// \brief Execute query in a C string
|
||||
///
|
||||
/// Executes the query immediately, and returns the results.
|
||||
ResNSel execute(const char* str);
|
||||
|
||||
/// \brief Execute query in a known-length string of characters.
|
||||
/// This can include null characters.
|
||||
///
|
||||
/// Executes the query immediately, and returns the results.
|
||||
ResNSel execute(const char* str, size_t len);
|
||||
|
||||
/// \brief Execute a query that can return a result set
|
||||
///
|
||||
/// Use one of the use() overloads if memory efficiency is
|
||||
/// important. They return an object that can walk through
|
||||
/// the result records one by one, without fetching the entire
|
||||
/// result set from the server. This is superior to store()
|
||||
/// when there are a large number of results; store() would have to
|
||||
/// allocate a large block of memory to hold all those records,
|
||||
/// which could cause problems.
|
||||
///
|
||||
/// A potential downside of this method is that MySQL database
|
||||
/// resources are tied up until the result set is completely
|
||||
/// consumed. Do your best to walk through the result set as
|
||||
/// expeditiously as possible.
|
||||
///
|
||||
/// The name of this method comes from the MySQL C API function
|
||||
/// that initiates the retrieval process, \c mysql_use_result().
|
||||
/// This method is implemented in terms of that function.
|
||||
///
|
||||
/// This function has the same set of overloads as execute().
|
||||
///
|
||||
/// \return ResUse object that can walk through result set serially
|
||||
///
|
||||
/// \sa exec(), execute(), store() and storein()
|
||||
ResUse use() { return use(def); }
|
||||
|
||||
/// \brief Execute query in a C++ string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// lets you walk through the result set one row at a time, in
|
||||
/// sequence. This is more memory-efficient than store().
|
||||
ResUse use(const SQLString& str);
|
||||
|
||||
/// \brief Execute query in a C string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// lets you walk through the result set one row at a time, in
|
||||
/// sequence. This is more memory-efficient than store().
|
||||
ResUse use(const char* str);
|
||||
|
||||
/// \brief Execute query in a known-length C string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// lets you walk through the result set one row at a time, in
|
||||
/// sequence. This is more memory-efficient than store().
|
||||
ResUse use(const char* str, size_t len);
|
||||
|
||||
/// \brief Execute a query that can return a result set
|
||||
///
|
||||
/// Use one of the store() overloads to execute a query and retrieve
|
||||
/// the entire result set into memory. This is useful if you
|
||||
/// actually need all of the records at once, but if not, consider
|
||||
/// using one of the use() methods instead, which returns the results
|
||||
/// one at a time, so they don't allocate as much memory as store().
|
||||
///
|
||||
/// You must use store(), storein() or use() for \c SELECT, \c SHOW,
|
||||
/// \c DESCRIBE and \c EXPLAIN queries. You can use these functions
|
||||
/// with other query types, but since they don't return a result
|
||||
/// set, exec() and execute() are more efficient.
|
||||
///
|
||||
/// The name of this method comes from the MySQL C API function it
|
||||
/// is implemented in terms of, \c mysql_store_result().
|
||||
///
|
||||
/// This function has the same set of overloads as execute().
|
||||
///
|
||||
/// \return Result object containing entire result set
|
||||
///
|
||||
/// \sa exec(), execute(), storein(), and use()
|
||||
Result store() { return store(def); }
|
||||
|
||||
/// \brief Execute query in a C++ string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// contains the entire result set. This is less memory-efficient
|
||||
/// than use(), but it lets you have random access to the results.
|
||||
Result store(const SQLString& str);
|
||||
|
||||
/// \brief Execute query in a C string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// contains the entire result set. This is less memory-efficient
|
||||
/// than use(), but it lets you have random access to the results.
|
||||
Result store(const char* str);
|
||||
|
||||
/// \brief Execute query in a known-length C string
|
||||
///
|
||||
/// Executes the query immediately, and returns an object that
|
||||
/// contains the entire result set. This is less memory-efficient
|
||||
/// than use(), but it lets you have random access to the results.
|
||||
Result store(const char* str, size_t len);
|
||||
|
||||
/// \brief Execute a query, and call a functor for each returned row
|
||||
///
|
||||
/// This method wraps a use() query, calling the given functor for
|
||||
/// every returned row. It is analogous to STL's for_each()
|
||||
/// algorithm, but instead of iterating over some range within a
|
||||
/// container, it iterates over a result set produced by a query.
|
||||
///
|
||||
/// \param query the query string
|
||||
/// \param fn the functor called for each row
|
||||
/// \return a copy of the passed functor
|
||||
template <typename Function>
|
||||
Function for_each(const SQLString& query, Function fn)
|
||||
{
|
||||
mysqlpp::ResUse res = use(query);
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
fn(row);
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Execute the query, and call a functor for each returned row
|
||||
///
|
||||
/// Just like for_each(const SQLString&, Function), but it uses
|
||||
/// the query string held by the Query object already
|
||||
///
|
||||
/// \param fn the functor called for each row
|
||||
/// \return a copy of the passed functor
|
||||
template <typename Function>
|
||||
Function for_each(Function fn)
|
||||
{
|
||||
mysqlpp::ResUse res = use();
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
fn(row);
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Run a functor for every row in a table
|
||||
///
|
||||
/// Just like for_each(Function), except that it builds a
|
||||
/// "select * from TABLE" query using the SQL table name from
|
||||
/// the SSQLS instance you pass.
|
||||
///
|
||||
/// \param ssqls the SSQLS instance to get a table name from
|
||||
/// \param fn the functor called for each row
|
||||
///
|
||||
/// \return a copy of the passed functor
|
||||
template <class SSQLS, typename Function>
|
||||
Function for_each(const SSQLS& ssqls, Function fn)
|
||||
{
|
||||
SQLString query("select * from ");
|
||||
query += ssqls._table;
|
||||
mysqlpp::ResUse res = use(query);
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
fn(row);
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Execute a query, conditionally storing each row in a
|
||||
/// container
|
||||
///
|
||||
/// This method wraps a use() query, calling the given functor for
|
||||
/// every returned row, and storing the results in the given
|
||||
/// sequence container if the functor returns true.
|
||||
///
|
||||
/// This is analogous to the STL copy_if() algorithm, except that
|
||||
/// the source rows come from a database query instead of another
|
||||
/// container. (copy_if() isn't a standard STL algorithm, but only
|
||||
/// due to an oversight by the standardization committee.) This
|
||||
/// fact may help you to remember the order of the parameters: the
|
||||
/// container is the destination, the query is the source, and the
|
||||
/// functor is the predicate; it's just like an STL algorithm.
|
||||
///
|
||||
/// \param seq the destination container; needs a push_back() method
|
||||
/// \param query the query string
|
||||
/// \param fn the functor called for each row
|
||||
/// \return a copy of the passed functor
|
||||
template <class Sequence, typename Function>
|
||||
Function store_if(Sequence& seq, const SQLString& query, Function fn)
|
||||
{
|
||||
mysqlpp::ResUse res = use(query);
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
if (fn(row)) {
|
||||
seq.push_back(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Pulls every row in a table, conditionally storing each
|
||||
/// one in a container
|
||||
///
|
||||
/// Just like store_if(Sequence&, const SQLString&, Function), but
|
||||
/// it uses the SSQLS instance to construct a "select * from TABLE"
|
||||
/// query, using the table name field in the SSQLS.
|
||||
///
|
||||
/// \param seq the destination container; needs a push_back() method
|
||||
/// \param ssqls the SSQLS instance to get a table name from
|
||||
/// \param fn the functor called for each row
|
||||
/// \return a copy of the passed functor
|
||||
template <class Sequence, class SSQLS, typename Function>
|
||||
Function store_if(Sequence& seq, const SSQLS& ssqls, Function fn)
|
||||
{
|
||||
SQLString query("select * from ");
|
||||
query += ssqls._table;
|
||||
mysqlpp::ResUse res = use(query);
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
if (fn(row)) {
|
||||
seq.push_back(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Execute the query, conditionally storing each row in a
|
||||
/// container
|
||||
///
|
||||
/// Just like store_if(Sequence&, const SQLString&, Function), but
|
||||
/// it uses the query string held by the Query object already
|
||||
///
|
||||
/// \param seq the destination container; needs a push_back() method
|
||||
/// \param fn the functor called for each row
|
||||
/// \return a copy of the passed functor
|
||||
template <class Sequence, typename Function>
|
||||
Function store_if(Sequence& seq, Function fn)
|
||||
{
|
||||
mysqlpp::ResUse res = use();
|
||||
if (res) {
|
||||
mysqlpp::NoExceptions ne(res);
|
||||
while (mysqlpp::Row row = res.fetch_row()) {
|
||||
if (fn(row)) {
|
||||
seq.push_back(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
/// \brief Return next result set, when processing a multi-query
|
||||
///
|
||||
/// There are two cases where you'd use this function instead of
|
||||
/// the regular store() functions.
|
||||
///
|
||||
/// First, when handling the result of executing multiple queries
|
||||
/// at once. (See <a
|
||||
/// href="http://dev.mysql.com/doc/mysql/en/c-api-multiple-queries.html">this
|
||||
/// page</a> in the MySQL documentation for details.)
|
||||
///
|
||||
/// Second, when calling a stored procedure, MySQL can return the
|
||||
/// result as a set of results.
|
||||
///
|
||||
/// In either case, you must consume all results before making
|
||||
/// another MySQL query, even if you don't care about the remaining
|
||||
/// results or result sets.
|
||||
///
|
||||
/// As the MySQL documentation points out, you must set the
|
||||
/// MYSQL_OPTION_MULTI_STATEMENTS_ON flag on the connection in order
|
||||
/// to use this feature. See Connection::set_option().
|
||||
///
|
||||
/// Multi-queries only exist in MySQL v4.1 and higher. Therefore,
|
||||
/// this function just wraps store() when built against older API
|
||||
/// libraries.
|
||||
///
|
||||
/// \return Result object containing the next result set.
|
||||
Result store_next();
|
||||
|
||||
/// \brief Return whether more results are waiting for a multi-query
|
||||
/// or stored procedure response.
|
||||
///
|
||||
/// If this function returns true, you must call store_next() to
|
||||
/// fetch the next result set before you can execute more queries.
|
||||
///
|
||||
/// Wraps mysql_more_results() in the MySQL C API. That function
|
||||
/// only exists in MySQL v4.1 and higher. Therefore, this function
|
||||
/// always returns false when built against older API libraries.
|
||||
///
|
||||
/// \return true if another result set exists
|
||||
bool more_results();
|
||||
|
||||
/// \brief Execute a query, storing the result set in an STL
|
||||
/// sequence container.
|
||||
///
|
||||
/// This function works much like store() from the caller's
|
||||
/// perspective, because it returns the entire result set at once.
|
||||
/// It's actually implemented in terms of use(), however, so that
|
||||
/// memory for the result set doesn't need to be allocated twice.
|
||||
///
|
||||
/// There are many overloads for this function, pretty much the same
|
||||
/// as for execute(), except that there is a Container parameter at
|
||||
/// the front of the list. So, you can pass a container and a query
|
||||
/// string, or a container and template query parameters.
|
||||
///
|
||||
/// \param con any STL sequence container, such as \c std::vector
|
||||
/// \param r whether the query automatically resets after being used
|
||||
///
|
||||
/// \sa exec(), execute(), store(), and use()
|
||||
template <class Sequence>
|
||||
void storein_sequence(Sequence& con, query_reset r = RESET_QUERY)
|
||||
{
|
||||
storein_sequence(con, def, r);
|
||||
}
|
||||
|
||||
/// \brief Execute a query, storing the result set in an STL
|
||||
/// associative container.
|
||||
///
|
||||
/// The same thing as storein_sequence(), except that it's used with
|
||||
/// associative STL containers, such as \c std::set. Other than
|
||||
/// that detail, that method's comments apply equally well to this
|
||||
/// one.
|
||||
template <class Set>
|
||||
void storein_set(Set& con, query_reset r = RESET_QUERY)
|
||||
{
|
||||
storein_set(con, def, r);
|
||||
}
|
||||
|
||||
/// \brief Execute a query, and store the entire result set
|
||||
/// in an STL container.
|
||||
///
|
||||
/// This is a set of specialized template functions that call either
|
||||
/// storein_sequence() or storein_set(), depending on the type of
|
||||
/// container you pass it. It understands \c std::vector, \c deque,
|
||||
/// \c list, \c slist (a common C++ library extension), \c set,
|
||||
/// and \c multiset.
|
||||
///
|
||||
/// Like the functions it wraps, this is actually an overloaded set
|
||||
/// of functions. See the other functions' documentation for details.
|
||||
///
|
||||
/// Use this function if you think you might someday switch your
|
||||
/// program from using a set-associative container to a sequence
|
||||
/// container for storing result sets, or vice versa.
|
||||
///
|
||||
/// See exec(), execute(), store(), and use() for alternative
|
||||
/// query execution mechanisms.
|
||||
template <class Container>
|
||||
void storein(Container& con, query_reset r = RESET_QUERY)
|
||||
{
|
||||
storein(con, def, r);
|
||||
}
|
||||
|
||||
/// \brief Specialization of storein_sequence() for \c std::vector
|
||||
template <class T>
|
||||
void storein(std::vector<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
|
||||
/// \brief Specialization of storein_sequence() for \c std::deque
|
||||
template <class T>
|
||||
void storein(std::deque<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
|
||||
/// \brief Specialization of storein_sequence() for \c std::list
|
||||
template <class T>
|
||||
void storein(std::list<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
|
||||
#if defined(HAVE_EXT_SLIST)
|
||||
/// \brief Specialization of storein_sequence() for g++ STL
|
||||
/// extension \c slist
|
||||
template <class T>
|
||||
void storein(__gnu_cxx::slist<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
#elif defined(HAVE_GLOBAL_SLIST)
|
||||
/// \brief Specialization of storein_sequence() for STL
|
||||
/// extension \c slist
|
||||
///
|
||||
/// This is primarily for older versions of g++, which put \c slist
|
||||
/// in the global namespace. This is a common language extension,
|
||||
/// so this may also work for other compilers.
|
||||
template <class T>
|
||||
void storein(slist<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
#elif defined(HAVE_STD_SLIST)
|
||||
/// \brief Specialization of storein_sequence() for STL
|
||||
/// extension \c slist
|
||||
///
|
||||
/// This is for those benighted compilers that include an \c slist
|
||||
/// implementation, but erroneously put it in the \c std namespace!
|
||||
template <class T>
|
||||
void storein(std::slist<T>& con, const char* s)
|
||||
{
|
||||
storein_sequence(con, s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/// \brief Specialization of storein_set() for \c std::set
|
||||
template <class T>
|
||||
void storein(std::set<T>& con, const char* s)
|
||||
{
|
||||
storein_set(con, s);
|
||||
}
|
||||
|
||||
/// \brief Specialization of storein_set() for \c std::multiset
|
||||
template <class T>
|
||||
void storein(std::multiset<T>& con, const char* s)
|
||||
{
|
||||
storein_set(con, s);
|
||||
}
|
||||
|
||||
/// \brief Replace an existing row's data with new data.
|
||||
///
|
||||
/// This function builds an UPDATE SQL query using the new row data
|
||||
/// for the SET clause, and the old row data for the WHERE clause.
|
||||
/// One uses it with MySQL++'s Specialized SQL Structures mechanism.
|
||||
///
|
||||
/// \param o old row
|
||||
/// \param n new row
|
||||
///
|
||||
/// \sa insert(), replace()
|
||||
template <class T>
|
||||
Query& update(const T& o, const T& n)
|
||||
{
|
||||
reset();
|
||||
|
||||
// Cast required for VC++ 2003 due to error in overloaded operator
|
||||
// lookup logic. For an explanation of the problem, see:
|
||||
// http://groups-beta.google.com/group/microsoft.public.vc.stl/browse_thread/thread/9a68d84644e64f15
|
||||
MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
|
||||
"UPDATE " << o.table() << " SET " << n.equal_list() <<
|
||||
" WHERE " << o.equal_list(" AND ", sql_use_compare);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Insert a new row.
|
||||
///
|
||||
/// This function builds an INSERT SQL query. One uses it with
|
||||
/// MySQL++'s Specialized SQL Structures mechanism.
|
||||
///
|
||||
/// \param v new row
|
||||
///
|
||||
/// \sa replace(), update()
|
||||
template <class T>
|
||||
Query& insert(const T& v)
|
||||
{
|
||||
reset();
|
||||
|
||||
MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
|
||||
"INSERT INTO " << v.table() << " (" <<
|
||||
v.field_list() << ") VALUES (" <<
|
||||
v.value_list() << ')';
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Insert multiple new rows.
|
||||
///
|
||||
/// Builds an INSERT SQL query using items from a range within an
|
||||
/// STL container. Insert the entire contents of the container by
|
||||
/// using the begin() and end() iterators of the container as
|
||||
/// parameters to this function.
|
||||
///
|
||||
/// \param first iterator pointing to first element in range to
|
||||
/// insert
|
||||
/// \param last iterator pointing to one past the last element to
|
||||
/// insert
|
||||
///
|
||||
/// \sa replace(), update()
|
||||
template <class Iter>
|
||||
Query& insert(Iter first, Iter last)
|
||||
{
|
||||
reset();
|
||||
if (first == last) {
|
||||
return *this; // empty set!
|
||||
}
|
||||
|
||||
MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
|
||||
"INSERT INTO " << first->table() << " (" <<
|
||||
first->field_list() << ") VALUES (" <<
|
||||
first->value_list() << ')';
|
||||
|
||||
Iter it = first + 1;
|
||||
while (it != last) {
|
||||
MYSQLPP_QUERY_THISPTR << ",(" << it->value_list() << ')';
|
||||
++it;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Insert new row unless there is an existing row that
|
||||
/// matches on a unique index, in which case we replace it.
|
||||
///
|
||||
/// This function builds a REPLACE SQL query. One uses it with
|
||||
/// MySQL++'s Specialized SQL Structures mechanism.
|
||||
///
|
||||
/// \param v new row
|
||||
///
|
||||
/// \sa insert(), update()
|
||||
template <class T>
|
||||
Query& replace(const T& v)
|
||||
{
|
||||
reset();
|
||||
|
||||
MYSQLPP_QUERY_THISPTR << std::setprecision(16) <<
|
||||
"REPLACE INTO " << v.table() << " (" <<
|
||||
v.field_list() << ") VALUES (" << v.value_list() << ')';
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return true if the last query was successful
|
||||
operator bool() { return success(); }
|
||||
|
||||
/// \brief Return true if the last query failed
|
||||
bool operator !() { return !success(); }
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Declare the remaining overloads. These are hidden down here partly
|
||||
// to keep the above code clear, but also so that we may hide them
|
||||
// from Doxygen, which gets confused by macro instantiations that look
|
||||
// like method declarations.
|
||||
mysql_query_define0(std::string, preview)
|
||||
mysql_query_define0(std::string, str)
|
||||
mysql_query_define1(ResNSel, execute)
|
||||
mysql_query_define1(Result, store)
|
||||
mysql_query_define1(ResUse, use)
|
||||
mysql_query_define2(storein_sequence)
|
||||
mysql_query_define2(storein_set)
|
||||
mysql_query_define2(storein)
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
/// \brief The default template parameters
|
||||
///
|
||||
/// Used for filling in parameterized queries.
|
||||
SQLQueryParms def;
|
||||
|
||||
private:
|
||||
friend class SQLQueryParms;
|
||||
|
||||
/// \brief Connection to send queries through
|
||||
Connection* conn_;
|
||||
|
||||
/// \brief If true, last query succeeded
|
||||
bool success_;
|
||||
|
||||
/// \brief List of template query parameters
|
||||
std::vector<SQLParseElement> parse_elems_;
|
||||
|
||||
/// \brief Maps template parameter position values to the
|
||||
/// corresponding parameter name.
|
||||
std::vector<std::string> parsed_names_;
|
||||
|
||||
/// \brief Maps template parameter names to their position value.
|
||||
std::map<std::string, short int> parsed_nums_;
|
||||
|
||||
/// \brief String buffer for storing assembled query
|
||||
std::stringbuf sbuffer_;
|
||||
|
||||
//// Internal support functions
|
||||
my_ulonglong affected_rows() const;
|
||||
my_ulonglong insert_id();
|
||||
std::string info();
|
||||
char* preview_char();
|
||||
|
||||
/// \brief Process a parameterized query list.
|
||||
void proc(SQLQueryParms& p);
|
||||
|
||||
// Locking mechanism
|
||||
bool lock();
|
||||
void unlock();
|
||||
|
||||
SQLString* pprepare(char option, SQLString& S, bool replace = true);
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
template <class Seq>
|
||||
void Query::storein_sequence(Seq& seq, SQLQueryParms& p, query_reset r)
|
||||
{
|
||||
r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
|
||||
storein_sequence(seq, str(p, r).c_str());
|
||||
}
|
||||
|
||||
|
||||
template <class Sequence>
|
||||
void Query::storein_sequence(Sequence& con, const char* s)
|
||||
{
|
||||
ResUse result = use(s);
|
||||
while (1) {
|
||||
MYSQL_ROW d = mysql_fetch_row(result.raw_result());
|
||||
if (!d)
|
||||
break;
|
||||
Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
|
||||
true);
|
||||
if (!row)
|
||||
break;
|
||||
con.push_back(typename Sequence::value_type(row));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class Set>
|
||||
void Query::storein_set(Set& sett, SQLQueryParms& p, query_reset r)
|
||||
{
|
||||
r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
|
||||
storein_set(sett, str(p, r).c_str());
|
||||
}
|
||||
|
||||
|
||||
template <class Set>
|
||||
void Query::storein_set(Set& con, const char* s)
|
||||
{
|
||||
ResUse result = use(s);
|
||||
while (1) {
|
||||
MYSQL_ROW d = mysql_fetch_row(result.raw_result());
|
||||
if (!d)
|
||||
return;
|
||||
Row row(d, &result, mysql_fetch_lengths(result.raw_result()),
|
||||
true);
|
||||
if (!row)
|
||||
break;
|
||||
con.insert(typename Set::value_type(row));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
void Query::storein(T& con, SQLQueryParms& p, query_reset r)
|
||||
{
|
||||
r = parse_elems_.size() ? DONT_RESET : RESET_QUERY;
|
||||
storein(con, str(p, r).c_str());
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,118 +0,0 @@
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// This file is generated by the Perl script querydef.pl. Please do
|
||||
// not modify this file directly. Change the script instead.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
#ifndef MYSQLPP_QUERYDEF_H
|
||||
#define MYSQLPP_QUERYDEF_H
|
||||
|
||||
#define mysql_query_define0(RETURN, FUNC) \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23); } \
|
||||
RETURN FUNC(const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23, const SQLString& arg24) \
|
||||
{ return FUNC(SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23 << arg24); } \
|
||||
|
||||
#define mysql_query_define1(RETURN, FUNC) \
|
||||
RETURN FUNC(SQLQueryParms& p); \
|
||||
mysql_query_define0(RETURN, FUNC)
|
||||
|
||||
#define mysql_query_define2(FUNC) \
|
||||
template <class T> void FUNC(T& container, const char* str); \
|
||||
template <class T> void FUNC(T& container, SQLQueryParms& p, \
|
||||
query_reset r = RESET_QUERY); \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23); } \
|
||||
template <class T> void FUNC(T& container, const SQLString& arg0, const SQLString& arg1, const SQLString& arg2, const SQLString& arg3, const SQLString& arg4, const SQLString& arg5, const SQLString& arg6, const SQLString& arg7, const SQLString& arg8, const SQLString& arg9, const SQLString& arg10, const SQLString& arg11, const SQLString& arg12, const SQLString& arg13, const SQLString& arg14, const SQLString& arg15, const SQLString& arg16, const SQLString& arg17, const SQLString& arg18, const SQLString& arg19, const SQLString& arg20, const SQLString& arg21, const SQLString& arg22, const SQLString& arg23, const SQLString& arg24) \
|
||||
{ FUNC(container, SQLQueryParms() << arg0 << arg1 << arg2 << arg3 << arg4 << arg5 << arg6 << arg7 << arg8 << arg9 << arg10 << arg11 << arg12 << arg13 << arg14 << arg15 << arg16 << arg17 << arg18 << arg19 << arg20 << arg21 << arg22 << arg23 << arg24); } \
|
||||
|
||||
#endif // !defined(MYSQLPP_QUERYDEF_H)
|
||||
@ -1,104 +0,0 @@
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
########################################################################
|
||||
# querydef.pl - Generates querydef.h, which defines a number of macros
|
||||
# used in query.h that differ only in the number of arguments. That
|
||||
# number limits the number of parameters a MySQL++ template query can
|
||||
# accept. This value can be changed from its default, below.
|
||||
#
|
||||
# Copyright (c) 2006-2007 by Educational Technology Resources, Inc.
|
||||
# Others may also hold copyrights on code in this file. See the CREDITS
|
||||
# file in the top directory of the distribution for details.
|
||||
#
|
||||
# This file is part of MySQL++.
|
||||
#
|
||||
# MySQL++ is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU Lesser General Public License as published
|
||||
# by the Free Software Foundation; either version 2.1 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
# License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public
|
||||
# License along with MySQL++; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
# USA
|
||||
########################################################################
|
||||
|
||||
|
||||
# The number of parameters a template query can accept. Make this value
|
||||
# larger only at need, as it adds code to the library proportionally.
|
||||
# You should not reduce this value if programs you did not write may
|
||||
# link to the library, as that would constitute an ABI breakage.
|
||||
my $max_parameters = 25;
|
||||
|
||||
|
||||
# No user-serviceable parts below.
|
||||
|
||||
use strict;
|
||||
|
||||
open (OUT, ">querydef.h");
|
||||
|
||||
print OUT << "---";
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// This file is generated by the Perl script querydef.pl. Please do
|
||||
// not modify this file directly. Change the script instead.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
#ifndef MYSQLPP_QUERYDEF_H
|
||||
#define MYSQLPP_QUERYDEF_H
|
||||
|
||||
---
|
||||
|
||||
## Build mysql_query_define0 macro
|
||||
print OUT "#define mysql_query_define0(RETURN, FUNC) \\\n";
|
||||
for (my $i = 1; $i < $max_parameters; ++$i) {
|
||||
print OUT "\tRETURN FUNC(";
|
||||
for (my $j = 0; $j < $i + 1; ++$j) {
|
||||
print OUT 'const SQLString& arg', $j;
|
||||
print OUT ', ' unless $j == $i;
|
||||
}
|
||||
print OUT ") \\\n";
|
||||
|
||||
print OUT "\t\t{ return FUNC(SQLQueryParms()";
|
||||
for (my $j = 0; $j < $i + 1; ++$j) {
|
||||
print OUT ' << arg', $j;
|
||||
}
|
||||
print OUT "); } \\\n";
|
||||
}
|
||||
|
||||
## Add mysql_query_define1 macro
|
||||
print OUT << "---";
|
||||
|
||||
#define mysql_query_define1(RETURN, FUNC) \\
|
||||
RETURN FUNC(SQLQueryParms& p); \\
|
||||
mysql_query_define0(RETURN, FUNC)
|
||||
---
|
||||
|
||||
## Add mysql_query_define2 macro
|
||||
print OUT << "---";
|
||||
|
||||
#define mysql_query_define2(FUNC) \\
|
||||
template <class T> void FUNC(T& container, const char* str); \\
|
||||
template <class T> void FUNC(T& container, SQLQueryParms& p, \\
|
||||
query_reset r = RESET_QUERY); \\
|
||||
---
|
||||
for (my $i = 0; $i < $max_parameters; ++$i) {
|
||||
print OUT "\ttemplate <class T> void FUNC(T& container";
|
||||
for (my $j = 0; $j < $i + 1; ++$j) {
|
||||
print OUT ', const SQLString& arg', $j;
|
||||
}
|
||||
print OUT ") \\\n";
|
||||
print OUT "\t\t{ FUNC(container, SQLQueryParms()";
|
||||
for (my $j = 0; $j < $i + 1; ++$j) {
|
||||
print OUT ' << arg', $j;
|
||||
}
|
||||
print OUT "); } \\\n";
|
||||
}
|
||||
|
||||
## That's all, folks!
|
||||
print OUT "\n#endif // !defined(MYSQLPP_QUERYDEF_H)\n";
|
||||
|
||||
@ -1,278 +0,0 @@
|
||||
/// \file resiter.h
|
||||
/// \brief Declares templates for adapting existing classes to
|
||||
/// be iteratable random-access containers.
|
||||
///
|
||||
/// The file name seems to tie it to the mysqlpp::Result class, which
|
||||
/// is so adapted, but these templates are also used to adapt the
|
||||
/// mysqlpp::Fields and mysqlpp::Row classes.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_RESITER_H
|
||||
#define MYSQLPP_RESITER_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <iterator>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
template <class OnType, class ReturnType, class SizeType,
|
||||
class DiffType> class subscript_iterator;
|
||||
|
||||
/// \brief A base class that one derives from to become a random
|
||||
/// access container, which can be accessed with subscript notation.
|
||||
///
|
||||
/// OnType must have the member functions \c operator[](SizeType) and
|
||||
// \c size() defined for it.
|
||||
|
||||
template <class OnType,
|
||||
class ValueType,
|
||||
class ReturnType = const ValueType&,
|
||||
class SizeType = unsigned int,
|
||||
class DiffType = int>
|
||||
class const_subscript_container
|
||||
{
|
||||
public:
|
||||
typedef const_subscript_container<OnType, ValueType, ReturnType,
|
||||
SizeType, DiffType> this_type; ///< this object's type
|
||||
typedef subscript_iterator<const this_type, ReturnType, SizeType,
|
||||
DiffType> iterator; ///< mutable iterator type
|
||||
typedef iterator const_iterator; ///< constant iterator type
|
||||
typedef const std::reverse_iterator<iterator>
|
||||
reverse_iterator; ///< mutable reverse iterator type
|
||||
typedef const std::reverse_iterator<const_iterator>
|
||||
const_reverse_iterator; ///< const reverse iterator type
|
||||
|
||||
typedef ValueType value_type; ///< type of data stored in container
|
||||
typedef value_type& reference; ///< reference to value_type
|
||||
typedef value_type& const_reference;///< const ref to value_type
|
||||
typedef value_type* pointer; ///< pointer to value_type
|
||||
typedef value_type* const_pointer; ///< const pointer to value_type
|
||||
|
||||
typedef DiffType difference_type; ///< for index differences
|
||||
typedef SizeType size_type; ///< for returned sizes
|
||||
|
||||
/// \brief Destroy object
|
||||
virtual ~const_subscript_container() { }
|
||||
|
||||
/// \brief Return count of elements in container
|
||||
virtual size_type size() const = 0;
|
||||
|
||||
/// \brief Return element at given index in container
|
||||
virtual ReturnType at(SizeType i) const = 0;
|
||||
|
||||
/// \brief Return maximum number of elements that can be stored
|
||||
/// in container without resizing.
|
||||
size_type max_size() const { return size(); }
|
||||
|
||||
/// \brief Returns true if container is empty
|
||||
bool empty() const { return size() == 0; }
|
||||
|
||||
/// \brief Return iterator pointing to first element in the
|
||||
/// container
|
||||
iterator begin() const { return iterator(this, 0); }
|
||||
|
||||
/// \brief Return iterator pointing to one past the last element
|
||||
/// in the container
|
||||
iterator end() const { return iterator(this, size()); }
|
||||
|
||||
/// \brief Return reverse iterator pointing to first element in the
|
||||
/// container
|
||||
reverse_iterator rbegin() const { return reverse_iterator(end()); }
|
||||
|
||||
/// \brief Return reverse iterator pointing to one past the last
|
||||
/// element in the container
|
||||
reverse_iterator rend() const { return reverse_iterator(begin()); }
|
||||
};
|
||||
|
||||
|
||||
/// \brief Iterator that can be subscripted.
|
||||
///
|
||||
/// This is the type of iterator used by the const_subscript_container
|
||||
/// template.
|
||||
|
||||
template <class OnType, class ReturnType, class SizeType,
|
||||
class DiffType>
|
||||
class subscript_iterator : public std::iterator<ReturnType, SizeType>
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
subscript_iterator() { }
|
||||
|
||||
/// \brief Create iterator given the container and a position
|
||||
/// within it.
|
||||
subscript_iterator(OnType* what, SizeType pos)
|
||||
{
|
||||
d_ = what;
|
||||
i_ = pos;
|
||||
}
|
||||
|
||||
/// \brief Return true if given iterator points to the same
|
||||
/// container and the same position within the container.
|
||||
bool operator ==(const subscript_iterator& j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ == j.i_);
|
||||
}
|
||||
|
||||
/// \brief Return true if given iterator is different from this
|
||||
/// one, but points to the same container.
|
||||
bool operator !=(const subscript_iterator& j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ != j.i_);
|
||||
}
|
||||
|
||||
/// \brief Return true if the given iterator points to the same
|
||||
/// container as this one, and that this iterator's position is
|
||||
/// less than the given iterator's.
|
||||
bool operator <(const subscript_iterator& j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ < j.i_);
|
||||
}
|
||||
|
||||
/// \brief Return true if the given iterator points to the same
|
||||
/// container as this one, and that this iterator's position is
|
||||
/// greater than the given iterator's.
|
||||
bool operator >(const subscript_iterator & j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ > j.i_);
|
||||
}
|
||||
|
||||
/// \brief Return true if the given iterator points to the same
|
||||
/// container as this one, and that this iterator's position is
|
||||
/// less than or equal to the given iterator's.
|
||||
bool operator <=(const subscript_iterator & j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ <= j.i_);
|
||||
}
|
||||
|
||||
/// \brief Return true if the given iterator points to the same
|
||||
/// container as this one, and that this iterator's position is
|
||||
/// greater than or equal to the given iterator's.
|
||||
bool operator >=(const subscript_iterator & j) const
|
||||
{
|
||||
return (d_ == j.d_ && i_ >= j.i_);
|
||||
}
|
||||
|
||||
/// \brief Dereference the iterator, returning a copy of the
|
||||
/// pointed-to element within the container.
|
||||
ReturnType operator *() const { return d_->at(i_); }
|
||||
|
||||
/// \brief Return a copy of the element at the given position
|
||||
/// within the container.
|
||||
ReturnType operator [](SizeType n) const { return d_->at(n); }
|
||||
|
||||
/// \brief Move the iterator to the next element, returning an
|
||||
/// iterator to that element
|
||||
subscript_iterator& operator ++() { ++i_; return *this; }
|
||||
|
||||
/// \brief Move the iterator to the next element, returning an
|
||||
/// iterator to the element we were pointing at before the change
|
||||
subscript_iterator operator ++(int)
|
||||
{
|
||||
subscript_iterator tmp = *this;
|
||||
++i_;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Move the iterator to the previous element, returning an
|
||||
/// iterator to that element
|
||||
subscript_iterator& operator --()
|
||||
{
|
||||
--i_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Move the iterator to the previous element, returning an
|
||||
/// iterator to the element we were pointing at before the change
|
||||
subscript_iterator operator --(int)
|
||||
{
|
||||
subscript_iterator tmp = *this;
|
||||
--i_;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Advance iterator position by \c n
|
||||
subscript_iterator& operator +=(SizeType n)
|
||||
{
|
||||
i_ += n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return an iterator \c n positions beyond this one
|
||||
subscript_iterator operator +(SizeType n) const
|
||||
{
|
||||
subscript_iterator tmp = *this;
|
||||
tmp.i_ += n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Move iterator position back by \c n
|
||||
subscript_iterator& operator -=(SizeType n)
|
||||
{
|
||||
i_ -= n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Return an iterator \c n positions before this one
|
||||
subscript_iterator operator -(SizeType n) const
|
||||
{
|
||||
subscript_iterator tmp = *this;
|
||||
tmp.i_ -= n;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Return an iterator \c n positions before this one
|
||||
DiffType operator -(const subscript_iterator& j) const
|
||||
{
|
||||
if (d_ == j.d_) {
|
||||
return static_cast<SizeType>(i_) - j.i_;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
SizeType i_;
|
||||
OnType* d_;
|
||||
};
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
template <class OnType, class ReturnType, class SizeType,
|
||||
class DiffType>
|
||||
inline subscript_iterator<OnType, ReturnType, SizeType, DiffType>
|
||||
operator +(SizeType x,
|
||||
const subscript_iterator <OnType, ReturnType, SizeType, DiffType>& y)
|
||||
{
|
||||
return y + x;
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,239 +0,0 @@
|
||||
/***********************************************************************
|
||||
result.cpp - Implements the Result, ResNSel, and ResUse classes.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "result.h"
|
||||
|
||||
#include "connection.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
ResNSel::ResNSel(Connection* q) :
|
||||
success(q->success()),
|
||||
insert_id(q->insert_id()),
|
||||
rows(q->affected_rows()),
|
||||
info(q->info())
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ResUse::ResUse(MYSQL_RES* result, Connection* c, bool te) :
|
||||
OptionalExceptions(te),
|
||||
conn_(c),
|
||||
initialized_(false),
|
||||
names_(0),
|
||||
types_(0),
|
||||
fields_(this)
|
||||
{
|
||||
if (!result) {
|
||||
result_ = 0;
|
||||
types_ = 0;
|
||||
names_ = 0;
|
||||
return;
|
||||
}
|
||||
result_ = result;
|
||||
names_ = new FieldNames(this);
|
||||
if (names_) {
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
table_ = fields(0).table;
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
|
||||
ResUse::~ResUse()
|
||||
{
|
||||
purge();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ResUse::copy(const ResUse& other)
|
||||
{
|
||||
if (initialized_) {
|
||||
purge();
|
||||
}
|
||||
|
||||
set_exceptions(other.throw_exceptions());
|
||||
|
||||
if (!other.result_) {
|
||||
result_ = 0;
|
||||
types_ = 0;
|
||||
names_ = 0;
|
||||
initialized_ = other.initialized_;
|
||||
return;
|
||||
}
|
||||
|
||||
result_ = other.result_;
|
||||
fields_ = Fields(this);
|
||||
|
||||
if (other.names_) {
|
||||
names_ = new FieldNames(*other.names_);
|
||||
}
|
||||
else {
|
||||
names_ = 0;
|
||||
}
|
||||
|
||||
if (other.types_) {
|
||||
types_ = new FieldTypes(*other.types_);
|
||||
}
|
||||
else {
|
||||
types_ = 0;
|
||||
}
|
||||
|
||||
table_ = other.table_;
|
||||
|
||||
conn_ = other.conn_;
|
||||
initialized_ = true;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ResUse::field_num(const std::string& i) const
|
||||
{
|
||||
if (!names_) {
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
|
||||
size_t index = (*names_)[i];
|
||||
if ((index >= names_->size()) && throw_exceptions()) {
|
||||
throw BadFieldName(i.c_str());
|
||||
}
|
||||
|
||||
return int(index);
|
||||
}
|
||||
|
||||
|
||||
std::string&
|
||||
ResUse::field_name(int i)
|
||||
{
|
||||
if (!names_) {
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
return (*names_)[i];
|
||||
}
|
||||
|
||||
|
||||
const std::string&
|
||||
ResUse::field_name(int i) const
|
||||
{
|
||||
if (!names_) {
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
return (*names_)[i];
|
||||
}
|
||||
|
||||
|
||||
FieldNames&
|
||||
ResUse::field_names()
|
||||
{
|
||||
if (!names_) {
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
return *names_;
|
||||
}
|
||||
|
||||
|
||||
const FieldNames&
|
||||
ResUse::field_names() const
|
||||
{
|
||||
if (!names_) {
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
return *names_;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ResUse::reset_field_names()
|
||||
{
|
||||
delete names_;
|
||||
names_ = 0;
|
||||
names_ = new FieldNames(this);
|
||||
}
|
||||
|
||||
|
||||
mysql_type_info&
|
||||
ResUse::field_type(int i)
|
||||
{
|
||||
if (!types_) {
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
return (*types_)[i];
|
||||
}
|
||||
|
||||
|
||||
const mysql_type_info&
|
||||
ResUse::field_type(int i) const
|
||||
{
|
||||
if (!types_) {
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
return (*types_)[i];
|
||||
}
|
||||
|
||||
|
||||
FieldTypes&
|
||||
ResUse::field_types()
|
||||
{
|
||||
if (!types_) {
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
return *types_;
|
||||
}
|
||||
|
||||
|
||||
const FieldTypes&
|
||||
ResUse::field_types() const
|
||||
{
|
||||
if (!types_) {
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
return *types_;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ResUse::reset_field_types()
|
||||
{
|
||||
delete types_;
|
||||
types_ = 0;
|
||||
types_ = new FieldTypes(this);
|
||||
}
|
||||
|
||||
|
||||
ResUse&
|
||||
ResUse::operator =(const ResUse& other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
copy(other);
|
||||
other.result_ = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,472 +0,0 @@
|
||||
/// \file result.h
|
||||
/// \brief Declares classes for holding SQL query result sets.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_RESULT_H
|
||||
#define MYSQLPP_RESULT_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "exceptions.h"
|
||||
#include "fields.h"
|
||||
#include "field_names.h"
|
||||
#include "field_types.h"
|
||||
#include "noexceptions.h"
|
||||
#include "resiter.h"
|
||||
#include "row.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT Connection;
|
||||
#endif
|
||||
|
||||
/// \brief A basic result set class, for use with "use" queries.
|
||||
///
|
||||
/// A "use" query is one where you make the query and then process just
|
||||
/// one row at a time in the result instead of dealing with them all as
|
||||
/// a single large chunk. (The name comes from the MySQL C API function
|
||||
/// that initiates this action, \c mysql_use_result().) By calling
|
||||
/// fetch_row() until it throws a mysqlpp::BadQuery exception (or an
|
||||
/// empty row if exceptions are disabled), you can process the result
|
||||
/// set one row at a time.
|
||||
|
||||
class MYSQLPP_EXPORT ResUse : public OptionalExceptions
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
ResUse() :
|
||||
OptionalExceptions(),
|
||||
conn_(0),
|
||||
result_(0),
|
||||
initialized_(false),
|
||||
names_(0),
|
||||
types_(0),
|
||||
fields_(this)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create the object, fully initialized
|
||||
ResUse(MYSQL_RES* result, Connection* c = 0, bool te = true);
|
||||
|
||||
/// \brief Create a copy of another ResUse object
|
||||
ResUse(const ResUse& other) :
|
||||
OptionalExceptions(),
|
||||
initialized_(false)
|
||||
{
|
||||
copy(other);
|
||||
other.result_ = 0;
|
||||
}
|
||||
|
||||
/// \brief Destroy object
|
||||
virtual ~ResUse();
|
||||
|
||||
/// \brief Copy another ResUse object's data into this object
|
||||
ResUse& operator =(const ResUse& other);
|
||||
|
||||
/// \brief Return raw MySQL C API result set
|
||||
MYSQL_RES* raw_result()
|
||||
{
|
||||
return result_;
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_fetch_row() in MySQL C API.
|
||||
///
|
||||
/// This is not a thin wrapper. It does a lot of error checking before
|
||||
/// returning the mysqlpp::Row object containing the row data.
|
||||
Row fetch_row()
|
||||
{
|
||||
if (!result_) {
|
||||
if (throw_exceptions()) {
|
||||
throw BadQuery("Results not fetched");
|
||||
}
|
||||
else {
|
||||
return Row();
|
||||
}
|
||||
}
|
||||
MYSQL_ROW row = mysql_fetch_row(result_);
|
||||
unsigned long* length = mysql_fetch_lengths(result_);
|
||||
if (!row || !length) {
|
||||
if (throw_exceptions()) {
|
||||
throw EndOfResults();
|
||||
}
|
||||
else {
|
||||
return Row();
|
||||
}
|
||||
}
|
||||
return Row(row, this, length, throw_exceptions());
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_fetch_lengths() in MySQL C API.
|
||||
unsigned long *fetch_lengths() const
|
||||
{
|
||||
return mysql_fetch_lengths(result_);
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_fetch_field() in MySQL C API.
|
||||
Field& fetch_field() const
|
||||
{
|
||||
return *mysql_fetch_field(result_);
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_field_seek() in MySQL C API.
|
||||
void field_seek(int field)
|
||||
{
|
||||
mysql_field_seek(result_, field);
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_num_fields() in MySQL C API.
|
||||
int num_fields() const
|
||||
{
|
||||
return mysql_num_fields(result_);
|
||||
}
|
||||
|
||||
/// \brief Documentation needed!
|
||||
void parent_leaving()
|
||||
{
|
||||
conn_ = 0;
|
||||
}
|
||||
|
||||
/// \brief Free all resources held by the object.
|
||||
///
|
||||
/// This class's destructor is little more than a call to purge(),
|
||||
/// so you can think of this as a way to re-use a ResUse object,
|
||||
/// to avoid having to completely re-create it.
|
||||
void purge()
|
||||
{
|
||||
if (result_) {
|
||||
mysql_free_result(result_);
|
||||
result_ = 0;
|
||||
}
|
||||
|
||||
delete names_;
|
||||
names_ = 0;
|
||||
|
||||
delete types_;
|
||||
types_ = 0;
|
||||
|
||||
table_.erase();
|
||||
}
|
||||
|
||||
/// \brief Return true if we have a valid result set
|
||||
///
|
||||
/// This operator is primarily used to determine if a query was
|
||||
/// successful:
|
||||
///
|
||||
/// \code
|
||||
/// Query q("....");
|
||||
/// if (q.use()) {
|
||||
/// ...
|
||||
/// \endcode
|
||||
///
|
||||
/// Query::use() returns a ResUse object, and it won't contain a
|
||||
/// valid result set if the query failed.
|
||||
operator bool() const
|
||||
{
|
||||
return result_;
|
||||
}
|
||||
|
||||
/// \brief Return the number of columns in the result set.
|
||||
unsigned int columns() const
|
||||
{
|
||||
return num_fields();
|
||||
}
|
||||
|
||||
/// \brief Get the name of table that the result set comes from.
|
||||
std::string& table()
|
||||
{
|
||||
return table_;
|
||||
}
|
||||
|
||||
/// \brief Return the name of the table
|
||||
///
|
||||
/// This is only valid
|
||||
const std::string& table() const
|
||||
{
|
||||
return table_;
|
||||
}
|
||||
|
||||
/// \brief Get the index of the named field.
|
||||
///
|
||||
/// This is the inverse of field_name().
|
||||
int field_num(const std::string&) const;
|
||||
|
||||
/// \brief Get the name of the field at the given index.
|
||||
///
|
||||
/// This is the inverse of field_num().
|
||||
std::string& field_name(int);
|
||||
|
||||
/// \brief Get the name of the field at the given index.
|
||||
const std::string& field_name(int) const;
|
||||
|
||||
/// \brief Get the names of the fields within this result set.
|
||||
FieldNames& field_names();
|
||||
|
||||
/// \brief Get the names of the fields within this result set.
|
||||
const FieldNames& field_names() const;
|
||||
|
||||
/// \brief Reset the names in the field list to their original
|
||||
/// values.
|
||||
void reset_field_names();
|
||||
|
||||
/// \brief Get the MySQL type for a field given its index.
|
||||
mysql_type_info& field_type(int i);
|
||||
|
||||
/// \brief Get the MySQL type for a field given its index.
|
||||
const mysql_type_info& field_type(int) const;
|
||||
|
||||
/// \brief Get a list of the types of the fields within this
|
||||
/// result set.
|
||||
FieldTypes& field_types();
|
||||
|
||||
/// \brief Get a list of the types of the fields within this
|
||||
/// result set.
|
||||
const FieldTypes& field_types() const;
|
||||
|
||||
/// \brief Reset the field types to their original values.
|
||||
void reset_field_types();
|
||||
|
||||
/// \brief Alias for field_num()
|
||||
int names(const std::string & s) const { return field_num(s); }
|
||||
|
||||
/// \brief Alias for field_name()
|
||||
std::string& names(int i) { return field_name(i); }
|
||||
|
||||
/// \brief Alias for field_name()
|
||||
const std::string& names(int i) const { return field_name(i); }
|
||||
|
||||
/// \brief Alias for field_names()
|
||||
FieldNames& names() { return field_names(); }
|
||||
|
||||
/// \brief Alias for field_names()
|
||||
const FieldNames& names() const { return field_names(); }
|
||||
|
||||
/// \brief Alias for reset_field_names()
|
||||
void reset_names() { reset_field_names(); }
|
||||
|
||||
/// \brief Alias for field_type()
|
||||
mysql_type_info& types(int i) { return field_type(i); }
|
||||
|
||||
/// \brief Alias for field_type()
|
||||
const mysql_type_info& types(int i) const { return field_type(i); }
|
||||
|
||||
/// \brief Alias for field_types()
|
||||
FieldTypes& types() { return field_types(); }
|
||||
|
||||
/// \brief Alias for field_types()
|
||||
const FieldTypes& types() const { return field_types(); }
|
||||
|
||||
/// \brief Alias for reset_field_types()
|
||||
void reset_types() { reset_field_types(); }
|
||||
|
||||
/// \brief Get the underlying Fields structure.
|
||||
const Fields& fields() const { return fields_; }
|
||||
|
||||
/// \brief Get the underlying Field structure given its index.
|
||||
const Field& fields(unsigned int i) const { return fields_.at(i); }
|
||||
|
||||
/// \brief Returns true if the other ResUse object shares the same
|
||||
/// underlying C API result set as this one.
|
||||
///
|
||||
/// This works because the underlying result set is stored as a
|
||||
/// pointer, and thus can be copied and then compared.
|
||||
bool operator ==(const ResUse& other) const
|
||||
{
|
||||
return result_ == other.result_;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the other ResUse object has a different
|
||||
/// underlying C API result set from this one.
|
||||
bool operator !=(const ResUse& other) const
|
||||
{
|
||||
return result_ != other.result_;
|
||||
}
|
||||
|
||||
protected:
|
||||
Connection* conn_; ///< server result set comes from
|
||||
mutable MYSQL_RES* result_; ///< underlying C API result set
|
||||
bool initialized_; ///< if true, object is fully initted
|
||||
mutable FieldNames* names_; ///< list of field names in result
|
||||
mutable FieldTypes* types_; ///< list of field types in result
|
||||
Fields fields_; ///< list of fields in result
|
||||
std::string table_; ///< table result set comes from
|
||||
|
||||
/// \brief Copy another ResUse object's contents into this one.
|
||||
///
|
||||
/// Self-copy is not allowed.
|
||||
void copy(const ResUse& other);
|
||||
};
|
||||
|
||||
|
||||
/// \brief This class manages SQL result sets.
|
||||
///
|
||||
/// Objects of this class are created to manage the result of "store"
|
||||
/// queries, where the result set is handed to the program as single
|
||||
/// block of row data. (The name comes from the MySQL C API function
|
||||
/// \c mysql_store_result() which creates these blocks of row data.)
|
||||
///
|
||||
/// This class is a random access container (in the STL sense) which
|
||||
/// is neither less-than comparable nor assignable. This container
|
||||
/// provides a reverse random-access iterator in addition to the normal
|
||||
/// forward one.
|
||||
|
||||
class MYSQLPP_EXPORT Result : public ResUse,
|
||||
public const_subscript_container<Result, Row, const Row>
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
Result()
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Fully initialize object
|
||||
Result(MYSQL_RES* result, bool te = true) :
|
||||
ResUse(result, 0, te)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object as a copy of another Result object
|
||||
Result(const Result& other) :
|
||||
ResUse(other),
|
||||
const_subscript_container<Result, Row, const Row>() // no copying here
|
||||
{
|
||||
conn_ = 0;
|
||||
}
|
||||
|
||||
/// \brief Destroy result set
|
||||
virtual ~Result() { }
|
||||
|
||||
/// \brief Wraps mysql_fetch_row() in MySQL C API.
|
||||
///
|
||||
/// This is simply the const version of the same function in our
|
||||
/// \link mysqlpp::ResUse parent class \endlink . Why this cannot
|
||||
/// actually \e be in our parent class is beyond me.
|
||||
const Row fetch_row() const
|
||||
{
|
||||
if (!result_) {
|
||||
if (throw_exceptions()) {
|
||||
throw BadQuery("Results not fetched");
|
||||
}
|
||||
else {
|
||||
return Row();
|
||||
}
|
||||
}
|
||||
MYSQL_ROW row = mysql_fetch_row(result_);
|
||||
unsigned long* length = mysql_fetch_lengths(result_);
|
||||
if (!row || !length) {
|
||||
if (throw_exceptions()) {
|
||||
throw EndOfResults();
|
||||
}
|
||||
else {
|
||||
return Row();
|
||||
}
|
||||
}
|
||||
return Row(row, this, length, throw_exceptions());
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_num_rows() in MySQL C API.
|
||||
my_ulonglong num_rows() const
|
||||
{
|
||||
if (initialized_)
|
||||
return mysql_num_rows(result_);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Wraps mysql_data_seek() in MySQL C API.
|
||||
void data_seek(uint offset) const
|
||||
{
|
||||
mysql_data_seek(result_, offset);
|
||||
}
|
||||
|
||||
/// \brief Alias for num_rows(), only with different return type.
|
||||
size_type size() const
|
||||
{
|
||||
return size_type(num_rows());
|
||||
}
|
||||
|
||||
/// \brief Alias for num_rows(), only with different return type.
|
||||
size_type rows() const
|
||||
{
|
||||
return size_type(num_rows());
|
||||
}
|
||||
|
||||
/// \brief Get the row with an offset of i.
|
||||
const Row at(size_type i) const
|
||||
{
|
||||
data_seek(i);
|
||||
return fetch_row();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Swaps two ResUse objects
|
||||
inline void swap(ResUse& x, ResUse& y)
|
||||
{
|
||||
ResUse tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
/// \brief Swaps two Result objects
|
||||
inline void swap(Result& x, Result& y)
|
||||
{
|
||||
Result tmp = x;
|
||||
x = y;
|
||||
y = tmp;
|
||||
}
|
||||
|
||||
/// \brief Holds the information on the success of queries that
|
||||
/// don't return any results.
|
||||
class MYSQLPP_EXPORT ResNSel
|
||||
{
|
||||
public:
|
||||
bool success; ///< if true, query was successful
|
||||
my_ulonglong insert_id; ///< last value used for AUTO_INCREMENT field
|
||||
my_ulonglong rows; ///< number of rows affected
|
||||
std::string info; ///< additional info about query result
|
||||
|
||||
ResNSel() :
|
||||
success(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Initialize object
|
||||
ResNSel(Connection* q);
|
||||
|
||||
/// \brief Returns true if the query was successful
|
||||
operator bool() { return success; }
|
||||
};
|
||||
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,186 +0,0 @@
|
||||
/***********************************************************************
|
||||
row.cpp - Implements the Row class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "row.h"
|
||||
#include "result.h"
|
||||
#include "exceptions.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
Row::Row(const MYSQL_ROW& d, const ResUse* r,
|
||||
unsigned long* jj, bool te) :
|
||||
OptionalExceptions(te),
|
||||
res_(r),
|
||||
initialized_(false)
|
||||
{
|
||||
if (!d || !r) {
|
||||
if (throw_exceptions()) {
|
||||
throw BadQuery("ROW or RES is NULL");
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
data_.clear();
|
||||
is_nulls_.clear();
|
||||
initialized_ = true;
|
||||
|
||||
for (size_type i = 0; i < size(); ++i) {
|
||||
data_.insert(data_.end(),
|
||||
(d[i] ? std::string(d[i], jj[i]) : std::string("NULL")));
|
||||
is_nulls_.insert(is_nulls_.end(), d[i] ? false : true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Row::~Row()
|
||||
{
|
||||
data_.clear();
|
||||
is_nulls_.clear();
|
||||
initialized_ = false;
|
||||
}
|
||||
|
||||
|
||||
Row::size_type Row::size() const
|
||||
{
|
||||
return res_->num_fields();
|
||||
}
|
||||
|
||||
const ColData Row::at(size_type i) const
|
||||
{
|
||||
if (initialized_) {
|
||||
const std::string& s = data_.at(i);
|
||||
return ColData(s.data(), s.length(), res_->types(i),
|
||||
is_nulls_[i]);
|
||||
}
|
||||
else {
|
||||
if (throw_exceptions())
|
||||
throw std::out_of_range("Row not initialized");
|
||||
else
|
||||
return ColData();
|
||||
}
|
||||
}
|
||||
|
||||
const ColData Row::operator [](const char* field) const
|
||||
{
|
||||
size_type si = res_->field_num(std::string(field));
|
||||
if (si < size()) {
|
||||
return at(si);
|
||||
}
|
||||
else {
|
||||
throw BadFieldName(field);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
value_list_ba<FieldNames, do_nothing_type0>
|
||||
Row::field_list(const char* d) const
|
||||
{
|
||||
return value_list_ba<FieldNames, do_nothing_type0>
|
||||
(parent().names(), d, do_nothing);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
value_list_ba<FieldNames, Manip>
|
||||
Row::field_list(const char *d, Manip m) const
|
||||
{
|
||||
return value_list_ba<FieldNames, Manip>(parent().names(), d, m);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
value_list_b<FieldNames, Manip>
|
||||
Row::field_list(const char *d, Manip m, const std::vector<bool>& vb) const
|
||||
{
|
||||
return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
|
||||
}
|
||||
|
||||
value_list_b<FieldNames, quote_type0>
|
||||
Row::field_list(const char* d, const std::vector<bool>& vb) const
|
||||
{
|
||||
return value_list_b<FieldNames, quote_type0>(parent().names(),
|
||||
vb, d, quote);
|
||||
}
|
||||
|
||||
value_list_b<FieldNames, quote_type0>
|
||||
Row::field_list(const std::vector<bool>& vb) const
|
||||
{
|
||||
return value_list_b<FieldNames, quote_type0>(parent().names(),
|
||||
vb, ",", quote);
|
||||
}
|
||||
|
||||
template <class Manip> value_list_b<FieldNames, Manip>
|
||||
Row::field_list(const char* d, Manip m, bool t0, bool t1, bool t2,
|
||||
bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
|
||||
bool ta, bool tb, bool tc) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
|
||||
t5, t6, t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
|
||||
}
|
||||
|
||||
value_list_b<FieldNames, quote_type0>
|
||||
Row::field_list(const char *d, bool t0, bool t1, bool t2, bool t3,
|
||||
bool t4, bool t5, bool t6, bool t7, bool t8, bool t9, bool ta,
|
||||
bool tb, bool tc) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
|
||||
t5, t6, t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<FieldNames, quote_type0>(parent().names(),
|
||||
vb, d, quote);
|
||||
}
|
||||
|
||||
value_list_b<FieldNames, quote_type0>
|
||||
Row::field_list(bool t0, bool t1, bool t2, bool t3, bool t4, bool t5,
|
||||
bool t6, bool t7, bool t8, bool t9, bool ta, bool tb,
|
||||
bool tc) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
|
||||
t5, t6, t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<FieldNames, quote_type0>(parent().names(),
|
||||
vb, ",", quote);
|
||||
}
|
||||
|
||||
equal_list_ba<FieldNames, Row, quote_type0>
|
||||
Row::equal_list(const char* d, const char* e) const
|
||||
{
|
||||
return equal_list_ba<FieldNames, Row, quote_type0>(
|
||||
parent().names(), *this, d, e, quote);
|
||||
}
|
||||
|
||||
template <class Manip>
|
||||
equal_list_ba<FieldNames, Row, Manip>
|
||||
Row::equal_list(const char* d, const char* e, Manip m) const
|
||||
{
|
||||
return equal_list_ba<FieldNames, Row, Manip>(
|
||||
parent().names(), *this, d, e, m);
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,479 +0,0 @@
|
||||
/// \file row.h
|
||||
/// \brief Declares the classes for holding row data from a result set.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_ROW_H
|
||||
#define MYSQLPP_ROW_H
|
||||
|
||||
#include "coldata.h"
|
||||
#include "exceptions.h"
|
||||
#include "noexceptions.h"
|
||||
#include "resiter.h"
|
||||
#include "vallist.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class FieldNames;
|
||||
class MYSQLPP_EXPORT ResUse;
|
||||
#endif
|
||||
|
||||
/// \brief Manages rows from a result set.
|
||||
class MYSQLPP_EXPORT Row :
|
||||
public const_subscript_container<Row, ColData, const ColData>,
|
||||
public OptionalExceptions
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
Row() :
|
||||
res_(0),
|
||||
initialized_(false)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create a row object
|
||||
///
|
||||
/// \param d MySQL C API row data
|
||||
/// \param r result set that the row comes from
|
||||
/// \param jj length of each item in d
|
||||
/// \param te if true, throw exceptions on errors
|
||||
Row(const MYSQL_ROW& d, const ResUse* r,
|
||||
unsigned long* jj, bool te = true);
|
||||
|
||||
/// \brief Destroy object
|
||||
~Row();
|
||||
|
||||
/// \brief Get a reference to our parent class.
|
||||
const ResUse& parent() const
|
||||
{
|
||||
return *res_;
|
||||
}
|
||||
|
||||
/// \brief Get the number of fields in the row.
|
||||
size_type size() const;
|
||||
|
||||
/// \brief Get the value of a field given its name.
|
||||
///
|
||||
/// If the field does not exist in this row, we throw a BadFieldName
|
||||
/// exception.
|
||||
///
|
||||
/// For this operator to work, the Result or ResUse object that
|
||||
/// created this object must still exist. In other words, you
|
||||
/// cannot re-use or destroy the result object until you are done
|
||||
/// retrieving data from this row object.
|
||||
///
|
||||
/// Note that we return the
|
||||
/// \link mysqlpp::ColData_Tmpl ColData \endlink object by value.
|
||||
/// The purpose of ColData is to make it easy to convert the string
|
||||
/// data returned by the MySQL server to some more appropriate type,
|
||||
/// so you're almost certain to use this operator in a construct
|
||||
/// like this:
|
||||
///
|
||||
/// \code
|
||||
/// string s = row["myfield"];
|
||||
/// \endcode
|
||||
///
|
||||
/// That accesses myfield within the row, returns a temporary
|
||||
/// ColData object, which is then automatically converted to a
|
||||
/// \c std::string and copied into \c s. That works fine, but
|
||||
/// beware of this similar but incorrect construct:
|
||||
///
|
||||
/// \code
|
||||
/// const char* pc = row["myfield"];
|
||||
/// \endcode
|
||||
///
|
||||
/// This one line of code does what you expect, but \c pc is then a
|
||||
/// dangling pointer: it points to memory owned by the temporary
|
||||
/// ColData object, which will have been destroyed by the time you
|
||||
/// get around to actually \e using the pointer.
|
||||
///
|
||||
/// This function is rather inefficient. If that is a concern for
|
||||
/// you, use at(), operator[](size_type) or the SSQLS mechanism'
|
||||
/// instead.
|
||||
const ColData operator [](const char* field) const;
|
||||
|
||||
/// \brief Get the value of a field given its index.
|
||||
///
|
||||
/// This function is just syntactic sugar, wrapping the at() method.
|
||||
/// The at() method is the only way to get at the first field in a
|
||||
/// result set by index, as \c row[0] is ambiguous: it could call
|
||||
/// either \c operator[] overload.
|
||||
///
|
||||
/// \sa at() for the full documentation for this operator, and
|
||||
/// operator[](const char*) for further caveats about using this
|
||||
/// operator.
|
||||
const ColData operator [](size_type i) const
|
||||
{
|
||||
return at(i);
|
||||
}
|
||||
|
||||
/// \brief Get the value of a field given its index.
|
||||
///
|
||||
/// If the index value is bad, the underlying std::vector is
|
||||
/// supposed to throw an exception, according to the Standard.
|
||||
///
|
||||
/// For this function to work, the Result or ResUse object that
|
||||
/// created this object must still exist. In other words, you
|
||||
/// cannot re-use or destroy the result object until you are done
|
||||
/// retrieving data from this row object.
|
||||
///
|
||||
/// See operator[](const char*) for more caveats.
|
||||
const ColData at(size_type i) const;
|
||||
|
||||
/// \brief Return the value of a field as a C string given its
|
||||
/// index, in raw form.
|
||||
///
|
||||
/// This is the same thing as operator[], except that the data isn't
|
||||
/// converted to a ColData object first. Also, this method does not
|
||||
/// check for out-of-bounds array indices.
|
||||
const char* raw_data(int i) const
|
||||
{
|
||||
return data_[i].data();
|
||||
}
|
||||
|
||||
/// \brief Return the size of a field's raw data given its index.
|
||||
std::string::size_type raw_size(int i) const
|
||||
{
|
||||
return data_[i].length();
|
||||
}
|
||||
|
||||
/// \brief Return the value of a field as a C++ string given its
|
||||
/// index, in raw form.
|
||||
///
|
||||
/// This is the same thing as operator[], except that the data isn't
|
||||
/// converted to a ColData object first.
|
||||
const std::string& raw_string(int i) const
|
||||
{
|
||||
return data_.at(i);
|
||||
}
|
||||
|
||||
/// \brief Returns true if there is data in the row.
|
||||
operator bool() const
|
||||
{
|
||||
return data_.size();
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// When inserted into a C++ stream, the delimiter 'd' will be used
|
||||
/// between the items, and the quoting and escaping rules will be
|
||||
/// set by the manipulator 'm' you choose.
|
||||
///
|
||||
/// \param d delimiter to use between values
|
||||
/// \param m manipulator to use when inserting values into a stream
|
||||
template <class Manip>
|
||||
value_list_ba<Row, Manip> value_list(const char* d = ",",
|
||||
Manip m = quote) const
|
||||
{
|
||||
return value_list_ba<Row, Manip>(*this, d, m);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// \param d delimiter to use between values
|
||||
/// \param vb for each true item in this list, add that value to the
|
||||
/// returned list; ignore the others
|
||||
/// \param m manipulator to use when inserting values into a stream
|
||||
template <class Manip>
|
||||
value_list_b<Row, Manip> value_list(const char *d,
|
||||
const std::vector<bool>& vb, Manip m = quote) const
|
||||
{
|
||||
return value_list_b<Row, Manip>(*this, vb, d, m);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// \param vb for each true item in this list, add that value to the
|
||||
/// returned list; ignore the others
|
||||
///
|
||||
/// Items will be quoted and escaped when inserted into a C++ stream,
|
||||
/// and a comma will be used as a delimiter between the items.
|
||||
value_list_b<Row, quote_type0> value_list(
|
||||
const std::vector<bool> &vb) const
|
||||
{
|
||||
return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// For each true parameter, the value in that position within the
|
||||
/// row is added to the returned list. When the list is inserted
|
||||
/// into a C++ stream, the delimiter 'd' will be placed between the
|
||||
/// items, and the manipulator 'm' used before each item.
|
||||
template <class Manip>
|
||||
value_list_b<Row, Manip> value_list(const char *d, Manip m,
|
||||
bool t0, bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
|
||||
t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<Row, Manip>(*this, vb, d, m);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// For each true parameter, the value in that position within the
|
||||
/// row is added to the returned list. When the list is inserted
|
||||
/// into a C++ stream, the delimiter 'd' will be placed between the
|
||||
/// items, and items will be quoted and escaped.
|
||||
value_list_b <Row, quote_type0>
|
||||
value_list(const char *d, bool t0, bool t1 = false, bool t2 = false,
|
||||
bool t3 = false, bool t4 = false, bool t5 = false,
|
||||
bool t6 = false, bool t7 = false, bool t8 = false,
|
||||
bool t9 = false, bool ta = false, bool tb = false,
|
||||
bool tc = false) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
|
||||
t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<Row, quote_type0>(*this, vb, d, quote);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// For each true parameter, the value in that position within the
|
||||
/// row is added to the returned list. When the list is inserted
|
||||
/// into a C++ stream, the a comma will be placed between the items,
|
||||
/// as a delimiter, and items will be quoted and escaped.
|
||||
value_list_b<Row, quote_type0> value_list(bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false) const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(size(), vb, t0, t1, t2, t3, t4, t5, t6,
|
||||
t7, t8, t9, ta, tb, tc);
|
||||
return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// The 's' parameters name the fields that will be added to the
|
||||
/// returned list. When inserted into a C++ stream, the delimiter
|
||||
/// 'd' will be placed between the items, and the manipulator 'm'
|
||||
/// will be inserted before each item.
|
||||
template <class Manip>
|
||||
value_list_b<Row, Manip> value_list(const char *d, Manip m,
|
||||
std::string s0, std::string s1 = "", std::string s2 = "",
|
||||
std::string s3 = "", std::string s4 = "",
|
||||
std::string s5 = "", std::string s6 = "",
|
||||
std::string s7 = "", std::string s8 = "",
|
||||
std::string s9 = "", std::string sa = "",
|
||||
std::string sb = "", std::string sc = "") const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
|
||||
s9, sa, sb, sc);
|
||||
return value_list_b<Row, Manip>(*this, vb, d, m);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// The 's' parameters name the fields that will be added to the
|
||||
/// returned list. When inserted into a C++ stream, the delimiter
|
||||
/// 'd' will be placed between the items, and items will be quoted
|
||||
/// and escaped.
|
||||
value_list_b<Row, quote_type0> value_list(
|
||||
const char *d,
|
||||
std::string s0, std::string s1 = "", std::string s2 = "",
|
||||
std::string s3 = "", std::string s4 = "",
|
||||
std::string s5 = "", std::string s6 = "",
|
||||
std::string s7 = "", std::string s8 = "",
|
||||
std::string s9 = "", std::string sa = "",
|
||||
std::string sb = "", std::string sc = "") const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
|
||||
s9, sa, sb, sc);
|
||||
return value_list_b<Row, quote_type0>(*this, vb, d, quote);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the values in this row
|
||||
///
|
||||
/// The 's' parameters name the fields that will be added to the
|
||||
/// returned list. When inserted into a C++ stream, a comma will be
|
||||
/// placed between the items as a delimiter, and items will be
|
||||
/// quoted and escaped.
|
||||
value_list_b<Row, quote_type0> value_list(
|
||||
std::string s0,
|
||||
std::string s1 = "", std::string s2 = "",
|
||||
std::string s3 = "", std::string s4 = "",
|
||||
std::string s5 = "", std::string s6 = "",
|
||||
std::string s7 = "", std::string s8 = "",
|
||||
std::string s9 = "", std::string sa = "",
|
||||
std::string sb = "", std::string sc = "") const
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(*this, vb, s0, s1, s2, s3, s4, s5, s6, s7, s8,
|
||||
s9, sa, sb, sc);
|
||||
return value_list_b<Row, quote_type0>(*this, vb, ",", quote);
|
||||
}
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// When inserted into a C++ stream, the delimiter 'd' will be used
|
||||
/// between the items, and no manipulator will be used on the items.
|
||||
value_list_ba<FieldNames, do_nothing_type0>
|
||||
field_list(const char* d = ",") const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// \param d delimiter to place between the items when the list is
|
||||
/// inserted into a C++ stream
|
||||
/// \param m manipulator to use before each item when the list is
|
||||
/// inserted into a C++ stream
|
||||
template <class Manip>
|
||||
value_list_ba<FieldNames, Manip> field_list(const char* d,
|
||||
Manip m) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// \param d delimiter to place between the items when the list is
|
||||
/// inserted into a C++ stream
|
||||
/// \param m manipulator to use before each item when the list is
|
||||
/// inserted into a C++ stream
|
||||
/// \param vb for each true item in this list, add that field name
|
||||
/// to the returned list; ignore the others
|
||||
template <class Manip>
|
||||
value_list_b<FieldNames, Manip> field_list(const char* d, Manip m,
|
||||
const std::vector<bool>& vb) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// \param d delimiter to place between the items when the list is
|
||||
/// inserted into a C++ stream
|
||||
/// \param vb for each true item in this list, add that field name
|
||||
/// to the returned list; ignore the others
|
||||
///
|
||||
/// Field names will be quoted and escaped when inserted into a C++
|
||||
/// stream.
|
||||
value_list_b<FieldNames, quote_type0> field_list(
|
||||
const char* d, const std::vector<bool>& vb) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// \param vb for each true item in this list, add that field name
|
||||
/// to the returned list; ignore the others
|
||||
///
|
||||
/// Field names will be quoted and escaped when inserted into a C++
|
||||
/// stream, and a comma will be placed between them as a delimiter.
|
||||
value_list_b<FieldNames, quote_type0> field_list(
|
||||
const std::vector<bool>& vb) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// For each true parameter, the field name in that position within
|
||||
/// the row is added to the returned list. When the list is
|
||||
/// inserted into a C++ stream, the delimiter 'd' will be placed
|
||||
/// between the items as a delimiter, and the manipulator 'm' used
|
||||
/// before each item.
|
||||
template <class Manip>
|
||||
value_list_b<FieldNames, Manip> field_list(const char *d, Manip m,
|
||||
bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// For each true parameter, the field name in that position within
|
||||
/// the row is added to the returned list. When the list is
|
||||
/// inserted into a C++ stream, the delimiter 'd' will be placed
|
||||
/// between the items as a delimiter, and the items will be quoted
|
||||
/// and escaped.
|
||||
value_list_b<FieldNames, quote_type0> field_list(
|
||||
const char *d, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false) const;
|
||||
|
||||
/// \brief Get a list of the field names in this row
|
||||
///
|
||||
/// For each true parameter, the field name in that position within
|
||||
/// the row is added to the returned list. When the list is
|
||||
/// inserted into a C++ stream, a comma will be placed between the
|
||||
/// items as a delimiter, and the items will be quoted and escaped.
|
||||
value_list_b<FieldNames, quote_type0> field_list(
|
||||
bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false) const;
|
||||
|
||||
/// \brief Get an "equal list" of the fields and values in this row
|
||||
///
|
||||
/// When inserted into a C++ stream, the delimiter 'd' will be used
|
||||
/// between the items, " = " is the relationship operator, and items
|
||||
/// will be quoted and escaped.
|
||||
equal_list_ba<FieldNames, Row, quote_type0>
|
||||
equal_list(const char* d = ",", const char* e = " = ") const;
|
||||
|
||||
/// \brief Get an "equal list" of the fields and values in this row
|
||||
///
|
||||
/// This method's parameters govern how the returned list will
|
||||
/// behave when you insert it into a C++ stream:
|
||||
///
|
||||
/// \param d delimiter to use between items
|
||||
/// \param e the operator to use between elements
|
||||
/// \param m the manipulator to use for each element
|
||||
///
|
||||
/// For example, if d is ",", e is " = ", and m is the quote
|
||||
/// manipulator, then the field and value lists (a, b) (c, d'e)
|
||||
/// will yield an equal list that gives the following when inserted
|
||||
/// into a C++ stream:
|
||||
///
|
||||
/// \code
|
||||
/// 'a' = 'c', 'b' = 'd''e'
|
||||
/// \endcode
|
||||
///
|
||||
/// Notice how the single quote was 'escaped' in the SQL way to
|
||||
/// avoid a syntax error.
|
||||
template <class Manip>
|
||||
equal_list_ba<FieldNames, Row, Manip> equal_list(const char* d,
|
||||
const char* e, Manip m) const;
|
||||
|
||||
private:
|
||||
std::vector<std::string> data_;
|
||||
std::vector<bool> is_nulls_;
|
||||
const ResUse* res_;
|
||||
bool initialized_;
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,178 +0,0 @@
|
||||
/***********************************************************************
|
||||
sql_string.cpp - Implements the SQLString template.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "sql_string.h"
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
SQLString::SQLString() :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
}
|
||||
|
||||
SQLString::SQLString(const string& str) :
|
||||
string(str),
|
||||
is_string(true),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
}
|
||||
|
||||
SQLString::SQLString(const char* str) :
|
||||
string(str),
|
||||
is_string(true),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
}
|
||||
|
||||
SQLString::SQLString(const char* str, size_t len) :
|
||||
string(str, len),
|
||||
is_string(true),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
}
|
||||
|
||||
SQLString::SQLString(char i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << static_cast<short int>(i);
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(unsigned char i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << static_cast<unsigned short int>(i);
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(short int i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(unsigned short int i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(int i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(unsigned int i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(longlong i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(ulonglong i) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs << i;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(float f) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs.precision(7); // max digits in IEEE 754 single-prec float
|
||||
outs << f;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(double f) :
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
ostringstream outs;
|
||||
outs.precision(16); // max digits in IEEE 754 double-prec float
|
||||
outs << f;
|
||||
assign(outs.str());
|
||||
}
|
||||
|
||||
SQLString::SQLString(const null_type& i) :
|
||||
string("NULL"),
|
||||
is_string(false),
|
||||
dont_escape(false),
|
||||
processed(false)
|
||||
{
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,143 +0,0 @@
|
||||
/// \file sql_string.h
|
||||
/// \brief Declares an \c std::string derivative that adds some things
|
||||
/// needed within the library.
|
||||
///
|
||||
/// This class adds some flags needed by other parts of MySQL++, and it
|
||||
/// adds conversion functions from any primitive type. This helps in
|
||||
/// inserting these primitive types into the database, because we need
|
||||
/// everything in string form to build SQL queries.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_SQL_STRING_H
|
||||
#define MYSQLPP_SQL_STRING_H
|
||||
|
||||
#include "common.h"
|
||||
#include "null.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief A specialized \c std::string that will convert from any
|
||||
/// valid MySQL type.
|
||||
|
||||
class MYSQLPP_EXPORT SQLString : public std::string {
|
||||
public:
|
||||
/// \brief If true, the object's string data is a copy of another
|
||||
/// string. Otherwise, it's the string form of an integral type.
|
||||
bool is_string;
|
||||
|
||||
/// \brief If true, the string data doesn't need to be SQL-escaped
|
||||
/// when building a query.
|
||||
bool dont_escape;
|
||||
|
||||
/// \brief If true, one of the MySQL++ manipulators has processed
|
||||
/// the string data.
|
||||
///
|
||||
/// "Processing" is escaping special SQL characters, and/or adding
|
||||
/// quotes. See the documentation for manip.h for details.
|
||||
///
|
||||
/// This flag is used by the template query mechanism, to prevent a
|
||||
/// string from being re-escaped or re-quoted each time that query
|
||||
/// is reused. The flag is reset by operator=, to force the new
|
||||
/// parameter value to be re-processed.
|
||||
bool processed;
|
||||
|
||||
/// \brief Default constructor; empty string
|
||||
SQLString();
|
||||
|
||||
/// \brief Create object as a copy of a C++ string
|
||||
SQLString(const std::string& str);
|
||||
|
||||
/// \brief Create object as a copy of a C string
|
||||
SQLString(const char* str);
|
||||
|
||||
/// \brief Create object as a copy of a known-length string of
|
||||
/// characters.
|
||||
SQLString(const char* str, size_t len);
|
||||
|
||||
/// \brief Create object as the string form of a \c char value
|
||||
SQLString(char i);
|
||||
|
||||
/// \brief Create object as the string form of an \c unsigned
|
||||
/// \c char value
|
||||
SQLString(unsigned char i);
|
||||
|
||||
/// \brief Create object as the string form of a \c short \c int
|
||||
/// value
|
||||
SQLString(short int i);
|
||||
|
||||
/// \brief Create object as the string form of an \c unsigned
|
||||
/// \c short \c int value
|
||||
SQLString(unsigned short int i);
|
||||
|
||||
/// \brief Create object as the string form of an \c int value
|
||||
SQLString(int i);
|
||||
|
||||
/// \brief Create object as the string form of an \c unsigned
|
||||
/// \c int value
|
||||
SQLString(unsigned int i);
|
||||
|
||||
/// \brief Create object as the string form of a \c longlong
|
||||
/// value
|
||||
SQLString(longlong i);
|
||||
|
||||
/// \brief Create object as the string form of an \c unsigned
|
||||
/// \c longlong value
|
||||
SQLString(ulonglong i);
|
||||
|
||||
/// \brief Create object as the string form of a \c float
|
||||
/// value
|
||||
SQLString(float i);
|
||||
|
||||
/// \brief Create object as the string form of a \c double
|
||||
/// value
|
||||
SQLString(double i);
|
||||
|
||||
/// \brief Create object representing NULL
|
||||
SQLString(const null_type& i);
|
||||
|
||||
/// \brief Copy a C string into this object
|
||||
SQLString& operator =(const char* str)
|
||||
{
|
||||
std::string::operator =(str);
|
||||
processed = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Copy a C++ \c string into this object
|
||||
SQLString& operator =(const std::string& str)
|
||||
{
|
||||
std::string::operator =(str);
|
||||
processed = false;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,85 +0,0 @@
|
||||
/// \file sql_types.h
|
||||
/// \brief Declares the closest C++ equivalent of each MySQL column type
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006 by Educational Technology Resources, Inc. Others
|
||||
may also hold copyrights on code in this file. See the CREDITS file in
|
||||
the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#if !defined(MYSQLPP_SQL_TYPES_H)
|
||||
#define MYSQLPP_SQL_TYPES_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
// Nearest C++ equivalents of MySQL data types. These are only the "NOT
|
||||
// NULL" variants. Wrap these types in MySQL++'s Null<> template to get
|
||||
// NULL-able types.
|
||||
typedef signed char sql_tinyint;
|
||||
typedef unsigned char sql_tinyint_unsigned;
|
||||
typedef short sql_smallint;
|
||||
typedef unsigned short sql_smallint_unsigned;
|
||||
typedef int sql_int;
|
||||
typedef unsigned int sql_int_unsigned;
|
||||
typedef int sql_mediumint;
|
||||
typedef unsigned int sql_mediumint_unsigned;
|
||||
typedef longlong sql_bigint;
|
||||
typedef ulonglong sql_bigint_unsigned;
|
||||
|
||||
typedef float sql_float;
|
||||
typedef double sql_double;
|
||||
typedef double sql_decimal;
|
||||
|
||||
typedef std::string sql_enum;
|
||||
|
||||
typedef ColData sql_blob;
|
||||
typedef ColData sql_tinyblob;
|
||||
typedef ColData sql_mediumblob;
|
||||
typedef ColData sql_longblob;
|
||||
|
||||
typedef std::string sql_char;
|
||||
typedef std::string sql_varchar;
|
||||
|
||||
#ifdef MYSQLPP_DATETIME_H
|
||||
// MySQL++ date and time types are defined, so make aliases for
|
||||
// them matching the style of the above types.
|
||||
typedef Date sql_date;
|
||||
typedef Time sql_time;
|
||||
typedef Time sql_timestamp;
|
||||
typedef DateTime sql_datetime;
|
||||
#endif
|
||||
#ifdef MYSQLPP_MYSET_H
|
||||
// Ditto for MySQL++'s SQL set type
|
||||
typedef Set<> sql_set;
|
||||
#endif
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_SQL_TYPES_H)
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/// \file stream2string.h
|
||||
/// \brief Declares an adapter that converts something that can be
|
||||
/// inserted into a C++ stream into a string type.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_STREAM2STRING_H
|
||||
#define MYSQLPP_STREAM2STRING_H
|
||||
|
||||
#include <sstream>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Converts a stream-able object to any type that can be
|
||||
/// initialized from an \c std::string.
|
||||
///
|
||||
/// This adapter takes any object that has an \c out_stream() member
|
||||
/// function and converts it to a string type. An example of such a
|
||||
/// type within the library is mysqlpp::Date.
|
||||
|
||||
template <class Strng, class T>
|
||||
Strng stream2string(const T& object)
|
||||
{
|
||||
std::ostringstream str;
|
||||
object.out_stream(str);
|
||||
str << std::ends;
|
||||
Strng s = str.str();
|
||||
return s;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,145 +0,0 @@
|
||||
/***********************************************************************
|
||||
string_util.cpp - Implements utility functions for manipulating
|
||||
C++ strings.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "string_util.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
void strip(std::string& s)
|
||||
{
|
||||
size_t i, j = s.size() - 1;
|
||||
if (!s.size()) {
|
||||
return;
|
||||
}
|
||||
for (i = 0; s[i] == ' '; i++) ;
|
||||
if (i) {
|
||||
s.erase(0, i);
|
||||
}
|
||||
j = s.size();
|
||||
if (!j) {
|
||||
return;
|
||||
}
|
||||
j--;
|
||||
for (i = j; i && s[i] == ' '; i--) ;
|
||||
if (i != j) {
|
||||
s.erase(i + 1, static_cast<size_t> (-1));
|
||||
}
|
||||
}
|
||||
|
||||
void escape_string(std::string & s)
|
||||
{
|
||||
if (!s.size()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < s.size(); i++) {
|
||||
switch (s[i]) {
|
||||
case '\0': // Must be escaped for "mysql"
|
||||
s[i] = '\\';
|
||||
s.insert(i, "0", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\n': // Must be escaped for logs
|
||||
s[i] = '\\';
|
||||
s.insert(i, "n", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\r':
|
||||
s[i] = '\\';
|
||||
s.insert(i, "r", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\\':
|
||||
s[i] = '\\';
|
||||
s.insert(i, "\\", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\"':
|
||||
s[i] = '\\';
|
||||
s.insert(i, "\"", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\'': // Better safe than sorry
|
||||
s[i] = '\\';
|
||||
s.insert(i, "\'", 1);
|
||||
i++;
|
||||
break;
|
||||
case '\032': // This gives problems on Win32
|
||||
s[i] = '\\';
|
||||
s.insert(i, "Z", 1);
|
||||
i++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
str_to_upr(std::string& s)
|
||||
{
|
||||
for (std::string::size_type i = 0; i < s.length(); ++i) {
|
||||
s[i] = toupper(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
str_to_lwr(std::string& s)
|
||||
{
|
||||
for (std::string::size_type i = 0; i < s.length(); ++i) {
|
||||
s[i] = tolower(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
strip_all_blanks(std::string& s)
|
||||
{
|
||||
for (std::string::size_type i = 0; i < s.length(); ++i) {
|
||||
if (s[i] == ' ') {
|
||||
s.erase(i, 1);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
strip_all_non_num(std::string& s)
|
||||
{
|
||||
for (std::string::size_type i = 0; i < s.length(); ++i) {
|
||||
if (!isdigit(s[i])) {
|
||||
s.erase(i, 1);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,61 +0,0 @@
|
||||
/// \file string_util.h
|
||||
/// \brief Declares string-handling utility functions used within
|
||||
/// the library.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_STRING_UTIL_H
|
||||
#define MYSQLPP_STRING_UTIL_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Strips blanks at left and right ends
|
||||
MYSQLPP_EXPORT extern void strip(std::string& s);
|
||||
|
||||
/// \brief C++ equivalent of mysql_escape_string()
|
||||
MYSQLPP_EXPORT extern void escape_string(std::string& s);
|
||||
|
||||
/// \brief Changes case of string to upper
|
||||
MYSQLPP_EXPORT extern void str_to_upr(std::string& s);
|
||||
|
||||
/// \brief Changes case of string to lower
|
||||
MYSQLPP_EXPORT extern void str_to_lwr(std::string& s);
|
||||
|
||||
/// \brief Removes all blanks
|
||||
MYSQLPP_EXPORT extern void strip_all_blanks(std::string& s);
|
||||
|
||||
/// \brief Removes all non-numerics
|
||||
MYSQLPP_EXPORT extern void strip_all_non_num(std::string& s);
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,239 +0,0 @@
|
||||
/// \file tiny_int.h
|
||||
/// \brief Declares class for holding a SQL tiny_int
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_TINY_INT_H
|
||||
#define MYSQLPP_TINY_INT_H
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
/// \brief Class for holding an SQL \c tiny_int object.
|
||||
///
|
||||
/// This is required because the closest C++ type, \c char, doesn't
|
||||
/// have all the right semantics. For one, inserting a \c char into a
|
||||
/// stream won't give you a number.
|
||||
///
|
||||
/// Several of the functions below accept a \c short \c int argument,
|
||||
/// but internally we store the data as a \c char. Beware of integer
|
||||
/// overflows!
|
||||
|
||||
class MYSQLPP_EXPORT tiny_int
|
||||
{
|
||||
public:
|
||||
/// \brief Default constructor
|
||||
///
|
||||
/// Value is uninitialized
|
||||
tiny_int() { }
|
||||
|
||||
/// \brief Create object from any integral type that can be
|
||||
/// converted to a \c short \c int.
|
||||
tiny_int(short int v) :
|
||||
value_(char(v))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Return value as a \c short \c int.
|
||||
operator short int() const
|
||||
{
|
||||
return static_cast<short int>(value_);
|
||||
}
|
||||
|
||||
/// \brief Assign a \c short \c int to the object.
|
||||
tiny_int& operator =(short int v)
|
||||
{
|
||||
value_ = char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Add another value to this object
|
||||
tiny_int& operator +=(short int v)
|
||||
{
|
||||
value_ += char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Subtract another value to this object
|
||||
tiny_int& operator -=(short int v)
|
||||
{
|
||||
value_ -= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Multiply this value by another object
|
||||
tiny_int& operator *=(short int v)
|
||||
{
|
||||
value_ *= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Divide this value by another object
|
||||
tiny_int& operator /=(short int v)
|
||||
{
|
||||
value_ /= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Divide this value by another object and store the
|
||||
/// remainder
|
||||
tiny_int& operator %=(short int v)
|
||||
{
|
||||
value_ %= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Bitwise AND this value by another value
|
||||
tiny_int& operator &=(short int v)
|
||||
{
|
||||
value_ &= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Bitwise OR this value by another value
|
||||
tiny_int& operator |=(short int v)
|
||||
{
|
||||
value_ |= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Bitwise XOR this value by another value
|
||||
tiny_int& operator ^=(short int v)
|
||||
{
|
||||
value_ ^= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Shift this value left by \c v positions
|
||||
tiny_int& operator <<=(short int v)
|
||||
{
|
||||
value_ <<= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Shift this value right by \c v positions
|
||||
tiny_int& operator >>=(short int v)
|
||||
{
|
||||
value_ >>= char(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Add one to this value and return that value
|
||||
tiny_int& operator ++()
|
||||
{
|
||||
value_++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Subtract one from this value and return that value
|
||||
tiny_int& operator --()
|
||||
{
|
||||
value_--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Add one to this value and return the previous value
|
||||
tiny_int operator ++(int)
|
||||
{
|
||||
tiny_int tmp = value_;
|
||||
value_++;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Subtract one from this value and return the previous
|
||||
/// value
|
||||
tiny_int operator --(int)
|
||||
{
|
||||
tiny_int tmp = value_;
|
||||
value_--;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/// \brief Return this value minus \c i
|
||||
tiny_int operator -(const tiny_int& i) const
|
||||
{
|
||||
return value_ - i;
|
||||
}
|
||||
|
||||
/// \brief Return this value plus \c i
|
||||
tiny_int operator +(const tiny_int& i) const
|
||||
{
|
||||
return value_ + i;
|
||||
}
|
||||
|
||||
/// \brief Return this value multiplied by \c i
|
||||
tiny_int operator *(const tiny_int& i) const
|
||||
{
|
||||
return value_ * i;
|
||||
}
|
||||
|
||||
/// \brief Return this value divided by \c i
|
||||
tiny_int operator /(const tiny_int& i) const
|
||||
{
|
||||
return value_ / i;
|
||||
}
|
||||
|
||||
/// \brief Return the modulus of this value divided by \c i
|
||||
tiny_int operator %(const tiny_int& i) const
|
||||
{
|
||||
return value_ % i;
|
||||
}
|
||||
|
||||
/// \brief Return this value bitwise OR'd by \c i
|
||||
tiny_int operator |(const tiny_int& i) const
|
||||
{
|
||||
return value_ | i;
|
||||
}
|
||||
|
||||
/// \brief Return this value bitwise AND'd by \c i
|
||||
tiny_int operator &(const tiny_int& i) const
|
||||
{
|
||||
return value_ & i;
|
||||
}
|
||||
|
||||
/// \brief Return this value bitwise XOR'd by \c i
|
||||
tiny_int operator ^(const tiny_int& i) const
|
||||
{
|
||||
return value_ ^ i;
|
||||
}
|
||||
|
||||
/// \brief Return this value bitwise shifted left by \c i
|
||||
tiny_int operator <<(const tiny_int& i) const
|
||||
{
|
||||
return value_ << i;
|
||||
}
|
||||
|
||||
/// \brief Return this value bitwise shifted right by \c i
|
||||
tiny_int operator >>(const tiny_int& i) const
|
||||
{
|
||||
return value_ >> i;
|
||||
}
|
||||
|
||||
private:
|
||||
char value_;
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
@ -1,97 +0,0 @@
|
||||
/***********************************************************************
|
||||
transaction.cpp - Implements the Transaction class.
|
||||
|
||||
Copyright (c) 2006 by Educational Technology Resources, Inc. Others
|
||||
may also hold copyrights on code in this file. See the CREDITS file
|
||||
in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#define MYSQLPP_NOT_HEADER
|
||||
#include "common.h"
|
||||
|
||||
#include "transaction.h"
|
||||
|
||||
#include "connection.h"
|
||||
#include "query.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace mysqlpp;
|
||||
|
||||
|
||||
//// ctor //////////////////////////////////////////////////////////////
|
||||
|
||||
Transaction::Transaction(Connection& conn, bool consistent) :
|
||||
conn_(conn),
|
||||
finished_(true) // don't bother rolling it back if ctor fails
|
||||
{
|
||||
// Begin the transaction set
|
||||
Query q(conn_.query());
|
||||
q << "START TRANSACTION";
|
||||
if (consistent) {
|
||||
q << " WITH CONSISTENT SNAPSHOT";
|
||||
}
|
||||
q.execute();
|
||||
|
||||
// Setup succeeded, so mark our transaction as not-finished.
|
||||
finished_ = false;
|
||||
}
|
||||
|
||||
|
||||
//// dtor //////////////////////////////////////////////////////////////
|
||||
|
||||
Transaction::~Transaction()
|
||||
{
|
||||
if (!finished_) {
|
||||
try {
|
||||
rollback();
|
||||
}
|
||||
catch (...) {
|
||||
// eat all exceptions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//// commit ////////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Transaction::commit()
|
||||
{
|
||||
Query q(conn_.query());
|
||||
q << "COMMIT";
|
||||
q.execute();
|
||||
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
|
||||
//// rollback //////////////////////////////////////////////////////////
|
||||
|
||||
void
|
||||
Transaction::rollback()
|
||||
{
|
||||
Query q(conn_.query());
|
||||
q << "ROLLBACK";
|
||||
q.execute();
|
||||
|
||||
finished_ = true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,91 +0,0 @@
|
||||
/// \file transaction.h
|
||||
/// \brief Declares the Transaction class.
|
||||
///
|
||||
/// This object works with the Connection class to automate the use of
|
||||
/// MySQL transactions. It allows you to express these transactions
|
||||
/// directly in C++ code instead of sending the raw SQL commands.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 2006 by Educational Technology Resources, Inc. Others
|
||||
may also hold copyrights on code in this file. See the CREDITS file
|
||||
in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#if !defined(MYSQLPP_TRANSACTION_H)
|
||||
#define MYSQLPP_TRANSACTION_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Make Doxygen ignore this
|
||||
class MYSQLPP_EXPORT Connection;
|
||||
#endif
|
||||
|
||||
/// \brief Helper object for creating exception-safe SQL transactions.
|
||||
|
||||
class MYSQLPP_EXPORT Transaction
|
||||
{
|
||||
public:
|
||||
/// \brief Constructor
|
||||
///
|
||||
/// \param conn The connection we use to manage the transaction set
|
||||
/// \param consistent Whether to use "consistent snapshots" during
|
||||
/// the transaction. See the documentation for "START TRANSACTION"
|
||||
/// in the MySQL manual for more on this.
|
||||
Transaction(Connection& conn, bool consistent = false);
|
||||
|
||||
/// \brief Destructor
|
||||
///
|
||||
/// If the transaction has not been committed or rolled back by the
|
||||
/// time the destructor is called, it is rolled back. This is the
|
||||
/// right thing because one way this can happen is if the object is
|
||||
/// being destroyed as the stack is unwound to handle an exception.
|
||||
/// In that instance, you certainly want to roll back the
|
||||
/// transaction.
|
||||
~Transaction();
|
||||
|
||||
/// \brief Commits the transaction
|
||||
///
|
||||
/// This commits all updates to the database using the connection
|
||||
/// we were created with since this object was created. This is a
|
||||
/// no-op if the table isn't stored using a transaction-aware
|
||||
/// storage engine. See CREATE TABLE in the MySQL manual for
|
||||
/// details.
|
||||
void commit();
|
||||
|
||||
/// \brief Rolls back the transaction
|
||||
///
|
||||
/// This abandons all SQL statements made on the connection since
|
||||
/// this object was created. This only works on tables stored using
|
||||
/// a transaction-aware storage engine. See CREATE TABLE in the
|
||||
/// MySQL manual for details.
|
||||
void rollback();
|
||||
|
||||
private:
|
||||
Connection& conn_; ///! Connection to send queries through
|
||||
bool finished_; ///! True when we commit or roll back xaction
|
||||
};
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif // !defined(MYSQLPP_TRANSACTION_H)
|
||||
|
||||
@ -1,192 +0,0 @@
|
||||
/***********************************************************************
|
||||
type_info.cpp - Implements the mysql_type_info class.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "common.h"
|
||||
#include "type_info.h"
|
||||
|
||||
#include "datetime.h"
|
||||
#include "myset.h"
|
||||
#include "sql_types.h"
|
||||
|
||||
#include <mysql.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
// The first half of this array roughly parallels enum_field_types
|
||||
// in mysql/mysql_com.h. It is a lookup table used by the type() method
|
||||
// below when translating from SQL type information to the closest
|
||||
// C++ equivalent.
|
||||
//
|
||||
// The second half of the list parallels the first, to handle null-able
|
||||
// versions of the types in the first half. This is required because
|
||||
// SQL's 'null' concept does not map neatly into the C++ type system, so
|
||||
// null-able versions of these types have to have a different C++ type,
|
||||
// implemented using the Null template. See null.h for further details.
|
||||
//
|
||||
// Types marked true (the "default" field) are added to a lookup map in
|
||||
// the mysql_type_info_lookup class in order to provide reverse lookup
|
||||
// of C++ types to SQL types. Put another way, if you take the subset
|
||||
// of all items marked true, the typeid() of each item must be unique.
|
||||
const mysql_type_info::sql_type_info mysql_type_info::types[62] = {
|
||||
sql_type_info("DECIMAL NOT NULL", typeid(sql_decimal), 0),
|
||||
sql_type_info("TINYINT NOT NULL", typeid(sql_tinyint), 1, true),
|
||||
sql_type_info("SMALLINT NOT NULL", typeid(sql_smallint), 2, true),
|
||||
sql_type_info("INT NOT NULL", typeid(sql_int), 3, true),
|
||||
sql_type_info("FLOAT NOT NULL", typeid(sql_float), 4, true),
|
||||
sql_type_info("DOUBLE NOT NULL", typeid(sql_double), 5, true),
|
||||
sql_type_info("NULL NOT NULL", typeid(void), 6),
|
||||
sql_type_info("TIMESTAMP NOT NULL", typeid(sql_timestamp), 7),
|
||||
sql_type_info("BIGINT NOT NULL", typeid(sql_bigint), 8, true),
|
||||
sql_type_info("MEDIUMINT NOT NULL", typeid(sql_mediumint), 9),
|
||||
sql_type_info("DATE NOT NULL", typeid(sql_date), 10, true),
|
||||
sql_type_info("TIME NOT NULL", typeid(sql_time), 11, true),
|
||||
sql_type_info("DATETIME NOT NULL", typeid(sql_datetime), 12, true),
|
||||
sql_type_info("ENUM NOT NULL", typeid(sql_enum), 13, true),
|
||||
sql_type_info("SET NOT NULL", typeid(sql_set), 14, true),
|
||||
sql_type_info("TINYBLOB NOT NULL", typeid(sql_tinyblob), 15),
|
||||
sql_type_info("MEDIUMBLOB NOT NULL", typeid(sql_mediumblob), 16),
|
||||
sql_type_info("LONGBLOB NOT NULL", typeid(sql_longblob), 17),
|
||||
sql_type_info("BLOB NOT NULL", typeid(sql_blob), 18),
|
||||
sql_type_info("VARCHAR NOT NULL", typeid(sql_varchar), 19, true),
|
||||
sql_type_info("CHAR NOT NULL", typeid(sql_char), 20),
|
||||
sql_type_info("CHAR NOT NULL", typeid(sql_char), 21),
|
||||
sql_type_info("TINYINT UNSIGNED NOT NULL", typeid(sql_tinyint_unsigned), 22, true),
|
||||
sql_type_info("SMALLINT UNSIGNED NOT NULL", typeid(sql_smallint_unsigned), 23, true),
|
||||
sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 24),
|
||||
sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 25),
|
||||
sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 26),
|
||||
sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 27),
|
||||
sql_type_info("INT UNSIGNED NOT NULL", typeid(sql_int_unsigned), 28, true),
|
||||
sql_type_info("BIGINT UNSIGNED NOT NULL", typeid(sql_bigint_unsigned), 29, true),
|
||||
sql_type_info("MEDIUMINT UNSIGNED NOT NULL", typeid(sql_mediumint_unsigned), 30),
|
||||
|
||||
sql_type_info("DECIMAL NULL", typeid(Null<sql_decimal>), 0),
|
||||
sql_type_info("TINYINT NULL", typeid(Null<sql_tinyint>), 1, true),
|
||||
sql_type_info("SMALLINT NULL", typeid(Null<sql_smallint>), 2, true),
|
||||
sql_type_info("INT NULL", typeid(Null<sql_int>), 3, true),
|
||||
sql_type_info("FLOAT NULL", typeid(Null<sql_float>), 4, true),
|
||||
sql_type_info("DOUBLE NULL", typeid(Null<sql_double>), 5, true),
|
||||
sql_type_info("NULL NULL", typeid(Null<void>), 6),
|
||||
sql_type_info("TIMESTAMP NULL", typeid(Null<sql_timestamp>), 7),
|
||||
sql_type_info("BIGINT NULL", typeid(Null<sql_bigint>), 8, true),
|
||||
sql_type_info("MEDIUMINT NULL", typeid(Null<sql_mediumint>), 9),
|
||||
sql_type_info("DATE NULL", typeid(Null<sql_date>), 10, true),
|
||||
sql_type_info("TIME NULL", typeid(Null<sql_time>), 11, true),
|
||||
sql_type_info("DATETIME NULL", typeid(Null<sql_datetime>), 12, true),
|
||||
sql_type_info("ENUM NULL", typeid(Null<sql_enum>), 13, true),
|
||||
sql_type_info("SET NULL", typeid(Null<sql_set>), 14, true),
|
||||
sql_type_info("TINYBLOB NULL", typeid(Null<sql_tinyblob>), 15),
|
||||
sql_type_info("MEDIUMBLOB NULL", typeid(Null<sql_mediumblob>), 16),
|
||||
sql_type_info("LONGBLOB NULL", typeid(Null<sql_longblob>), 17),
|
||||
sql_type_info("BLOB NULL", typeid(Null<sql_blob>), 18),
|
||||
sql_type_info("VARCHAR NULL", typeid(Null<sql_varchar>), 19, true),
|
||||
sql_type_info("CHAR NULL", typeid(Null<sql_char>), 20),
|
||||
sql_type_info("CHAR NULL", typeid(Null<sql_char>), 21),
|
||||
sql_type_info("TINYINT UNSIGNED NULL", typeid(Null<sql_tinyint_unsigned>), 22, true),
|
||||
sql_type_info("SMALLINT UNSIGNED NULL", typeid(Null<sql_smallint_unsigned>), 23, true),
|
||||
sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 24),
|
||||
sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 25),
|
||||
sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 26),
|
||||
sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 27),
|
||||
sql_type_info("INT UNSIGNED NULL", typeid(Null<sql_int_unsigned>), 28, true),
|
||||
sql_type_info("BIGINT UNSIGNED NULL", typeid(Null<sql_bigint_unsigned>), 29, true),
|
||||
sql_type_info("MEDIUMINT UNSIGNED NULL", typeid(Null<sql_mediumint_unsigned>), 30),
|
||||
};
|
||||
|
||||
const mysql_type_info::sql_type_info_lookup
|
||||
mysql_type_info::lookups(mysql_type_info::types, 62);
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
mysql_ti_sql_type_info_lookup::mysql_ti_sql_type_info_lookup(
|
||||
const sql_type_info types[], const int size)
|
||||
{
|
||||
for (int i = 0; i != size; i++) {
|
||||
if (types[i].default_) {
|
||||
map_[types[i].c_type_] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
unsigned char mysql_type_info::type(enum_field_types t,
|
||||
bool _unsigned, bool _null)
|
||||
{
|
||||
if (_null) {
|
||||
if (_unsigned) {
|
||||
return unsigned_null_offset + t;
|
||||
}
|
||||
else {
|
||||
if (t < 200)
|
||||
return null_offset + t;
|
||||
else
|
||||
return null_offset + (t - 234);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_unsigned) {
|
||||
return unsigned_offset + t;
|
||||
}
|
||||
else {
|
||||
if (t < 200)
|
||||
return offset + t;
|
||||
else
|
||||
return offset + (t - 234);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool mysql_type_info::quote_q() const
|
||||
{
|
||||
const type_info& ti = base_type().c_type();
|
||||
return ti == typeid(string) ||
|
||||
ti == typeid(sql_date) ||
|
||||
ti == typeid(sql_time) ||
|
||||
ti == typeid(sql_datetime) ||
|
||||
ti == typeid(sql_set);
|
||||
}
|
||||
|
||||
bool mysql_type_info::escape_q() const
|
||||
{
|
||||
const type_info& ti = c_type();
|
||||
return ti == typeid(string) ||
|
||||
ti == typeid(sql_enum) ||
|
||||
ti == typeid(sql_blob) ||
|
||||
ti == typeid(sql_tinyblob) ||
|
||||
ti == typeid(sql_mediumblob) ||
|
||||
ti == typeid(sql_longblob) ||
|
||||
ti == typeid(sql_char) ||
|
||||
ti == typeid(sql_varchar);
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,368 +0,0 @@
|
||||
/// \file type_info.h
|
||||
/// \brief Declares classes that provide an interface between the SQL
|
||||
/// and C++ type systems.
|
||||
///
|
||||
/// These classes are mostly used internal to the library.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2006 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_TYPE_INFO_H
|
||||
#define MYSQLPP_TYPE_INFO_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <map>
|
||||
#include <typeinfo>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Doxygen will not generate documentation for this section.
|
||||
|
||||
class MYSQLPP_EXPORT mysql_type_info;
|
||||
class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup;
|
||||
|
||||
class MYSQLPP_EXPORT mysql_ti_sql_type_info
|
||||
{
|
||||
private:
|
||||
friend class mysql_type_info;
|
||||
friend class mysql_ti_sql_type_info_lookup;
|
||||
|
||||
mysql_ti_sql_type_info& operator=(
|
||||
const mysql_ti_sql_type_info& b);
|
||||
|
||||
// Not initting _base_type and _default because only mysql_type_info
|
||||
// can create them. There *must* be only one copy of each.
|
||||
mysql_ti_sql_type_info() :
|
||||
sql_name_(0),
|
||||
c_type_(0),
|
||||
base_type_(0),
|
||||
default_(false)
|
||||
{
|
||||
}
|
||||
|
||||
mysql_ti_sql_type_info(const char* s,
|
||||
const std::type_info& t, const unsigned char bt = 0,
|
||||
const bool d = false) :
|
||||
sql_name_(s),
|
||||
c_type_(&t),
|
||||
base_type_(bt),
|
||||
default_(d)
|
||||
{
|
||||
}
|
||||
|
||||
const char* sql_name_;
|
||||
const std::type_info* c_type_;
|
||||
const unsigned char base_type_;
|
||||
const bool default_;
|
||||
};
|
||||
|
||||
|
||||
struct type_info_cmp
|
||||
{
|
||||
bool operator() (const std::type_info* lhs,
|
||||
const std::type_info* rhs) const
|
||||
{
|
||||
return lhs->before(*rhs) != 0;
|
||||
}
|
||||
};
|
||||
|
||||
class MYSQLPP_EXPORT mysql_ti_sql_type_info_lookup
|
||||
{
|
||||
private:
|
||||
friend class mysql_type_info;
|
||||
|
||||
typedef mysql_ti_sql_type_info sql_type_info;
|
||||
|
||||
mysql_ti_sql_type_info_lookup(
|
||||
const sql_type_info types[], const int size);
|
||||
|
||||
const unsigned char& operator [](
|
||||
const std::type_info& ti) const
|
||||
{
|
||||
return map_.find(&ti)->second;
|
||||
}
|
||||
|
||||
std::map<const std::type_info*, unsigned char, type_info_cmp> map_;
|
||||
};
|
||||
|
||||
#endif // !defined(DOXYGEN_IGNORE)
|
||||
|
||||
|
||||
/// \brief Holds basic type information for ColData.
|
||||
///
|
||||
/// Class to hold basic type information for mysqlpp::ColData.
|
||||
class MYSQLPP_EXPORT mysql_type_info
|
||||
{
|
||||
public:
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param n index into the internal type table
|
||||
///
|
||||
/// Because of the \c n parameter's definition, this constructor
|
||||
/// shouldn't be used outside the library.
|
||||
///
|
||||
/// The default is intended to try and crash a program using a
|
||||
/// default mysql_type_info object. This is a very wrong thing
|
||||
/// to do.
|
||||
mysql_type_info(unsigned char n = static_cast<unsigned char>(-1)) :
|
||||
_length(0),
|
||||
_max_length(0),
|
||||
num_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create object from MySQL C API type info
|
||||
///
|
||||
/// \param t the MySQL C API type ID for this type
|
||||
/// \param _unsigned if true, this is the unsigned version of the type
|
||||
/// \param _null if true, this type can hold a SQL null
|
||||
mysql_type_info(enum_field_types t, bool _unsigned, bool _null) :
|
||||
_length(0),
|
||||
_max_length(0),
|
||||
num_(type(t, _unsigned, _null))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create object from a MySQL C API field
|
||||
///
|
||||
/// \param f field from which we extract the type info
|
||||
mysql_type_info(const MYSQL_FIELD& f) :
|
||||
_length(f.length),
|
||||
_max_length(f.max_length),
|
||||
num_(type(f.type, (f.flags & UNSIGNED_FLAG) != 0,
|
||||
(f.flags & NOT_NULL_FLAG) == 0))
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create object as a copy of another
|
||||
mysql_type_info(const mysql_type_info& t) :
|
||||
_length(0),
|
||||
_max_length(0),
|
||||
num_(t.num_)
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Create object from a C++ type_info object
|
||||
///
|
||||
/// This tries to map a C++ type to the closest MySQL data type.
|
||||
/// It is necessarily somewhat approximate.
|
||||
mysql_type_info(const std::type_info& t) :
|
||||
num_(lookups[t])
|
||||
{
|
||||
}
|
||||
|
||||
/// \brief Assign a new internal type value
|
||||
///
|
||||
/// \param n an index into the internal MySQL++ type table
|
||||
///
|
||||
/// This function shouldn't be used outside the library.
|
||||
mysql_type_info& operator =(unsigned char n)
|
||||
{
|
||||
num_ = n;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign another mysql_type_info object to this object
|
||||
mysql_type_info& operator =(const mysql_type_info& t)
|
||||
{
|
||||
num_ = t.num_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Assign a C++ type_info object to this object
|
||||
///
|
||||
/// This tries to map a C++ type to the closest MySQL data type.
|
||||
/// It is necessarily somewhat approximate.
|
||||
mysql_type_info& operator =(const std::type_info& t)
|
||||
{
|
||||
num_ = lookups[t];
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// \brief Returns an implementation-defined name of the C++ type.
|
||||
///
|
||||
/// Returns the name that would be returned by typeid().name() for
|
||||
/// the C++ type associated with the SQL type.
|
||||
const char* name() const { return deref().c_type_->name(); }
|
||||
|
||||
/// \brief Returns the name of the SQL type.
|
||||
///
|
||||
/// Returns the SQL name for the type.
|
||||
const char* sql_name() const { return deref().sql_name_; }
|
||||
|
||||
/// \brief Returns the type_info for the C++ type associated with
|
||||
/// the SQL type.
|
||||
///
|
||||
/// Returns the C++ type_info record corresponding to the SQL type.
|
||||
const std::type_info& c_type() const { return *deref().c_type_; }
|
||||
|
||||
/// \brief Return length of data in this field
|
||||
///
|
||||
/// This only works if you initialized this object from a
|
||||
/// MYSQL_FIELD object.
|
||||
const unsigned int length() const { return _length; }
|
||||
|
||||
/// \brief Return maximum length of data in this field
|
||||
///
|
||||
/// This only works if you initialized this object from a
|
||||
/// MYSQL_FIELD object.
|
||||
const unsigned int max_length() const { return _max_length; }
|
||||
|
||||
/// \brief Returns the type_info for the C++ type inside of the
|
||||
/// mysqlpp::Null type.
|
||||
///
|
||||
/// Returns the type_info for the C++ type inside the mysqlpp::Null
|
||||
/// type. If the type is not Null then this is the same as c_type().
|
||||
const mysql_type_info base_type() const
|
||||
{
|
||||
return mysql_type_info(deref().base_type_);
|
||||
}
|
||||
|
||||
/// \brief Returns the ID of the SQL type.
|
||||
///
|
||||
/// Returns the ID number MySQL uses for this type. Note: Do not
|
||||
/// depend on the value of this ID as it may change between MySQL
|
||||
/// versions.
|
||||
int id() const
|
||||
{
|
||||
return num_;
|
||||
}
|
||||
|
||||
/// \brief Returns true if the SQL type is of a type that needs to
|
||||
/// be quoted.
|
||||
///
|
||||
/// \return true if the type needs to be quoted for syntactically
|
||||
/// correct SQL.
|
||||
bool quote_q() const;
|
||||
|
||||
/// \brief Returns true if the SQL type is of a type that needs to
|
||||
/// be escaped.
|
||||
///
|
||||
/// \return true if the type needs to be escaped for syntactically
|
||||
/// correct SQL.
|
||||
bool escape_q() const;
|
||||
|
||||
/// \brief Provides a way to compare two types for sorting.
|
||||
///
|
||||
/// Returns true if the SQL ID of this type is lower than that of
|
||||
/// another. Used by mysqlpp::type_info_cmp when comparing types.
|
||||
bool before(mysql_type_info& b)
|
||||
{
|
||||
return num_ < b.num_;
|
||||
}
|
||||
|
||||
/// \brief The internal constant we use for our string type.
|
||||
///
|
||||
/// We expose this because other parts of MySQL++ need to know
|
||||
/// what the string constant is at the moment.
|
||||
static const unsigned char string_type = 20;
|
||||
|
||||
unsigned int _length; ///< field length, from MYSQL_FIELD
|
||||
unsigned int _max_length; ///< max data length, from MYSQL_FIELD
|
||||
|
||||
private:
|
||||
typedef mysql_ti_sql_type_info sql_type_info;
|
||||
typedef mysql_ti_sql_type_info_lookup sql_type_info_lookup;
|
||||
|
||||
static const sql_type_info types[62];
|
||||
|
||||
static const unsigned char offset = 0;
|
||||
static const unsigned char unsigned_offset = 21;
|
||||
static const unsigned char null_offset = 31;
|
||||
static const unsigned char unsigned_null_offset = 52;
|
||||
|
||||
static const sql_type_info_lookup lookups;
|
||||
|
||||
/// \brief Return an index into mysql_type_info::types array given
|
||||
/// MySQL type information.
|
||||
///
|
||||
/// This function is used in mapping from MySQL type information
|
||||
/// (a type enum, and flags indicating whether it is unsigned and
|
||||
/// whether it can be 'null') to the closest C++ types available
|
||||
/// within MySQL++. Notice that nulls have to be handled specially:
|
||||
/// the SQL null concept doesn't map directly onto the C++ type
|
||||
/// system. See null.h for details.
|
||||
///
|
||||
/// \param t MySQL C API type constant, from mysql_com.h
|
||||
/// \param _unsigned if true, indicates the unsigned variant of a
|
||||
/// MySQL type
|
||||
/// \param _null if true, indicates the variant of the MySQL type
|
||||
/// that can also hold an SQL 'null' instead of regular data.
|
||||
static unsigned char type(enum_field_types t,
|
||||
bool _unsigned, bool _null = false);
|
||||
|
||||
const sql_type_info& deref() const
|
||||
{
|
||||
return types[num_];
|
||||
}
|
||||
|
||||
unsigned char num_;
|
||||
};
|
||||
|
||||
/// \brief Returns true if two mysql_type_info objects are equal.
|
||||
inline bool operator ==(const mysql_type_info& a, const mysql_type_info& b)
|
||||
{
|
||||
return a.id() == b.id();
|
||||
}
|
||||
|
||||
/// \brief Returns true if two mysql_type_info objects are not equal.
|
||||
inline bool operator !=(const mysql_type_info& a, const mysql_type_info& b)
|
||||
{
|
||||
return a.id() != b.id();
|
||||
}
|
||||
|
||||
/// \brief Returns true if a given mysql_type_info object is equal
|
||||
/// to a given C++ type_info object.
|
||||
inline bool operator ==(const std::type_info& a, const mysql_type_info& b)
|
||||
{
|
||||
return a == b.c_type();
|
||||
}
|
||||
|
||||
/// \brief Returns true if a given mysql_type_info object is not equal
|
||||
/// to a given C++ type_info object.
|
||||
inline bool operator !=(const std::type_info& a, const mysql_type_info& b)
|
||||
{
|
||||
return a != b.c_type();
|
||||
}
|
||||
|
||||
/// \brief Returns true if a given mysql_type_info object is equal
|
||||
/// to a given C++ type_info object.
|
||||
inline bool operator ==(const mysql_type_info& a, const std::type_info& b)
|
||||
{
|
||||
return a.c_type() == b;
|
||||
}
|
||||
|
||||
/// \brief Returns true if a given mysql_type_info object is not equal
|
||||
/// to a given C++ type_info object.
|
||||
inline bool operator !=(const mysql_type_info& a, const std::type_info& b)
|
||||
{
|
||||
return a.c_type() != b;
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,144 +0,0 @@
|
||||
/***********************************************************************
|
||||
vallist.cpp - Implements utility functions for building value lists.
|
||||
This is internal functionality used within the library.
|
||||
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004-2007 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#include "vallist.h"
|
||||
|
||||
#include "result.h"
|
||||
#include "row.h"
|
||||
|
||||
using std::string;
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
void
|
||||
create_vector(size_t size, std::vector<bool>& v, bool t0, bool t1, bool t2,
|
||||
bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
|
||||
bool ta, bool tb, bool tc)
|
||||
{
|
||||
v.reserve(size);
|
||||
|
||||
v.push_back(t0);
|
||||
if (size == 1) return;
|
||||
|
||||
v.push_back(t1);
|
||||
if (size == 2) return;
|
||||
|
||||
v.push_back(t2);
|
||||
if (size == 3) return;
|
||||
|
||||
v.push_back(t3);
|
||||
if (size == 4) return;
|
||||
|
||||
v.push_back(t4);
|
||||
if (size == 5) return;
|
||||
|
||||
v.push_back(t5);
|
||||
if (size == 6) return;
|
||||
|
||||
v.push_back(t6);
|
||||
if (size == 7) return;
|
||||
|
||||
v.push_back(t7);
|
||||
if (size == 8) return;
|
||||
|
||||
v.push_back(t8);
|
||||
if (size == 9) return;
|
||||
|
||||
v.push_back(t9);
|
||||
if (size == 10) return;
|
||||
|
||||
v.push_back(ta);
|
||||
if (size == 11) return;
|
||||
|
||||
v.push_back(tb);
|
||||
if (size == 12) return;
|
||||
|
||||
v.push_back(tc);
|
||||
}
|
||||
|
||||
|
||||
template <class Container>
|
||||
void create_vector(const Container& c, std::vector<bool>& v,
|
||||
std::string s0, std::string s1, std::string s2, std::string s3,
|
||||
std::string s4, std::string s5, std::string s6, std::string s7,
|
||||
std::string s8, std::string s9, std::string sa, std::string sb,
|
||||
std::string sc)
|
||||
{
|
||||
v.insert(v.begin(), c.size(), false);
|
||||
|
||||
v[c.parent().field_num(s0)] = true;
|
||||
if (s1.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s1)] = true;
|
||||
if (s2.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s2)] = true;
|
||||
if (s3.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s3)] = true;
|
||||
if (s4.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s4)] = true;
|
||||
if (s5.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s5)] = true;
|
||||
if (s6.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s6)] = true;
|
||||
if (s7.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s7)] = true;
|
||||
if (s8.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s8)] = true;
|
||||
if (s9.empty()) return;
|
||||
|
||||
v[c.parent().field_num(s9)] = true;
|
||||
if (sa.empty()) return;
|
||||
|
||||
v[c.parent().field_num(sa)] = true;
|
||||
if (sb.empty()) return;
|
||||
|
||||
v[c.parent().field_num(sb)] = true;
|
||||
if (sc.empty()) return;
|
||||
|
||||
v[c.parent().field_num(sc)] = true;
|
||||
}
|
||||
|
||||
|
||||
#if !defined(DOXYGEN_IGNORE)
|
||||
// Instantiate above template. Not sure why this is necessary. Hide it
|
||||
// from Doxygen, because we clearly cannot appease it by documenting it.
|
||||
template void
|
||||
create_vector(const Row& c, std::vector<bool>& v, string s0,
|
||||
string s1, string s2, string s3, string s4, string s5,
|
||||
string s6, string s7, string s8, string s9, string sa,
|
||||
string sb, string sc);
|
||||
#endif
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
@ -1,688 +0,0 @@
|
||||
/// \file vallist.h
|
||||
/// \brief Declares templates for holding lists of values.
|
||||
|
||||
/***********************************************************************
|
||||
Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
|
||||
MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
|
||||
Others may also hold copyrights on code in this file. See the CREDITS
|
||||
file in the top directory of the distribution for details.
|
||||
|
||||
This file is part of MySQL++.
|
||||
|
||||
MySQL++ is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published
|
||||
by the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
MySQL++ is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
|
||||
License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with MySQL++; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
|
||||
USA
|
||||
***********************************************************************/
|
||||
|
||||
#ifndef MYSQLPP_VALLIST_H
|
||||
#define MYSQLPP_VALLIST_H
|
||||
|
||||
#include "manip.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace mysqlpp {
|
||||
|
||||
|
||||
/// \brief Holds two lists of items, typically used to construct a
|
||||
/// SQL "equals clause".
|
||||
///
|
||||
/// The WHERE clause in a SQL SELECT statment is an example of an
|
||||
/// equals clause.
|
||||
///
|
||||
/// Imagine an object of this type contains the lists (a, b) (c, d),
|
||||
/// and that the object's delimiter and equals symbols are set to ", "
|
||||
/// and " = " respectively. When you insert that object into a C++
|
||||
/// stream, you would get "a = c, b = d".
|
||||
///
|
||||
/// This class is never instantiated by hand. The equal_list()
|
||||
/// functions build instances of this structure template to do their
|
||||
/// work. MySQL++'s SSQLS mechanism calls those functions when
|
||||
/// building SQL queries; you can call them yourself to do similar work.
|
||||
/// The "Harnessing SSQLS Internals" section of the user manual has
|
||||
/// some examples of this.
|
||||
///
|
||||
/// \sa equal_list_b
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
struct equal_list_ba
|
||||
{
|
||||
/// \brief the list of objects on the left-hand side of the
|
||||
/// equals sign
|
||||
const Seq1* list1;
|
||||
|
||||
/// \brief the list of objects on the right-hand side of the
|
||||
/// equals sign
|
||||
const Seq2* list2;
|
||||
|
||||
/// \brief delimiter to use between each pair of elements
|
||||
const char* delem;
|
||||
|
||||
/// \brief "equal" sign to use between each item in each equal
|
||||
/// pair; doesn't have to actually be " = "
|
||||
const char* equl;
|
||||
|
||||
/// \brief manipulator to use when inserting the equal_list into
|
||||
/// a C++ stream
|
||||
Manip manip;
|
||||
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param s1 list of objects on left-hand side of equal sign
|
||||
/// \param s2 list of objects on right-hand side of equal sign
|
||||
/// \param d what delimiter to use between each group in the list
|
||||
/// when inserting the list into a C++ stream
|
||||
/// \param e the "equals" sign between each pair of items in the
|
||||
/// equal list; doesn't actually have to be " = "!
|
||||
/// \param m manipulator to use when inserting the list into a
|
||||
/// C++ stream
|
||||
equal_list_ba(const Seq1& s1, const Seq2& s2, const char* d,
|
||||
const char* e, Manip m) :
|
||||
list1(&s1),
|
||||
list2(&s2),
|
||||
delem(d),
|
||||
equl(e),
|
||||
manip(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Same as equal_list_ba, plus the option to have some elements
|
||||
/// of the equals clause suppressed.
|
||||
///
|
||||
/// Imagine an object of this type contains the lists (a, b, c)
|
||||
/// (d, e, f), that the object's 'fields' list is (true, false, true),
|
||||
/// and that the object's delimiter and equals symbols are set to
|
||||
/// " AND " and " = " respectively. When you insert that object into a
|
||||
/// C++ stream, you would get "a = d AND c = f".
|
||||
///
|
||||
/// See equal_list_ba's documentation for more details.
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
struct equal_list_b
|
||||
{
|
||||
/// \brief the list of objects on the left-hand side of the
|
||||
/// equals sign
|
||||
const Seq1* list1;
|
||||
|
||||
/// \brief the list of objects on the right-hand side of the
|
||||
/// equals sign
|
||||
const Seq2* list2;
|
||||
|
||||
/// \brief for each true item in the list, the pair in that position
|
||||
/// will be inserted into a C++ stream
|
||||
const std::vector<bool> fields;
|
||||
|
||||
/// \brief delimiter to use between each pair of elements
|
||||
const char* delem;
|
||||
|
||||
/// \brief "equal" sign to use between each item in each equal
|
||||
/// pair; doesn't have to actually be " = "
|
||||
const char* equl;
|
||||
|
||||
/// \brief manipulator to use when inserting the equal_list into
|
||||
/// a C++ stream
|
||||
Manip manip;
|
||||
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param s1 list of objects on left-hand side of equal sign
|
||||
/// \param s2 list of objects on right-hand side of equal sign
|
||||
/// \param f for each true item in the list, the pair of items
|
||||
/// in that position will be inserted into a C++ stream
|
||||
/// \param d what delimiter to use between each group in the list
|
||||
/// when inserting the list into a C++ stream
|
||||
/// \param e the "equals" sign between each pair of items in the
|
||||
/// equal list; doesn't actually have to be " = "!
|
||||
/// \param m manipulator to use when inserting the list into a
|
||||
/// C++ stream
|
||||
equal_list_b(const Seq1& s1, const Seq2& s2,
|
||||
const std::vector<bool>& f, const char* d,
|
||||
const char* e, Manip m) :
|
||||
list1(&s1),
|
||||
list2(&s2),
|
||||
fields(f),
|
||||
delem(d),
|
||||
equl(e),
|
||||
manip(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Holds a list of items, typically used to construct a SQL
|
||||
/// "value list".
|
||||
///
|
||||
/// The SQL INSERT statement has a VALUES clause; this class can
|
||||
/// be used to construct the list of items for that clause.
|
||||
///
|
||||
/// Imagine an object of this type contains the list (a, b, c), and
|
||||
/// that the object's delimiter symbol is set to ", ". When you
|
||||
/// insert that object into a C++ stream, you would get "a, b, c".
|
||||
///
|
||||
/// This class is never instantiated by hand. The value_list()
|
||||
/// functions build instances of this structure template to do their
|
||||
/// work. MySQL++'s SSQLS mechanism calls those functions when
|
||||
/// building SQL queries; you can call them yourself to do similar work.
|
||||
/// The "Harnessing SSQLS Internals" section of the user manual has
|
||||
/// some examples of this.
|
||||
///
|
||||
/// \sa value_list_b
|
||||
|
||||
template <class Seq, class Manip>
|
||||
struct value_list_ba
|
||||
{
|
||||
/// \brief set of objects in the value list
|
||||
const Seq* list;
|
||||
|
||||
/// \brief delimiter to use between each value in the list when
|
||||
/// inserting it into a C++ stream
|
||||
const char* delem;
|
||||
|
||||
/// \brief manipulator to use when inserting the list into a
|
||||
/// C++ stream
|
||||
Manip manip;
|
||||
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param s set of objects in the value list
|
||||
/// \param d what delimiter to use between each value in the list
|
||||
/// when inserting the list into a C++ stream
|
||||
/// \param m manipulator to use when inserting the list into a
|
||||
/// C++ stream
|
||||
value_list_ba(const Seq& s, const char* d, Manip m) :
|
||||
list(&s),
|
||||
delem(d),
|
||||
manip(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Same as value_list_ba, plus the option to have some elements
|
||||
/// of the list suppressed.
|
||||
///
|
||||
/// Imagine an object of this type contains the list (a, b, c), that
|
||||
/// the object's 'fields' list is (true, false, true), and that the
|
||||
/// object's delimiter is set to ":". When you insert that object
|
||||
/// into a C++ stream, you would get "a:c".
|
||||
///
|
||||
/// See value_list_ba's documentation for more details.
|
||||
|
||||
#pragma warning(disable:4512)
|
||||
|
||||
template <class Seq, class Manip>
|
||||
struct value_list_b
|
||||
{
|
||||
/// \brief set of objects in the value list
|
||||
const Seq* list;
|
||||
|
||||
/// \brief delimiter to use between each value in the list when
|
||||
/// inserting it into a C++ stream
|
||||
const std::vector<bool> fields;
|
||||
|
||||
/// \brief delimiter to use between each value in the list when
|
||||
/// inserting it into a C++ stream
|
||||
const char* delem;
|
||||
|
||||
/// \brief manipulator to use when inserting the list into a C++
|
||||
/// stream
|
||||
Manip manip;
|
||||
|
||||
/// \brief Create object
|
||||
///
|
||||
/// \param s set of objects in the value list
|
||||
/// \param f for each true item in the list, the list item
|
||||
/// in that position will be inserted into a C++ stream
|
||||
/// \param d what delimiter to use between each value in the list
|
||||
/// when inserting the list into a C++ stream
|
||||
/// \param m manipulator to use when inserting the list into a
|
||||
/// C++ stream
|
||||
value_list_b(const Seq& s, const std::vector<bool>& f,
|
||||
const char* d, Manip m) :
|
||||
list(&s),
|
||||
fields(f),
|
||||
delem(d),
|
||||
manip(m)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// \brief Inserts an equal_list_ba into an std::ostream.
|
||||
///
|
||||
/// Given two lists (a, b) and (c, d), a delimiter D, and an equals
|
||||
/// symbol E, this operator will insert "aEcDbEd" into the stream.
|
||||
///
|
||||
/// See equal_list_ba's documentation for concrete examples.
|
||||
///
|
||||
/// \sa equal_list()
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
std::ostream& operator <<(std::ostream& o,
|
||||
const equal_list_ba<Seq1, Seq2, Manip>& el)
|
||||
{
|
||||
typename Seq1::const_iterator i = el.list1->begin();
|
||||
typename Seq2::const_iterator j = el.list2->begin();
|
||||
|
||||
while (1) {
|
||||
o << *i << el.equl << el.manip << *j;
|
||||
if ((++i == el.list1->end()) || (++j == el.list2->end())) {
|
||||
break;
|
||||
}
|
||||
o << el.delem;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Same as operator<< for equal_list_ba, plus the option to
|
||||
/// suppress insertion of some list items in the stream.
|
||||
///
|
||||
/// See equal_list_b's documentation for examples of how this works.
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
std::ostream& operator <<(std::ostream& o,
|
||||
const equal_list_b <Seq1, Seq2, Manip>& el)
|
||||
{
|
||||
typename Seq1::const_iterator i = el.list1->begin();
|
||||
typename Seq2::const_iterator j = el.list2->begin();
|
||||
|
||||
int k = 0;
|
||||
while (1) {
|
||||
if (el.fields[k++]) {
|
||||
o << *i << el.equl << el.manip << *j;
|
||||
}
|
||||
if ((++i == el.list1->end()) || (++j == el.list2->end())) {
|
||||
break;
|
||||
}
|
||||
if (el.fields[k]) {
|
||||
o << el.delem;
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Inserts a value_list_ba into an std::ostream.
|
||||
///
|
||||
/// Given a list (a, b) and a delimiter D, this operator will insert
|
||||
/// "aDb" into the stream.
|
||||
///
|
||||
/// See value_list_ba's documentation for concrete examples.
|
||||
///
|
||||
/// \sa value_list()
|
||||
|
||||
template <class Seq, class Manip>
|
||||
std::ostream& operator <<(std::ostream& o,
|
||||
const value_list_ba<Seq, Manip>& cl)
|
||||
{
|
||||
typename Seq::const_iterator i = cl.list->begin();
|
||||
|
||||
while (1) {
|
||||
o << cl.manip << *i;
|
||||
if (++i == cl.list->end()) {
|
||||
break;
|
||||
}
|
||||
o << cl.delem;
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Same as operator<< for value_list_ba, plus the option to
|
||||
/// suppress insertion of some list items in the stream.
|
||||
///
|
||||
/// See value_list_b's documentation for examples of how this works.
|
||||
|
||||
template <class Seq, class Manip>
|
||||
std::ostream& operator <<(std::ostream& o,
|
||||
const value_list_b<Seq, Manip>& cl)
|
||||
{
|
||||
typename Seq::const_iterator i = cl.list->begin();
|
||||
|
||||
int k = 0;
|
||||
while (1) {
|
||||
if (cl.fields[k++]) {
|
||||
o << cl.manip << *i;
|
||||
}
|
||||
if (++i == cl.list->end()) {
|
||||
break;
|
||||
}
|
||||
if (cl.fields[k]) {
|
||||
o << cl.delem;
|
||||
}
|
||||
}
|
||||
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/// \brief Create a vector of bool with the given arguments as values.
|
||||
///
|
||||
/// This function takes up to 13 bools, with the size parameter
|
||||
/// controlling the actual number of parameters we pay attention to.
|
||||
///
|
||||
/// This function is used within the library to build the vector used
|
||||
/// in calling the vector form of Row::equal_list(), Row::value_list(),
|
||||
/// and Row::field_list(). See the "Harnessing SSQLS Internals" section
|
||||
/// of the user manual to see that feature at work.
|
||||
|
||||
void create_vector(size_t size, std::vector<bool>& v, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false);
|
||||
|
||||
|
||||
/// \brief Create a vector of bool using a list of named fields.
|
||||
///
|
||||
/// This function is used with the ResUse and Result containers,
|
||||
/// which have a field_num() member function that maps a field name
|
||||
/// to its position number. So for each named field, we set the
|
||||
/// bool in the vector at the corresponding position to true.
|
||||
///
|
||||
/// This function is used within the library to build the vector used
|
||||
/// in calling the vector form of Row::equal_list(), Row::value_list(),
|
||||
/// and Row::field_list(). See the "Harnessing SSQLS Internals" section
|
||||
/// of the user manual to see that feature at work.
|
||||
|
||||
template <class Container>
|
||||
void create_vector(const Container& c, std::vector<bool>& v,
|
||||
std::string s0, std::string s1, std::string s2,
|
||||
std::string s3, std::string s4, std::string s5,
|
||||
std::string s6, std::string s7, std::string s8,
|
||||
std::string s9, std::string sa, std::string sb,
|
||||
std::string sc);
|
||||
|
||||
|
||||
|
||||
/// \brief Constructs a value_list_ba
|
||||
///
|
||||
/// This function returns a value list that uses the 'do_nothing'
|
||||
/// manipulator. That is, the items are not quoted or escaped in any
|
||||
/// way. See value_list(Seq, const char*, Manip) if you need to
|
||||
/// specify a manipulator.
|
||||
///
|
||||
/// \param s an STL sequence of items in the value list
|
||||
/// \param d delimiter operator<< should place between items
|
||||
|
||||
template <class Seq>
|
||||
value_list_ba<Seq, do_nothing_type0>
|
||||
value_list(const Seq& s, const char* d = ",")
|
||||
{
|
||||
return value_list_ba<Seq, do_nothing_type0>(s, d, do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a value_list_ba
|
||||
///
|
||||
/// \param s an STL sequence of items in the value list
|
||||
/// \param d delimiter operator<< should place between items
|
||||
/// \param m manipulator to use when inserting items into a stream
|
||||
|
||||
template <class Seq, class Manip>
|
||||
value_list_ba<Seq, Manip>
|
||||
value_list(const Seq& s, const char* d, Manip m)
|
||||
{
|
||||
return value_list_ba<Seq, Manip>(s, d, m);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a value_list_b (sparse value list)
|
||||
///
|
||||
/// \param s an STL sequence of items in the value list
|
||||
/// \param d delimiter operator<< should place between items
|
||||
/// \param m manipulator to use when inserting items into a stream
|
||||
/// \param vb for each item in this vector that is true, the
|
||||
/// corresponding item in the value list is inserted into a stream;
|
||||
/// the others are suppressed
|
||||
|
||||
template <class Seq, class Manip>
|
||||
inline value_list_b<Seq, Manip>
|
||||
value_list(const Seq& s, const char* d, Manip m,
|
||||
const std::vector<bool>& vb)
|
||||
{
|
||||
return value_list_b<Seq, Manip>(s, vb, d, m);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a value_list_b (sparse value list)
|
||||
///
|
||||
/// Same as value_list(Seq&, const char*, Manip, const vector<bool>&),
|
||||
/// except that it takes the bools as arguments instead of wrapped up
|
||||
/// in a vector object.
|
||||
|
||||
template <class Seq, class Manip>
|
||||
value_list_b<Seq, Manip>
|
||||
value_list(const Seq& s, const char* d, Manip m, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
|
||||
ta, tb, tc);
|
||||
return value_list_b<Seq, Manip>(s, vb, d, m);
|
||||
}
|
||||
|
||||
/// \brief Constructs a sparse value list
|
||||
///
|
||||
/// Same as value_list(Seq&, const char*, Manip, bool, bool...) but
|
||||
/// without the Manip parameter. We use the do_nothing manipulator,
|
||||
/// meaning that the value list items are neither escaped nor quoted
|
||||
/// when being inserted into a stream.
|
||||
|
||||
template <class Seq>
|
||||
value_list_b<Seq, do_nothing_type0>
|
||||
value_list(const Seq& s, const char* d, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
|
||||
ta, tb, tc);
|
||||
return value_list_b<Seq, do_nothing_type0>(s, vb, d, do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a sparse value list
|
||||
///
|
||||
/// Same as value_list(Seq&, const char*, Manip, bool, bool...) but
|
||||
/// without the Manip or delimiter parameters. We use the do_nothing
|
||||
/// manipulator, meaning that the value list items are neither escaped
|
||||
/// nor quoted when being inserted into a stream. The delimiter is a
|
||||
/// comma. This form is suitable for lists of simple data, such as
|
||||
/// integers.
|
||||
|
||||
template <class Seq>
|
||||
value_list_b<Seq, do_nothing_type0>
|
||||
value_list(const Seq& s, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
|
||||
ta, tb, tc);
|
||||
return value_list_b<Seq, do_nothing_type0>(s, vb, ",", do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs an equal_list_ba
|
||||
///
|
||||
/// This function returns an equal list that uses the 'do_nothing'
|
||||
/// manipulator. That is, the items are not quoted or escaped in any
|
||||
/// way when inserted into a stream. See equal_list(Seq, Seq,
|
||||
/// const char*, const char*, Manip) if you need a different
|
||||
/// manipulator.
|
||||
///
|
||||
/// The idea is for both lists to be of equal length because
|
||||
/// corresponding elements from each list are handled as pairs, but if
|
||||
/// one list is shorter than the other, the generated list will have
|
||||
/// that many elements.
|
||||
///
|
||||
/// \param s1 items on the left side of the equals sign when the
|
||||
/// equal list is inserted into a stream
|
||||
/// \param s2 items on the right side of the equals sign
|
||||
/// \param d delimiter operator<< should place between pairs
|
||||
/// \param e what operator<< should place between items in each pair;
|
||||
/// by default, an equals sign, as that is the primary use for this
|
||||
/// mechanism.
|
||||
|
||||
template <class Seq1, class Seq2>
|
||||
equal_list_ba<Seq1, Seq2, do_nothing_type0>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char *d = ",",
|
||||
const char *e = " = ")
|
||||
{
|
||||
return equal_list_ba<Seq1, Seq2, do_nothing_type0>(s1, s2, d,
|
||||
e, do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs an equal_list_ba
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, const char*) except that
|
||||
/// it also lets you specify the manipulator. Use this version if the
|
||||
/// data must be escaped or quoted when being inserted into a stream.
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
equal_list_ba<Seq1, Seq2, Manip>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
|
||||
const char* e, Manip m)
|
||||
{
|
||||
return equal_list_ba<Seq1, Seq2, Manip>(s1, s2, d, e, m);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a equal_list_b (sparse equal list)
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip) except
|
||||
/// that you can pass a vector of bools. For each true item in that
|
||||
/// list, operator<< adds the corresponding item is put in the equal
|
||||
/// list. This lets you pass in sequences when you don't want all of
|
||||
/// the elements to be inserted into a stream.
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
equal_list_b<Seq1, Seq2, Manip>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
|
||||
const char *e, Manip m, const std::vector<bool>& vb)
|
||||
{
|
||||
return equal_list_b<Seq1, Seq2, Manip>(s1, s2, vb, d, e, m);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a equal_list_b (sparse equal list)
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip,
|
||||
/// vector<bool>&) except that it takes boolean parameters
|
||||
/// instead of a list of bools.
|
||||
|
||||
template <class Seq1, class Seq2, class Manip>
|
||||
equal_list_b<Seq1, Seq2, Manip>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
|
||||
const char* e, Manip m, bool t0, bool t1 = false,
|
||||
bool t2 = false, bool t3 = false, bool t4 = false,
|
||||
bool t5 = false, bool t6 = false, bool t7 = false,
|
||||
bool t8 = false, bool t9 = false, bool ta = false,
|
||||
bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
|
||||
t9, ta, tb, tc);
|
||||
return equal_list_b<Seq1, Seq2, Manip>(s1, s2, vb, d, e, m);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a equal_list_b (sparse equal list)
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, const char*, Manip,
|
||||
/// bool, bool...) except that it doesn't take the Manip argument.
|
||||
/// It uses the do_nothing manipulator instead, meaning that none of
|
||||
/// the elements are escaped when being inserted into a stream.
|
||||
|
||||
template <class Seq1, class Seq2>
|
||||
equal_list_b<Seq1, Seq2, do_nothing_type0>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char* d,
|
||||
const char* e, bool t0, bool t1 = false, bool t2 = false,
|
||||
bool t3 = false, bool t4 = false, bool t5 = false,
|
||||
bool t6 = false, bool t7 = false, bool t8 = false,
|
||||
bool t9 = false, bool ta = false, bool tb = false,
|
||||
bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
|
||||
t9, ta, tb, tc);
|
||||
return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
|
||||
d, e, do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a equal_list_b (sparse equal list)
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, const char*, bool,
|
||||
/// bool...) except that it doesn't take the second const char*
|
||||
/// argument. It uses " = " for the equals symbol.
|
||||
|
||||
template <class Seq1, class Seq2>
|
||||
equal_list_b<Seq1, Seq2, do_nothing_type0>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, const char* d, bool t0,
|
||||
bool t1 = false, bool t2 = false, bool t3 = false,
|
||||
bool t4 = false, bool t5 = false, bool t6 = false,
|
||||
bool t7 = false, bool t8 = false, bool t9 = false,
|
||||
bool ta = false, bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
|
||||
t9, ta, tb, tc);
|
||||
return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
|
||||
d, " = ", do_nothing);
|
||||
}
|
||||
|
||||
|
||||
/// \brief Constructs a equal_list_b (sparse equal list)
|
||||
///
|
||||
/// Same as equal_list(Seq&, Seq&, const char*, bool, bool...) except
|
||||
/// that it doesn't take the const char* argument. It uses a comma for
|
||||
/// the delimiter. This form is useful for building simple equals
|
||||
/// lists, where no manipulators are necessary, and the default
|
||||
/// delimiter and equals symbol are suitable.
|
||||
|
||||
template <class Seq1, class Seq2>
|
||||
equal_list_b<Seq1, Seq2, do_nothing_type0>
|
||||
equal_list(const Seq1& s1, const Seq2& s2, bool t0, bool t1 = false,
|
||||
bool t2 = false, bool t3 = false, bool t4 = false,
|
||||
bool t5 = false, bool t6 = false, bool t7 = false,
|
||||
bool t8 = false, bool t9 = false, bool ta = false,
|
||||
bool tb = false, bool tc = false)
|
||||
{
|
||||
std::vector<bool> vb;
|
||||
create_vector(s1.size(), vb, t0, t1, t2, t3, t4, t5, t6, t7, t8,
|
||||
t9, ta, tb, tc);
|
||||
return equal_list_b<Seq1, Seq2, do_nothing_type0>(s1, s2, vb,
|
||||
",", " = ", do_nothing);
|
||||
}
|
||||
|
||||
} // end namespace mysqlpp
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user