mirror of
https://github.com/nextcloud/desktop.git
synced 2024-11-27 09:30:13 +03:00
4bd062f5be
This could fix a problem where the client incorrectly decides to delete local data. Previously any sqlite3_step() return value that wasn't SQLITE_ROW would be interpreted as "there's no more data here". Thus an sqlite error at a bad time could cause the remote discovery to fail to read an unchanged subtree from the database. These files would then be deleted locally. With this change sqlite errors from sqlite3_step are detected and logged. For the particular case of SyncJournalDb::getFilesBelowPath() the error will now be propagated and the sync run will fail instead of performing spurious deletes. Note that many other database functions still don't distinguish not-found from error cases. Most of them won't have as severe effects on affected sync runs though.
149 lines
4.1 KiB
C++
149 lines
4.1 KiB
C++
/*
|
|
* This software is in the public domain, furnished "as is", without technical
|
|
* support, and with no warranty, express or implied, as to its usefulness for
|
|
* any purpose.
|
|
* */
|
|
|
|
#include <QtTest>
|
|
|
|
#include <sqlite3.h>
|
|
|
|
#include "common/ownsql.h"
|
|
|
|
using namespace OCC;
|
|
|
|
class TestOwnSql : public QObject
|
|
{
|
|
Q_OBJECT
|
|
QTemporaryDir _tempDir;
|
|
|
|
private slots:
|
|
void testOpenDb() {
|
|
QFileInfo fi( _tempDir.path() + "/testdb.sqlite" );
|
|
QVERIFY( !fi.exists() ); // must not exist
|
|
_db.openOrCreateReadWrite(fi.filePath());
|
|
fi.refresh();
|
|
QVERIFY(fi.exists());
|
|
}
|
|
|
|
void testCreate() {
|
|
const char *sql = "CREATE TABLE addresses ( id INTEGER, name VARCHAR(4096), "
|
|
"address VARCHAR(4096), entered INTEGER(8), PRIMARY KEY(id));";
|
|
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
QVERIFY(q.exec());
|
|
}
|
|
|
|
void testIsSelect() {
|
|
SqlQuery q(_db);
|
|
q.prepare("SELECT id FROM addresses;");
|
|
QVERIFY( q.isSelect() );
|
|
|
|
q.prepare("UPDATE addresses SET id = 1;");
|
|
QVERIFY( !q.isSelect());
|
|
}
|
|
|
|
void testInsert() {
|
|
const char *sql = "INSERT INTO addresses (id, name, address, entered) VALUES "
|
|
"(1, 'Gonzo Alberto', 'Moriabata 24, Palermo', 1403100844);";
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
QVERIFY(q.exec());
|
|
}
|
|
|
|
void testInsert2() {
|
|
const char *sql = "INSERT INTO addresses (id, name, address, entered) VALUES "
|
|
"(?1, ?2, ?3, ?4);";
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
q.bindValue(1, 2);
|
|
q.bindValue(2, "Brucely Lafayette");
|
|
q.bindValue(3, "Nurderway5, New York");
|
|
q.bindValue(4, 1403101224);
|
|
QVERIFY(q.exec());
|
|
}
|
|
|
|
void testSelect() {
|
|
const char *sql = "SELECT * FROM addresses;";
|
|
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
|
|
q.exec();
|
|
while( q.next().hasData ) {
|
|
qDebug() << "Name: " << q.stringValue(1);
|
|
qDebug() << "Address: " << q.stringValue(2);
|
|
}
|
|
}
|
|
|
|
void testSelect2() {
|
|
const char *sql = "SELECT * FROM addresses WHERE id=?1";
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
q.bindValue(1, 2);
|
|
q.exec();
|
|
if( q.next().hasData ) {
|
|
qDebug() << "Name:" << q.stringValue(1);
|
|
qDebug() << "Address:" << q.stringValue(2);
|
|
}
|
|
}
|
|
|
|
void testPragma() {
|
|
const char *sql = "PRAGMA table_info(addresses)";
|
|
|
|
SqlQuery q(_db);
|
|
int rc = q.prepare(sql);
|
|
qDebug() << "Pragma:" << rc;
|
|
q.exec();
|
|
if( q.next().hasData ) {
|
|
qDebug() << "P:" << q.stringValue(1);
|
|
}
|
|
}
|
|
|
|
void testUnicode() {
|
|
const char *sql = "INSERT INTO addresses (id, name, address, entered) VALUES "
|
|
"(?1, ?2, ?3, ?4);";
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
q.bindValue(1, 3);
|
|
q.bindValue(2, QString::fromUtf8("пятницы"));
|
|
q.bindValue(3, QString::fromUtf8("проспект"));
|
|
q.bindValue(4, 1403002224);
|
|
QVERIFY(q.exec());
|
|
}
|
|
|
|
void testReadUnicode() {
|
|
const char *sql = "SELECT * FROM addresses WHERE id=3;";
|
|
SqlQuery q(_db);
|
|
q.prepare(sql);
|
|
|
|
if(q.next().hasData) {
|
|
QString name = q.stringValue(1);
|
|
QString address = q.stringValue(2);
|
|
QVERIFY( name == QString::fromUtf8("пятницы") );
|
|
QVERIFY( address == QString::fromUtf8("проспект"));
|
|
}
|
|
}
|
|
|
|
void testDestructor()
|
|
{
|
|
// This test make sure that the destructor of SqlQuery works even if the SqlDatabase
|
|
// is destroyed before
|
|
QScopedPointer<SqlDatabase> db(new SqlDatabase());
|
|
SqlQuery q1(_db);
|
|
SqlQuery q2(_db);
|
|
q2.prepare("SELECT * FROM addresses");
|
|
SqlQuery q3("SELECT * FROM addresses", _db);
|
|
SqlQuery q4;
|
|
SqlQuery q5;
|
|
q5.initOrReset("SELECT * FROM addresses", _db);
|
|
db.reset();
|
|
}
|
|
|
|
private:
|
|
SqlDatabase _db;
|
|
};
|
|
|
|
QTEST_APPLESS_MAIN(TestOwnSql)
|
|
#include "testownsql.moc"
|