SQL/Tests: Cleanup of tst_databases.h

Cleanup tst_databases.h: fix identation, replace qGetHostName() with
QSysInfo::machineHostName(), use QSqlTableModel::EditStrategy instead
int for submitpolicy data to avoid casts.

Change-Id: I4917ca23c4b39ab15bc0e006e6111baefb82d278
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Christian Ehrlicher 2023-03-12 21:10:30 +01:00
parent 17e4b2d8ed
commit d184c66ad5
2 changed files with 84 additions and 124 deletions

View File

@ -19,6 +19,7 @@
#include <QJsonArray> #include <QJsonArray>
#include <QJsonObject> #include <QJsonObject>
#include <QJsonDocument> #include <QJsonDocument>
#include <QSysInfo>
#include <QtSql/private/qsqldriver_p.h> #include <QtSql/private/qsqldriver_p.h>
#include <QTest> #include <QTest>
@ -31,39 +32,20 @@
#define DBMS_SPECIFIC(db, driver) \ #define DBMS_SPECIFIC(db, driver) \
if (!db.driverName().startsWith(driver)) { QSKIP(driver " specific test"); } if (!db.driverName().startsWith(driver)) { QSKIP(driver " specific test"); }
// ### use QSystem::hostName if it is integrated in qtest/main
static QString qGetHostName()
{
static QString hostname;
if (hostname.isEmpty()) {
hostname = QSysInfo::machineHostName();
hostname.replace(QLatin1Char( '.' ), QLatin1Char( '_' ));
hostname.replace(QLatin1Char( '-' ), QLatin1Char( '_' ));
}
return hostname;
}
inline QString fixupTableName(const QString &tableName, const QSqlDatabase &db)
{
QString tbName = tableName;
// Oracle & Interbase/Firebird have a limit on the tablename length
QSqlDriver *drv = db.driver();
if (drv)
tbName.truncate(drv->maximumIdentifierLength(QSqlDriver::TableName));
return tbName;
}
// to prevent nameclashes on our database server, each machine // to prevent nameclashes on our database server, each machine
// will use its own set of table names. Call this function to get // will use its own set of table names. Call this function to get
// "tablename_hostname" // "tablename_hostname"
inline static QString qTableName(const QString &prefix, const char *sourceFileName, inline static QString qTableName(const QString &prefix, const char *sourceFileName,
QSqlDatabase db, bool escape = true) QSqlDatabase db, bool escape = true)
{ {
const auto tableStr = fixupTableName(QString(QLatin1String("dbtst") + db.driverName() + "_" + const auto hash = qHash(QLatin1String(sourceFileName) + '_' +
prefix + QString::number(qHash(QLatin1String(sourceFileName) + QSysInfo::machineHostName().replace('-', '_'));
"_" + qGetHostName().replace("-", "_")), 16)), db); auto tableStr = QLatin1String("dbtst") + db.driverName() + '_' + prefix +
QString::number(hash, 16);
// Oracle & Interbase/Firebird have a limit on the tablename length
QSqlDriver *drv = db.driver();
if (drv)
tableStr.truncate(drv->maximumIdentifierLength(QSqlDriver::TableName));
return escape ? db.driver()->escapeIdentifier(tableStr, QSqlDriver::TableName) : tableStr; return escape ? db.driver()->escapeIdentifier(tableStr, QSqlDriver::TableName) : tableStr;
} }
@ -77,67 +59,60 @@ public:
// returns a testtable consisting of the names of all database connections if // returns a testtable consisting of the names of all database connections if
// driverPrefix is empty, otherwise only those that start with driverPrefix. // driverPrefix is empty, otherwise only those that start with driverPrefix.
int fillTestTable( const QString& driverPrefix = QString() ) const int fillTestTable(const QString &driverPrefix = QString()) const
{ {
QTest::addColumn<QString>( "dbName" ); QTest::addColumn<QString>("dbName");
int count = 0; int count = 0;
for ( int i = 0; i < dbNames.size(); ++i ) { for (const auto &dbName : std::as_const(dbNames)) {
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) ); QSqlDatabase db = QSqlDatabase::database(dbName);
if (!db.isValid())
if ( !db.isValid() )
continue; continue;
if (driverPrefix.isEmpty() || db.driverName().startsWith(driverPrefix)) {
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) { QTest::newRow(dbName.toLatin1()) << dbName;
QTest::newRow( dbNames.at( i ).toLatin1() ) << dbNames.at( i );
++count; ++count;
} }
} }
return count; return count;
} }
int fillTestTableWithStrategies( const QString& driverPrefix = QString() ) const int fillTestTableWithStrategies(const QString &driverPrefix = QString()) const
{ {
QTest::addColumn<QString>( "dbName" ); QTest::addColumn<QString>("dbName");
QTest::addColumn<int>("submitpolicy_i"); QTest::addColumn<QSqlTableModel::EditStrategy>("submitpolicy");
int count = 0; int count = 0;
for ( int i = 0; i < dbNames.size(); ++i ) { for (const auto &dbName : std::as_const(dbNames)) {
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) ); QSqlDatabase db = QSqlDatabase::database(dbName);
if (!db.isValid())
if ( !db.isValid() )
continue; continue;
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) { if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
QTest::newRow( QString("%1 [field]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnFieldChange; QTest::newRow(QString("%1 [field]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnFieldChange;
QTest::newRow( QString("%1 [row]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnRowChange; QTest::newRow(QString("%1 [row]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnRowChange;
QTest::newRow( QString("%1 [manual]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnManualSubmit; QTest::newRow(QString("%1 [manual]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnManualSubmit;
++count; ++count;
} }
} }
return count; return count;
} }
void addDb( const QString& driver, const QString& dbName, void addDb(const QString &driver, const QString &dbName,
const QString& user = QString(), const QString& passwd = QString(), const QString &user = QString(), const QString &passwd = QString(),
const QString& host = QString(), int port = -1, const QString params = QString() ) const QString &host = QString(), int port = -1, const QString &params = QString())
{ {
QSqlDatabase db; if (!QSqlDatabase::drivers().contains(driver)) {
if ( !QSqlDatabase::drivers().contains( driver ) ) {
qWarning() << "Driver" << driver << "is not installed"; qWarning() << "Driver" << driver << "is not installed";
return; return;
} }
// construct a stupid unique name // construct a stupid unique name
QString cName = QString::number( counter++ ) + QLatin1Char('_') + driver + QLatin1Char('@'); QString cName = QString::number(counter++) + QLatin1Char('_') + driver + QLatin1Char('@');
cName += host.isEmpty() ? dbName : host; cName += host.isEmpty() ? dbName : host;
if ( port > 0 ) if (port > 0)
cName += QLatin1Char(':') + QString::number( port ); cName += QLatin1Char(':') + QString::number(port);
if (driver == "QSQLITE") { if (driver == "QSQLITE") {
// Since the database for sqlite is generated at runtime it's always // Since the database for sqlite is generated at runtime it's always
@ -147,21 +122,19 @@ public:
qInfo("SQLite will use the database located at %ls", qUtf16Printable(dbName)); qInfo("SQLite will use the database located at %ls", qUtf16Printable(dbName));
} }
db = QSqlDatabase::addDatabase( driver, cName ); auto db = QSqlDatabase::addDatabase(driver, cName);
if (!db.isValid()) {
if ( !db.isValid() ) {
qWarning( "Could not create database object" ); qWarning( "Could not create database object" );
return; return;
} }
db.setDatabaseName( dbName ); db.setDatabaseName(dbName);
db.setUserName(user);
db.setUserName( user ); db.setPassword(passwd);
db.setPassword( passwd ); db.setHostName(host);
db.setHostName( host ); db.setPort(port);
db.setPort( port ); db.setConnectOptions(params);
db.setConnectOptions( params ); dbNames.append(cName);
dbNames.append( cName );
} }
bool addDbs() bool addDbs()
@ -196,10 +169,9 @@ public:
qWarning() << "No entries in " + f.fileName(); qWarning() << "No entries in " + f.fileName();
} else { } else {
const QJsonArray entriesA = entriesV.toArray(); const QJsonArray entriesA = entriesV.toArray();
QJsonArray::const_iterator it = entriesA.constBegin(); for (const auto &elem : entriesA) {
while (it != entriesA.constEnd()) { if (elem.isObject()) {
if ((*it).isObject()) { const QJsonObject object = elem.toObject();
const QJsonObject object = (*it).toObject();
addDb(object.value(QStringLiteral("driver")).toString(), addDb(object.value(QStringLiteral("driver")).toString(),
object.value(QStringLiteral("name")).toString(), object.value(QStringLiteral("name")).toString(),
object.value(QStringLiteral("username")).toString(), object.value(QStringLiteral("username")).toString(),
@ -209,7 +181,6 @@ public:
object.value(QStringLiteral("parameters")).toString()); object.value(QStringLiteral("parameters")).toString());
added = true; added = true;
} }
++it;
} }
} }
} }
@ -227,17 +198,18 @@ public:
if (!addDbs()) if (!addDbs())
return false; return false;
QStringList::Iterator it = dbNames.begin(); auto it = dbNames.begin();
while (it != dbNames.end()) {
const auto &dbName = *it;
QSqlDatabase db = QSqlDatabase::database(dbName, false );
qDebug() << "Opening:" << dbName;
while ( it != dbNames.end() ) { if (db.isValid() && !db.isOpen()) {
QSqlDatabase db = QSqlDatabase::database(( *it ), false ); if (!db.open()) {
qDebug() << "Opening:" << (*it); qWarning("tst_Databases: Unable to open %s on %s:\n%s", qPrintable(db.driverName()),
qPrintable(dbName), qPrintable(db.lastError().databaseText()));
if ( db.isValid() && !db.isOpen() ) {
if ( !db.open() ) {
qWarning( "tst_Databases: Unable to open %s on %s:\n%s", qPrintable( db.driverName() ), qPrintable( *it ), qPrintable( db.lastError().databaseText() ) );
// well... opening failed, so we just ignore the server, maybe it is not running // well... opening failed, so we just ignore the server, maybe it is not running
it = dbNames.erase( it ); it = dbNames.erase(it);
} else { } else {
++it; ++it;
} }
@ -248,40 +220,35 @@ public:
void close() void close()
{ {
for ( QStringList::Iterator it = dbNames.begin(); it != dbNames.end(); ++it ) { for (const auto &dbName : std::as_const(dbNames)) {
{ {
QSqlDatabase db = QSqlDatabase::database(( *it ), false ); QSqlDatabase db = QSqlDatabase::database(dbName, false);
if (db.isValid() && db.isOpen())
if ( db.isValid() && db.isOpen() )
db.close(); db.close();
} }
QSqlDatabase::removeDatabase(dbName);
QSqlDatabase::removeDatabase(( *it ) );
} }
dbNames.clear(); dbNames.clear();
} }
// for debugging only: outputs the connection as string // for debugging only: outputs the connection as string
static QString dbToString( const QSqlDatabase db ) static QString dbToString(const QSqlDatabase &db)
{ {
QString res = db.driverName() + QLatin1Char('@'); QString res = db.driverName() + QLatin1Char('@');
if ( db.driverName().startsWith( "QODBC" ) || db.driverName().startsWith( "QOCI" ) ) { if (db.driverName().startsWith("QODBC") || db.driverName().startsWith("QOCI"))
res += db.databaseName(); res += db.databaseName();
} else { else
res += db.hostName(); res += db.hostName();
}
if ( db.port() > 0 ) { if (db.port() > 0)
res += QLatin1Char(':') + QString::number( db.port() ); res += QLatin1Char(':') + QString::number(db.port());
}
return res; return res;
} }
// drop a table only if it exists to prevent warnings // drop a table only if it exists to prevent warnings
static void safeDropTables(QSqlDatabase db, const QStringList &tableNames) static void safeDropTables(const QSqlDatabase &db, const QStringList &tableNames)
{ {
QSqlQuery q(db); QSqlQuery q(db);
QStringList dbtables = db.tables(); QStringList dbtables = db.tables();
@ -314,7 +281,7 @@ public:
} }
} }
static void safeDropViews(QSqlDatabase db, const QStringList &viewNames) static void safeDropViews(const QSqlDatabase &db, const QStringList &viewNames)
{ {
if (isMSAccess(db)) // Access is sooo stupid. if (isMSAccess(db)) // Access is sooo stupid.
safeDropTables(db, viewNames); safeDropTables(db, viewNames);
@ -348,7 +315,7 @@ public:
// returns the type name of the blob datatype for the database db. // returns the type name of the blob datatype for the database db.
// blobSize is only used if the db doesn't have a generic blob type // blobSize is only used if the db doesn't have a generic blob type
static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 ) static QString blobTypeName(const QSqlDatabase &db, int blobSize = 10000)
{ {
const QSqlDriver::DbmsType dbType = getDatabaseType(db); const QSqlDriver::DbmsType dbType = getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer) if (dbType == QSqlDriver::MySqlServer)
@ -377,7 +344,7 @@ public:
return "blob"; return "blob";
} }
static QString dateTimeTypeName(QSqlDatabase db) static QString dateTimeTypeName(const QSqlDatabase &db)
{ {
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::PostgreSQL) if (dbType == QSqlDriver::PostgreSQL)
@ -389,7 +356,7 @@ public:
return QLatin1String("datetime"); return QLatin1String("datetime");
} }
static QString timeTypeName(QSqlDatabase db) static QString timeTypeName(const QSqlDatabase &db)
{ {
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9) if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
@ -397,7 +364,7 @@ public:
return QLatin1String("time"); return QLatin1String("time");
} }
static QString dateTypeName(QSqlDatabase db) static QString dateTypeName(const QSqlDatabase &db)
{ {
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9) if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
@ -405,7 +372,7 @@ public:
return QLatin1String("date"); return QLatin1String("date");
} }
static QString autoFieldName( QSqlDatabase db ) static QString autoFieldName(const QSqlDatabase &db)
{ {
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db); const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
if (dbType == QSqlDriver::MySqlServer) if (dbType == QSqlDriver::MySqlServer)
@ -437,18 +404,18 @@ public:
return dbToString(db).toLocal8Bit() + ": " + printError(err); return dbToString(db).toLocal8Bit() + ": " + printError(err);
} }
static QSqlDriver::DbmsType getDatabaseType(QSqlDatabase db) static QSqlDriver::DbmsType getDatabaseType(const QSqlDatabase &db)
{ {
return db.driver()->dbmsType(); return db.driver()->dbmsType();
} }
static bool isMSAccess( QSqlDatabase db ) static bool isMSAccess(const QSqlDatabase &db)
{ {
return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive ); return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive );
} }
// -1 on fail, else Oracle version // -1 on fail, else Oracle version
static int getOraVersion( QSqlDatabase db ) static int getOraVersion(const QSqlDatabase &db)
{ {
int ver = -1; int ver = -1;
QSqlQuery q( "SELECT banner FROM v$version", db ); QSqlQuery q( "SELECT banner FROM v$version", db );

View File

@ -425,8 +425,7 @@ void tst_QSqlTableModel::insertColumns()
{ {
// Just like the select test, with extra stuff // Just like the select test, with extra stuff
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db); const auto test = qTableName("test1", __FILE__, db);
@ -582,7 +581,7 @@ void tst_QSqlTableModel::setRecord()
for (QSqlTableModel::EditStrategy submitpolicy : policies) { for (QSqlTableModel::EditStrategy submitpolicy : policies) {
QSqlTableModel model(0, db); QSqlTableModel model(0, db);
model.setEditStrategy((QSqlTableModel::EditStrategy)submitpolicy); model.setEditStrategy(submitpolicy);
model.setTable(test3); model.setTable(test3);
model.setSort(0, Qt::AscendingOrder); model.setSort(0, Qt::AscendingOrder);
QVERIFY_SQL(model, select()); QVERIFY_SQL(model, select());
@ -596,7 +595,7 @@ void tst_QSqlTableModel::setRecord()
QVERIFY(model.setRecord(i, rec)); QVERIFY(model.setRecord(i, rec));
// dataChanged() emitted by setData() for each *changed* column // dataChanged() emitted by setData() for each *changed* column
if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnManualSubmit) { if (submitpolicy == QSqlTableModel::OnManualSubmit) {
QCOMPARE(spy.size(), 2); QCOMPARE(spy.size(), 2);
QCOMPARE(spy.at(0).size(), 2); QCOMPARE(spy.at(0).size(), 2);
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(0)), model.index(i, 1)); QCOMPARE(qvariant_cast<QModelIndex>(spy.at(0).at(0)), model.index(i, 1));
@ -604,10 +603,10 @@ void tst_QSqlTableModel::setRecord()
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(0)), model.index(i, 2)); QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(0)), model.index(i, 2));
QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(1)), model.index(i, 2)); QCOMPARE(qvariant_cast<QModelIndex>(spy.at(1).at(1)), model.index(i, 2));
QVERIFY(model.submitAll()); QVERIFY(model.submitAll());
} else if ((QSqlTableModel::EditStrategy)submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1) } else if (submitpolicy == QSqlTableModel::OnRowChange && i == model.rowCount() -1)
model.submit(); model.submit();
else { else {
if ((QSqlTableModel::EditStrategy)submitpolicy != QSqlTableModel::OnManualSubmit) if (submitpolicy != QSqlTableModel::OnManualSubmit)
// dataChanged() also emitted by selectRow() // dataChanged() also emitted by selectRow()
QCOMPARE(spy.size(), 3); QCOMPARE(spy.size(), 3);
else else
@ -709,8 +708,7 @@ void tst_QSqlTableModel::recordReimpl()
void tst_QSqlTableModel::insertRow() void tst_QSqlTableModel::insertRow()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db); const auto test = qTableName("test1", __FILE__, db);
@ -819,8 +817,7 @@ void tst_QSqlTableModel::insertRowFailure()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
CHECK_DATABASE(db); CHECK_DATABASE(db);
QSqlTableModel model(0, db); QSqlTableModel model(0, db);
@ -969,8 +966,7 @@ void tst_QSqlTableModel::insertMultiRecords()
void tst_QSqlTableModel::insertWithAutoColumn() void tst_QSqlTableModel::insertWithAutoColumn()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
@ -1192,8 +1188,7 @@ void tst_QSqlTableModel::removeRows()
void tst_QSqlTableModel::removeInsertedRow() void tst_QSqlTableModel::removeInsertedRow()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db); const auto test = qTableName("test1", __FILE__, db);
@ -1377,8 +1372,7 @@ void tst_QSqlTableModel::removeInsertedRows()
void tst_QSqlTableModel::revert() void tst_QSqlTableModel::revert()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
@ -1454,8 +1448,7 @@ void tst_QSqlTableModel::revert()
void tst_QSqlTableModel::isDirty() void tst_QSqlTableModel::isDirty()
{ {
QFETCH(QString, dbName); QFETCH(QString, dbName);
QFETCH(int, submitpolicy_i); QFETCH(QSqlTableModel::EditStrategy, submitpolicy);
QSqlTableModel::EditStrategy submitpolicy = (QSqlTableModel::EditStrategy) submitpolicy_i;
QSqlDatabase db = QSqlDatabase::database(dbName); QSqlDatabase db = QSqlDatabase::database(dbName);
CHECK_DATABASE(db); CHECK_DATABASE(db);
const auto test = qTableName("test1", __FILE__, db); const auto test = qTableName("test1", __FILE__, db);