upgrade passed by sqlite [skip ci]

This commit is contained in:
Hamed Masafi 2019-02-16 17:06:38 +03:30
parent a0550b4e65
commit f3748241ff
19 changed files with 160 additions and 75 deletions

View File

@ -35,7 +35,7 @@ class ChangeLogTable : public Table
NUT_DECLARE_FIELD(QString, data, data, setData)
NUT_DECLARE_FIELD(QString, version, version, setVersion)
NUT_DECLARE_FIELD(int, version, version, setVersion)
public:
explicit ChangeLogTable(QObject *parentTableSet = Q_NULLPTR);

View File

@ -173,16 +173,6 @@ bool DatabasePrivate::updateDatabase()
if (db.lastError().type() == QSqlError::NoError) {
q->databaseUpdated(last.version(), current.version());
//TODO: remove this
for (int i = 0; i < q->metaObject()->methodCount(); i++) {
QMetaMethod m = q->metaObject()->method(i);
if (m.name() == "update" + current.version()) {
m.invoke(q, Qt::DirectConnection,
Q_ARG(QString, current.version()));
break;
}
}
} else {
qWarning("Unable update database, error = %s",
db.lastError().text().toLatin1().data());
@ -220,7 +210,9 @@ bool DatabasePrivate::getCurrectScheema()
if (!nutClassInfoString(q->metaObject()->classInfo(i),
type, name, value)) {
qDebug() << "No valid table in" << q->metaObject()->classInfo(i).value();
errorMessage = QString("No valid table in %1")
.arg(q->metaObject()->classInfo(i).value());
continue;
}
if (type == __nut_TABLE) {
@ -232,13 +224,17 @@ bool DatabasePrivate::getCurrectScheema()
if (!typeId)
qFatal("The class %s is not registered with qt meta object", qPrintable(name));
qDebug() << "Table found" << typeId;
TableModel *sch = new TableModel(typeId, value);
currentModel.append(sch);
}
if (type == __nut_DB_VERSION)
currentModel.setVersion(name);
if (type == __nut_DB_VERSION) {
bool ok;
int version = value.toInt(&ok);
if (!ok)
qFatal("NUT_DB_VERSION macro accept version in format 'x'");
currentModel.setVersion(version);
/* TODO: remove
QStringList version
@ -255,6 +251,7 @@ qDebug() << "Table found" << typeId;
qFatal("NUT_DB_VERSION macro accept version in format 'x' or "
"'x[.y]' only, and x,y must be integer values\n");*/
}
}
for (int i = 1; i < q->metaObject()->propertyCount(); i++) {
QMetaProperty tableProperty = q->metaObject()->property(i);
@ -337,7 +334,7 @@ bool DatabasePrivate::putModelToDatabase()
/*current.remove(__CHANGE_LOG_TABLE_NAME)*/;
auto *changeLog = new ChangeLogTable();
changeLog->setData(QJsonDocument(current.toJson()).toJson());
changeLog->setData(QJsonDocument(current.toJson()).toJson(QJsonDocument::Compact));
changeLog->setVersion(current.version());
changeLogs->append(changeLog);
q->saveChanges();
@ -359,9 +356,10 @@ bool DatabasePrivate::putModelToDatabase()
void DatabasePrivate::createChangeLogs()
{
// currentModel.model("change_log")
QString diff = sqlGenertor->diff(nullptr, currentModel.tableByName("__change_log"));
QStringList diff = sqlGenertor->diff(nullptr, currentModel.tableByName("__change_log"));
db.exec(diff);
foreach (QString s, diff)
db.exec(s);
}
/*!
@ -530,7 +528,7 @@ QSqlDatabase Database::database()
return d->db;
}
void Database::databaseUpdated(QString oldVersion, QString newVersion)
void Database::databaseUpdated(int oldVersion, int newVersion)
{
Q_UNUSED(oldVersion);
Q_UNUSED(newVersion);

View File

@ -73,7 +73,7 @@ public:
protected:
//remove minor version
virtual void databaseUpdated(QString oldVersion, QString newVersion);
virtual void databaseUpdated(int oldVersion, int newVersion);
public slots:
void setDatabaseName(QString databaseName);

View File

@ -70,6 +70,8 @@ public:
QSet<TableSetBase *> tableSets;
bool isDatabaseNew;
QString errorMessage;
};
NUT_END_NAMESPACE

View File

@ -31,13 +31,13 @@ QMap<QString, DatabaseModel*> DatabaseModel::_models;
#define NODE_VERSION "version"
#define NODE_TABLES "tables"
DatabaseModel::DatabaseModel(const QString &name) :
QList<TableModel*>(), _databaseClassName(name), _version(QString())
QList<TableModel*>(), _databaseClassName(name), _version(0)
{
_models.insert(name, this);
}
DatabaseModel::DatabaseModel(const DatabaseModel &other) :
QList<TableModel*>(other), _version(QString())
QList<TableModel*>(other), _version(0)
{
}
@ -45,7 +45,7 @@ DatabaseModel::DatabaseModel(const DatabaseModel &other) :
DatabaseModel::DatabaseModel(const QJsonObject &json) :
QList<TableModel*>()
{
setVersion(json.value(NODE_VERSION).toString());
setVersion(json.value(NODE_VERSION).toInt());
QJsonObject tables = json.value(NODE_TABLES).toObject();
foreach (QString key, tables.keys()) {
@ -171,7 +171,7 @@ DatabaseModel DatabaseModel::fromJson(QJsonObject &json)
{
DatabaseModel model;
model.setVersion(json.value(NODE_VERSION).toString());
model.setVersion(json.value(NODE_VERSION).toInt());
QJsonObject tables = json.value(NODE_TABLES).toObject();
foreach (QString key, tables.keys()) {
@ -184,12 +184,12 @@ DatabaseModel DatabaseModel::fromJson(QJsonObject &json)
return model;
}
QString DatabaseModel::version() const
int DatabaseModel::version() const
{
return _version;
}
void DatabaseModel::setVersion(QString version)
void DatabaseModel::setVersion(int version)
{
_version = version;
}

View File

@ -36,7 +36,7 @@ struct RelationModel;
class DatabaseModel : public QList<TableModel *>
{
QString _databaseClassName;
QString _version;
int _version;
static QMap<QString, DatabaseModel *> _models;
public:
@ -61,8 +61,8 @@ public:
QJsonObject toJson() const;
operator QJsonObject();
QString version() const;
void setVersion(QString version);
int version() const;
void setVersion(int version);
bool remove(const QString &tableName);

View File

@ -171,13 +171,9 @@ QString PostgreSqlGenerator::fieldType(FieldModel *field)
return "TEXT";
default:
qDebug() << "Type for " << (int)field->type << field->type << "(" << QMetaType::typeName(field->type) << ")" << "nut supported";
dbType = QString();
}
if(field->type == (unsigned)QMetaType::type("Nut::DbGeography"))
dbType = "GEOGRAPHY";
return dbType;
}

View File

@ -132,7 +132,7 @@ QStringList SqlGeneratorBase::diff(const DatabaseModel &lastModel,
foreach (TableModel *table, unionModel) {
TableModel *oldTable = lastModel.tableByName(table->name());
TableModel *newTable = newModel.tableByName(table->name());
QString sql = diff(oldTable, newTable);
QStringList sql = diff(oldTable, newTable);
if (!sql.isEmpty())
ret << sql;
// QString sqlRel = diffRelation(oldTable, newTable);
@ -148,7 +148,7 @@ QString SqlGeneratorBase::diff(FieldModel *oldField, FieldModel *newField)
QString sql = QString();
if (oldField && newField)
if (*oldField == *newField)
return QString();
return sql;
if (!newField) {
sql = "DROP COLUMN " + oldField->name;
@ -162,14 +162,14 @@ QString SqlGeneratorBase::diff(FieldModel *oldField, FieldModel *newField)
return sql;
}
QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
QStringList SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
{
if (oldTable && newTable)
if (*oldTable == *newTable)
return QString();
return QStringList();
if (!newTable)
return "DROP TABLE " + oldTable->name();
return QStringList() << ("DROP TABLE " + oldTable->name());
QList<QString> fieldNames;
QList<QString> relations;
@ -197,12 +197,12 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
FieldModel *oldField = oldTable->field(fieldName);
QString buffer = diff(oldField, newField);
if (!buffer.isNull())
if (!buffer.isEmpty())
columnSql << buffer;
} else {
QString declare = fieldDeclare(newField);
if (declare.isEmpty())
return declare;
return QStringList() << declare;
columnSql << declare;
}
}
@ -231,14 +231,16 @@ QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable)
sql = QString("CREATE TABLE %1 \n(%2)")
.arg(newTable->name(), columnSql.join(",\n"));
}
return sql;
return QStringList() << sql;
}
QString SqlGeneratorBase::diffRelation(TableModel *oldTable, TableModel *newTable)
QStringList SqlGeneratorBase::diffRelation(TableModel *oldTable, TableModel *newTable)
{
QStringList ret;
if (!newTable)
return QString();
return ret;
QList<QString> relations;
@ -258,20 +260,21 @@ QString SqlGeneratorBase::diffRelation(TableModel *oldTable, TableModel *newTabl
if (oldTable)
oldRelation = oldTable->foregionKeyByField(fieldName);
QString buffer = diff(oldRelation, newRelation);
if (!buffer.isNull())
columnSql << buffer;
QStringList buffer = diff(oldRelation, newRelation);
if (!buffer.isEmpty())
columnSql << buffer.at(0);
}
if (columnSql.count())
return "ALTER TABLE " + newTable->name() + "\n"
+ columnSql.join(",\n");
ret.append("ALTER TABLE " + newTable->name() + "\n"
+ columnSql.join(",\n"));
return QString();
return ret;
}
QString SqlGeneratorBase::diff(RelationModel *oldRel, RelationModel *newRel)
QStringList SqlGeneratorBase::diff(RelationModel *oldRel, RelationModel *newRel)
{
QStringList ret;
/*
CONSTRAINT FK_PersonOrder FOREIGN KEY (PersonID)
REFERENCES Persons(PersonID)
@ -285,19 +288,19 @@ QString SqlGeneratorBase::diff(RelationModel *oldRel, RelationModel *newRel)
.arg(newRelation->foreignColumn);
*/
if (!oldRel)
return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
ret.append(QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
"REFERENCES %2(%3)")
.arg(newRel->localColumn, newRel->masterTable->name(),
newRel->foreignColumn);
newRel->foreignColumn));
if (!newRel)
return QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
ret.append(QString("ADD CONSTRAINT FK_%1 FOREIGN KEY (%1) "
"REFERENCES %2(%3)")
.arg(oldRel->localColumn, oldRel->masterTable->name(),
oldRel->foreignColumn);
oldRel->foreignColumn));
// if (*oldRel == *newRel)
return QString();
return ret;
}
QString SqlGeneratorBase::join(const QString &mainTable,

View File

@ -84,9 +84,9 @@ public:
virtual QStringList diff(const DatabaseModel &lastModel, const DatabaseModel &newModel);
virtual QString diff(FieldModel *oldField, FieldModel *newField);
virtual QString diff(TableModel *oldTable, TableModel *newTable);
virtual QString diffRelation(TableModel *oldTable, TableModel *newTable);
virtual QString diff(RelationModel *oldRel, RelationModel *newRel);
virtual QStringList diff(TableModel *oldTable, TableModel *newTable);
virtual QStringList diffRelation(TableModel *oldTable, TableModel *newTable);
virtual QStringList diff(RelationModel *oldRel, RelationModel *newRel);
virtual QString join(const QString &mainTable,
const QList<RelationModel*> &list,

View File

@ -95,6 +95,79 @@ QString SqliteGenerator::fieldType(FieldModel *field)
}
}
QStringList SqliteGenerator::diff(TableModel *oldTable, TableModel *newTable)
{
QStringList ret;
if (oldTable && newTable)
if (*oldTable == *newTable)
return ret;
QStringList newTableSql = SqlGeneratorBase::diff(nullptr, newTable);
if (!newTable)
return QStringList() << "DROP TABLE " + oldTable->name();
if (!oldTable)
return newTableSql;
QList<QString> fieldNames;
QList<QString> relations;
foreach (FieldModel *f, oldTable->fields())
if (!fieldNames.contains(f->name))
fieldNames.append(f->name);
foreach (RelationModel *r, oldTable->foregionKeys())
if (!relations.contains(r->localColumn))
relations.append(r->localColumn);
foreach (FieldModel *f, newTable->fields())
if (!fieldNames.contains(f->name))
fieldNames.append(f->name);
foreach (RelationModel *r, newTable->foregionKeys())
if (!relations.contains(r->localColumn))
relations.append(r->localColumn);
QString columns;
foreach (FieldModel *f, oldTable->fields()) {
if (!newTable->field(f->name))
continue;
if (!columns.isEmpty())
columns.append(", ");
columns.append(f->name);
}
/*
ALTER TABLE sampleTable RENAME TO sqlitestudio_temp_table;
CREATE TABLE sampleTable (
id INTEGER PRIMARY KEY AUTOINCREMENT,
t BIGINT,
m CHAR
);
INSERT INTO sampleTable (
id,
t,
m
)
SELECT id,
t,
m
FROM sqlitestudio_temp_table;
DROP TABLE sqlitestudio_temp_table;
*/
ret.append("ALTER TABLE " + newTable->name() + " RENAME TO sqlitestudio_temp_table;");
ret.append(newTableSql);
ret.append(QString("INSERT INTO %1 ( %2 ) SELECT %2 FROM sqlitestudio_temp_table;")
.arg(newTable->name(), columns));
ret.append("DROP TABLE sqlitestudio_temp_table;");
return ret;
}
void SqliteGenerator::appendSkipTake(QString &sql, int skip, int take)
{
if (take != -1 && skip != -1)

View File

@ -31,11 +31,12 @@ class SqliteGenerator : public SqlGeneratorBase
public:
explicit SqliteGenerator(Database *parent = nullptr);
QString fieldType(FieldModel *field);
QString fieldType(FieldModel *field) override;
void appendSkipTake(QString &sql, int skip, int take);
void appendSkipTake(QString &sql, int skip, int take) override;
QString primaryKeyConstraint(const TableModel *table) const;
QString primaryKeyConstraint(const TableModel *table) const override;
QStringList diff(TableModel *oldTable, TableModel *newTable) override;
};
NUT_END_NAMESPACE

View File

@ -146,7 +146,7 @@ QString SqlServerGenerator::diff(FieldModel *oldField, FieldModel *newField)
QString sql = QString();
if (oldField && newField)
if (*oldField == *newField)
return QString();
return sql;
if (!newField) {
sql = "DROP COLUMN " + oldField->name;

View File

@ -97,14 +97,12 @@ AbstractFieldPhrase::AbstractFieldPhrase(const char *className,
const char *fieldName)
:data(new PhraseData(className, fieldName))
{
qDebug() <<"AbstractFieldPhrase created"<<className<<fieldName;
}
AbstractFieldPhrase::AbstractFieldPhrase(const AbstractFieldPhrase &other)
{
data = other.data;
data->parents++;
qDebug() <<"Copy ctor"<<other.data->toString()<<other.data->parents;
}
AbstractFieldPhrase::AbstractFieldPhrase(AbstractFieldPhrase &&other)
@ -358,7 +356,6 @@ ConditionalPhrase::ConditionalPhrase() : data(nullptr)
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
{
qDebug() << "************* ctor called:";
data = other.data;
data->parents++;
// const_cast<ConditionalPhrase&>(other).data = 0;
@ -367,7 +364,6 @@ ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &other)
#ifdef Q_COMPILER_RVALUE_REFS
ConditionalPhrase::ConditionalPhrase(const ConditionalPhrase &&other)
{
qDebug() << "************* ctor called:";
this->data = qMove(other.data);
}
#endif

View File

@ -39,9 +39,11 @@ NUT_BEGIN_NAMESPACE
* This should be fixed to v1.2
*/
Table::Table(QObject *parent) : QObject(parent), myModel(nullptr),
Table::Table(QObject *parent) : QObject(parent),
_status(NewCreated), _parentTableSet(nullptr)
{ }
{
myModel = TableModel::findByClassName(metaObject()->className());
}
void Table::add(TableSetBase *t)
{

View File

@ -22,11 +22,11 @@ JoinTest::JoinTest(QObject *parent) : QObject(parent)
void JoinTest::initTestCase()
{
qDebug() << "User type id:" << qRegisterMetaType<User*>();
qDebug() << "Post type id:" << qRegisterMetaType<Post*>();
qDebug() << "Comment type id:" << qRegisterMetaType<Comment*>();
qDebug() << "Score type id:" << qRegisterMetaType<Score*>();
qDebug() << "DB type id:" << qRegisterMetaType<WeblogDatabase*>();
REGISTER(User);
REGISTER(Post);
REGISTER(Comment);
REGISTER(Score);
REGISTER(WeblogDatabase);
db.setDriver(DRIVER);
db.setHostName(HOST);

View File

@ -19,8 +19,8 @@ UuidTest::UuidTest(QObject *parent) : QObject(parent)
void UuidTest::initTestCase()
{
qDebug() << "Test type id:" << qRegisterMetaType<Test*>();
qDebug() << "DB type id:" << qRegisterMetaType<TestDatabase*>();
REGISTER(Test);
REGISTER(TestDatabase);
QFile::remove(DATABASE);

View File

@ -10,6 +10,8 @@ class Table3 : public Nut::Table
NUT_PRIMARY_AUTO_INCREMENT(id)
NUT_DECLARE_FIELD(int, id, id, setId)
NUT_DECLARE_FIELD(QString, grade, grade, setGrade)
public:
Q_INVOKABLE Table3(QObject *parent = Q_NULLPTR);

View File

@ -7,6 +7,7 @@
#include "table1.h"
#include "table2.h"
#include "table3.h"
#include "query.h"
#include "tst_upgrades.h"
#include "consts.h"
@ -55,6 +56,12 @@ void Upgrades::version2()
DB2 db;
initDb(db);
QTEST_ASSERT(db.open());
Table2 t;
t.setStr("0");
db.sampleTable()->append(&t);
db.saveChanges();
id = t.id();
}
void Upgrades::version3()
@ -62,6 +69,10 @@ void Upgrades::version3()
DB3 db;
initDb(db);
QTEST_ASSERT(db.open());
auto t = db.sampleTable()->query()
->first();
QTEST_ASSERT(id == t->id());
}

View File

@ -12,6 +12,7 @@ class Upgrades : public QObject
void initDb(Nut::Database &db);
int id;
public:
Upgrades();
~Upgrades();