/************************************************************************** ** ** 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 . ** **************************************************************************/ #include #include #include "table.h" #include "database.h" #include "databasemodel.h" #include "generators/sqlgeneratorbase_p.h" NUT_BEGIN_NAMESPACE /* * FIXME: * Qt can not access metaObject inside of constructor * so, if we can't initalize myModel inside of ctor. in * other side myModel inited in propertyChanged signal, so * any method that uses myModel (like: primaryKey, ...) can't * be accessed before any property set. So ugly, but there are * no other way for now. * * This should be fixed to v1.2 */ Table::Table(QObject *parent) : QObject(parent), myModel(nullptr), _status(NewCreated), _parentTableSet(nullptr) { } void Table::add(TableSetBase *t) { this->childTableSets.insert(t); } QString Table::primaryKey() const { return myModel->primaryKey(); } bool Table::isPrimaryKeyAutoIncrement() const { FieldModel *pk = myModel->field(myModel->primaryKey()); if (!pk) return false; return pk->isAutoIncrement; } QVariant Table::primaryValue() const { return property(primaryKey().toLatin1().data()); } void Table::propertyChanged(const QString &propName) { if (!myModel) myModel = TableModel::findByClassName(metaObject()->className()); if (!myModel) qFatal ("model for class '%s' not found", qPrintable(metaObject()->className())); foreach (FieldModel *f, myModel->fields()) if(f->isPrimaryKey && propName == f->name && f->isAutoIncrement) return; _changedProperties.insert(propName); if (_status == FeatchedFromDB) _status = Modified; if (_status == NewCreated) _status = Added; } void Table::clear() { _changedProperties.clear(); } QSet Table::changedProperties() const { return _changedProperties; } bool Table::setParentTable(Table *master) { QString masterClassName = master->metaObject()->className(); foreach (RelationModel *r, myModel->foregionKeys()) if(r->masterClassName == masterClassName) { setProperty(QString(r->localColumn).toLatin1().data(), master->primaryValue()); _changedProperties.insert(r->localColumn); return true; } return false; } TableSetBase *Table::parentTableSet() const { return _parentTableSet; } void Table::setParentTableSet(TableSetBase *parent) { _parentTableSet = parent; _parentTableSet->add(this); } TableSetBase *Table::childTableSet(const QString &name) const { foreach (TableSetBase *t, childTableSets) if (t->childClassName() == name) return t; return Q_NULLPTR; } int Table::save(Database *db) { QSqlQuery q = db->exec(db->sqlGenertor()->saveRecord(this, db->tableName(metaObject()->className()))); if(status() == Added && isPrimaryKeyAutoIncrement()) setProperty(primaryKey().toLatin1().data(), q.lastInsertId()); foreach(TableSetBase *ts, childTableSets) ts->save(db); setStatus(FeatchedFromDB); return q.numRowsAffected(); } Table::Status Table::status() const { return _status; } void Table::setStatus(const Status &status) { _status = status; } NUT_END_NAMESPACE