diff --git a/3rdparty/serializer b/3rdparty/serializer index e2d8a72..f9d81fc 160000 --- a/3rdparty/serializer +++ b/3rdparty/serializer @@ -1 +1 @@ -Subproject commit e2d8a726ef1396c47bf35347ea8b55ca47c6af3b +Subproject commit f9d81fcc6244271b3926891b0c86554e1e6b967e diff --git a/include/header_copier b/include/header_copier index e2ef200..e4cd72b 100755 --- a/include/header_copier +++ b/include/header_copier @@ -3,7 +3,7 @@ src_dir="src" namespace_name="nut" -ns=$(echo $namespace_name|awk '{print tolower($0)}') +#ns=$(echo $namespace_name|awk '{print tolower($0)}') Ns="Nut" NS=$(echo $namespace_name|awk '{print toupper($0)}') diff --git a/nut.pri b/nut.pri index b0f235b..b0931d8 100644 --- a/nut.pri +++ b/nut.pri @@ -3,6 +3,7 @@ QT += core sql CONFIG += c++11 INCLUDEPATH += $$PWD/include +DEFINES += NUT_SHARED_POINTER include(3rdparty/serializer/src/src.pri) HEADERS += \ diff --git a/nut.pro b/nut.pro index 3a52ab6..5a35529 100644 --- a/nut.pro +++ b/nut.pro @@ -4,4 +4,3 @@ SUBDIRS += \ src \ test - diff --git a/src/database.cpp b/src/database.cpp index 7f26b8d..e804ef4 100644 --- a/src/database.cpp +++ b/src/database.cpp @@ -278,7 +278,7 @@ bool DatabasePrivate::getCurrectScheema() DatabaseModel DatabasePrivate::getLastScheema() { - ChangeLogTable *u = changeLogs->query() + Row u = changeLogs->query() ->orderBy(!ChangeLogTable::idField()) ->first(); @@ -321,7 +321,7 @@ bool DatabasePrivate::putModelToDatabase() DatabaseModel current = currentModel; /*current.remove(__CHANGE_LOG_TABLE_NAME)*/; - auto *changeLog = new ChangeLogTable(); + auto changeLog = create(); changeLog->setData(QJsonDocument(current.toJson()).toJson(QJsonDocument::Compact)); changeLog->setVersion(current.version()); changeLogs->append(changeLog); diff --git a/src/defines.h b/src/defines.h index 86a96a3..22efbb0 100644 --- a/src/defines.h +++ b/src/defines.h @@ -209,6 +209,15 @@ inline Row create() { return QSharedPointer(new T); } +template +inline T *get(T *row) { + return row; +} +template +inline T *get(const QSharedPointer row) { + return row.data(); +} + #else template using RowList = QList; @@ -223,6 +232,17 @@ template inline Row create() { return new T; } + +template +inline T *get(const Row row) { + return row; +} + +template +inline T *get(const QSharedPointer row) { + return row.data(); +} + #endif NUT_END_NAMESPACE diff --git a/src/generators/sqlgeneratorbase.cpp b/src/generators/sqlgeneratorbase.cpp index 52ff9df..0f9590d 100644 --- a/src/generators/sqlgeneratorbase.cpp +++ b/src/generators/sqlgeneratorbase.cpp @@ -834,6 +834,9 @@ QString SqlGeneratorBase::escapeValue(const QVariant &v) const return QString(); } + if (v.type() == QVariant::List) + return serialized; + return "'" + serialized + "'"; } diff --git a/src/generators/sqlitegenerator.cpp b/src/generators/sqlitegenerator.cpp index d62f895..e97687b 100644 --- a/src/generators/sqlitegenerator.cpp +++ b/src/generators/sqlitegenerator.cpp @@ -95,7 +95,7 @@ QString SqliteGenerator::fieldDeclare(FieldModel *field) if (type.isEmpty()) return type; - if (field->isPrimaryKey) { + if (isNumeric(field->type) && field->isPrimaryKey) { type = "INTEGER PRIMARY KEY"; if (field->isAutoIncrement) type.append(" AUTOINCREMENT"); diff --git a/src/query.h b/src/query.h index e4c0c9a..57b6a1d 100644 --- a/src/query.h +++ b/src/query.h @@ -185,7 +185,7 @@ Q_OUTOFLINE_TEMPLATE RowList Query::toList(int count) d->sql = d->database->sqlGenertor()->selectCommand( d->tableName, d->fieldPhrase, d->wherePhrase, d->orderPhrase, d->relations, d->skip, d->take); - +qDebug()<sql; QSqlQuery q = d->database->exec(d->sql); if (q.lastError().isValid()) { qDebug() << q.lastError().text(); @@ -346,7 +346,6 @@ Q_OUTOFLINE_TEMPLATE RowList Query::toList(int count) if (m_autoDelete) deleteLater(); #endif - return returnList; } diff --git a/src/query_p.h b/src/query_p.h index 7fe9eec..b0b3c4a 100644 --- a/src/query_p.h +++ b/src/query_p.h @@ -23,8 +23,9 @@ #include "phrase.h" -#include -#include +#include +#include +#include NUT_BEGIN_NAMESPACE @@ -32,7 +33,7 @@ class Database; class TableSetBase; class QueryBase; struct RelationModel; -class QueryPrivate{ +class QueryPrivate : public QSharedData { QueryBase *q_ptr; Q_DECLARE_PUBLIC(QueryBase) diff --git a/src/querybase.cpp b/src/querybase.cpp index 5a9526d..f14f16e 100644 --- a/src/querybase.cpp +++ b/src/querybase.cpp @@ -11,9 +11,9 @@ QueryBase::QueryBase(QObject *parent) : QObject(parent) } -void QueryBase::addTableToSet(TableSetBase *set, Table *table) -{ - set->add(table); -} +//void QueryBase::addTableToSet(TableSetBase *set, Table *table) +//{ +// set->add(table); +//} NUT_END_NAMESPACE diff --git a/src/querybase_p.h b/src/querybase_p.h index 4d53ce3..2ef0386 100644 --- a/src/querybase_p.h +++ b/src/querybase_p.h @@ -23,7 +23,10 @@ #include #include +#include + #include "defines.h" +#include "query_p.h" NUT_BEGIN_NAMESPACE @@ -33,11 +36,15 @@ class TableSetBase; class QueryBase : public QObject { Q_OBJECT + +protected: + QExplicitlySharedDataPointer d; + public: explicit QueryBase(QObject *parent = 0); protected: - void addTableToSet(TableSetBase *set, Table *table); +// void addTableToSet(TableSetBase *set, Table *table); public slots: }; diff --git a/src/sqlmodel_p.h b/src/sqlmodel_p.h index f3ec5c4..1991d9c 100644 --- a/src/sqlmodel_p.h +++ b/src/sqlmodel_p.h @@ -1,6 +1,7 @@ #ifndef SQLMODEL_P_H #define SQLMODEL_P_H +#include #include #include "defines.h" @@ -17,7 +18,7 @@ public: QString tableName; - QList rows; + RowList rows; TableModel *model; }; diff --git a/src/src.pri b/src/src.pri index 84d9a48..79319e3 100644 --- a/src/src.pri +++ b/src/src.pri @@ -1,9 +1,12 @@ +DEFINES += NUT_SHARED_POINTER + HEADERS += \ $$PWD/generators/sqlgeneratorbase_p.h \ $$PWD/generators/postgresqlgenerator.h \ $$PWD/generators/mysqlgenerator.h \ $$PWD/generators/sqlitegenerator.h \ $$PWD/generators/sqlservergenerator.h \ + $$PWD/tablesetbasedata.h \ $$PWD/types/dbgeography.h \ $$PWD/tableset.h \ $$PWD/defines_p.h \ diff --git a/src/tableset.h b/src/tableset.h index 7748614..d85e1d6 100644 --- a/src/tableset.h +++ b/src/tableset.h @@ -30,8 +30,8 @@ #include "tablesetbase_p.h" #include "table.h" #include "bulkinserter.h" -//#include "database.h" #include "databasemodel.h" +#include "tablesetbasedata.h" NUT_BEGIN_NAMESPACE @@ -40,20 +40,23 @@ class Query; class BulkInserter; class Database; + template class NUT_EXPORT TableSet : public TableSetBase { public: + typedef T value_type; + typedef T *pointer; + typedef T &reference; + explicit TableSet(Database *parent); explicit TableSet(Table *parent); - void append(T *t); - void append(QList t); + void append(Row t); + void append(RowList t); void remove(T *t); void remove(QList t); - inline T *type() const {} - int length() const; T *at(int i) const; const T &operator[](int i) const; @@ -65,19 +68,19 @@ public: template Q_OUTOFLINE_TEMPLATE TableSet::TableSet(Database *parent) : TableSetBase(parent) { - _childClassName = T::staticMetaObject.className(); + data->childClassName = T::staticMetaObject.className(); } template Q_OUTOFLINE_TEMPLATE TableSet::TableSet(Table *parent) : TableSetBase(parent) { - _childClassName = T::staticMetaObject.className(); + data->childClassName = T::staticMetaObject.className(); } template Q_OUTOFLINE_TEMPLATE Query *TableSet::query(bool autoDelete) { - Query *q = new Query(_database, this, autoDelete); + Query *q = new Query(data->database, this, autoDelete); return q; } @@ -85,34 +88,36 @@ Q_OUTOFLINE_TEMPLATE Query *TableSet::query(bool autoDelete) template Q_OUTOFLINE_TEMPLATE BulkInserter *TableSet::bulkInserter() { - BulkInserter *bi = new BulkInserter(_database, _childClassName); + BulkInserter *bi = new BulkInserter(data->database, data->childClassName); return bi; - } template Q_OUTOFLINE_TEMPLATE int TableSet::length() const { - return _tables.count(); + return data->tables.count(); } template Q_OUTOFLINE_TEMPLATE T *TableSet::at(int i) const { - return reinterpret_cast(_childRows.at(i)); + //TODO: check + return reinterpret_cast(data->childRows.at(i)); } template Q_OUTOFLINE_TEMPLATE const T &TableSet::operator[](int i) const { - return _childRows[i]; + return data->childRows[i]; } template -Q_OUTOFLINE_TEMPLATE void TableSet::append(T *t) +Q_OUTOFLINE_TEMPLATE void TableSet::append(Row t) { - _tables.insert(t); - _childRows.append(t); + data.detach(); + data->childs.append(t); + data->tables.insert(t.data()); + data->childRows.append(t.data()); // if (_database) // t->setModel(_database->model().tableByClassName(t->metaObject()->className())); @@ -123,16 +128,18 @@ Q_OUTOFLINE_TEMPLATE void TableSet::append(T *t) } template -Q_OUTOFLINE_TEMPLATE void TableSet::append(QList t) +Q_OUTOFLINE_TEMPLATE void TableSet::append(RowList t) { - foreach (T* i, t) + foreach (Row i, t) append(i); } template Q_OUTOFLINE_TEMPLATE void TableSet::remove(T *t) { - _tables.remove(t); + data.detach(); + data->childs.removeOne(t); + data->tables.remove(t); t->setStatus(Table::Deleted); } diff --git a/src/tablesetbase.cpp b/src/tablesetbase.cpp index 9b04a7a..1cf0b0d 100644 --- a/src/tablesetbase.cpp +++ b/src/tablesetbase.cpp @@ -22,24 +22,25 @@ #include "database.h" #include "tablesetbase_p.h" #include "databasemodel.h" +#include "tablesetbasedata.h" NUT_BEGIN_NAMESPACE TableSetBase::TableSetBase(Database *parent) : QObject(parent), - _database(parent), _table(nullptr)//, _tableName(QString()) + data(new TableSetBaseData(parent)) { parent->add(this); } TableSetBase::TableSetBase(Table *parent) : QObject(parent), - _database(nullptr), _table(parent)//, _tableName(QString()) + data(new TableSetBaseData(parent)) { parent->add(this); } TableSetBase::~TableSetBase() { - foreach (Table *t, _tables) + foreach (Table *t, data->tables) t->setParentTableSet(nullptr); } @@ -47,12 +48,13 @@ int TableSetBase::save(Database *db, bool cleanUp) { int rowsAffected = 0; TableModel *masterModel = nullptr; - if (_table) - masterModel = db->model().tableByClassName(_table->metaObject()->className()); + if (data->table) + masterModel = db->model().tableByClassName(data->table->metaObject()->className()); - foreach (Table *t, _childRows) { - if(_table) - t->setParentTable(_table, masterModel, + foreach (Table *t, data->childRows) { + if(data->table) + t->setParentTable(data->table, + masterModel, db->model().tableByClassName(t->metaObject()->className())); if(t->status() == Table::Added @@ -66,45 +68,50 @@ int TableSetBase::save(Database *db, bool cleanUp) } if (cleanUp) - _childRows.clear(); + data->childRows.clear(); return rowsAffected; } void TableSetBase::clearChilds() { - foreach (Table *t, _childRows) +#ifndef NUT_SHARED_POINTER + foreach (Table *t, data->_childRows) t->deleteLater(); - _childRows.clear(); +#endif + data->childRows.clear(); } void TableSetBase::add(Table *t) { - if(!_tables.contains(t)){ - _tables.insert(t); - _childRows.append(t); + if(!data->tables.contains(get(t))){ + data.detach(); + data->tables.insert(get(t)); + data->childRows.append(get(t)); } } void TableSetBase::remove(Table *t) { - _tables.remove(t); - _childRows.removeOne(t); + data.detach(); + data->tables.remove(get(t)); + data->childRows.removeOne(get(t)); } QString TableSetBase::childClassName() const { - return _childClassName; + return data->childClassName; } Database *TableSetBase::database() const { - return _database; + return data->database; } void TableSetBase::setDatabase(Database *database) { - _database = database; + data.detach(); + data->database = database; } NUT_END_NAMESPACE diff --git a/src/tablesetbase_p.h b/src/tablesetbase_p.h index 114f458..cb8c6d2 100644 --- a/src/tablesetbase_p.h +++ b/src/tablesetbase_p.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "defines.h" @@ -31,6 +32,7 @@ NUT_BEGIN_NAMESPACE class Table; class Database; +class TableSetBaseData; class TableSetBase : public QObject { @@ -47,16 +49,17 @@ public: void setDatabase(Database *database); protected: - QSet _tables; - QList _childRows; - Database *_database; - Table *_table; -// QString _tableName; - QString _childClassName; +// QSet _tables; +// RowList
_childRows; +// Database *_database; +// Table *_table; +//// QString _tableName; +// QString _childClassName; + QExplicitlySharedDataPointer data; private: void add(Table* t); - void remove(Table* t); + void remove(Table *t); friend class Table; friend class QueryBase; diff --git a/src/tablesetbasedata.h b/src/tablesetbasedata.h new file mode 100644 index 0000000..f0fe881 --- /dev/null +++ b/src/tablesetbasedata.h @@ -0,0 +1,53 @@ +/************************************************************************** +** +** This file is part of Nut project. +** https://github.com/HamedMasafi/Nut +** +** Nut is free software: you can redistribute it and/or modify +** it under the terms of the GNU Lesser General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** Nut is distributed in the hope that it will be useful, +** but WITHOUT ANY WARRANTY; without even the implied warranty of +** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +** GNU Lesser General Public License for more details. +** +** You should have received a copy of the GNU Lesser General Public License +** along with Nut. If not, see . +** +**************************************************************************/ + +#ifndef TABLESETBASEDATA_H +#define TABLESETBASEDATA_H + +#include +#include "defines.h" + +NUT_BEGIN_NAMESPACE + +class Table; +class Database; +class TableSetBaseData : public QSharedData +{ +public: + TableSetBaseData(Database *parent) : + database(parent), table(nullptr) + { } + + TableSetBaseData(Table *parent) : + database(nullptr), table(parent) + { } + + QSet tables; + QList childRows; + RowList
childs; + + Database *database; + Table *table; + QString childClassName; +}; + +NUT_END_NAMESPACE + +#endif // TABLESETBASEDATA_H diff --git a/test/common/consts.h b/test/common/consts.h index 5b34315..ca49e2e 100644 --- a/test/common/consts.h +++ b/test/common/consts.h @@ -11,7 +11,7 @@ .arg(timer.elapsed() / 1000.) \ .arg(__func__) -#define DRIVER "QPSQL" +#define DRIVER "QSQLITE" #define DATABASE QString("nut_test_%1_db").arg(metaObject()->className()).toLower() #define HOST "127.0.0.1" #define USERNAME "postgres" diff --git a/test/common/nut-lib.pri b/test/common/nut-lib.pri index 47b0640..ade3e61 100644 --- a/test/common/nut-lib.pri +++ b/test/common/nut-lib.pri @@ -8,3 +8,5 @@ win32 { LIBS += -L$$LIBDIR -lnut INCLUDEPATH += $$PWD/../../src $$PWD/../common #include(../../src/src.pri) + +DEFINES += NUT_SHARED_POINTER diff --git a/test/tst_basic/tst_basic.cpp b/test/tst_basic/tst_basic.cpp index df3c568..f728887 100644 --- a/test/tst_basic/tst_basic.cpp +++ b/test/tst_basic/tst_basic.cpp @@ -56,7 +56,7 @@ void BasicTest::dataScheema() void BasicTest::createUser() { - user = new User; + user = Nut::create(); user->setUsername("admin"); user->setPassword("123456"); db.users()->append(user); @@ -66,7 +66,7 @@ void BasicTest::createUser() void BasicTest::createPost() { TIC(); - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(QDateTime::currentDateTime()); newPost->setPublic(false); @@ -74,14 +74,14 @@ void BasicTest::createPost() db.posts()->append(newPost); for(int i = 0 ; i < 3; i++){ - auto *comment = new Comment; + auto comment = Nut::create(); comment->setMessage("comment #" + QString::number(i)); comment->setSaveDate(QDateTime::currentDateTime()); comment->setAuthorId(user->id()); - newPost->comments()->append(comment); + db.comments()->append(comment); } for (int i = 0; i < 10; ++i) { - auto *score = new Score; + auto score = Nut::create(); score->setScore(i % 5); newPost->scores()->append(score); } @@ -106,7 +106,7 @@ void BasicTest::createPost2() int postId = postIdVar.toInt(); for(int i = 0 ; i < 3; i++){ - auto *comment = new Comment; + auto comment = Nut::create(); comment->setMessage("comment #" + QString::number(i + 2)); comment->setSaveDate(QDateTime::currentDateTime()); comment->setAuthor(user); @@ -205,7 +205,7 @@ void BasicTest::testDate() QTime t = QTime(d.time().hour(), d.time().minute(), d.time().second()); d.setTime(t); - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(d); @@ -249,7 +249,7 @@ void BasicTest::modifyPost() auto q = db.posts()->query(); q->setWhere(Post::idField() == postId); - Post *post = q->first(); + Nut::Row post = q->first(); QTEST_ASSERT(post != nullptr); diff --git a/test/tst_basic/tst_basic.h b/test/tst_basic/tst_basic.h index d682b91..89b59a9 100644 --- a/test/tst_basic/tst_basic.h +++ b/test/tst_basic/tst_basic.h @@ -12,8 +12,8 @@ class BasicTest : public QObject Q_OBJECT WeblogDatabase db; int postId; - Post *post; - User *user; + Nut::Row post; + Nut::Row user; public: explicit BasicTest(QObject *parent = nullptr); diff --git a/test/tst_benckmark/tst_benchmark.cpp b/test/tst_benckmark/tst_benchmark.cpp index 157bb83..2618f14 100644 --- a/test/tst_benckmark/tst_benchmark.cpp +++ b/test/tst_benckmark/tst_benchmark.cpp @@ -45,7 +45,7 @@ void BenchmarkTest::insert1kPost() t.start(); for (int i = 0; i < 100; ++i) { - Post *newPost = new Post; + auto newPost = Nut::create(); newPost->setTitle("post title"); newPost->setSaveDate(QDateTime::currentDateTime()); diff --git a/test/tst_datatypes/tst_datatypes.cpp b/test/tst_datatypes/tst_datatypes.cpp index 4696244..2016137 100644 --- a/test/tst_datatypes/tst_datatypes.cpp +++ b/test/tst_datatypes/tst_datatypes.cpp @@ -85,53 +85,54 @@ void DataTypesTest::initTestCase() void DataTypesTest::insert() { - SampleTable t; - t.setInt8(f_int8); - t.setInt16(f_int16); - t.setInt32(f_int32); - t.setInt64(f_int64); + auto t = Nut::create(); - t.setUint8(f_uint8); - t.setUint16(f_uint16); - t.setUint32(f_uint32); - t.setUint64(f_uint64); + t->setInt8(f_int8); + t->setInt16(f_int16); + t->setInt32(f_int32); + t->setInt64(f_int64); - t.setReal(f_real); - t.setFloat(f_float); + t->setUint8(f_uint8); + t->setUint16(f_uint16); + t->setUint32(f_uint32); + t->setUint64(f_uint64); - t.setUrl(f_url); + t->setReal(f_real); + t->setFloat(f_float); - t.setTime(f_time); - t.setDate(f_date); - t.setDateTime(f_dateTime); - t.setUuid(f_uuid); + t->setUrl(f_url); - t.setJsonDoc(f_jsonDoc); - t.setJsonObj(f_jsonObj); - t.setJsonArray(f_jsonArray); - t.setJsonValue(f_jsonValue); + t->setTime(f_time); + t->setDate(f_date); + t->setDateTime(f_dateTime); + t->setUuid(f_uuid); - t.setString(f_string); - t.setStringList(f_stringList); - t.setQchar(f_qchar); + t->setJsonDoc(f_jsonDoc); + t->setJsonObj(f_jsonObj); + t->setJsonArray(f_jsonArray); + t->setJsonValue(f_jsonValue); + + t->setString(f_string); + t->setStringList(f_stringList); + t->setQchar(f_qchar); #ifdef QT_GUI_LIB - t.setColor(f_color); + t->setColor(f_color); - t.setPoint(f_point); - t.setPointf(f_pointf); + t->setPoint(f_point); + t->setPointf(f_pointf); - t.setPolygon(f_polygon); - t.setPolygonf(f_polygonf); + t->setPolygon(f_polygon); + t->setPolygonf(f_polygonf); #endif - db.sampleTables()->append(&t); + db.sampleTables()->append(t); db.saveChanges(); } void DataTypesTest::retrive() { - QList list = db.sampleTables()->query()->toList(); + Nut::RowList list = db.sampleTables()->query()->toList(); QTEST_ASSERT(list.count() == 1); - SampleTable *t = list.first(); + Nut::Row t = list.first(); QTEST_ASSERT(t->f_int8() == f_int8); QTEST_ASSERT(t->f_int16() == f_int16); diff --git a/test/tst_json/tst_json.cpp b/test/tst_json/tst_json.cpp index 4b56f3d..81c2977 100644 --- a/test/tst_json/tst_json.cpp +++ b/test/tst_json/tst_json.cpp @@ -39,7 +39,7 @@ void TestJson::store() db.open(); - Table *t = new Table; + auto t = Nut::create
(); QJsonParseError e; QJsonDocument doc = QJsonDocument::fromJson(R"({"a": 4, "b":3.14})", &e); qDebug() << e.errorString(); diff --git a/test/tst_quuid/tst_uuid.cpp b/test/tst_quuid/tst_uuid.cpp index 446ad38..21dadae 100644 --- a/test/tst_quuid/tst_uuid.cpp +++ b/test/tst_quuid/tst_uuid.cpp @@ -41,14 +41,13 @@ void UuidTest::initTestCase() void UuidTest::save() { TIC(); - Test t; - t.setId(QUuid::createUuid()); - t.setUuid(uuid); - db.tests()->append(&t); + auto t = Nut::create(); + t->setId(QUuid::createUuid()); + t->setUuid(uuid); + db.tests()->append(t); int n = db.saveChanges(); TOC(); - TOC(); QTEST_ASSERT(n == 1); } diff --git a/test/tst_upgrades/tst_upgrades.cpp b/test/tst_upgrades/tst_upgrades.cpp index 602f9c6..c91576b 100644 --- a/test/tst_upgrades/tst_upgrades.cpp +++ b/test/tst_upgrades/tst_upgrades.cpp @@ -58,11 +58,11 @@ void Upgrades::version2() initDb(db); QTEST_ASSERT(db.open()); - Table2 t; - t.setStr("0"); - db.sampleTable()->append(&t); + auto t = Nut::create(); + t->setStr("0"); + db.sampleTable()->append(t); db.saveChanges(); - id = t.id(); + id = t->id(); } void Upgrades::version3()