Revision 3160499c
Von Christian Ehringfeld vor mehr als 9 Jahren hinzugefügt
EntityManager.pro | ||
---|---|---|
src/query.h \
|
||
src/join.h \
|
||
src/queryinterpreter.h \
|
||
src/condition.h
|
||
src/condition.h \
|
||
src/expression.h \
|
||
src/orderby.h
|
||
|
||
SOURCES += \
|
||
src/entity.cpp \
|
||
... | ... | |
src/query.cpp \
|
||
src/join.cpp \
|
||
src/queryinterpreter.cpp \
|
||
src/condition.cpp
|
||
src/condition.cpp \
|
||
src/expression.cpp \
|
||
src/orderby.cpp
|
||
|
||
unix {
|
||
target.path = /usr/lib
|
src/expression.cpp | ||
---|---|---|
#include "expression.h"
|
||
using namespace CuteEntityManager;
|
||
Expression::Expression() {
|
||
}
|
||
|
||
Expression::Expression(QString expression,
|
||
bool onlyColumn) {
|
||
this->expression = expression;
|
||
this->onlyColumn = onlyColumn;
|
||
}
|
||
|
||
QString Expression::getExpression() const {
|
||
return this->expression;
|
||
}
|
||
|
||
void Expression::setExpression(const QString &value) {
|
||
this->expression = value;
|
||
}
|
||
|
||
QString Expression::toString() const {
|
||
return this->expression;
|
||
}
|
||
|
||
bool Expression::getOnlyColumn() const {
|
||
return onlyColumn;
|
||
}
|
||
|
||
void Expression::setOnlyColumn(bool value) {
|
||
onlyColumn = value;
|
||
}
|
||
|
src/expression.h | ||
---|---|---|
#ifndef EXPRESSION_H
|
||
#define EXPRESSION_H
|
||
|
||
#include <QHash>
|
||
#include <QString>
|
||
#include <QVariant>
|
||
namespace CuteEntityManager {
|
||
class Expression {
|
||
public:
|
||
Expression();
|
||
Expression(QString expression,
|
||
bool onlyColumn = false);
|
||
QString getExpression() const;
|
||
void setExpression(const QString &value);
|
||
|
||
QString toString() const;
|
||
|
||
bool getOnlyColumn() const;
|
||
void setOnlyColumn(bool value);
|
||
|
||
private:
|
||
QString expression;
|
||
bool onlyColumn;
|
||
};
|
||
}
|
||
#endif // EXPRESSION_H
|
src/join.cpp | ||
---|---|---|
}
|
||
|
||
Join::Join(QString foreignTable, QString condition, QString type) {
|
||
this->foreignTable = foreignTable;
|
||
this->condition = Condition(condition);
|
||
this->type = type;
|
||
}
|
||
|
||
Join::Join(QString foreignTable, Condition condition, QString type) {
|
||
this->foreignTable = foreignTable;
|
||
this->condition = condition;
|
||
this->type = type;
|
||
... | ... | |
foreignTable = value;
|
||
}
|
||
|
||
QString Join::getCondition() const {
|
||
Condition Join::getCondition() const {
|
||
return condition;
|
||
}
|
||
|
||
void Join::setCondition(const QString &value) {
|
||
condition = value;
|
||
QString Join::getMainCondition() const {
|
||
auto conditions = this->condition.getConditions();
|
||
if (!conditions.isEmpty()) {
|
||
return conditions.at(0);
|
||
} else {
|
||
return "";
|
||
}
|
||
}
|
||
|
||
void Join::setCondition(const Condition &value) {
|
||
condition = value;
|
||
}
|
||
|
src/join.h | ||
---|---|---|
#ifndef JOIN_H
|
||
#define JOIN_H
|
||
#include <QString>
|
||
|
||
#include "condition.h"
|
||
namespace CuteEntityManager {
|
||
class Join {
|
||
|
||
public:
|
||
Join();
|
||
Join(QString foreignTable, QString condition,
|
||
explicit Join(QString foreignTable, QString condition,
|
||
QString type = QStringLiteral("LEFT JOIN"));
|
||
explicit Join(QString foreignTable, Condition condition,
|
||
QString type = QStringLiteral("LEFT JOIN"));
|
||
|
||
QString getType() const;
|
||
... | ... | |
QString getForeignTable() const;
|
||
void setForeignTable(const QString &value);
|
||
|
||
QString getCondition() const;
|
||
void setCondition(const QString &value);
|
||
Condition getCondition() const;
|
||
QString getMainCondition() const;
|
||
void setCondition(const Condition &value);
|
||
|
||
private:
|
||
private:
|
||
QString type = QStringLiteral("LEFT JOIN");
|
||
QString foreignTable;
|
||
QString condition;
|
||
Condition condition;
|
||
|
||
};
|
||
}
|
src/orderby.cpp | ||
---|---|---|
#include "orderby.h"
|
||
using namespace CuteEntityManager;
|
||
OrderBy::OrderBy() {
|
||
this->direction = Direction::DEFAULT;
|
||
}
|
||
|
||
OrderBy::OrderBy(QString column, Direction direction) {
|
||
this->column = column;
|
||
this->direction = direction;
|
||
}
|
||
|
||
OrderBy::OrderBy(Expression direction) {
|
||
this->column = "";
|
||
this->expressedDirection = direction;
|
||
}
|
||
|
||
QString OrderBy::getColumn() const {
|
||
return column;
|
||
}
|
||
|
||
void OrderBy::setColumn(const QString &value) {
|
||
column = value;
|
||
}
|
||
|
||
Direction OrderBy::getDirection() const {
|
||
return direction;
|
||
}
|
||
|
||
void OrderBy::setDirection(const Direction &value) {
|
||
direction = value;
|
||
}
|
||
|
||
Expression OrderBy::getExpressedDirection() const {
|
||
return expressedDirection;
|
||
}
|
||
|
||
void OrderBy::setExpressedDirection(const Expression &value) {
|
||
expressedDirection = value;
|
||
}
|
||
|
src/orderby.h | ||
---|---|---|
#ifndef ORDERBY_H
|
||
#define ORDERBY_H
|
||
|
||
#include <QString>
|
||
#include "expression.h"
|
||
namespace CuteEntityManager {
|
||
enum class Direction {
|
||
SORT_ASC,
|
||
SORT_DESC,
|
||
DEFAULT
|
||
};
|
||
|
||
//class Expression;
|
||
class OrderBy {
|
||
public:
|
||
OrderBy();
|
||
OrderBy(QString column, Direction direction = Direction::DEFAULT);
|
||
OrderBy(Expression direction);
|
||
QString getColumn() const;
|
||
void setColumn(const QString &value);
|
||
|
||
Direction getDirection() const;
|
||
void setDirection(const Direction &value);
|
||
|
||
Expression getExpressedDirection() const;
|
||
void setExpressedDirection(const Expression &value);
|
||
|
||
private:
|
||
QString column;
|
||
Direction direction;
|
||
Expression expressedDirection;
|
||
};
|
||
}
|
||
#endif // ORDERBY_H
|
src/query.cpp | ||
---|---|---|
#include "query.h"
|
||
#include "condition.h"
|
||
#include "orderby.h"
|
||
using namespace CuteEntityManager;
|
||
Query::Query() {
|
||
this->select << "*";
|
||
//this->select << Expression("*");
|
||
}
|
||
|
||
QStringList Query::getSelect() const {
|
||
return select;
|
||
void Query::appendWhereCondition(const QString &condition) {
|
||
this->where.append(Condition(condition));
|
||
}
|
||
|
||
void Query::appendCondition(const QString &condition) {
|
||
this->conditions.append(Condition(condition));
|
||
}
|
||
|
||
void Query::appendCondition(const Condition &condition) {
|
||
this->conditions.append(condition);
|
||
}
|
||
QLinkedList<Condition> Query::getConditions() const {
|
||
return conditions;
|
||
}
|
||
|
||
void Query::setConditions(const QLinkedList<Condition> &value) {
|
||
conditions = value;
|
||
void Query::appendWhereCondition(const Condition &condition) {
|
||
this->where.append(condition);
|
||
}
|
||
|
||
void Query::setSelect(const QStringList &value) {
|
||
select = value;
|
||
for (int var = 0; var < value.size(); ++var) {
|
||
this->appendSelect(value.at(var));
|
||
}
|
||
}
|
||
|
||
QString Query::getSelectOption() const {
|
||
return selectOption;
|
||
}
|
||
... | ... | |
void Query::setSelectOption(const QString &value) {
|
||
selectOption = value;
|
||
}
|
||
|
||
bool Query::getDistinct() const {
|
||
return distinct;
|
||
}
|
||
... | ... | |
void Query::setDistinct(bool value) {
|
||
distinct = value;
|
||
}
|
||
|
||
QStringList Query::getFrom() const {
|
||
return from;
|
||
}
|
||
... | ... | |
void Query::setFrom(const QStringList &value) {
|
||
from = value;
|
||
}
|
||
|
||
QStringList Query::getGroupBy() const {
|
||
return groupBy;
|
||
}
|
||
... | ... | |
void Query::setGroupBy(const QStringList &value) {
|
||
groupBy = value;
|
||
}
|
||
QStringList Query::getOrderBy() const {
|
||
return orderBy;
|
||
|
||
void Query::appendSelect(const Expression &value) {
|
||
this->select.append(value);
|
||
}
|
||
|
||
void Query::setOrderBy(const QStringList &value) {
|
||
orderBy = value;
|
||
void Query::appendSelect(const QString &value) {
|
||
this->select.append(Expression(value, true));
|
||
}
|
||
|
||
QList<Join> Query::getJoins() const {
|
||
return joins;
|
||
}
|
||
... | ... | |
void Query::setOffset(const uint &value) {
|
||
offset = value;
|
||
}
|
||
|
||
void Query::appendHavingCondition(const QString &condition) {
|
||
this->having.append(Condition(condition));
|
||
}
|
||
|
||
void Query::appendHavingCondition(const Condition &condition) {
|
||
this->having.append(condition);
|
||
}
|
||
|
||
QList<Condition> Query::getWhere() const {
|
||
return where;
|
||
}
|
||
|
||
void Query::setWhere(const QList<Condition> &value) {
|
||
where = value;
|
||
}
|
||
|
||
QList<Condition> Query::getHaving() const {
|
||
return having;
|
||
}
|
||
|
||
void Query::setHaving(const QList<Condition> &value) {
|
||
having = value;
|
||
}
|
||
|
||
void Query::appendOrderBy(const OrderBy &orderBy) {
|
||
this->orderBy.append(orderBy);
|
||
}
|
||
|
||
void Query::appendOrderBy(const QString &column, const Direction &direction) {
|
||
this->orderBy.append(OrderBy(column, direction));
|
||
}
|
||
|
||
QList<OrderBy> Query::getOrderBy() const {
|
||
return orderBy;
|
||
}
|
||
|
||
void Query::setOrderBy(const QList<OrderBy> &value) {
|
||
orderBy = value;
|
||
}
|
src/query.h | ||
---|---|---|
#include <QVariant>
|
||
#include <QLinkedList>
|
||
#include "join.h"
|
||
#include "expression.h"
|
||
|
||
namespace CuteEntityManager {
|
||
class Condition;
|
||
class OrderBy;
|
||
enum class Direction;
|
||
class Query {
|
||
public:
|
||
Query();
|
||
QStringList getSelect() const;
|
||
void setSelect(const QStringList &value);
|
||
|
||
QString getSelectOption() const;
|
||
void setSelectOption(const QString &value);
|
||
... | ... | |
QStringList getFrom() const;
|
||
void setFrom(const QStringList &value);
|
||
|
||
QStringList getGroupBy() const;
|
||
void setGroupBy(const QStringList &value);
|
||
|
||
QStringList getOrderBy() const;
|
||
void setOrderBy(const QStringList &value);
|
||
|
||
QList<Join> getJoins() const;
|
||
void setJoins(const QList<Join> &value);
|
||
|
||
... | ... | |
uint getOffset() const;
|
||
void setOffset(const uint &value);
|
||
|
||
void appendCondition(const QString &condition);
|
||
void appendCondition(const Condition &condition);
|
||
QLinkedList<Condition> getConditions() const;
|
||
void setConditions(const QLinkedList<Condition> &value);
|
||
void appendWhereCondition(const QString &condition);
|
||
void appendWhereCondition(const Condition &condition);
|
||
|
||
void appendHavingCondition(const QString &condition);
|
||
void appendHavingCondition(const Condition &condition);
|
||
|
||
QList<Condition> getWhere() const;
|
||
void setWhere(const QList<Condition> &value);
|
||
|
||
QList<Condition> getHaving() const;
|
||
void setHaving(const QList<Condition> &value);
|
||
|
||
void appendOrderBy(const OrderBy &orderBy);
|
||
void appendOrderBy(const QString &column, const Direction &direction);
|
||
QList<OrderBy> getOrderBy() const;
|
||
void setOrderBy(const QList<OrderBy> &value);
|
||
|
||
QStringList getGroupBy() const;
|
||
void setGroupBy(const QStringList &value);
|
||
|
||
QList<Expression> getSelect() const;
|
||
void appendSelect(const Expression &value);
|
||
void appendSelect(const QString &value);
|
||
void setSelect(const QList<Expression> &value);
|
||
void setSelect(const QStringList &value);
|
||
|
||
private:
|
||
QStringList select;
|
||
private:
|
||
QList<Expression> select;
|
||
QString selectOption = QStringLiteral("");
|
||
bool distinct = false;
|
||
QStringList from;
|
||
QStringList groupBy;
|
||
QStringList orderBy;
|
||
QLinkedList<Condition> conditions;
|
||
QList<OrderBy> orderBy;
|
||
QList<Condition> where;
|
||
QList<Condition> having;
|
||
QList<Join> joins;
|
||
QHash<QString, QVariant> params;
|
||
uint limit = 0;
|
src/querybuilder.cpp | ||
---|---|---|
QSharedPointer<Database> database) {
|
||
this->schema = schema;
|
||
this->database = database;
|
||
this->separator = " ";
|
||
}
|
||
|
||
QueryBuilder::~QueryBuilder() {
|
||
... | ... | |
return QString("CuteEntityManager::Entity");
|
||
}
|
||
|
||
QString QueryBuilder::limit(const qint64 &limit, const qint64 &offset) const {
|
||
QStringList QueryBuilder::quoteTableNames(const QStringList &tables) {
|
||
QStringList r = QStringList();
|
||
for (int i = 0; i < tables.size(); ++i) {
|
||
r.append(this->schema->quoteTableName(tables.at(i)));
|
||
}
|
||
return r;
|
||
}
|
||
|
||
QString QueryBuilder::getSeparator() const {
|
||
return separator;
|
||
}
|
||
|
||
void QueryBuilder::setSeparator(const QString &value) {
|
||
separator = value;
|
||
}
|
||
|
||
|
||
QString QueryBuilder::limit(const quint64 &limit, const quint64 &offset) const {
|
||
QString s = "";
|
||
if (limit > 0) {
|
||
s.append(" " + this->limitKeyword() + " ").append(QString::number(limit));
|
||
... | ... | |
this->placeHolder(var.key());
|
||
query.appendParam(var.key(), var.value());
|
||
}
|
||
query.appendCondition(condition);
|
||
query.appendWhereCondition(condition);
|
||
}
|
||
|
||
void QueryBuilder::arbitraryOperator(Query &query, QString op, QString column,
|
||
QVariant value) {
|
||
query.appendCondition(this->schema->quoteColumnName(column) + " " + op + " " +
|
||
this->placeHolder(column));
|
||
query.appendWhereCondition(this->schema->quoteColumnName(
|
||
column) + " " + op + " " +
|
||
this->placeHolder(column));
|
||
query.appendParam(column, value);
|
||
}
|
||
|
||
void QueryBuilder::isNull(Query &query, QString column) {
|
||
query.appendCondition(this->schema->quoteColumnName(column) + " IS NULL");
|
||
query.appendWhereCondition(this->schema->quoteColumnName(column) + " IS NULL");
|
||
}
|
||
|
||
void QueryBuilder::isNotNull(Query &query, QString column) {
|
||
query.appendCondition(this->schema->quoteColumnName(column) + " IS " +
|
||
this->notKeyword() + " NULL");
|
||
query.appendWhereCondition(this->schema->quoteColumnName(column) + " IS " +
|
||
this->notKeyword() + " NULL");
|
||
}
|
||
|
||
void QueryBuilder::plainOr(Query &query) {
|
||
query.appendCondition(this->orKeyword());
|
||
query.appendWhereCondition(this->orKeyword());
|
||
}
|
||
|
||
void QueryBuilder::plainNor(Query &query) {
|
||
query.appendCondition(this->notKeyword() + " " + this->orKeyword());
|
||
query.appendWhereCondition(this->notKeyword() + " " + this->orKeyword());
|
||
}
|
||
|
||
void QueryBuilder::plainAnd(Query &query) {
|
||
query.appendCondition(this->andKeyword());
|
||
query.appendWhereCondition(this->andKeyword());
|
||
}
|
||
|
||
void QueryBuilder::plainNand(Query &query) {
|
||
query.appendCondition(this->notKeyword() + " " + this->andKeyword());
|
||
query.appendWhereCondition(this->notKeyword() + " " + this->andKeyword());
|
||
}
|
||
|
||
void QueryBuilder::like(Query &query, QString column, QVariant value,
|
||
... | ... | |
query.appendParam(i.key(), newVal.isEmpty() ? i.value() : newVal);
|
||
}
|
||
condition += ")";
|
||
query.appendCondition(condition);
|
||
query.appendWhereCondition(condition);
|
||
}
|
||
}
|
||
|
||
void QueryBuilder::where(Query &query, QString column, QVariant value) {
|
||
QString placeholder = column + "_where";
|
||
query.appendCondition(this->schema->quoteColumnName(column) + "=" +
|
||
this->placeHolder(placeholder));
|
||
query.appendWhereCondition(this->schema->quoteColumnName(column) + "=" +
|
||
this->placeHolder(placeholder));
|
||
query.appendParam(placeholder, value);
|
||
}
|
||
|
||
... | ... | |
for (auto i = conditions.constBegin(); i != conditions.constEnd(); ++i) {
|
||
query.appendParam(i.key(), i.value());
|
||
}
|
||
query.appendCondition(condition);
|
||
query.appendWhereCondition(condition);
|
||
}
|
||
|
||
void QueryBuilder::where(Query &query, QString condition,
|
||
QHash<QString, QVariant> values) {
|
||
query.appendCondition(condition);
|
||
query.appendWhereCondition(condition);
|
||
for (auto i = values.constBegin(); i != values.constEnd(); ++i) {
|
||
query.appendParam(i.key(), i.value());
|
||
}
|
||
... | ... | |
QVariant val1, QVariant val2, QString condition) {
|
||
q.appendParam(ph1, val1);
|
||
q.appendParam(ph2, val2);
|
||
q.appendCondition(condition);
|
||
q.appendWhereCondition(condition);
|
||
}
|
||
|
||
void QueryBuilder::in(Query &query, QString column, QList<QVariant> values) {
|
||
query.appendCondition(this->inFunction(query, column, values));
|
||
query.appendWhereCondition(this->inFunction(query, column, values));
|
||
}
|
||
|
||
void QueryBuilder::notIn(Query &query, QString column, QList<QVariant> values) {
|
||
query.appendCondition(this->inFunction(query, column,
|
||
values, true));
|
||
query.appendWhereCondition(this->inFunction(query, column,
|
||
values, true));
|
||
}
|
||
|
||
void QueryBuilder::orOperator(Query &query,
|
||
... | ... | |
query.appendParam(i.key(), i.value());
|
||
}
|
||
condition += ")";
|
||
query.appendCondition(condition);
|
||
query.appendWhereCondition(condition);
|
||
}
|
||
}
|
||
|
src/querybuilder.h | ||
---|---|---|
* EntityManager is a friend class, cause we want a light public api.
|
||
*/
|
||
friend class EntityManager;
|
||
friend class QueryInterpreter;
|
||
public:
|
||
QueryBuilder(QSharedPointer<Schema> schema, QSharedPointer<Database> database);
|
||
virtual ~QueryBuilder();
|
||
... | ... | |
QString conjunction = "AND",
|
||
JokerPosition jp = JokerPosition::BOTH, QChar wildcard = '%');
|
||
|
||
QStringList quoteTableNames(const QStringList &tables);
|
||
QString getSeparator() const;
|
||
void setSeparator(const QString &value);
|
||
|
||
protected:
|
||
class ClassAttributes {
|
||
public:
|
||
... | ... | |
const QString &primaryKey = "id") const;
|
||
QList<QSqlQuery> createOrMerge(const QSharedPointer<Entity> &entity,
|
||
bool insert) const;
|
||
virtual QString limit(const qint64 &limit, const qint64 &offset) const;
|
||
virtual QString limit(const quint64 &limit, const quint64 &offset) const;
|
||
QString generateIndexName(const QString &name, const QString &table,
|
||
const QString &refColumn, const QString &refTable, const bool fk) const;
|
||
QString generateColumnNameID(QString name) const;
|
||
... | ... | |
virtual void appendCondition(Query &q, QString ph1, QString ph2, QVariant val1,
|
||
QVariant val2, QString condition);
|
||
QString entityClassname() const;
|
||
|
||
QString separator;
|
||
QSharedPointer<Schema> schema;
|
||
QSharedPointer<Database> database;
|
||
};
|
src/queryinterpreter.cpp | ||
---|---|---|
#include "queryinterpreter.h"
|
||
#include "condition.h"
|
||
#include "join.h"
|
||
#include "query.h"
|
||
#include "querybuilder.h"
|
||
#include "orderby.h"
|
||
#include "expression.h"
|
||
#include "schema.h"
|
||
using namespace CuteEntityManager;
|
||
|
||
|
||
... | ... | |
this->builder = builder;
|
||
}
|
||
|
||
QSqlQuery QueryInterpreter::interpretQuery(Query &q) {
|
||
QSqlQuery QueryInterpreter::build(const Query &q) {
|
||
QList<QString> clauses = QList<QString>();
|
||
clauses.append(this->buildSelect(q.getSelect(), q.getDistinct(),
|
||
q.getSelectOption()));
|
||
clauses.append(this->buildFrom(q.getFrom()));
|
||
clauses.append(this->buildJoin(q.getJoins()));
|
||
clauses.append(this->buildWhere(q.getWhere()));
|
||
clauses.append(this->buildGroupBy(q.getGroupBy()));
|
||
clauses.append(this->buildHaving(q.getHaving()));
|
||
QString sql = "";
|
||
bool first = true;
|
||
for (int i = 0; i < clauses.size(); ++i) {
|
||
QString clause = clauses.at(i);
|
||
if (!clause.isEmpty()) {
|
||
if (first) {
|
||
first = false;
|
||
} else {
|
||
sql += this->builder->getSeparator();
|
||
}
|
||
sql += clause;
|
||
}
|
||
}
|
||
sql = this->buildOrderByAndLimit(sql, q.getOrderBy(), q.getLimit(),
|
||
q.getOffset());
|
||
QSqlQuery sqlQuery = this->builder->getQuery();
|
||
sqlQuery.prepare(sql);
|
||
this->builder->bindValues(q.getParams(), sqlQuery, false);
|
||
return sqlQuery;
|
||
}
|
||
|
||
QString QueryInterpreter::buildSelect(const QList<Expression> &columns,
|
||
const bool &distinct, const QString &selectOption) const {
|
||
QString sqlSelect = distinct ? "SELECT DISTINCT" : "SELECT";
|
||
if (!selectOption.isEmpty()) {
|
||
sqlSelect += this->builder->getSeparator() + selectOption;
|
||
}
|
||
if (columns.isEmpty()) {
|
||
return sqlSelect + " *";
|
||
}
|
||
bool first = true;
|
||
for (int i = 0; i < columns.size(); ++i) {
|
||
if (first) {
|
||
first = false;
|
||
} else {
|
||
sqlSelect += ", ";
|
||
}
|
||
Expression e = columns.at(i);
|
||
QString nExp = e.getExpression();
|
||
if (e.getOnlyColumn()) {
|
||
sqlSelect += this->builder->getSchema()->quoteColumnName(e.getExpression());
|
||
} else if (!nExp.contains("(")) {
|
||
QRegularExpression re =
|
||
QRegularExpression(
|
||
QRegularExpression::escape("/^(.*?)(?i:\\s+as\\s+|\\s+)([\\w\\-_\\.]+)$/"));
|
||
re.optimize();
|
||
QRegularExpressionMatchIterator iterator = re.globalMatch(nExp, 0,
|
||
QRegularExpression::PartialPreferFirstMatch);
|
||
|
||
if (iterator.hasNext()) {
|
||
for (int var = 0; var < 2; ++var) {
|
||
QRegularExpressionMatch match = iterator.next();
|
||
if (var == 1) {
|
||
sqlSelect += this->builder->getSchema()->quoteColumnName(
|
||
match.captured()) + " AS " + this->builder->getSchema()->quoteColumnName("a" +
|
||
QString::number(i));
|
||
}
|
||
}
|
||
|
||
} else {
|
||
nExp = this->builder->getSchema()->quoteColumnName(nExp);
|
||
}
|
||
} else {
|
||
sqlSelect += nExp + " AS " + this->builder->getSchema()->quoteColumnName("a" +
|
||
QString::number(i));
|
||
}
|
||
}
|
||
return sqlSelect;
|
||
}
|
||
|
||
QString QueryInterpreter::buildFrom(const QStringList &from) const {
|
||
if (from.isEmpty()) {
|
||
return "";
|
||
}
|
||
auto tables = this->builder->quoteTableNames(from);
|
||
QString clause = "FROM ";
|
||
bool first = true;
|
||
for (int var = 0; var < tables.size(); ++var) {
|
||
if (first) {
|
||
first = false;
|
||
} else {
|
||
clause += ", ";
|
||
}
|
||
clause += from.at(var);
|
||
}
|
||
return clause;
|
||
}
|
||
|
||
QString QueryInterpreter::buildJoin(const QList<Join> &joins) const {
|
||
if (joins.isEmpty()) {
|
||
return "";
|
||
}
|
||
QString sqlJoin = "";
|
||
for (int i = 0; i < joins.size(); ++i) {
|
||
Join j = joins.at(i);
|
||
sqlJoin += j.getType() + this->builder->getSeparator() +
|
||
this->builder->getSchema()->quoteTableName(j.getForeignTable());
|
||
if (!j.getCondition().getConditions().isEmpty()) {
|
||
QString condition = this->buildCondition(j.getCondition());
|
||
if (!condition.isEmpty()) {
|
||
sqlJoin += " ON " + condition;
|
||
}
|
||
}
|
||
}
|
||
return sqlJoin;
|
||
}
|
||
|
||
QString QueryInterpreter::buildWhere(const QList<Condition> &conditions)
|
||
const {
|
||
QString where = this->buildCondition(conditions);
|
||
return where.isEmpty() ? "" : ("WHERE " + where);
|
||
}
|
||
|
||
QString QueryInterpreter::buildGroupBy(const QStringList &groupBy) const {
|
||
return groupBy.isEmpty() ? "" : "GROUP BY " + this->builder->buildColumns(
|
||
groupBy);
|
||
}
|
||
|
||
QString QueryInterpreter::buildHaving(const QList<Condition> &conditions)
|
||
const {
|
||
QString having = this->buildCondition(conditions);
|
||
return having.isEmpty() ? "" : ("HAVING " + having);
|
||
}
|
||
|
||
QString QueryInterpreter::buildOrderByAndLimit(QString sql,
|
||
const QList<OrderBy> &orderBy, const quint64 &limit,
|
||
const quint64 &offset) const {
|
||
QString sqlOrderBy = this->buildOrderBy(orderBy);
|
||
if (!sqlOrderBy.isEmpty()) {
|
||
sql += this->builder->getSeparator() + sqlOrderBy;
|
||
}
|
||
QString sqlLimit = this->builder->limit(limit, offset);
|
||
if (!sqlLimit.isEmpty()) {
|
||
sql += this->builder->getSeparator() + sqlLimit;
|
||
}
|
||
return sql;
|
||
}
|
||
|
||
QString QueryInterpreter::buildOrderBy(const QList<OrderBy> &columns) const {
|
||
if (columns.isEmpty()) {
|
||
return "";
|
||
}
|
||
bool first = true;
|
||
QString sqlOrder = "ORDER BY ";
|
||
for (int i = 0; i < columns.size(); ++i) {
|
||
if (first) {
|
||
first = false;
|
||
} else {
|
||
sqlOrder += ", ";
|
||
}
|
||
OrderBy order = columns.at(i);
|
||
if (order.getColumn().isEmpty()) {
|
||
sqlOrder += order.getExpressedDirection().getExpression();
|
||
} else {
|
||
sqlOrder += this->builder->getSchema()->quoteColumnName(order.getColumn());
|
||
switch (order.getDirection()) {
|
||
case Direction::SORT_ASC:
|
||
sqlOrder += " ASC";
|
||
break;
|
||
case Direction::SORT_DESC:
|
||
sqlOrder += " DESC";
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
return sqlOrder;
|
||
}
|
||
|
||
QString QueryInterpreter::buildCondition(const QList<Condition> &conditions)
|
||
const {
|
||
if (conditions.isEmpty()) {
|
||
return "";
|
||
}
|
||
return "";
|
||
}
|
||
|
||
QString QueryInterpreter::buildCondition(const Condition &conditions) const {
|
||
return "";
|
||
}
|
||
|
src/queryinterpreter.h | ||
---|---|---|
|
||
#include <QSqlQuery>
|
||
#include <QSharedPointer>
|
||
#include <QRegularExpressionMatchIterator>
|
||
namespace CuteEntityManager {
|
||
class Query;
|
||
class QueryBuilder;
|
||
class Condition;
|
||
class Join;
|
||
class OrderBy;
|
||
class Expression;
|
||
class QueryInterpreter {
|
||
public:
|
||
QueryInterpreter(QSharedPointer<QueryBuilder> builder);
|
||
QSqlQuery interpretQuery(Query &q);
|
||
QSqlQuery build(const Query &q);
|
||
|
||
protected:
|
||
QString buildSelect(const QList<Expression> &columns, const bool &distinct = false,
|
||
const QString &selectOption = "") const;
|
||
QString buildFrom(const QStringList &from) const;
|
||
QString buildJoin(const QList<Join> &joins) const;
|
||
QString buildWhere(const QList<Condition> &conditions) const;
|
||
QString buildGroupBy(const QStringList &groupBy) const;
|
||
QString buildHaving(const QList<Condition> &conditions) const;
|
||
QString buildOrderByAndLimit(QString sql, const QList<OrderBy> &orderBy,
|
||
const quint64 &limit, const quint64 &offset) const;
|
||
QString buildOrderBy(const QList<OrderBy> &columns) const;
|
||
QString buildCondition(const QList<Condition> &conditions) const;
|
||
QString buildCondition(const Condition &conditions) const;
|
||
|
||
private:
|
||
QSharedPointer<QueryBuilder> builder;
|
||
|
||
};
|
||
|
||
|
||
|
||
|
||
//QStringList select;
|
||
//QString selectOption = QStringLiteral("");
|
||
//bool distinct = false;
|
||
//QStringList from;
|
||
//QStringList groupBy;
|
||
//QStringList orderBy;
|
||
//QLinkedList<Condition> conditions;
|
||
//QList<Join> joins;
|
||
//QHash<QString, QVariant> params;
|
||
//uint limit = 0;
|
||
//uint offset = 0;
|
||
|
||
|
||
|
||
//protected $conditionBuilders = [
|
||
// 'NOT' => 'buildNotCondition',
|
||
// 'AND' => 'buildAndCondition',
|
||
// 'OR' => 'buildAndCondition',
|
||
// 'BETWEEN' => 'buildBetweenCondition',
|
||
// 'NOT BETWEEN' => 'buildBetweenCondition',
|
||
// 'IN' => 'buildInCondition',
|
||
// 'NOT IN' => 'buildInCondition',
|
||
// 'LIKE' => 'buildLikeCondition',
|
||
// 'NOT LIKE' => 'buildLikeCondition',
|
||
// 'OR LIKE' => 'buildLikeCondition',
|
||
// 'OR NOT LIKE' => 'buildLikeCondition',
|
||
// 'EXISTS' => 'buildExistsCondition',
|
||
// 'NOT EXISTS' => 'buildExistsCondition',
|
||
// ];
|
||
|
||
|
||
}
|
||
|
||
#endif // QUERYINTERPRETER_H
|
Auch abrufbar als: Unified diff
queryinterpreter/builder wip