mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-02 23:35:28 +08:00
qt 6.6.0 clean
This commit is contained in:
@ -5,6 +5,7 @@ add_subdirectory(qsqlfield)
|
||||
add_subdirectory(qsqldatabase)
|
||||
add_subdirectory(qsqlerror)
|
||||
add_subdirectory(qsqldriver)
|
||||
add_subdirectory(qsqlindex)
|
||||
add_subdirectory(qsqlquery)
|
||||
add_subdirectory(qsqlrecord)
|
||||
add_subdirectory(qsqlthread)
|
||||
|
@ -19,11 +19,6 @@ class tst_QSql : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QSql();
|
||||
virtual ~tst_QSql();
|
||||
|
||||
|
||||
public slots:
|
||||
void initTestCase();
|
||||
void cleanupTestCase();
|
||||
@ -41,15 +36,6 @@ private slots:
|
||||
};
|
||||
|
||||
/****************** General Qt SQL Module tests *****************/
|
||||
|
||||
tst_QSql::tst_QSql()
|
||||
{
|
||||
}
|
||||
|
||||
tst_QSql::~tst_QSql()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QSql::initTestCase()
|
||||
{
|
||||
}
|
||||
@ -80,7 +66,7 @@ void tst_QSql::basicDriverTest()
|
||||
tst_Databases dbs;
|
||||
QVERIFY(dbs.open());
|
||||
|
||||
foreach (const QString& dbName, dbs.dbNames) {
|
||||
for (const QString &dbName : std::as_const(dbs.dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
QVERIFY_SQL(db, isValid());
|
||||
|
||||
@ -154,7 +140,7 @@ void tst_QSql::concurrentAccess()
|
||||
tst_Databases dbs;
|
||||
|
||||
QVERIFY(dbs.open());
|
||||
foreach (const QString& dbName, dbs.dbNames) {
|
||||
for (const QString &dbName : std::as_const(dbs.dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
QVERIFY(db.isValid());
|
||||
if (tst_Databases::isMSAccess(db))
|
||||
@ -186,7 +172,7 @@ void tst_QSql::openErrorRecovery()
|
||||
QVERIFY(dbs.addDbs());
|
||||
if (dbs.dbNames.isEmpty())
|
||||
QSKIP("No database drivers installed");
|
||||
foreach (const QString& dbName, dbs.dbNames) {
|
||||
for (const QString &dbName : std::as_const(dbs.dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName, false);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <QSqlDriver>
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlRecord>
|
||||
#include <QRegularExpression>
|
||||
#include <QRegularExpressionMatch>
|
||||
#include <QDir>
|
||||
@ -19,9 +20,13 @@
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonDocument>
|
||||
#include <QSysInfo>
|
||||
#include <QVersionNumber>
|
||||
#include <QtSql/private/qsqldriver_p.h>
|
||||
#include <QTest>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
#define CHECK_DATABASE( db ) \
|
||||
if ( !db.isValid() ) { qFatal( "db is Invalid" ); }
|
||||
|
||||
@ -31,88 +36,26 @@
|
||||
#define DBMS_SPECIFIC(db, driver) \
|
||||
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, QSqlDatabase db)
|
||||
{
|
||||
QString tbName = tableName;
|
||||
// On Oracle we are limited to 30 character tablenames
|
||||
QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
|
||||
if (d && d->dbmsType == QSqlDriver::Oracle)
|
||||
tbName.truncate(30);
|
||||
// On Interbase we are limited to 31 character tablenames
|
||||
if (d && d->dbmsType == QSqlDriver::Interbase)
|
||||
tbName.truncate(31);
|
||||
return tbName;
|
||||
}
|
||||
|
||||
// to prevent nameclashes on our database server, each machine
|
||||
// will use its own set of table names. Call this function to get
|
||||
// "tablename_hostname"
|
||||
inline static QString qTableName(const QString &prefix, const char *sourceFileName,
|
||||
QSqlDatabase db, bool escape = true)
|
||||
{
|
||||
const auto tableStr = fixupTableName(QString(QLatin1String("dbtst") + db.driverName() + "_" +
|
||||
prefix + QString::number(qHash(QLatin1String(sourceFileName) +
|
||||
"_" + qGetHostName().replace("-", "_")), 16)), db);
|
||||
const auto hash = qHash(QLatin1String(sourceFileName) + '_' +
|
||||
QSysInfo::machineHostName().replace('-', '_'));
|
||||
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;
|
||||
}
|
||||
|
||||
inline static QString qTableName(const QString& prefix, QSqlDatabase db)
|
||||
{
|
||||
QString tableStr;
|
||||
if (db.driverName().toLower().contains("ODBC"))
|
||||
tableStr += QLatin1String("_odbc");
|
||||
return fixupTableName(QString(db.driver()->escapeIdentifier(prefix + tableStr + QLatin1Char('_') +
|
||||
qGetHostName(), QSqlDriver::TableName)),db);
|
||||
}
|
||||
|
||||
inline static bool testWhiteSpaceNames( const QString &name )
|
||||
{
|
||||
/* return name.startsWith( "QPSQL" )
|
||||
|| name.startsWith( "QODBC" )
|
||||
|| name.startsWith( "QSQLITE" )
|
||||
|| name.startsWith( "QMYSQL" );*/
|
||||
return name != QLatin1String("QSQLITE2");
|
||||
}
|
||||
|
||||
inline static QString toHex( const QString& binary )
|
||||
{
|
||||
QString str;
|
||||
static char const hexchars[] = "0123456789ABCDEF";
|
||||
|
||||
for ( int i = 0; i < binary.size(); i++ ) {
|
||||
ushort code = binary.at(i).unicode();
|
||||
str += (QChar)(hexchars[ (code >> 12) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ (code >> 8) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ (code >> 4) & 0x0F ]);
|
||||
str += (QChar)(hexchars[ code & 0x0F ]);
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
class tst_Databases
|
||||
{
|
||||
|
||||
public:
|
||||
tst_Databases(): counter( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
~tst_Databases()
|
||||
{
|
||||
close();
|
||||
@ -120,67 +63,60 @@ public:
|
||||
|
||||
// returns a testtable consisting of the names of all database connections if
|
||||
// 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;
|
||||
|
||||
for ( int i = 0; i < dbNames.size(); ++i ) {
|
||||
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
|
||||
|
||||
if ( !db.isValid() )
|
||||
for (const auto &dbName : std::as_const(dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
if (!db.isValid())
|
||||
continue;
|
||||
|
||||
if ( driverPrefix.isEmpty() || db.driverName().startsWith( driverPrefix ) ) {
|
||||
QTest::newRow( dbNames.at( i ).toLatin1() ) << dbNames.at( i );
|
||||
if (driverPrefix.isEmpty() || db.driverName().startsWith(driverPrefix)) {
|
||||
QTest::newRow(dbName.toLatin1()) << dbName;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
int fillTestTableWithStrategies( const QString& driverPrefix = QString() ) const
|
||||
int fillTestTableWithStrategies(const QString &driverPrefix = QString()) const
|
||||
{
|
||||
QTest::addColumn<QString>( "dbName" );
|
||||
QTest::addColumn<int>("submitpolicy_i");
|
||||
QTest::addColumn<QString>("dbName");
|
||||
QTest::addColumn<QSqlTableModel::EditStrategy>("submitpolicy");
|
||||
int count = 0;
|
||||
|
||||
for ( int i = 0; i < dbNames.size(); ++i ) {
|
||||
QSqlDatabase db = QSqlDatabase::database( dbNames.at( i ) );
|
||||
|
||||
if ( !db.isValid() )
|
||||
for (const auto &dbName : std::as_const(dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
if (!db.isValid())
|
||||
continue;
|
||||
|
||||
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 [row]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnRowChange;
|
||||
QTest::newRow( QString("%1 [manual]").arg(dbNames.at( i )).toLatin1() ) << dbNames.at( i ) << (int)QSqlTableModel::OnManualSubmit;
|
||||
QTest::newRow(QString("%1 [field]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnFieldChange;
|
||||
QTest::newRow(QString("%1 [row]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnRowChange;
|
||||
QTest::newRow(QString("%1 [manual]").arg(dbName).toLatin1() ) << dbName << QSqlTableModel::OnManualSubmit;
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
void addDb( const QString& driver, const QString& dbName,
|
||||
const QString& user = QString(), const QString& passwd = QString(),
|
||||
const QString& host = QString(), int port = -1, const QString params = QString() )
|
||||
void addDb(const QString &driver, const QString &dbName,
|
||||
const QString &user = QString(), const QString &passwd = QString(),
|
||||
const QString &host = QString(), int port = -1, const QString ¶ms = QString())
|
||||
{
|
||||
QSqlDatabase db;
|
||||
|
||||
if ( !QSqlDatabase::drivers().contains( driver ) ) {
|
||||
if (!QSqlDatabase::drivers().contains(driver)) {
|
||||
qWarning() << "Driver" << driver << "is not installed";
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
if ( port > 0 )
|
||||
cName += QLatin1Char(':') + QString::number( port );
|
||||
if (port > 0)
|
||||
cName += QLatin1Char(':') + QString::number(port);
|
||||
|
||||
if (driver == "QSQLITE") {
|
||||
// Since the database for sqlite is generated at runtime it's always
|
||||
@ -190,21 +126,19 @@ public:
|
||||
qInfo("SQLite will use the database located at %ls", qUtf16Printable(dbName));
|
||||
}
|
||||
|
||||
db = QSqlDatabase::addDatabase( driver, cName );
|
||||
|
||||
if ( !db.isValid() ) {
|
||||
auto db = QSqlDatabase::addDatabase(driver, cName);
|
||||
if (!db.isValid()) {
|
||||
qWarning( "Could not create database object" );
|
||||
return;
|
||||
}
|
||||
|
||||
db.setDatabaseName( dbName );
|
||||
|
||||
db.setUserName( user );
|
||||
db.setPassword( passwd );
|
||||
db.setHostName( host );
|
||||
db.setPort( port );
|
||||
db.setConnectOptions( params );
|
||||
dbNames.append( cName );
|
||||
db.setDatabaseName(dbName);
|
||||
db.setUserName(user);
|
||||
db.setPassword(passwd);
|
||||
db.setHostName(host);
|
||||
db.setPort(port);
|
||||
db.setConnectOptions(params);
|
||||
dbNames.append(cName);
|
||||
}
|
||||
|
||||
bool addDbs()
|
||||
@ -239,10 +173,9 @@ public:
|
||||
qWarning() << "No entries in " + f.fileName();
|
||||
} else {
|
||||
const QJsonArray entriesA = entriesV.toArray();
|
||||
QJsonArray::const_iterator it = entriesA.constBegin();
|
||||
while (it != entriesA.constEnd()) {
|
||||
if ((*it).isObject()) {
|
||||
const QJsonObject object = (*it).toObject();
|
||||
for (const auto &elem : entriesA) {
|
||||
if (elem.isObject()) {
|
||||
const QJsonObject object = elem.toObject();
|
||||
addDb(object.value(QStringLiteral("driver")).toString(),
|
||||
object.value(QStringLiteral("name")).toString(),
|
||||
object.value(QStringLiteral("username")).toString(),
|
||||
@ -252,7 +185,6 @@ public:
|
||||
object.value(QStringLiteral("parameters")).toString());
|
||||
added = true;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -270,17 +202,18 @@ public:
|
||||
if (!addDbs())
|
||||
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() ) {
|
||||
QSqlDatabase db = QSqlDatabase::database(( *it ), false );
|
||||
qDebug() << "Opening:" << (*it);
|
||||
|
||||
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() ) );
|
||||
if (db.isValid() && !db.isOpen()) {
|
||||
if (!db.open()) {
|
||||
qWarning("tst_Databases: Unable to open %s on %s:\n%s", qPrintable(db.driverName()),
|
||||
qPrintable(dbName), qPrintable(db.lastError().databaseText()));
|
||||
// well... opening failed, so we just ignore the server, maybe it is not running
|
||||
it = dbNames.erase( it );
|
||||
it = dbNames.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@ -291,57 +224,51 @@ public:
|
||||
|
||||
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 );
|
||||
|
||||
if ( db.isValid() && db.isOpen() )
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName, false);
|
||||
if (db.isValid() && db.isOpen())
|
||||
db.close();
|
||||
}
|
||||
|
||||
QSqlDatabase::removeDatabase(( *it ) );
|
||||
QSqlDatabase::removeDatabase(dbName);
|
||||
}
|
||||
|
||||
dbNames.clear();
|
||||
}
|
||||
|
||||
// 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('@');
|
||||
|
||||
if ( db.driverName().startsWith( "QODBC" ) || db.driverName().startsWith( "QOCI" ) ) {
|
||||
if (db.driverName().startsWith("QODBC") || db.driverName().startsWith("QOCI"))
|
||||
res += db.databaseName();
|
||||
} else {
|
||||
else
|
||||
res += db.hostName();
|
||||
}
|
||||
|
||||
if ( db.port() > 0 ) {
|
||||
res += QLatin1Char(':') + QString::number( db.port() );
|
||||
}
|
||||
if (db.port() > 0)
|
||||
res += QLatin1Char(':') + QString::number(db.port());
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
bool wasDropped;
|
||||
QSqlQuery q( db );
|
||||
QStringList dbtables=db.tables();
|
||||
QSqlQuery q(db);
|
||||
QStringList dbtables = db.tables();
|
||||
QSqlDriver::DbmsType dbType = getDatabaseType(db);
|
||||
foreach(const QString &tableName, tableNames)
|
||||
for (const QString &tableName : tableNames)
|
||||
{
|
||||
wasDropped = true;
|
||||
QString table=tableName;
|
||||
if ( db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
|
||||
bool wasDropped = true;
|
||||
QString table = tableName;
|
||||
if (db.driver()->isIdentifierEscaped(table, QSqlDriver::TableName))
|
||||
table = db.driver()->stripDelimiters(table, QSqlDriver::TableName);
|
||||
|
||||
if ( dbtables.contains( table, Qt::CaseInsensitive ) ) {
|
||||
foreach(const QString &table2, dbtables.filter(table, Qt::CaseInsensitive)) {
|
||||
if(table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
table=db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
|
||||
if (dbType == QSqlDriver::PostgreSQL)
|
||||
if (dbtables.contains(table, Qt::CaseInsensitive)) {
|
||||
for (const QString &table2 : dbtables.filter(table, Qt::CaseInsensitive)) {
|
||||
if (table2.compare(table.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
table = db.driver()->escapeIdentifier(table2, QSqlDriver::TableName);
|
||||
if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
|
||||
wasDropped = q.exec( "drop table " + table + " cascade");
|
||||
else
|
||||
wasDropped = q.exec( "drop table " + table);
|
||||
@ -349,7 +276,7 @@ public:
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( !wasDropped ) {
|
||||
if (!wasDropped) {
|
||||
qWarning() << dbToString(db) << "unable to drop table" << tableName << ':' << q.lastError();
|
||||
// qWarning() << "last query:" << q.lastQuery();
|
||||
// qWarning() << "dbtables:" << dbtables;
|
||||
@ -358,38 +285,31 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void safeDropTable( QSqlDatabase db, const QString& tableName )
|
||||
static void safeDropViews(const QSqlDatabase &db, const QStringList &viewNames)
|
||||
{
|
||||
safeDropTables(db, QStringList() << tableName);
|
||||
}
|
||||
if (isMSAccess(db)) // Access is sooo stupid.
|
||||
safeDropTables(db, viewNames);
|
||||
|
||||
static void safeDropViews( QSqlDatabase db, const QStringList &viewNames )
|
||||
{
|
||||
if ( isMSAccess( db ) ) // Access is sooo stupid.
|
||||
safeDropTables( db, viewNames );
|
||||
|
||||
bool wasDropped;
|
||||
QSqlQuery q( db );
|
||||
QStringList dbtables=db.tables(QSql::Views);
|
||||
|
||||
foreach(QString viewName, viewNames)
|
||||
QSqlQuery q(db);
|
||||
QStringList dbtables = db.tables(QSql::Views);
|
||||
for (const QString &viewName : viewNames)
|
||||
{
|
||||
wasDropped = true;
|
||||
QString view=viewName;
|
||||
if ( db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
|
||||
bool wasDropped = true;
|
||||
QString view = viewName;
|
||||
if (db.driver()->isIdentifierEscaped(view, QSqlDriver::TableName))
|
||||
view = db.driver()->stripDelimiters(view, QSqlDriver::TableName);
|
||||
|
||||
if ( dbtables.contains( view, Qt::CaseInsensitive ) ) {
|
||||
foreach(const QString &view2, dbtables.filter(view, Qt::CaseInsensitive)) {
|
||||
if(view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
view=db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
|
||||
wasDropped = q.exec( "drop view " + view);
|
||||
if (dbtables.contains(view, Qt::CaseInsensitive)) {
|
||||
for (const QString &view2 : dbtables.filter(view, Qt::CaseInsensitive)) {
|
||||
if (view2.compare(view.section('.', -1, -1), Qt::CaseInsensitive) == 0) {
|
||||
view = db.driver()->escapeIdentifier(view2, QSqlDriver::TableName);
|
||||
wasDropped = q.exec("drop view " + view);
|
||||
dbtables.removeAll(view);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( !wasDropped )
|
||||
if (!wasDropped)
|
||||
qWarning() << dbToString(db) << "unable to drop view" << viewName << ':' << q.lastError();
|
||||
// << "\nlast query:" << q.lastQuery()
|
||||
// << "\ndbtables:" << dbtables
|
||||
@ -397,14 +317,9 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void safeDropView( QSqlDatabase db, const QString& tableName )
|
||||
{
|
||||
safeDropViews(db, QStringList() << tableName);
|
||||
}
|
||||
|
||||
// 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
|
||||
static QString blobTypeName( QSqlDatabase db, int blobSize = 10000 )
|
||||
static QString blobTypeName(const QSqlDatabase &db, int blobSize = 10000)
|
||||
{
|
||||
const QSqlDriver::DbmsType dbType = getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::MySqlServer)
|
||||
@ -433,19 +348,19 @@ public:
|
||||
return "blob";
|
||||
}
|
||||
|
||||
static QString dateTimeTypeName(QSqlDatabase db)
|
||||
static QString dateTimeTypeName(const QSqlDatabase &db)
|
||||
{
|
||||
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::PostgreSQL)
|
||||
return QLatin1String("timestamptz");
|
||||
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
|
||||
return QLatin1String("timestamp(0)");
|
||||
if (dbType == QSqlDriver::Interbase)
|
||||
if (dbType == QSqlDriver::Interbase || dbType == QSqlDriver::MimerSQL)
|
||||
return QLatin1String("timestamp");
|
||||
return QLatin1String("datetime");
|
||||
}
|
||||
|
||||
static QString timeTypeName(QSqlDatabase db)
|
||||
static QString timeTypeName(const QSqlDatabase &db)
|
||||
{
|
||||
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
|
||||
@ -453,7 +368,7 @@ public:
|
||||
return QLatin1String("time");
|
||||
}
|
||||
|
||||
static QString dateTypeName(QSqlDatabase db)
|
||||
static QString dateTypeName(const QSqlDatabase &db)
|
||||
{
|
||||
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::Oracle && getOraVersion(db) >= 9)
|
||||
@ -461,7 +376,7 @@ public:
|
||||
return QLatin1String("date");
|
||||
}
|
||||
|
||||
static QString autoFieldName( QSqlDatabase db )
|
||||
static QString autoFieldName(const QSqlDatabase &db)
|
||||
{
|
||||
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::MySqlServer)
|
||||
@ -476,43 +391,35 @@ public:
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QByteArray printError( const QSqlError& err )
|
||||
static QByteArray printError(const QSqlError &err)
|
||||
{
|
||||
QString result;
|
||||
if (!err.nativeErrorCode().isEmpty())
|
||||
result += '(' + err.nativeErrorCode() + ") ";
|
||||
result += '\'';
|
||||
if(!err.driverText().isEmpty())
|
||||
result += u'(' + err.nativeErrorCode() + ") ";
|
||||
result += u'\'';
|
||||
if (!err.driverText().isEmpty())
|
||||
result += err.driverText() + "' || '";
|
||||
result += err.databaseText() + QLatin1Char('\'');
|
||||
result += err.databaseText() + u'\'';
|
||||
return result.toLocal8Bit();
|
||||
}
|
||||
|
||||
static QByteArray printError( const QSqlError& err, const QSqlDatabase& db )
|
||||
static QByteArray printError(const QSqlError &err, const QSqlDatabase &db)
|
||||
{
|
||||
QString result(dbToString(db) + ": ");
|
||||
if (!err.nativeErrorCode().isEmpty())
|
||||
result += '(' + err.nativeErrorCode() + ") ";
|
||||
result += '\'';
|
||||
if(!err.driverText().isEmpty())
|
||||
result += err.driverText() + "' || '";
|
||||
result += err.databaseText() + QLatin1Char('\'');
|
||||
return result.toLocal8Bit();
|
||||
return dbToString(db).toLocal8Bit() + ": " + printError(err);
|
||||
}
|
||||
|
||||
static QSqlDriver::DbmsType getDatabaseType(QSqlDatabase db)
|
||||
static QSqlDriver::DbmsType getDatabaseType(const QSqlDatabase &db)
|
||||
{
|
||||
QSqlDriverPrivate *d = static_cast<QSqlDriverPrivate *>(QObjectPrivate::get(db.driver()));
|
||||
return d->dbmsType;
|
||||
return db.driver()->dbmsType();
|
||||
}
|
||||
|
||||
static bool isMSAccess( QSqlDatabase db )
|
||||
static bool isMSAccess(const QSqlDatabase &db)
|
||||
{
|
||||
return db.databaseName().contains( "Access Driver", Qt::CaseInsensitive );
|
||||
}
|
||||
|
||||
// -1 on fail, else Oracle version
|
||||
static int getOraVersion( QSqlDatabase db )
|
||||
static int getOraVersion(const QSqlDatabase &db)
|
||||
{
|
||||
int ver = -1;
|
||||
QSqlQuery q( "SELECT banner FROM v$version", db );
|
||||
@ -531,28 +438,18 @@ public:
|
||||
return ver;
|
||||
}
|
||||
|
||||
static QString getMySqlVersion( const QSqlDatabase &db )
|
||||
static QVersionNumber getIbaseEngineVersion(const QSqlDatabase &db)
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
q.exec( "select version()" );
|
||||
if(q.next())
|
||||
return q.value( 0 ).toString();
|
||||
else
|
||||
return QString();
|
||||
}
|
||||
|
||||
static QString getPSQLVersion( const QSqlDatabase &db )
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
q.exec( "select version()" );
|
||||
if(q.next())
|
||||
return q.value( 0 ).toString();
|
||||
else
|
||||
return QString();
|
||||
q.exec("SELECT rdb$get_context('SYSTEM', 'ENGINE_VERSION') as version from rdb$database;"_L1);
|
||||
q.next();
|
||||
auto record = q.record();
|
||||
auto version = QVersionNumber::fromString(record.value(0).toString());
|
||||
return version;
|
||||
}
|
||||
|
||||
QStringList dbNames;
|
||||
int counter;
|
||||
int counter = 0;
|
||||
|
||||
private:
|
||||
QTemporaryDir *dbDir()
|
||||
@ -570,5 +467,61 @@ private:
|
||||
QScopedPointer<QTemporaryDir> m_dbDir;
|
||||
};
|
||||
|
||||
class TableScope
|
||||
{
|
||||
public:
|
||||
TableScope(const QSqlDatabase &db, const QString &fullTableName)
|
||||
: m_db(db)
|
||||
, m_tableName(fullTableName)
|
||||
{
|
||||
tst_Databases::safeDropTables(m_db, {m_tableName});
|
||||
}
|
||||
TableScope(const QSqlDatabase &db, const char *tableName, const char *file, bool escape = true)
|
||||
: TableScope(db, qTableName(tableName, file, db, escape))
|
||||
{
|
||||
}
|
||||
|
||||
~TableScope()
|
||||
{
|
||||
tst_Databases::safeDropTables(m_db, {m_tableName});
|
||||
}
|
||||
|
||||
QString tableName() const
|
||||
{
|
||||
return m_tableName;
|
||||
}
|
||||
private:
|
||||
QSqlDatabase m_db;
|
||||
QString m_tableName;
|
||||
};
|
||||
|
||||
class ProcScope
|
||||
{
|
||||
public:
|
||||
ProcScope(const QSqlDatabase &db, const char *procName, const char *file)
|
||||
: m_db(db),
|
||||
m_procName(qTableName(procName, file, db))
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
~ProcScope()
|
||||
{
|
||||
cleanup();
|
||||
}
|
||||
QString name() const
|
||||
{
|
||||
return m_procName;
|
||||
}
|
||||
protected:
|
||||
void cleanup()
|
||||
{
|
||||
QSqlQuery q(m_db);
|
||||
q.exec("DROP PROCEDURE IF EXISTS " + m_procName);
|
||||
}
|
||||
private:
|
||||
QSqlDatabase m_db;
|
||||
const QString m_procName;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -52,47 +52,48 @@ void tst_QSqlDriver::initTestCase_data()
|
||||
void tst_QSqlDriver::recreateTestTables(QSqlDatabase db)
|
||||
{
|
||||
QSqlQuery q(db);
|
||||
const QString relTEST1(qTableName("relTEST1", __FILE__, db));
|
||||
const QString tableName(qTableName("relTEST1", __FILE__, db));
|
||||
tst_Databases::safeDropTables(db, {tableName});
|
||||
|
||||
QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::PostgreSQL)
|
||||
QVERIFY_SQL( q, exec("set client_min_messages='warning'"));
|
||||
|
||||
tst_Databases::safeDropTable( db, relTEST1 );
|
||||
QString doubleField;
|
||||
if (dbType == QSqlDriver::SQLite)
|
||||
doubleField = "more_data double";
|
||||
else if (dbType == QSqlDriver::Oracle)
|
||||
doubleField = "more_data number(8,7)";
|
||||
else if (dbType == QSqlDriver::PostgreSQL)
|
||||
else if (dbType == QSqlDriver::PostgreSQL || dbType == QSqlDriver::MimerSQL)
|
||||
doubleField = "more_data double precision";
|
||||
else if (dbType == QSqlDriver::Interbase)
|
||||
doubleField = "more_data numeric(8,7)";
|
||||
else
|
||||
doubleField = "more_data double(8,7)";
|
||||
const QString defValue(driverSupportsDefaultValues(dbType) ? QStringLiteral("DEFAULT 'defaultVal'") : QString());
|
||||
QVERIFY_SQL( q, exec("create table " + relTEST1 +
|
||||
QVERIFY_SQL( q, exec("create table " + tableName +
|
||||
" (id int not null primary key, name varchar(20) " + defValue + ", title_key int, another_title_key int, " + doubleField + QLatin1Char(')')));
|
||||
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(1, 'harry', 1, 2, 1.234567)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(2, 'trond', 2, 1, 8.901234)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(3, 'vohi', 1, 2, 5.678901)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + relTEST1 + " values(4, 'boris', 2, 2, 2.345678)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + tableName + " values(1, 'harry', 1, 2, 1.234567)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + tableName + " values(2, 'trond', 2, 1, 8.901234)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + tableName + " values(3, 'vohi', 1, 2, 5.678901)"));
|
||||
QVERIFY_SQL( q, exec("insert into " + tableName + " values(4, 'boris', 2, 2, 2.345678)"));
|
||||
}
|
||||
|
||||
void tst_QSqlDriver::initTestCase()
|
||||
{
|
||||
foreach (const QString &dbname, dbs.dbNames)
|
||||
for (const QString &dbname : std::as_const(dbs.dbNames))
|
||||
recreateTestTables(QSqlDatabase::database(dbname));
|
||||
}
|
||||
|
||||
void tst_QSqlDriver::cleanupTestCase()
|
||||
{
|
||||
foreach (const QString &dbName, dbs.dbNames) {
|
||||
for (const QString &dbName : std::as_const(dbs.dbNames)) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
tst_Databases::safeDropTable(db, qTableName("relTEST1", __FILE__, db));
|
||||
QStringList tables = {qTableName("relTEST1", __FILE__, db)};
|
||||
const QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
|
||||
if (dbType == QSqlDriver::Oracle)
|
||||
tst_Databases::safeDropTable(db, qTableName("clobTable", __FILE__, db));
|
||||
tables.push_back(qTableName("clobTable", __FILE__, db));
|
||||
tst_Databases::safeDropTables(db, tables);
|
||||
}
|
||||
dbs.close();
|
||||
}
|
||||
@ -111,7 +112,7 @@ void tst_QSqlDriver::record()
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
QString tablename(qTableName("relTEST1", __FILE__, db));
|
||||
QString tablename(qTableName("relTEST1", __FILE__, db, false));
|
||||
QStringList fields;
|
||||
fields << "id" << "name" << "title_key" << "another_title_key" << "more_data";
|
||||
|
||||
@ -155,8 +156,9 @@ void tst_QSqlDriver::record()
|
||||
|
||||
//check that we can't get records using incorrect tablename casing that's been quoted
|
||||
rec = db.driver()->record(db.driver()->escapeIdentifier(tablename,QSqlDriver::TableName));
|
||||
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::Sybase
|
||||
|| dbType == QSqlDriver::MSSqlServer || tst_Databases::isMSAccess(db))
|
||||
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite
|
||||
|| dbType == QSqlDriver::Sybase || dbType == QSqlDriver::MSSqlServer
|
||||
|| tst_Databases::isMSAccess(db) || dbType == QSqlDriver::MimerSQL)
|
||||
QCOMPARE(rec.count(), 5); //mysql, sqlite and tds will match
|
||||
else
|
||||
QCOMPARE(rec.count(), 0);
|
||||
@ -169,7 +171,7 @@ void tst_QSqlDriver::primaryIndex()
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
CHECK_DATABASE(db);
|
||||
|
||||
QString tablename(qTableName("relTEST1", __FILE__, db));
|
||||
QString tablename(qTableName("relTEST1", __FILE__, db, false));
|
||||
//check that we can get primary index using unquoted mixed case table name
|
||||
QSqlIndex index = db.driver()->primaryIndex(tablename);
|
||||
QCOMPARE(index.count(), 1);
|
||||
@ -205,22 +207,23 @@ void tst_QSqlDriver::primaryIndex()
|
||||
tablename = tablename.toUpper();
|
||||
|
||||
index = db.driver()->primaryIndex(db.driver()->escapeIdentifier(tablename, QSqlDriver::TableName));
|
||||
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite || dbType == QSqlDriver::Sybase
|
||||
|| dbType == QSqlDriver::MSSqlServer || tst_Databases::isMSAccess(db))
|
||||
if (dbType == QSqlDriver::MySqlServer || dbType == QSqlDriver::SQLite
|
||||
|| dbType == QSqlDriver::Sybase || dbType == QSqlDriver::MSSqlServer
|
||||
|| tst_Databases::isMSAccess(db) || dbType == QSqlDriver::MimerSQL)
|
||||
QCOMPARE(index.count(), 1); //mysql will always find the table name regardless of casing
|
||||
else
|
||||
QCOMPARE(index.count(), 0);
|
||||
|
||||
// Test getting a primary index for a table with a clob in it - QTBUG-64427
|
||||
if (dbType == QSqlDriver::Oracle) {
|
||||
const QString clobTable(qTableName("clobTable", __FILE__, db));
|
||||
TableScope ts(db, "clobTable", __FILE__);
|
||||
QSqlQuery qry(db);
|
||||
QVERIFY_SQL(qry, exec("CREATE TABLE " + clobTable + " (id INTEGER, clobField CLOB)"));
|
||||
QVERIFY_SQL(qry, exec("CREATE UNIQUE INDEX " + clobTable + "IDX ON " + clobTable + " (id)"));
|
||||
QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " ADD CONSTRAINT " + clobTable +
|
||||
QVERIFY_SQL(qry, exec("CREATE TABLE " + ts.tableName() + " (id INTEGER, clobField CLOB)"));
|
||||
QVERIFY_SQL(qry, exec("CREATE UNIQUE INDEX " + ts.tableName() + "IDX ON " + ts.tableName() + " (id)"));
|
||||
QVERIFY_SQL(qry, exec("ALTER TABLE " + ts.tableName() + " ADD CONSTRAINT " + ts.tableName() +
|
||||
"PK PRIMARY KEY(id)"));
|
||||
QVERIFY_SQL(qry, exec("ALTER TABLE " + clobTable + " MODIFY (id NOT NULL ENABLE)"));
|
||||
const QSqlIndex primaryIndex = db.driver()->primaryIndex(clobTable);
|
||||
QVERIFY_SQL(qry, exec("ALTER TABLE " + ts.tableName() + " MODIFY (id NOT NULL ENABLE)"));
|
||||
const QSqlIndex primaryIndex = db.driver()->primaryIndex(ts.tableName());
|
||||
QCOMPARE(primaryIndex.count(), 1);
|
||||
QCOMPARE(primaryIndex.fieldName(0), QStringLiteral("ID"));
|
||||
}
|
||||
|
@ -108,12 +108,16 @@ void tst_QSqlError::moveOperator()
|
||||
|
||||
void tst_QSqlError::operators()
|
||||
{
|
||||
QSqlError error1(QString(), QString(), QSqlError::NoError);
|
||||
QSqlError error2(QString(), QString(), QSqlError::NoError);
|
||||
QSqlError error3(QString(), QString(), QSqlError::UnknownError);
|
||||
QSqlError error1(QStringLiteral("a"), QStringLiteral("b"), QSqlError::NoError, QStringLiteral("ec1"));
|
||||
QSqlError error2(QStringLiteral("c"), QStringLiteral("d"), QSqlError::NoError, QStringLiteral("ec1"));
|
||||
QSqlError error3(QString(), QString(), QSqlError::UnknownError, QStringLiteral("ec1"));
|
||||
QSqlError error4(QString(), QString(), QSqlError::NoError, QStringLiteral("ec2"));
|
||||
QSqlError error5(QString(), QString(), QSqlError::UnknownError, QStringLiteral("ec2"));
|
||||
|
||||
QCOMPARE(error1, error2);
|
||||
QVERIFY(error1 != error3);
|
||||
QVERIFY(error1 != error4);
|
||||
QVERIFY(error4 != error5);
|
||||
}
|
||||
|
||||
void tst_QSqlError::qtbug_74575()
|
||||
|
@ -39,6 +39,7 @@ private slots:
|
||||
void clear();
|
||||
void setTableName_data();
|
||||
void setTableName();
|
||||
void moveSemantics();
|
||||
};
|
||||
|
||||
// Testing get/set functions
|
||||
@ -344,5 +345,24 @@ void tst_QSqlField::setTableName()
|
||||
QCOMPARE(field.tableName(), tableName);
|
||||
}
|
||||
|
||||
void tst_QSqlField::moveSemantics()
|
||||
{
|
||||
QSqlField field("test", QMetaType(QMetaType::QString), "testTable");
|
||||
QSqlField empty;
|
||||
field.setValue("string");
|
||||
auto moved = std::move(field);
|
||||
// `field` is now partially-formed
|
||||
|
||||
// moving transfers state:
|
||||
QCOMPARE(moved.value().toString(), QLatin1String("string"));
|
||||
|
||||
// moved-from objects can be assigned-to:
|
||||
field = empty;
|
||||
QVERIFY(field.value().isNull());
|
||||
|
||||
// moved-from object can be destroyed:
|
||||
moved = std::move(field);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSqlField)
|
||||
#include "tst_qsqlfield.moc"
|
||||
|
15
tests/auto/sql/kernel/qsqlindex/CMakeLists.txt
Normal file
15
tests/auto/sql/kernel/qsqlindex/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2023 The Qt Company Ltd.
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#####################################################################
|
||||
## tst_qsqlindex Test:
|
||||
#####################################################################
|
||||
|
||||
qt_internal_add_test(tst_qsqlindex
|
||||
SOURCES
|
||||
tst_qsqlindex.cpp
|
||||
LIBRARIES
|
||||
Qt::CorePrivate
|
||||
Qt::Sql
|
||||
Qt::SqlPrivate
|
||||
)
|
126
tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp
Normal file
126
tests/auto/sql/kernel/qsqlindex/tst_qsqlindex.cpp
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include <QTest>
|
||||
#include <QtSql/QtSql>
|
||||
|
||||
#include <QtCore/QDateTime>
|
||||
#include <QtCore/QTimeZone>
|
||||
|
||||
#include <numeric>
|
||||
|
||||
#include "../qsqldatabase/tst_databases.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
QString qtest;
|
||||
|
||||
class tst_QSqlIndex : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
tst_QSqlIndex();
|
||||
|
||||
private slots:
|
||||
void construction_data();
|
||||
void construction();
|
||||
void assignment_data();
|
||||
void assignment();
|
||||
void basicFunctions();
|
||||
};
|
||||
|
||||
tst_QSqlIndex::tst_QSqlIndex()
|
||||
{
|
||||
}
|
||||
|
||||
void tst_QSqlIndex::construction_data()
|
||||
{
|
||||
QTest::addColumn<QSqlIndex>("sqlIndex");
|
||||
QTest::addColumn<QString>("cursorName");
|
||||
QTest::addColumn<QString>("name");
|
||||
|
||||
const QString cursorName("cusorName"_L1);
|
||||
const QString name("name"_L1);
|
||||
QSqlIndex sqlIndex(cursorName, name);
|
||||
QTest::newRow("ctor1") << QSqlIndex() << QString() << QString();
|
||||
QTest::newRow("ctor2") << sqlIndex << cursorName << name;
|
||||
QTest::newRow("copy ctor") << QSqlIndex(sqlIndex) << cursorName << name;
|
||||
QTest::newRow("move ctor") << QSqlIndex(std::move(sqlIndex)) << cursorName << name;
|
||||
}
|
||||
|
||||
void tst_QSqlIndex::construction()
|
||||
{
|
||||
QFETCH(QSqlIndex, sqlIndex);
|
||||
QFETCH(QString, cursorName);
|
||||
QFETCH(QString, name);
|
||||
|
||||
QCOMPARE(sqlIndex.cursorName(), cursorName);
|
||||
QCOMPARE(sqlIndex.name(), name);
|
||||
QCOMPARE(sqlIndex.isDescending(0), false);
|
||||
QCOMPARE(sqlIndex.count(), 0);
|
||||
}
|
||||
|
||||
void tst_QSqlIndex::assignment_data()
|
||||
{
|
||||
QTest::addColumn<QSqlIndex>("sqlIndex");
|
||||
QTest::addColumn<QString>("cursorName");
|
||||
QTest::addColumn<QString>("name");
|
||||
|
||||
const QString cursorName("cusorName"_L1);
|
||||
const QString name("name"_L1);
|
||||
QSqlIndex sqlIndex(cursorName, name);
|
||||
QSqlIndex sqlIndex1 = sqlIndex;
|
||||
QSqlIndex sqlIndex2 = std::move(sqlIndex);
|
||||
sqlIndex = std::move(sqlIndex2);
|
||||
QTest::newRow("copy assignment") << sqlIndex1 << cursorName << name;
|
||||
QTest::newRow("move assignment") << sqlIndex << cursorName << name;
|
||||
}
|
||||
|
||||
void tst_QSqlIndex::assignment()
|
||||
{
|
||||
QFETCH(QSqlIndex, sqlIndex);
|
||||
QFETCH(QString, cursorName);
|
||||
QFETCH(QString, name);
|
||||
|
||||
QCOMPARE(sqlIndex.cursorName(), cursorName);
|
||||
QCOMPARE(sqlIndex.name(), name);
|
||||
QCOMPARE(sqlIndex.isDescending(0), false);
|
||||
QCOMPARE(sqlIndex.count(), 0);
|
||||
}
|
||||
|
||||
void tst_QSqlIndex::basicFunctions()
|
||||
{
|
||||
QSqlIndex sqlIndex("cursorName"_L1, "name"_L1);
|
||||
const QSqlField f1("field1"_L1, QMetaType(QMetaType::UInt), "table1"_L1);
|
||||
const QSqlField f2("field2"_L1, QMetaType(QMetaType::Double), "table2"_L1);
|
||||
|
||||
QCOMPARE(sqlIndex.cursorName(), "cursorName"_L1);
|
||||
sqlIndex.setCursorName("updatedCursorName"_L1);
|
||||
QCOMPARE(sqlIndex.name(), "name"_L1);
|
||||
sqlIndex.setName("updatedName"_L1);
|
||||
QCOMPARE(sqlIndex.cursorName(), "updatedCursorName"_L1);
|
||||
QCOMPARE(sqlIndex.name(), "updatedName"_L1);
|
||||
|
||||
sqlIndex.append(f1);
|
||||
QCOMPARE(sqlIndex.count(), 1);
|
||||
QCOMPARE(sqlIndex.isDescending(0), false);
|
||||
|
||||
sqlIndex.append(f2, true);
|
||||
QCOMPARE(sqlIndex.count(), 2);
|
||||
QCOMPARE(sqlIndex.isDescending(0), false);
|
||||
QCOMPARE(sqlIndex.isDescending(1), true);
|
||||
|
||||
sqlIndex.setDescending(0, true);
|
||||
sqlIndex.setDescending(1, false);
|
||||
sqlIndex.setDescending(2, true);
|
||||
QCOMPARE(sqlIndex.count(), 2);
|
||||
QCOMPARE(sqlIndex.isDescending(0), true);
|
||||
QCOMPARE(sqlIndex.isDescending(1), false);
|
||||
|
||||
QCOMPARE(sqlIndex.field(0), f1);
|
||||
QCOMPARE(sqlIndex.field(1), f2);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSqlIndex)
|
||||
#include "tst_qsqlindex.moc"
|
File diff suppressed because it is too large
Load Diff
@ -40,6 +40,7 @@ private slots:
|
||||
void clearValues();
|
||||
void clear();
|
||||
void append();
|
||||
void moveSemantics();
|
||||
|
||||
private:
|
||||
std::unique_ptr<QSqlRecord> rec;
|
||||
@ -449,5 +450,24 @@ void tst_QSqlRecord::value()
|
||||
QCOMPARE(rec2.value("string").toString(), QLatin1String("Harry"));
|
||||
}
|
||||
|
||||
void tst_QSqlRecord::moveSemantics()
|
||||
{
|
||||
QSqlRecord rec, empty;
|
||||
rec.append(QSqlField("string", QMetaType(QMetaType::QString)));
|
||||
rec.setValue("string", "Harry");
|
||||
auto moved = std::move(rec);
|
||||
// `rec` is not partially-formed
|
||||
|
||||
// moving transfers state:
|
||||
QCOMPARE(moved.value("string").toString(), QLatin1String("Harry"));
|
||||
|
||||
// moved-from objects can be assigned-to:
|
||||
rec = empty;
|
||||
QVERIFY(rec.value("string").isNull());
|
||||
|
||||
// moved-from object can be destroyed:
|
||||
moved = std::move(rec);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QSqlRecord)
|
||||
#include "tst_qsqlrecord.moc"
|
||||
|
@ -258,18 +258,16 @@ void tst_QSqlThread::generic_data(const QString& engine)
|
||||
|
||||
void tst_QSqlThread::dropTestTables()
|
||||
{
|
||||
for (int i = 0; i < dbs.dbNames.size(); ++i) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
|
||||
QSqlQuery q(db);
|
||||
|
||||
tst_Databases::safeDropTables(db, QStringList() << qtest << qTableName("qtest2", __FILE__, db) << qTableName("emptytable", __FILE__, db));
|
||||
for (const auto &dbName : dbs.dbNames) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
tst_Databases::safeDropTables(db, { qtest, qTableName("qtest2", __FILE__, db), qTableName("emptytable", __FILE__, db) });
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSqlThread::createTestTables()
|
||||
{
|
||||
for (int i = 0; i < dbs.dbNames.size(); ++i) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
|
||||
for (const auto &dbName : dbs.dbNames) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
QSqlQuery q(db);
|
||||
|
||||
QVERIFY_SQL(q, exec("create table " + qtest
|
||||
@ -285,8 +283,8 @@ void tst_QSqlThread::createTestTables()
|
||||
|
||||
void tst_QSqlThread::repopulateTestTables()
|
||||
{
|
||||
for (int i = 0; i < dbs.dbNames.size(); ++i) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbs.dbNames.at(i));
|
||||
for (const auto &dbName : dbs.dbNames) {
|
||||
QSqlDatabase db = QSqlDatabase::database(dbName);
|
||||
QSqlQuery q(db);
|
||||
|
||||
QVERIFY_SQL(q, exec("delete from " + qtest));
|
||||
|
Reference in New Issue
Block a user