mirror of
https://github.com/silverqx/TinyORM.git
synced 2026-05-08 18:09:52 -05:00
added support for table prefixes
- also added tests
This commit is contained in:
@@ -59,6 +59,11 @@ namespace Query
|
||||
/*! Get the value of a raw expression. */
|
||||
QVariant getValue(const Expression &expression) const;
|
||||
|
||||
/*! Get the grammar's table prefix. */
|
||||
QString getTablePrefix() const;
|
||||
/*! Set the grammar's table prefix. */
|
||||
BaseGrammar &setTablePrefix(const QString &prefix);
|
||||
|
||||
protected:
|
||||
/*! Convert the vector of column names into a delimited string. */
|
||||
QString columnize(const QStringList &columns) const;
|
||||
@@ -68,11 +73,6 @@ namespace Query
|
||||
/*! Get the appropriate query parameter place-holder for a value. */
|
||||
QString parameter(const QVariant &value) const;
|
||||
|
||||
/*! Get the grammar's table prefix. */
|
||||
QString getTablePrefix() const;
|
||||
/*! Set the grammar's table prefix. */
|
||||
BaseGrammar &setTablePrefix(const QString &prefix);
|
||||
|
||||
/*! Wrap a value that has an alias. */
|
||||
QString wrapAliasedValue(const QString &value, bool prefixAlias = false) const;
|
||||
/*! Wrap a single string in keyword identifiers. */
|
||||
@@ -94,6 +94,11 @@ namespace Query
|
||||
QString m_tablePrefix = "";
|
||||
};
|
||||
|
||||
inline QString BaseGrammar::getTablePrefix() const
|
||||
{
|
||||
return m_tablePrefix;
|
||||
}
|
||||
|
||||
template<QStringContainer T>
|
||||
T BaseGrammar::wrapArray(T values) const
|
||||
{
|
||||
|
||||
@@ -16,6 +16,7 @@ namespace TINYORM_COMMON_NAMESPACE
|
||||
namespace Orm
|
||||
{
|
||||
|
||||
class BaseGrammar;
|
||||
class DatabaseConnection;
|
||||
|
||||
namespace Query
|
||||
@@ -228,6 +229,13 @@ namespace Grammars
|
||||
virtual void recordsHaveBeenModified(bool value = true) = 0;
|
||||
/*! Reset the record modification state. */
|
||||
virtual void forgetRecordModificationState() = 0;
|
||||
|
||||
/*! Get the table prefix for the connection. */
|
||||
virtual QString getTablePrefix() const = 0;
|
||||
/*! Set the table prefix in use by the connection. */
|
||||
virtual DatabaseConnection &setTablePrefix(const QString &prefix) = 0;
|
||||
/*! Set the table prefix and return the query grammar. */
|
||||
virtual BaseGrammar &withTablePrefix(BaseGrammar &grammar) const = 0;
|
||||
};
|
||||
|
||||
} // namespace Orm
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace TINYORM_COMMON_NAMESPACE
|
||||
namespace Orm
|
||||
{
|
||||
|
||||
// CUR return DatabaseConnection vs ConnectionInterface silverqx
|
||||
class SHAREDLIB_EXPORT DatabaseConnection :
|
||||
public ConnectionInterface,
|
||||
public Concerns::DetectsLostConnections
|
||||
@@ -43,13 +44,19 @@ namespace Orm
|
||||
QSharedPointer<QueryBuilder>
|
||||
table(const QString &table, const QString &as = "") override;
|
||||
|
||||
/*! Get the table prefix for the connection. */
|
||||
QString getTablePrefix() const override;
|
||||
/*! Set the table prefix in use by the connection. */
|
||||
DatabaseConnection &setTablePrefix(const QString &prefix) override;
|
||||
/*! Set the table prefix and return the query grammar. */
|
||||
BaseGrammar &withTablePrefix(BaseGrammar &grammar) const override;
|
||||
|
||||
/*! Get a new query builder instance. */
|
||||
QSharedPointer<QueryBuilder> query() override;
|
||||
|
||||
// FEATURE dilemma Raw Expressions fuckup🤔 silverqx
|
||||
/*! Get a new raw query expression. */
|
||||
inline Query::Expression raw(const QVariant &value) const override
|
||||
{ return value; }
|
||||
Query::Expression raw(const QVariant &value) const override;
|
||||
|
||||
// TODO next transaction method with callback silverqx
|
||||
/*! Start a new database transaction. */
|
||||
@@ -67,8 +74,7 @@ namespace Orm
|
||||
/*! Rollback to a named transaction savepoint. */
|
||||
bool rollbackToSavepoint(size_t id) override;
|
||||
/*! Get the number of active transactions. */
|
||||
inline uint transactionLevel() const override
|
||||
{ return m_savepoints; }
|
||||
uint transactionLevel() const override;
|
||||
|
||||
/*! Run a select statement against the database. */
|
||||
QSqlQuery
|
||||
@@ -109,9 +115,8 @@ namespace Orm
|
||||
/*! Get underlying database connection without executing any reconnect logic. */
|
||||
QSqlDatabase getRawQtConnection() const;
|
||||
/*! Get the connection resolver for an underlying database connection. */
|
||||
inline const std::function<Connectors::ConnectionName()> &
|
||||
getQtConnectionResolver() const
|
||||
{ return m_qtConnectionResolver; }
|
||||
const std::function<Connectors::ConnectionName()> &
|
||||
getQtConnectionResolver() const;
|
||||
/*! Set the connection resolver for an underlying database connection. */
|
||||
DatabaseConnection &setQtConnectionResolver(
|
||||
const std::function<Connectors::ConnectionName()> &resolver);
|
||||
@@ -137,8 +142,7 @@ namespace Orm
|
||||
/*! Get the database connection name. */
|
||||
const QString &getName() const override;
|
||||
/*! Get the name of the connected database. */
|
||||
inline const QString &getDatabaseName() const override
|
||||
{ return m_database; }
|
||||
const QString &getDatabaseName() const override;
|
||||
|
||||
/*! Set the query grammar to the default implementation. */
|
||||
void useDefaultQueryGrammar() override;
|
||||
@@ -293,9 +297,8 @@ namespace Orm
|
||||
std::function<Connectors::ConnectionName()> m_qtConnectionResolver;
|
||||
/*! The name of the connected database. */
|
||||
const QString m_database;
|
||||
// FEATURE table prefix silverqx
|
||||
/*! The table prefix for the connection. */
|
||||
const QString m_tablePrefix {""};
|
||||
QString m_tablePrefix;
|
||||
/*! The database connection configuration options. */
|
||||
const QVariantHash m_config;
|
||||
/*! The reconnector instance for the connection. */
|
||||
@@ -359,6 +362,9 @@ namespace Orm
|
||||
QVariantMap
|
||||
convertPositionalToNamedBindings(const QVector<QVariant> &bindings) const;
|
||||
|
||||
/*! Get the query grammar used by the connection. */
|
||||
QueryGrammar &getQueryGrammar();
|
||||
|
||||
/*! The flag for the database was disconnected. */
|
||||
bool m_disconnectedLogged = false;
|
||||
/*! The flag for the database was connected. */
|
||||
@@ -387,11 +393,38 @@ namespace Orm
|
||||
};
|
||||
|
||||
// TODO inline functions, do it like below silverqx
|
||||
inline QString DatabaseConnection::getTablePrefix() const
|
||||
{
|
||||
return m_tablePrefix;
|
||||
}
|
||||
|
||||
inline Query::Expression
|
||||
DatabaseConnection::raw(const QVariant &value) const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
inline uint DatabaseConnection::transactionLevel() const
|
||||
{
|
||||
return m_savepoints;
|
||||
}
|
||||
|
||||
inline const std::function<Connectors::ConnectionName()> &
|
||||
DatabaseConnection::getQtConnectionResolver() const
|
||||
{
|
||||
return m_qtConnectionResolver;
|
||||
}
|
||||
|
||||
inline const QString &DatabaseConnection::getName() const
|
||||
{
|
||||
return m_connectionName;
|
||||
}
|
||||
|
||||
inline const QString &DatabaseConnection::getDatabaseName() const
|
||||
{
|
||||
return m_database;
|
||||
}
|
||||
|
||||
inline std::shared_ptr<QVector<Log>>
|
||||
DatabaseConnection::getQueryLog() const
|
||||
{
|
||||
|
||||
@@ -372,7 +372,6 @@ namespace Relations
|
||||
: m_query(query)
|
||||
, m_model(model)
|
||||
{
|
||||
// FEATURE table prefix, check for 'as'? silverqx
|
||||
m_query->from(m_model.getTable());
|
||||
}
|
||||
|
||||
|
||||
+7
-12
@@ -65,6 +65,13 @@ QVariant BaseGrammar::getValue(const Expression &expression) const
|
||||
return expression.getValue();
|
||||
}
|
||||
|
||||
BaseGrammar &BaseGrammar::setTablePrefix(const QString &prefix)
|
||||
{
|
||||
m_tablePrefix = prefix;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QString BaseGrammar::columnize(const QStringList &columns) const
|
||||
{
|
||||
return wrapArray(columns).join(", ");
|
||||
@@ -78,18 +85,6 @@ QString BaseGrammar::parameter(const QVariant &value) const
|
||||
: QStringLiteral("?");
|
||||
}
|
||||
|
||||
QString BaseGrammar::getTablePrefix() const
|
||||
{
|
||||
return m_tablePrefix;
|
||||
}
|
||||
|
||||
BaseGrammar &BaseGrammar::setTablePrefix(const QString &prefix)
|
||||
{
|
||||
m_tablePrefix = prefix;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
QString BaseGrammar::wrapAliasedValue(const QString &value, const bool prefixAlias) const
|
||||
{
|
||||
auto segments = getSegmentsFromFrom(value);
|
||||
|
||||
@@ -60,6 +60,22 @@ DatabaseConnection::table(const QString &table, const QString &as)
|
||||
return builder;
|
||||
}
|
||||
|
||||
DatabaseConnection &DatabaseConnection::setTablePrefix(const QString &prefix)
|
||||
{
|
||||
m_tablePrefix = prefix;
|
||||
|
||||
getQueryGrammar().setTablePrefix(prefix);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BaseGrammar &DatabaseConnection::withTablePrefix(BaseGrammar &grammar) const
|
||||
{
|
||||
grammar.setTablePrefix(m_tablePrefix);
|
||||
|
||||
return grammar;
|
||||
}
|
||||
|
||||
QSharedPointer<QueryBuilder> DatabaseConnection::query()
|
||||
{
|
||||
return QSharedPointer<QueryBuilder>::create(*this, *m_queryGrammar);
|
||||
@@ -979,6 +995,11 @@ DatabaseConnection::convertPositionalToNamedBindings(
|
||||
return result;
|
||||
}
|
||||
|
||||
QueryGrammar &DatabaseConnection::getQueryGrammar()
|
||||
{
|
||||
return *m_queryGrammar;
|
||||
}
|
||||
|
||||
} // namespace Orm
|
||||
#ifdef TINYORM_COMMON_NAMESPACE
|
||||
} // namespace TINYORM_COMMON_NAMESPACE
|
||||
|
||||
@@ -114,14 +114,22 @@ bool MySqlConnection::pingDatabase()
|
||||
|
||||
std::unique_ptr<QueryGrammar> MySqlConnection::getDefaultQueryGrammar() const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
return std::make_unique<Query::Grammars::MySqlGrammar>();
|
||||
// Ownership of a unique_ptr()
|
||||
auto grammar = std::make_unique<Query::Grammars::MySqlGrammar>();
|
||||
|
||||
withTablePrefix(*grammar);
|
||||
|
||||
return grammar;
|
||||
}
|
||||
|
||||
std::unique_ptr<SchemaGrammar> MySqlConnection::getDefaultSchemaGrammar() const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
return std::make_unique<Schema::Grammars::MySqlSchemaGrammar>();
|
||||
// Ownership of a unique_ptr()
|
||||
auto grammar = std::make_unique<Schema::Grammars::MySqlSchemaGrammar>();
|
||||
|
||||
withTablePrefix(*grammar);
|
||||
|
||||
return grammar;
|
||||
}
|
||||
|
||||
std::unique_ptr<QueryProcessor> MySqlConnection::getDefaultPostProcessor() const
|
||||
|
||||
@@ -11,11 +11,10 @@ namespace Orm::Schema
|
||||
|
||||
QStringList MySqlSchemaBuilder::getColumnListing(const QString &table) const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
// const auto table_ = m_connection.getTablePrefix() + table;
|
||||
const QString table_ = m_connection.getTablePrefix() + table;
|
||||
|
||||
auto query = m_connection.select(m_grammar.compileColumnListing(), {
|
||||
m_connection.getDatabaseName(), table
|
||||
m_connection.getDatabaseName(), table_
|
||||
});
|
||||
|
||||
return m_connection.getPostProcessor().processColumnListing(query);
|
||||
|
||||
@@ -16,8 +16,8 @@ SchemaBuilder::SchemaBuilder(DatabaseConnection &connection)
|
||||
|
||||
QStringList SchemaBuilder::getColumnListing(const QString &table) const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
auto query = m_connection.selectFromWriteConnection(
|
||||
m_connection.getTablePrefix() +
|
||||
m_grammar.compileColumnListing(table));
|
||||
|
||||
return m_connection.getPostProcessor().processColumnListing(query);
|
||||
|
||||
@@ -37,14 +37,22 @@ std::unique_ptr<SchemaBuilder> SQLiteConnection::getSchemaBuilder()
|
||||
|
||||
std::unique_ptr<QueryGrammar> SQLiteConnection::getDefaultQueryGrammar() const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
return std::make_unique<Query::Grammars::SQLiteGrammar>();
|
||||
// Ownership of a unique_ptr()
|
||||
auto grammar = std::make_unique<Query::Grammars::SQLiteGrammar>();
|
||||
|
||||
withTablePrefix(*grammar);
|
||||
|
||||
return grammar;
|
||||
}
|
||||
|
||||
std::unique_ptr<SchemaGrammar> SQLiteConnection::getDefaultSchemaGrammar() const
|
||||
{
|
||||
// FEATURE table prefix silverqx
|
||||
return std::make_unique<Schema::Grammars::SQLiteSchemaGrammar>();
|
||||
// Ownership of a unique_ptr()
|
||||
auto grammar = std::make_unique<Schema::Grammars::SQLiteSchemaGrammar>();
|
||||
|
||||
withTablePrefix(*grammar);
|
||||
|
||||
return grammar;
|
||||
}
|
||||
|
||||
std::unique_ptr<QueryProcessor> SQLiteConnection::getDefaultPostProcessor() const
|
||||
|
||||
@@ -18,6 +18,8 @@ private slots:
|
||||
|
||||
void from() const;
|
||||
void from_TableWrappingQuotationMarks() const;
|
||||
void from_WithPrefix() const;
|
||||
void from_AliasWithPrefix() const;
|
||||
|
||||
void select() const;
|
||||
void addSelect() const;
|
||||
@@ -160,6 +162,54 @@ void tst_MySql_QueryBuilder::from_TableWrappingQuotationMarks() const
|
||||
}
|
||||
}
|
||||
|
||||
void tst_MySql_QueryBuilder::from_WithPrefix() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
const auto prefix = QStringLiteral("xyz_");
|
||||
const auto table = QStringLiteral("table");
|
||||
builder->from(table);
|
||||
|
||||
builder->getConnection().setTablePrefix(prefix);
|
||||
|
||||
QCOMPARE(builder->getFrom(), table);
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from `xyz_table`");
|
||||
|
||||
// Restore
|
||||
builder->getConnection().setTablePrefix("");
|
||||
}
|
||||
|
||||
void tst_MySql_QueryBuilder::from_AliasWithPrefix() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
const auto prefix = QStringLiteral("xyz_");
|
||||
builder->getConnection().setTablePrefix(prefix);
|
||||
|
||||
{
|
||||
const auto table = QStringLiteral("table");
|
||||
const auto alias = QStringLiteral("alias");
|
||||
builder->from(table, alias);
|
||||
|
||||
QCOMPARE(builder->getFrom(), QStringLiteral("%1 as %2").arg(table, alias));
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from `xyz_table` as `xyz_alias`");
|
||||
}
|
||||
|
||||
{
|
||||
const auto table = QStringLiteral("table as alias");
|
||||
builder->from(table);
|
||||
|
||||
QCOMPARE(builder->getFrom(), table);
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from `xyz_table` as `xyz_alias`");
|
||||
}
|
||||
|
||||
// Restore
|
||||
builder->getConnection().setTablePrefix("");
|
||||
}
|
||||
|
||||
void tst_MySql_QueryBuilder::select() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
@@ -18,6 +18,8 @@ private slots:
|
||||
|
||||
void from() const;
|
||||
void from_TableWrappingQuotationMarks() const;
|
||||
void from_WithPrefix() const;
|
||||
void from_AliasWithPrefix() const;
|
||||
|
||||
void select() const;
|
||||
void addSelect() const;
|
||||
@@ -141,6 +143,54 @@ void tst_SQLite_QueryBuilder::from_TableWrappingQuotationMarks() const
|
||||
}
|
||||
}
|
||||
|
||||
void tst_SQLite_QueryBuilder::from_WithPrefix() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
const auto prefix = QStringLiteral("xyz_");
|
||||
const auto table = QStringLiteral("table");
|
||||
builder->from(table);
|
||||
|
||||
builder->getConnection().setTablePrefix(prefix);
|
||||
|
||||
QCOMPARE(builder->getFrom(), table);
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from \"xyz_table\"");
|
||||
|
||||
// Restore
|
||||
builder->getConnection().setTablePrefix("");
|
||||
}
|
||||
|
||||
void tst_SQLite_QueryBuilder::from_AliasWithPrefix() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
const auto prefix = QStringLiteral("xyz_");
|
||||
builder->getConnection().setTablePrefix(prefix);
|
||||
|
||||
{
|
||||
const auto table = QStringLiteral("table");
|
||||
const auto alias = QStringLiteral("alias");
|
||||
builder->from(table, alias);
|
||||
|
||||
QCOMPARE(builder->getFrom(), QStringLiteral("%1 as %2").arg(table, alias));
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from \"xyz_table\" as \"xyz_alias\"");
|
||||
}
|
||||
|
||||
{
|
||||
const auto table = QStringLiteral("table as alias");
|
||||
builder->from(table);
|
||||
|
||||
QCOMPARE(builder->getFrom(), table);
|
||||
QCOMPARE(builder->toSql(),
|
||||
"select * from \"xyz_table\" as \"xyz_alias\"");
|
||||
}
|
||||
|
||||
// Restore
|
||||
builder->getConnection().setTablePrefix("");
|
||||
}
|
||||
|
||||
void tst_SQLite_QueryBuilder::select() const
|
||||
{
|
||||
auto builder = createQuery(m_connection);
|
||||
|
||||
Reference in New Issue
Block a user