/************************************************************************** ** ** 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 #include #include "databasemodel.h" #include "sqlgeneratorbase_p.h" #include "table.h" #include "tablemodel.h" QT_BEGIN_NAMESPACE SqlGeneratorBase::SqlGeneratorBase(QObject *parent) : QObject(parent) { } SqlGeneratorBase::~SqlGeneratorBase() { } QString SqlGeneratorBase::masterDatabaseName(QString databaseName) { Q_UNUSED(databaseName); return ""; } QString SqlGeneratorBase::saveRecord(Table *t, QString tableName) { switch(t->status()){ case Table::Added: return insertRecord(t, tableName); case Table::Deleted: return deleteRecord(t, tableName); case Table::Modified: return updateRecord(t, tableName); case Table::NewCreated: case Table::FeatchedFromDB: // disable compiler warning return ""; } return ""; } QString SqlGeneratorBase::fieldDeclare(FieldModel *field) { return field->name + " " + fieldType(field); } QStringList SqlGeneratorBase::diff(DatabaseModel lastModel, DatabaseModel newModel) { QStringList ret; QSet tableNames; foreach (TableModel *table, lastModel) tableNames.insert(table->name()); foreach (TableModel *table, newModel) tableNames.insert(table->name()); foreach (QString tableName, tableNames) { TableModel *oldTable = lastModel.model(tableName); TableModel *newTable = newModel.model(tableName); ret << diff(oldTable, newTable); } return ret; } QString SqlGeneratorBase::diff(FieldModel *oldField, FieldModel *newField) { QString sql = ""; if(oldField && newField) if(*oldField == *newField) return QString::null; if(!newField){ sql = "DROP COLUMN " + oldField->name; }else{ if(oldField) sql = "ALTER COLUMN "; else sql = "ADD COLUMN "; sql.append(fieldDeclare(newField)); } return sql; } QString SqlGeneratorBase::diff(TableModel *oldTable, TableModel *newTable) { if(oldTable && newTable) if(*oldTable == *newTable) return ""; if(!newTable) return "DROP TABLE " + oldTable->name(); QSet fieldNames; if(oldTable) foreach (FieldModel *f, oldTable->fields()) fieldNames.insert(f->name); foreach (FieldModel *f, newTable->fields()) fieldNames.insert(f->name); QStringList columnSql; foreach (QString fieldName, fieldNames) { FieldModel *newField = newTable->field(fieldName); if(oldTable){ FieldModel *oldField = oldTable->field(fieldName); QString buffer = diff(oldField, newField); if(!buffer.isNull()) columnSql << buffer; }else{ columnSql << fieldDeclare(newField); } } QString sql; if(oldTable){ sql = QString("ALTER TABLE %1 \n%2") .arg(newTable->name()) .arg(columnSql.join(",\n")); }else{ if(!newTable->primaryKey().isNull()) columnSql << QString("CONSTRAINT pk_%1 PRIMARY KEY (%2)") .arg(newTable->name()) .arg(newTable->primaryKey()); sql = QString("CREATE TABLE %1 \n(%2)") .arg(newTable->name()) .arg(columnSql.join(",\n")); } return sql; } QString SqlGeneratorBase::insertRecord(Table *t, QString tableName) { QString sql = ""; QString key = t->primaryKey(); QStringList values; foreach (QString f, t->changedProperties()) if(f != key) values.append("'" + t->property(f.toLatin1().data()).toString() + "'"); sql = QString("INSERT INTO %1 (%2) VALUES (%3)") .arg(tableName) .arg(t->changedProperties().toList().join(", ")) .arg(values.join(", ")); return sql; } QString SqlGeneratorBase::updateRecord(Table *t, QString tableName) { QString sql = ""; QString key = t->primaryKey(); QStringList values; foreach (QString f, t->changedProperties()) if(f != key) values.append(f + "='" + t->property(f.toLatin1().data()).toString() + "'"); sql = QString("UPDATE %1 SET %2 WHERE %3=%4") .arg(tableName) .arg(values.join(", ")) .arg(key) .arg(t->primaryValue().toString()); return sql; } QString SqlGeneratorBase::deleteRecord(Table *t, QString tableName) { return QString("DELETE FROM %1 WHERE %2='%3'") .arg(tableName) .arg(t->primaryKey()) .arg(t->primaryValue().toString()); } QString SqlGeneratorBase::deleteRecords(QString tableName, QString where) { QString sql = ""; if(where.isEmpty() || where.isNull()) sql = "DELETE FROM " + tableName; else sql = "DELETE FROM " + tableName + " WHERE " + where; return sql; } QString SqlGeneratorBase::escapeFieldValue(QVariant &field) const { switch (field.type()) { case QVariant::Int: case QVariant::Double: return field.toString(); break; case QVariant::String: return "'" + field.toString() + "'"; case QVariant::DateTime: return "'" + field.toDateTime().toString(Qt::ISODate) + "'"; case QVariant::Date: return "'" + field.toDate().toString(Qt::ISODate) + "'"; case QVariant::Time: return "'" + field.toTime().toString(Qt::ISODate) + "'"; case QVariant::StringList: case QVariant::List: return "['" + field.toStringList().join("', '") + "']"; case QVariant::Invalid: qFatal("Invalud field value"); return ""; default: return ""; } } QT_END_NAMESPACE