Created
October 6, 2014 23:08
-
-
Save ianmac45/9fae0872b92e6da76cce to your computer and use it in GitHub Desktop.
the "sugar coating" for working with "raw" sql in c++, using qt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <QDebug> | |
#include <QString> | |
#include <QVariant> | |
#include <QSqlField> | |
#include <QSqlQuery> | |
#include <QSqlError> | |
#include <QSqlDriver> | |
#include <QSqlRecord> | |
#include <QSqlDatabase> | |
#ifndef VAL_EXIT | |
#define VAL_EXIT(RETURN_VALUE) { qWarning() << (RETURN_VALUE); return 0; } | |
#endif | |
namespace sql | |
{ | |
static QSqlQuery generateSql(QSqlDatabase db, QSqlDriver::StatementType type, const QString &tableName, const QSqlRecord &values, const QSqlRecord &wheres = QSqlRecord()) | |
{ | |
QSqlQuery q(db); | |
QString sql = q.driver()->sqlStatement(type, tableName, values, false); | |
if(!wheres.isEmpty()) | |
sql += " " + q.driver()->sqlStatement(QSqlDriver::WhereStatement, tableName, wheres, false); | |
q.prepare(sql); | |
return q; | |
} | |
//facilitates intuitive execution of sql commands | |
// => bool execOk = sql::insert(table) << [[field1]] << sql::where() << field("id", 1); | |
class field_dest | |
{ | |
public: | |
const bool IsWhere; | |
field_dest(bool _isWhere) : | |
IsWhere(_isWhere) | |
{ | |
} | |
}; | |
//helpful ctor for QSqlField | |
class field : QSqlField | |
{ | |
public: | |
explicit field(const QString &name, const QVariant &value = QVariant()) : | |
QSqlField(name, value.type()) | |
{ | |
setValue(value); | |
} | |
field(const QSqlField &other) : | |
QSqlField(other) | |
{ | |
} | |
}; | |
//generalized structure (& support classes) for executing normal CRUD operations | |
class command_data | |
{ | |
public: | |
QSqlRecord values, wheres; | |
QString table; | |
QSqlDatabase database; | |
QSqlDriver::StatementType type; | |
bool isWheres; | |
unsigned status; //0 = not exec'ed, 1 = bad, 2 = good | |
command_data(const QString &tableName, QSqlDatabase db, QSqlDriver::StatementType _type) : | |
table(tableName), | |
database(db), | |
type(_type), | |
status(0), | |
isWheres(false) | |
{ | |
} | |
virtual ~command_data() | |
{ | |
doExec(); | |
} | |
bool exec() const | |
{ | |
if(type == QSqlDriver::InsertStatement || type == QSqlDriver::UpdateStatement) | |
if(values.isEmpty()) | |
return true; | |
QSqlQuery q = generateSql(database, type, table, values, wheres); | |
if(!q.exec()) | |
VAL_EXIT(q.lastError().text() + "\n" + q.executedQuery()); | |
return true; | |
} | |
void doExec() | |
{ | |
if(!status) | |
status = exec() + 1; | |
} | |
}; | |
class command | |
{ | |
std::auto_ptr<command_data> d; | |
public: | |
command(command_data *data = 0) : | |
d(data) | |
{ | |
} | |
operator bool() | |
{ | |
if(!d.get()) return false; | |
d->doExec(); | |
return d->status == 2; | |
} | |
command& operator<< (const field &f) | |
{ | |
if(d.get()) (d->isWheres ? d->wheres : d->values).append(f); | |
return *this; | |
} | |
command& operator<< (const field_dest &dest) | |
{ | |
if(d.get()) d->isWheres = dest.IsWhere; | |
return *this; | |
} | |
}; | |
inline command insert(const QString &table, QSqlDatabase db = QSqlDatabase::database()) { return command(new command_data(table, db, QSqlDriver::InsertStatement)); } | |
inline command update(const QString &table, QSqlDatabase db = QSqlDatabase::database()) { return command(new command_data(table, db, QSqlDriver::UpdateStatement)); } | |
inline command delete_(const QString &table, QSqlDatabase db = QSqlDatabase::database()) { return command(new command_data(table, db, QSqlDriver::DeleteStatement)) << field_dest(true); } | |
} | |
inline sql::command& where (sql::command &c) { return c << sql::field_dest (true); } | |
inline sql::command& values(sql::command &c) { return c << sql::field_dest(false); } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment