QString QDjangoCompiler::databaseColumn(const QString &name) { QDjangoMetaModel model = baseModel; QString modelPath; QString modelRef = referenceModel(QString(), &model); QStringList bits = name.split(QLatin1String("__")); while (bits.size() > 1) { const QByteArray fk = bits.first().toLatin1(); QDjangoMetaModel foreignModel; if (!model.foreignFields().contains(fk)) { // this might be a reverse relation, so look for the model // and if it exists continue foreignModel = QDjango::metaModel(fk); if (!foreignModel.isValid()) break; reverseModelRefs[bits.first()] = foreignModel.primaryKey(); } else { foreignModel = QDjango::metaModel(model.foreignFields()[fk]); } // store reference if (!modelPath.isEmpty()) modelPath += QLatin1String("__"); modelPath += bits.first(); modelRef = referenceModel(modelPath, &foreignModel); model = foreignModel; bits.takeFirst(); } const QDjangoMetaField field = model.localField(bits.join(QLatin1String("__")).toLatin1()); return modelRef + QLatin1Char('.') + driver->escapeIdentifier(field.column(), QSqlDriver::FieldName); }
/** Test foreign key constraint sql generation */ void tst_QDjangoMetaModel::testConstraints() { QStringList sql; if (QDjango::database().driverName() == QLatin1String("QPSQL")) { sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" (" "\"id\" serial PRIMARY KEY, " "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED, " "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, " "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE RESTRICT DEFERRABLE INITIALLY DEFERRED, " "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") ON DELETE SET NULL DEFERRABLE INITIALLY DEFERRED" ")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_f388fc3c\" ON \"tst_fkconstraint\" (\"noConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_4634d592\" ON \"tst_fkconstraint\" (\"cascadeConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_728cefe1\" ON \"tst_fkconstraint\" (\"restrictConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_44c71620\" ON \"tst_fkconstraint\" (\"nullConstraint_id\")"); } else if (QDjango::database().driverName() == QLatin1String("QMYSQL") || QDjango::database().driverName() == QLatin1String("QMYSQL3")) { sql << QLatin1String("CREATE TABLE `tst_fkconstraint` (" "`id` integer NOT NULL PRIMARY KEY AUTO_INCREMENT, " "`noConstraint_id` integer NOT NULL, " "`cascadeConstraint_id` integer NOT NULL, " "`restrictConstraint_id` integer NOT NULL, " "`nullConstraint_id` integer, " "CONSTRAINT `FK_noConstraint_id_8049d4ec` FOREIGN KEY (`noConstraint_id`) REFERENCES `user` (`id`), " "CONSTRAINT `FK_cascadeConstraint_id_d2686b82` FOREIGN KEY (`cascadeConstraint_id`) REFERENCES `user` (`id`) ON DELETE CASCADE, " "CONSTRAINT `FK_restrictConstraint_id_99b64be3` FOREIGN KEY (`restrictConstraint_id`) REFERENCES `user` (`id`) ON DELETE RESTRICT, " "CONSTRAINT `FK_nullConstraint_id_b4eac280` FOREIGN KEY (`nullConstraint_id`) REFERENCES `user` (`id`) ON DELETE SET NULL" ")"); sql << QLatin1String("CREATE INDEX `tst_fkconstraint_f388fc3c` ON `tst_fkconstraint` (`noConstraint_id`)"); sql << QLatin1String("CREATE INDEX `tst_fkconstraint_4634d592` ON `tst_fkconstraint` (`cascadeConstraint_id`)"); sql << QLatin1String("CREATE INDEX `tst_fkconstraint_728cefe1` ON `tst_fkconstraint` (`restrictConstraint_id`)"); sql << QLatin1String("CREATE INDEX `tst_fkconstraint_44c71620` ON `tst_fkconstraint` (`nullConstraint_id`)"); } else { sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" (" "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, " "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\"), " "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE CASCADE, " "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE RESTRICT, " "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") ON DELETE SET NULL" ")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_f388fc3c\" ON \"tst_fkconstraint\" (\"noConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_4634d592\" ON \"tst_fkconstraint\" (\"cascadeConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_728cefe1\" ON \"tst_fkconstraint\" (\"restrictConstraint_id\")"); sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_44c71620\" ON \"tst_fkconstraint\" (\"nullConstraint_id\")"); } // create tables QDjangoMetaModel userModel = QDjango::registerModel<User>(); QCOMPARE(userModel.createTable(), true); QDjangoMetaModel metaModel = QDjango::registerModel<tst_FkConstraint>(); QCOMPARE(metaModel.createTableSql(), sql); QCOMPARE(metaModel.createTable(), true); QDjango::setDebugEnabled(false); // drop tables QCOMPARE(metaModel.dropTable(), true); QCOMPARE(userModel.dropTable(), true); }
QString QDjangoCompiler::databaseColumn(const QString &name) { QDjangoMetaModel model = baseModel; QString modelName; QString modelPath; QString modelRef = referenceModel(QString(), &model, false); QStringList bits = name.split(QLatin1String("__")); while (bits.size() > 1) { const QByteArray fk = bits.first().toLatin1(); QDjangoMetaModel foreignModel; bool foreignNullable = false; if (!modelPath.isEmpty()) modelPath += QLatin1String("__"); modelPath += bits.first(); if (!model.foreignFields().contains(fk)) { // this might be a reverse relation, so look for the model // and if it exists continue foreignModel = QDjango::metaModel(fk); QDjangoReverseReference rev; const QMap<QByteArray, QByteArray> foreignFields = foreignModel.foreignFields(); foreach (const QByteArray &foreignKey, foreignFields.keys()) { if (foreignFields[foreignKey] == baseModel.className()) { rev.leftHandKey = foreignModel.localField(foreignKey + "_id").column(); break; } } if (rev.leftHandKey.isEmpty()) { qWarning() << "Invalid field lookup" << name; return QString(); } rev.rightHandKey = foreignModel.primaryKey(); reverseModelRefs[modelPath] = rev; } else {
void cleanup() { const QDjangoMetaModel metaModel = QDjango::registerModel<T>(); QCOMPARE(metaModel.dropTable(), true); }
void init(const QStringList &sql) { const QDjangoMetaModel metaModel = QDjango::registerModel<T>(); QCOMPARE(metaModel.createTableSql(), sql); QCOMPARE(metaModel.createTable(), true); }
/** Returns a string representation of the model instance. */ QString QDjangoModel::toString() const { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); const QByteArray pkName = metaModel.primaryKey(); return QString::fromLatin1("%1(%2=%3)").arg(QString::fromLatin1(metaObject()->className()), QString::fromLatin1(pkName), property(pkName).toString()); }
void tst_QDjangoMetaModel::testOptions() { QStringList sql; if (QDjango::database().driverName() == QLatin1String("QPSQL")) { sql << QLatin1String( "CREATE TABLE \"some_table\" (" "\"id\" serial PRIMARY KEY, " "\"aField\" integer NOT NULL, " "\"b_field\" integer NOT NULL, " "\"blankField\" integer NOT NULL, " "\"indexField\" integer NOT NULL, " "\"nullField\" integer, " "\"uniqueField\" integer NOT NULL UNIQUE, " "UNIQUE (\"aField\", \"b_field\")" ")"); sql << QLatin1String("CREATE INDEX \"some_table_ac243651\" ON \"some_table\" (\"indexField\")"); } else if (QDjango::database().driverName() == QLatin1String("QMYSQL") || QDjango::database().driverName() == QLatin1String("QMYSQL3")) { sql << QLatin1String( "CREATE TABLE `some_table` (" "`id` integer NOT NULL PRIMARY KEY AUTO_INCREMENT, " "`aField` integer NOT NULL, " "`b_field` integer NOT NULL, " "`blankField` integer NOT NULL, " "`indexField` integer NOT NULL, " "`nullField` integer, " "`uniqueField` integer NOT NULL UNIQUE, " "UNIQUE (`aField`, `b_field`)" ")"); sql << QLatin1String("CREATE INDEX `some_table_ac243651` ON `some_table` (`indexField`)"); } else { sql << QLatin1String( "CREATE TABLE \"some_table\" (" "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, " "\"aField\" integer NOT NULL, " "\"b_field\" integer NOT NULL, " "\"blankField\" integer NOT NULL, " "\"indexField\" integer NOT NULL, " "\"nullField\" integer, " "\"uniqueField\" integer NOT NULL UNIQUE, " "UNIQUE (\"aField\", \"b_field\")" ")"); sql << QLatin1String("CREATE INDEX \"some_table_ac243651\" ON \"some_table\" (\"indexField\")"); } init<tst_Options>(sql); QDjangoMetaField metaField; const QDjangoMetaModel metaModel = QDjango::registerModel<tst_Options>(); metaField = metaModel.localField("aField"); QCOMPARE(metaField.isAutoIncrement(), false); QCOMPARE(metaField.isBlank(), false); QCOMPARE(metaField.isNullable(), false); QCOMPARE(metaField.isUnique(), false); QCOMPARE(metaField.isValid(), true); metaField = metaModel.localField("bField"); QCOMPARE(metaField.isAutoIncrement(), false); QCOMPARE(metaField.isBlank(), false); QCOMPARE(metaField.isNullable(), false); QCOMPARE(metaField.isUnique(), false); QCOMPARE(metaField.isValid(), true); metaField = metaModel.localField("blankField"); QCOMPARE(metaField.isAutoIncrement(), false); QCOMPARE(metaField.isBlank(), true); QCOMPARE(metaField.isNullable(), false); QCOMPARE(metaField.isUnique(), false); QCOMPARE(metaField.isValid(), true); metaField = metaModel.localField("nullField"); QCOMPARE(metaField.isAutoIncrement(), false); QCOMPARE(metaField.isBlank(), false); QCOMPARE(metaField.isNullable(), true); QCOMPARE(metaField.isUnique(), false); QCOMPARE(metaField.isValid(), true); metaField = metaModel.localField("uniqueField"); QCOMPARE(metaField.isAutoIncrement(), false); QCOMPARE(metaField.isBlank(), false); QCOMPARE(metaField.isNullable(), false); QCOMPARE(metaField.isUnique(), true); QCOMPARE(metaField.isValid(), true); cleanup<tst_Options>(); }
/** Saves the QDjangoModel to the database. * * \return true if saving succeeded, false otherwise */ bool QDjangoModel::save() { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); return metaModel.save(this); }
/** Sets the QDjangoModel pointed to by the given foreign-key. * * \param name * \param value * * \note The current QDjangoModel will take ownership of the given \c value. */ void QDjangoModel::setForeignKey(const char *name, QObject *value) { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); metaModel.setForeignKey(this, name, value); }
/** Retrieves the QDjangoModel pointed to by the given foreign-key. * * \param name */ QObject *QDjangoModel::foreignKey(const char *name) const { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); return metaModel.foreignKey(this, name); }
/** Sets the primary key for this QDjangoModel. * * \param pk */ void QDjangoModel::setPk(const QVariant &pk) { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); setProperty(metaModel.primaryKey(), pk); }
/** Returns the primary key for this QDjangoModel. */ QVariant QDjangoModel::pk() const { const QDjangoMetaModel metaModel = QDjango::metaModel(metaObject()->className()); return property(metaModel.primaryKey()); }