mirror of
https://github.com/QuasarApp/Heart.git
synced 2025-04-28 02:34:41 +00:00
Merge pull request #41 from QuasarApp/dbPatches
Added support Database patches
This commit is contained in:
commit
38366cfa32
@ -34,6 +34,14 @@ public:
|
||||
*/
|
||||
using Job = std::function<bool()>;
|
||||
|
||||
/**
|
||||
* @brief asyncLauncher This method invoke a job on the thread (using the asyncHandler method) of this object.
|
||||
* @param job This is function with needed job.
|
||||
* @param await This is boolean option for enable or disable wait for finish of the job function.
|
||||
* @return true if the job function started correctly. If the await option is true then
|
||||
* this method return result of job function.
|
||||
*/
|
||||
bool asyncLauncher(const Job &job, bool await = false) const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
@ -66,14 +74,6 @@ protected:
|
||||
*/
|
||||
bool waitFor(const Job &condition, int timeout = WAIT_TIME) const;
|
||||
|
||||
/**
|
||||
* @brief asyncLauncher This method invoke a job on the thread (using the asyncHandler method) of this object.
|
||||
* @param job This is function with needed job.
|
||||
* @param await This is boolean option for enable or disable wait for finish of the job function.
|
||||
* @return true if the job function started correctly. If the await option is true then
|
||||
* this method return result of job function.
|
||||
*/
|
||||
bool asyncLauncher(const Job &job, bool await = false) const;
|
||||
private slots:
|
||||
|
||||
/**
|
||||
|
@ -29,5 +29,11 @@ CREATE TABLE IF NOT EXISTS DefaultPermissions (
|
||||
FOREIGN KEY(dbAddress) REFERENCES MemberPermisions(dbAddress)
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS DataBaseAttributes (
|
||||
name TEXT NOT NULL PRIMARY KEY,
|
||||
value INT NOT NULL UNIQUE
|
||||
);
|
||||
|
||||
|
||||
|
@ -32,3 +32,8 @@ CREATE TABLE IF NOT EXISTS DefaultPermissions (
|
||||
ON UPDATE CASCADE
|
||||
ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS DataBaseAttributes (
|
||||
name TEXT NOT NULL PRIMARY KEY,
|
||||
value INT NOT NULL UNIQUE
|
||||
);
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <sqlitedbcache.h>
|
||||
#include <sqldb.h>
|
||||
#include <QCryptographicHash>
|
||||
#include "getsinglevalue.h"
|
||||
#include "setsinglevalue.h"
|
||||
|
||||
#define THIS_NODE "this_node_key"
|
||||
namespace QH {
|
||||
@ -64,10 +66,22 @@ bool DataBaseNode::initSqlDb(QString DBparamsFile,
|
||||
|
||||
if (DBparamsFile.isEmpty()) {
|
||||
params = defaultDbParams();
|
||||
return _db->init(params);
|
||||
|
||||
if (!_db->init(params)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (!_db->init(DBparamsFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!_db->init(DBparamsFile)) {
|
||||
if (!upgradeDataBase()) {
|
||||
QuasarAppUtils::Params::log("Failed to upgrade database",
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -180,6 +194,10 @@ void DataBaseNode::objectChanged(const QSharedPointer<DBObject> &) {
|
||||
|
||||
}
|
||||
|
||||
DBPatchMap DataBaseNode::dbPatches() const {
|
||||
return {};
|
||||
}
|
||||
|
||||
void DataBaseNode::handleObjectChanged(const QSharedPointer<DBObject> &item) {
|
||||
notifyObjectChanged(item.staticCast<PKG::ISubscribableData>());
|
||||
objectChanged(item);
|
||||
@ -371,6 +389,71 @@ bool DataBaseNode::isForbidenTable(const QString &table) {
|
||||
return systemTables().contains(table);
|
||||
}
|
||||
|
||||
bool DataBaseNode::upgradeDataBase() {
|
||||
auto patches = dbPatches();
|
||||
int actyalyVersion = patches.size();
|
||||
int currentVersion = 0;
|
||||
|
||||
if (!db())
|
||||
return false;
|
||||
|
||||
bool fsupportUpgrade = db()->doQuery("SELECT COUNT(*) FROM DataBaseAttributes", true);
|
||||
|
||||
if (!fsupportUpgrade) {
|
||||
|
||||
QuasarAppUtils::Params::log("The data base of application do not support soft upgrade. "
|
||||
"Please remove database monyaly and restart application.",
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
PKG::GetSingleValue request({"DataBaseAttributes", "version"}, "value", "name");
|
||||
|
||||
if (auto responce = _db->getObject(request)) {
|
||||
currentVersion = responce->value().toInt();
|
||||
}
|
||||
|
||||
bool fUpdated = false;
|
||||
while (currentVersion < actyalyVersion) {
|
||||
|
||||
auto patch = patches.value(currentVersion, {});
|
||||
|
||||
QString message;
|
||||
if (currentVersion == 0) {
|
||||
message = "Initialize data base!";
|
||||
} else {
|
||||
message = "Upgrade data base!. from %0 to %1 versions";
|
||||
}
|
||||
|
||||
QuasarAppUtils::Params::log(message,
|
||||
QuasarAppUtils::Info);
|
||||
|
||||
if (patch && !patch(db())) {
|
||||
message = message.arg(currentVersion).arg(currentVersion);
|
||||
QuasarAppUtils::Params::log("Failed to " + message,
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentVersion++;
|
||||
fUpdated = true;
|
||||
}
|
||||
|
||||
if (fUpdated) {
|
||||
auto updateVersionRequest = QSharedPointer<PKG::SetSingleValue>::create(
|
||||
DbAddress{"DataBaseAttributes", "version"},
|
||||
"value", currentVersion, "name");
|
||||
|
||||
if (!_db->insertIfExistsUpdateObject(updateVersionRequest, true)) {
|
||||
QuasarAppUtils::Params::log("Failed to update version attribute",
|
||||
QuasarAppUtils::Error);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void DataBaseNode::setLocalNodeName(const QString &newLocalNodeName) {
|
||||
_localNodeName = newLocalNodeName;
|
||||
}
|
||||
|
@ -27,8 +27,22 @@ class SqlDBWriter;
|
||||
class WebSocketController;
|
||||
class DbAddress;
|
||||
class NodeId;
|
||||
class iObjectProvider;
|
||||
|
||||
|
||||
/**
|
||||
* @brief DBPatch This is function that should be upgrade database.
|
||||
* @see DBPatchMap
|
||||
* @see DataBaseNode::dbPatch
|
||||
*/
|
||||
typedef std::function<bool (const QH::iObjectProvider *)> DBPatch;
|
||||
/**
|
||||
* @brief DBPatchMap This is list when index of list is version of database and value if function that should be upgrade database.
|
||||
* @see DataBaseNode::dbPatch
|
||||
* @see DBPatchMap
|
||||
*/
|
||||
typedef QList<DBPatch> DBPatchMap;
|
||||
|
||||
/**
|
||||
* @brief The BaseNode class is database base implementation of nodes or servers.
|
||||
* This implementation contains methods for work with database.
|
||||
@ -395,6 +409,40 @@ protected:
|
||||
*/
|
||||
virtual void objectChanged(const QSharedPointer<PKG::DBObject>& obj);
|
||||
|
||||
/**
|
||||
* @brief dbPatches This method should be return map with functions that upgrade production data base.
|
||||
* Eeach function shoul be can upgrade databae from preview version to own version.
|
||||
* **Example**:
|
||||
*
|
||||
* We have 4 version of data base {0, 1, 2, 3} each version should be contains own function for upgrade data base.
|
||||
* Where the 0 version is first version of database. (genesis)
|
||||
*
|
||||
* @code{cpp}
|
||||
* QH::DBPatchMap dbPatches() const {
|
||||
QH::DBPatchMap result;
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 0 to 1
|
||||
};
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 1 to 2
|
||||
};
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
// Some code for update from 2 to 3
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
* @endcode
|
||||
*
|
||||
* @return Map of database pactches.
|
||||
*
|
||||
* @see DBPatchMap
|
||||
* @see DBPatch
|
||||
*/
|
||||
virtual DBPatchMap dbPatches() const;
|
||||
|
||||
private slots:
|
||||
void handleObjectChanged(const QSharedPointer<PKG::DBObject> &item);
|
||||
@ -415,6 +463,13 @@ private:
|
||||
|
||||
bool isForbidenTable(const QString& table);
|
||||
|
||||
/**
|
||||
* @brief upgradeDataBase This method upgrade data base to actyaly database version.
|
||||
* @note The last version of dbPatches is actyaly version.
|
||||
* @return true if operation finished successful
|
||||
*/
|
||||
bool upgradeDataBase();
|
||||
|
||||
ISqlDBCache *_db = nullptr;
|
||||
QString _localNodeName;
|
||||
WebSocketController *_webSocketWorker = nullptr;
|
||||
|
@ -120,6 +120,14 @@ public:
|
||||
bool insertIfExistsUpdateObject(const QSharedPointer<QH::PKG::DBObject>& saveObject,
|
||||
bool wait = true);
|
||||
|
||||
/**
|
||||
* @brief doQuery This method execute a @a query in this database.
|
||||
* @param query This is query that will be executed.
|
||||
* @param result This is query result value.
|
||||
* @warning The result works onlt on await mode. Set the @a wait param to true.
|
||||
* @return true if the query finished successful
|
||||
*/
|
||||
virtual bool doQuery(const QString& query, bool wait = false, QSqlQuery* result = nullptr) const = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -214,6 +214,16 @@ bool ISqlDBCache::insertObject(const QSharedPointer<DBObject> &saveObject, bool
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ISqlDBCache::doQuery(const QString &query, bool wait,
|
||||
QSqlQuery *result) const {
|
||||
|
||||
if (!_writer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return _writer->doQuery(query, wait, result);
|
||||
}
|
||||
|
||||
bool ISqlDBCache::init(const QString &initDbParams) {
|
||||
|
||||
if (!_writer) {
|
||||
|
@ -107,6 +107,8 @@ public:
|
||||
bool insertObject(const QSharedPointer<QH::PKG::DBObject>& saveObject,
|
||||
bool wait = false) override;
|
||||
|
||||
bool doQuery(const QString &query, bool wait = false, QSqlQuery* result = nullptr) const override;
|
||||
|
||||
/**
|
||||
* @brief changeObjects This method change object of the database.
|
||||
* @param templateObject This is template for get objects from database.
|
||||
@ -258,6 +260,7 @@ signals:
|
||||
*/
|
||||
void sigItemDeleted(const DbAddress& obj);
|
||||
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -14,10 +14,11 @@ namespace QH {
|
||||
|
||||
namespace PKG {
|
||||
|
||||
GetSingleValue::GetSingleValue(const DbAddress& address, const QString& field):
|
||||
GetSingleValue::GetSingleValue(const DbAddress& address, const QString& field, const QString& primaryKey):
|
||||
DBObject(address) {
|
||||
|
||||
_field = field;
|
||||
_key = primaryKey;
|
||||
}
|
||||
|
||||
QVariant GetSingleValue::value() const {
|
||||
@ -29,9 +30,9 @@ DBObject *GetSingleValue::createDBObject() const {
|
||||
}
|
||||
|
||||
PrepareResult GetSingleValue::prepareSelectQuery(QSqlQuery &q) const {
|
||||
QString queryString = "SELECT %0 FROM %1 WHERE id='%2'";
|
||||
QString queryString = "SELECT %0 FROM %1 WHERE %2='%3'";
|
||||
|
||||
queryString = queryString.arg(_field, tableName(), getId().toString());
|
||||
queryString = queryString.arg(_field, tableName(), _key, getId().toString());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
return PrepareResult::Fail;
|
||||
@ -51,7 +52,7 @@ bool GetSingleValue::isCached() const {
|
||||
}
|
||||
|
||||
QString GetSingleValue::primaryKey() const {
|
||||
return "";
|
||||
return _key;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ namespace PKG {
|
||||
|
||||
/**
|
||||
* @brief The GetSingleValue class is intended for get a single value from database.
|
||||
* The value is selected by id.
|
||||
* The value is selected by primaryKey. By Default the primary key is 'id'
|
||||
*/
|
||||
class HEARTSHARED_EXPORT GetSingleValue final: public DBObject
|
||||
{
|
||||
@ -29,8 +29,9 @@ public:
|
||||
* @brief GetSingleValue This is default constructor of the GetMaxIntegerId class.
|
||||
* @param address This is address of getting object.
|
||||
* @param field This is name of field.
|
||||
* @param primaryKey This is primary key that will be using in selected query.
|
||||
*/
|
||||
GetSingleValue(const DbAddress& address, const QString& field);
|
||||
GetSingleValue(const DbAddress& address, const QString& field, const QString& primaryKey = "id");
|
||||
|
||||
/**
|
||||
* @brief value This method return Maximum value of a sql tables field.
|
||||
@ -50,6 +51,7 @@ protected:
|
||||
private:
|
||||
QString _field;
|
||||
QVariant _value;
|
||||
QString _key;
|
||||
|
||||
};
|
||||
}
|
||||
|
@ -6,7 +6,8 @@
|
||||
*/
|
||||
|
||||
#include "setsinglevalue.h"
|
||||
|
||||
#include "quasarapp.h"
|
||||
#include <QSqlError>
|
||||
#include <QSqlQuery>
|
||||
|
||||
namespace QH {
|
||||
@ -17,11 +18,13 @@ namespace PKG {
|
||||
|
||||
SetSingleValue::SetSingleValue(const DbAddress& address,
|
||||
const QString& field,
|
||||
const QVariant& value):
|
||||
const QVariant& value,
|
||||
const QString &primaryKey):
|
||||
DBObject(address)
|
||||
{
|
||||
_field = field;
|
||||
_value = value;
|
||||
_primaryKey = primaryKey;
|
||||
}
|
||||
|
||||
DBObject *SetSingleValue::createDBObject() const {
|
||||
@ -29,12 +32,14 @@ DBObject *SetSingleValue::createDBObject() const {
|
||||
}
|
||||
|
||||
PrepareResult SetSingleValue::prepareUpdateQuery(QSqlQuery &q) const {
|
||||
QString queryString = "UPDATE %0 SET %1=:%1 WHERE id='%2'";
|
||||
QString queryString = "UPDATE %0 SET %1=:%1 WHERE %2='%3'";
|
||||
|
||||
queryString = queryString.arg(tableName(), _field, getId().toString());
|
||||
queryString = queryString.arg(tableName(), _field, primaryKey(), getId().toString());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
|
||||
QuasarAppUtils::Params::log("Failed to prepare query: " + q.lastError().text(),
|
||||
QuasarAppUtils::Error);
|
||||
return PrepareResult::Fail;
|
||||
}
|
||||
|
||||
@ -43,6 +48,24 @@ PrepareResult SetSingleValue::prepareUpdateQuery(QSqlQuery &q) const {
|
||||
return PrepareResult::Success;
|
||||
}
|
||||
|
||||
PrepareResult SetSingleValue::prepareInsertQuery(QSqlQuery &q) const {
|
||||
QString queryString = "INSERT INTO %0 (%1, %2) VALUES (:%1, :%2)";
|
||||
|
||||
queryString = queryString.arg(tableName(), primaryKey(), _field, getId().toString());
|
||||
|
||||
if (!q.prepare(queryString)) {
|
||||
|
||||
QuasarAppUtils::Params::log("Failed to prepare query: " + q.lastError().text(),
|
||||
QuasarAppUtils::Error);
|
||||
return PrepareResult::Fail;
|
||||
}
|
||||
|
||||
q.bindValue(":" + primaryKey(), getId().toString());
|
||||
q.bindValue(":" + _field, _value);
|
||||
|
||||
return PrepareResult::Success;
|
||||
}
|
||||
|
||||
bool SetSingleValue::fromSqlRecord(const QSqlRecord &) {
|
||||
return true;
|
||||
}
|
||||
@ -52,7 +75,7 @@ bool SetSingleValue::isCached() const {
|
||||
}
|
||||
|
||||
QString SetSingleValue::primaryKey() const {
|
||||
return "";
|
||||
return _primaryKey;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -38,13 +38,17 @@ public:
|
||||
* @param address This is address of the field intended for update object.
|
||||
* @param field This is field id (column name ) of the intended for update object.
|
||||
* @param value This is a new value.
|
||||
* @param primaryKey This is primary key that will be used for insert of update value. By Default is is id
|
||||
*/
|
||||
SetSingleValue(const DbAddress& address,
|
||||
const QString& field,
|
||||
const QVariant& value);
|
||||
const QVariant& value,
|
||||
const QString& primaryKey = "id");
|
||||
|
||||
DBObject *createDBObject() const override;
|
||||
PrepareResult prepareUpdateQuery(QSqlQuery &q) const override;
|
||||
PrepareResult prepareInsertQuery(QSqlQuery &q) const override;
|
||||
|
||||
bool fromSqlRecord(const QSqlRecord &q) override;
|
||||
bool isCached() const override;
|
||||
|
||||
@ -54,6 +58,7 @@ protected:
|
||||
|
||||
private:
|
||||
QString _field;
|
||||
QString _primaryKey;
|
||||
QVariant _value;
|
||||
};
|
||||
|
||||
|
@ -131,6 +131,26 @@ bool SqlDBWriter::initDbPrivate(const QVariantMap ¶ms) {
|
||||
return initSuccessful;
|
||||
}
|
||||
|
||||
bool SqlDBWriter::doQueryPrivate(const QString &query, QSqlQuery* result) const {
|
||||
if (!db()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
QSqlQuery q(query, *db());
|
||||
|
||||
if (!q.exec()) {
|
||||
QuasarAppUtils::Params::log("request error : " + q.lastError().text());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (result) {
|
||||
*result = q;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool SqlDBWriter::enableFK() {
|
||||
if (!db()) {
|
||||
return false;
|
||||
@ -317,6 +337,18 @@ bool SqlDBWriter::insertQuery(const QSharedPointer<DBObject> &ptr) const {
|
||||
return workWithQuery(q, prepare, cb, ptr->printError());
|
||||
}
|
||||
|
||||
bool SqlDBWriter::doQuery(const QString &query,
|
||||
bool wait, QSqlQuery* result) const {
|
||||
|
||||
wait = result || wait;
|
||||
|
||||
Async::Job job = [this, query, result]() {
|
||||
return doQueryPrivate(query, result);
|
||||
};
|
||||
|
||||
return asyncLauncher(job, wait);
|
||||
}
|
||||
|
||||
bool SqlDBWriter::selectQuery(const DBObject& requestObject,
|
||||
QList<QSharedPointer<QH::PKG::DBObject>> &result) {
|
||||
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
bool deleteObject(const QSharedPointer<PKG::DBObject> &ptr, bool wait = false) override;
|
||||
bool insertObject(const QSharedPointer<PKG::DBObject> &ptr, bool wait = false) override;
|
||||
void setSQLSources(const QStringList &list) override;
|
||||
bool doQuery(const QString& query, bool wait = false, QSqlQuery *result = nullptr) const override;
|
||||
|
||||
/**
|
||||
* @brief databaseLocation This method return location of database.
|
||||
@ -213,6 +214,14 @@ private:
|
||||
*/
|
||||
bool initDbPrivate(const QVariantMap ¶ms);
|
||||
|
||||
/**
|
||||
* @brief doQueryPrivate This method execute a @a query in this database.
|
||||
* @param query This is query that will be executed.
|
||||
* @param result This is pointer to result value.
|
||||
* @return true if query finished successfull
|
||||
*/
|
||||
bool doQueryPrivate(const QString& query, QSqlQuery *result) const;
|
||||
|
||||
bool initSuccessful = false;
|
||||
QVariantMap _config;
|
||||
QStringList _SQLSources;
|
||||
|
@ -36,8 +36,10 @@ protected:
|
||||
_ping.setAnsver(ping->ansver());
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
QH::PKG::Ping _ping;
|
||||
|
||||
};
|
||||
|
||||
class BadTstClient: public QH::DataBaseNode {
|
||||
|
83
HeartTests/DataBaseSpace/upgradedatabasetest.cpp
Normal file
83
HeartTests/DataBaseSpace/upgradedatabasetest.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include "upgradedatabasetest.h"
|
||||
#include "databasenode.h"
|
||||
|
||||
#include <QSqlQuery>
|
||||
#include <QSqlResult>
|
||||
#include <iobjectprovider.h>
|
||||
#include <QtTest>
|
||||
#include <isqldbcache.h>
|
||||
#define LOCAL_TEST_PORT TEST_PORT + 5
|
||||
|
||||
class UpgradableDatabase: public QH::DataBaseNode {
|
||||
|
||||
|
||||
// DataBaseNode interface
|
||||
public:
|
||||
|
||||
bool checkVersion(int version) {
|
||||
QSqlQuery query;
|
||||
if (!db()->doQuery("SELECT * FROM DataBaseAttributes WHERE name='version'", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
if (!query.next()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int ver = query.value("value").toInt();
|
||||
return ver == version;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
QH::DBPatchMap dbPatches() const {
|
||||
QH::DBPatchMap result;
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
result += [](const QH::iObjectProvider* database) -> bool {
|
||||
QSqlQuery query;
|
||||
if (!database->doQuery("select * from DataBaseAttributes", true, &query)){
|
||||
return false;
|
||||
};
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
UpgradeDataBaseTest::UpgradeDataBaseTest() {
|
||||
|
||||
}
|
||||
|
||||
void UpgradeDataBaseTest::test() {
|
||||
|
||||
UpgradableDatabase *db = new UpgradableDatabase();
|
||||
|
||||
QVERIFY(db->run(TEST_LOCAL_HOST, LOCAL_TEST_PORT, "UpgradeDBTest"));
|
||||
|
||||
QVERIFY(db->checkVersion(3));
|
||||
|
||||
db->stop();
|
||||
QVERIFY(db->run(TEST_LOCAL_HOST, LOCAL_TEST_PORT, "UpgradeDBTest"));
|
||||
db->softDelete();
|
||||
}
|
16
HeartTests/DataBaseSpace/upgradedatabasetest.h
Normal file
16
HeartTests/DataBaseSpace/upgradedatabasetest.h
Normal file
@ -0,0 +1,16 @@
|
||||
#ifndef UPGRADEDATABASETEST_H
|
||||
#define UPGRADEDATABASETEST_H
|
||||
#include "test.h"
|
||||
#include "basetestutils.h"
|
||||
|
||||
class UpgradeDataBaseTest: public Test, protected BaseTestUtils
|
||||
{
|
||||
public:
|
||||
UpgradeDataBaseTest();
|
||||
|
||||
// Test interface
|
||||
public:
|
||||
void test();
|
||||
};
|
||||
|
||||
#endif // UPGRADEDATABASETEST_H
|
@ -15,6 +15,7 @@
|
||||
#include <basenodetest.h>
|
||||
#include <bigdatatest.h>
|
||||
#include <singleservertest.h>
|
||||
#include <upgradedatabasetest.h>
|
||||
#endif
|
||||
#if HEART_BUILD_LVL >= 2
|
||||
#include <networknodetest.h>
|
||||
@ -43,6 +44,7 @@ private slots:
|
||||
#if HEART_BUILD_LVL >= 1
|
||||
TestCase(baseNodeTest, BaseNodeTest)
|
||||
TestCase(singleNodeTest, SingleServerTest)
|
||||
TestCase(upgradeDataBaseTest, UpgradeDataBaseTest)
|
||||
#endif
|
||||
#if HEART_BUILD_LVL >= 2
|
||||
TestCase(networkNodeTest, NetworkNodeTest)
|
||||
|
Loading…
x
Reference in New Issue
Block a user