218 lines
6.1 KiB
C++
218 lines
6.1 KiB
C++
#pragma once
|
|
/************************************************************************
|
|
MeOS - Orienteering Software
|
|
Copyright (C) 2009-2024 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 fro 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
|
|
|
|
************************************************************************/
|
|
|
|
|
|
#include <string>
|
|
#include <map>
|
|
#include <vector>
|
|
#include "mysql/mysql.h"
|
|
|
|
using std::string;
|
|
using std::map;
|
|
|
|
namespace sqlwrapper {
|
|
|
|
class ConnectionWrapper;
|
|
class QueryWrapper;
|
|
class ResultWrapper;
|
|
class ResultBase;
|
|
|
|
class CellWrapper {
|
|
char *data;
|
|
unsigned int length;
|
|
CellWrapper(char *data, unsigned int length) : data(data), length(length) {}
|
|
friend class RowWrapper;
|
|
public:
|
|
const char *c_str() const;
|
|
string get_string() const;
|
|
operator string() const;
|
|
operator int() const;
|
|
operator unsigned int() const;
|
|
operator bool() const;
|
|
int64_t longlong() const;
|
|
uint64_t ulonglong() const;
|
|
void storeBlob(std::vector<uint8_t>& d) const;
|
|
bool is_null() const;
|
|
};
|
|
|
|
class RowWrapper {
|
|
MYSQL_ROW row;
|
|
ResultBase *res;
|
|
RowWrapper(ResultBase *res, MYSQL_ROW row);
|
|
friend class ResultWrapper;
|
|
friend class ResUseWrapper;
|
|
public:
|
|
RowWrapper() : row(nullptr), res(nullptr) {}
|
|
CellWrapper at(int col) const;
|
|
int size() const;
|
|
operator bool() const;
|
|
CellWrapper operator[](const char *col) const;
|
|
CellWrapper operator[](int ix) const;
|
|
const char *raw_string(int ix) const;
|
|
};
|
|
|
|
class ResultBase {
|
|
protected:
|
|
ConnectionWrapper *con;
|
|
MYSQL_RES *result;
|
|
map<string, int> name2Col;
|
|
ResultBase(ConnectionWrapper *con, MYSQL_RES *result);
|
|
friend class QueryWrapper;
|
|
friend class RowWrapper;
|
|
public:
|
|
ResultBase(ResultBase &&r);
|
|
const ResultBase &operator=(ResultBase &&);
|
|
ResultBase(const ResultBase& r) = delete;
|
|
const ResultBase& operator=(const ResultBase&) = delete;
|
|
|
|
virtual ~ResultBase();
|
|
int field_num(const string &field);
|
|
};
|
|
|
|
|
|
class ResultWrapper : public ResultBase {
|
|
ResultWrapper(ConnectionWrapper &con, MYSQL_RES *result);
|
|
friend class QueryWrapper;
|
|
friend class RowWrapper;
|
|
public:
|
|
ResultWrapper() : ResultBase(nullptr, nullptr) {}
|
|
ResultWrapper(ResultWrapper &&r) : ResultBase(std::move(r)) {}
|
|
ResultWrapper(const ResultWrapper& r) = delete;
|
|
const ResultBase &operator=(ResultWrapper &&r) {
|
|
ResultBase::operator=(std::move(r));
|
|
return *this;
|
|
}
|
|
const ResultBase& operator=(const ResultBase& r) = delete;
|
|
|
|
//ResultWrapper(ResultWrapper &r);
|
|
//~ResultWrapper();
|
|
//const ResultWrapper &operator=(ResultWrapper &);
|
|
|
|
int num_rows() const;
|
|
RowWrapper at(int row);
|
|
operator bool() const;
|
|
bool empty() const;
|
|
};
|
|
|
|
class ResUseWrapper : public ResultBase {
|
|
ResUseWrapper(ConnectionWrapper& con, MYSQL_RES* result);
|
|
friend class QueryWrapper;
|
|
friend class RowWrapper;
|
|
public:
|
|
ResUseWrapper(ResUseWrapper&& r) : ResultBase(std::move(r)) {}
|
|
const ResUseWrapper& operator=(ResUseWrapper&& r) {
|
|
ResultBase::operator=(std::move(r));
|
|
return *this;
|
|
}
|
|
ResUseWrapper(const ResUseWrapper& r) = delete;
|
|
const ResUseWrapper& operator=(const ResUseWrapper& r) = delete;
|
|
|
|
operator bool() const;
|
|
RowWrapper fetch_row();
|
|
};
|
|
|
|
class ResNSel {
|
|
public:
|
|
ResNSel(int insert_id, int rows) : insert_id(insert_id), rows(rows) {}
|
|
const int insert_id;
|
|
const int rows;
|
|
operator bool() const;
|
|
};
|
|
|
|
|
|
class Exception {
|
|
string w;
|
|
public:
|
|
Exception(const char *w);
|
|
const char *what() const;
|
|
};
|
|
|
|
class BadFieldName : public Exception {
|
|
string fieldName;
|
|
public:
|
|
BadFieldName(const string &n) : Exception("Bad field name"), fieldName(n) {}
|
|
const string &name() const { return fieldName; }
|
|
};
|
|
|
|
class EndOfResults : public Exception {
|
|
public:
|
|
EndOfResults() : Exception("End of results") {}
|
|
};
|
|
|
|
enum QT {
|
|
quote
|
|
};
|
|
|
|
class QueryWrapper {
|
|
ConnectionWrapper &con;
|
|
string sql;
|
|
bool qnext = false;
|
|
QueryWrapper(ConnectionWrapper &con);
|
|
public:
|
|
|
|
~QueryWrapper();
|
|
ResultWrapper store(const string &q);
|
|
ResultWrapper store();
|
|
|
|
ResUseWrapper use(const string &q);
|
|
|
|
void reset();
|
|
ResNSel execute();
|
|
ResNSel execute(const string &sql);
|
|
void exec(const string &sql);
|
|
|
|
const string& str() const;
|
|
QueryWrapper & operator<<(const string &arg);
|
|
QueryWrapper & operator<<(const char *arg);
|
|
QueryWrapper & operator<<(int arg);
|
|
QueryWrapper & operator<<(uint32_t arg);
|
|
QueryWrapper & operator<<(int64_t arg);
|
|
QueryWrapper & operator<<(QT arg);
|
|
|
|
friend class ConnectionWrapper;
|
|
};
|
|
|
|
class ConnectionWrapper {
|
|
private:
|
|
MYSQL *mysql = nullptr;
|
|
protected:
|
|
MYSQL *get() const;
|
|
|
|
friend class QueryWrapper;
|
|
bool unusedResult = false;
|
|
public:
|
|
ConnectionWrapper();
|
|
virtual ~ConnectionWrapper();
|
|
void close();
|
|
bool select_db(const string &db);
|
|
void create_db(const string &db);
|
|
void drop_db(const string &db);
|
|
string server_info() const;
|
|
bool connected() const;
|
|
void connect(const string &unused, const string &server, const string &user,
|
|
const string &pwd, int port);
|
|
QueryWrapper query();
|
|
};
|
|
|
|
}
|