MeOS version 3.8.1255 Beta

This commit is contained in:
Erik Melin 2021-07-14 14:09:14 +02:00
parent 035fec52ec
commit adb3e81676
308 changed files with 32285 additions and 64691 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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;
@ -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);

View File

@ -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;

View File

@ -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,15 +1370,96 @@ 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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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");

View File

@ -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);

View File

@ -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;

View File

@ -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};

View File

@ -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

Binary file not shown.

BIN
code/dll64/libmysql.dll Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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

View File

@ -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));

View File

@ -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;

View File

@ -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;}

View File

@ -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);

View File

@ -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

Binary file not shown.

BIN
code/lib64/RestBed.lib Normal file

Binary file not shown.

BIN
code/lib64/libharu.lib Normal file

Binary file not shown.

BIN
code/lib64/libmysql.lib Normal file

Binary file not shown.

BIN
code/lib64/libpng.lib Normal file

Binary file not shown.

BIN
code/lib64/zlibstat.lib Normal file

Binary file not shown.

BIN
code/lib_db/libmysql.lib Normal file

Binary file not shown.

View File

@ -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());
@ -901,7 +981,10 @@ void ListEditor::editListPost(gdioutput &gdi, const MetaListPost &mlp, int id) {
else
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);
}

View File

@ -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 *);
};

View File

@ -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) {

View File

@ -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_)

View File

@ -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();

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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="&quot;mysql++&quot;;&quot;mysql50&quot;"
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="&quot;mysql++&quot;;&quot;mysql50&quot;"
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>

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 $_;
}

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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 != &param) {
// 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

View File

@ -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

View File

@ -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)

View File

@ -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";

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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