155 Q_ASSERT(m_parent !=
nullptr);
158 model =
new QRelatedTableModel(
this, m_parent, m_parent->database());
159 model->setTable(rel.tableName());
161 QObject::connect(model, &QAbstractItemModel::dataChanged, model, [&](
const QModelIndex &tl,
const QModelIndex &br)
163 if (tl.column() >= col && br.column() <= col)
166 QObject::connect(model, &QAbstractItemModel::rowsRemoved, model, [&]()
170 QObject::connect(model, &QAbstractItemModel::rowsInserted, model, [&]()
187 if (
model ==
nullptr)
192 QString displayColumn;
193 for (
int i=0; i <
model->rowCount(); ++i) {
194 record =
model->record(i);
196 indexColumn = rel.indexColumn();
197 if (m_parent->database().driver()->isIdentifierEscaped(indexColumn, QSqlDriver::FieldName))
198 indexColumn = m_parent->database().driver()->stripDelimiters(indexColumn, QSqlDriver::FieldName);
200 displayColumn = rel.displayColumn();
201 if (m_parent->database().driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
202 displayColumn = m_parent->database().driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
204 dictionary[record.field(indexColumn).value().toString()] =
205 record.field(displayColumn).value();
207 m_dictInitialized =
true;
410QVariant QSqlRelationalTableModel::data(
const QModelIndex &index,
int role)
const
412 Q_D(
const QSqlRelationalTableModel);
414 if (role == Qt::DisplayRole && index.column() >= 0 && index.column() < d->relations.size() &&
415 d->relations.at(index.column())->isValid()) {
416 auto relation = d->relations.at(index.column());
417 if (!relation->isDictionaryInitialized())
418 relation->populateDictionary();
424 if (d->strategy != OnFieldChange) {
425 const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
426 if (row.op() != QSqlTableModelPrivate::None && row.rec().isGenerated(index.column())) {
427 if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Delete) {
428 QVariant v = row.rec().value(index.column());
430 return relation->dictionary[v.toString()];
435 return QSqlTableModel::data(index, role);
454bool QSqlRelationalTableModel::setData(
const QModelIndex &index,
const QVariant &value,
457 Q_D(QSqlRelationalTableModel);
458 if ( role == Qt::EditRole && index.column() > 0 && index.column() < d->relations.size()
459 && d->relations.at(index.column())->isValid()) {
460 auto relation = d->relations.at(index.column());
461 if (!relation->isDictionaryInitialized())
462 relation->populateDictionary();
463 if (value.isValid() && !relation->dictionary.contains(value.toString()))
466 return QSqlTableModel::setData(index, value, role);
526QString QSqlRelationalTableModel::selectStatement()
const
528 Q_D(
const QSqlRelationalTableModel);
530 if (tableName().isEmpty())
532 if (d->relations.isEmpty())
533 return QSqlTableModel::selectStatement();
536 QHash<QString,
int> fieldNames;
537 QStringList fieldList;
538 for (
int i = 0; i < d->baseRec.count(); ++i) {
539 QSqlRelation relation = d->relations.value(i) ? d->relations.at(i)->rel : QSqlRelation();
541 if (relation.isValid()) {
543 name = relation.displayColumn();
544 if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName))
545 name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName);
547 const QSqlRecord rec = database().record(relation.tableName());
548 for (
int i = 0; i < rec.count(); ++i) {
549 if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) {
550 name = rec.fieldName(i);
556 name = d->baseRec.fieldName(i);
558 fieldNames[name] = fieldNames.value(name, 0) + 1;
559 fieldList.append(name);
564 QString from = SqlrTm::from(tableName());
565 for (
int i = 0; i < d->baseRec.count(); ++i) {
566 QSqlRelation relation = d->relations.value(i) ? d->relations.at(i)->rel : QSqlRelation();
567 const QString tableField = d->fullyQualifiedFieldName(tableName(), d->db.driver()->escapeIdentifier(d->baseRec.fieldName(i), QSqlDriver::FieldName));
568 if (relation.isValid()) {
569 const QString relTableAlias = SqlrTm::relTablePrefix(i);
570 QString displayTableField = d->fullyQualifiedFieldName(relTableAlias, relation.displayColumn());
573 if (fieldNames.value(fieldList[i]) > 1) {
574 QString relTableName = relation.tableName().section(QChar::fromLatin1(
'.'), -1, -1);
575 if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName))
576 relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName);
577 QString displayColumn = relation.displayColumn();
578 if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
579 displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
580 QString alias = QString::fromLatin1(
"%1_%2_%3")
581 .arg(relTableName, displayColumn, QString::number(fieldNames.value(fieldList[i])));
582 alias.truncate(d->db.driver()->maximumIdentifierLength(QSqlDriver::FieldName));
583 alias = d->db.driver()->escapeIdentifier(alias, QSqlDriver::FieldName);
584 displayTableField = SqlrTm::as(displayTableField, alias);
585 --fieldNames[fieldList[i]];
588 fList = SqlrTm::comma(fList, displayTableField);
591 const QString tblexpr = SqlrTm::concat(relation.tableName(), relTableAlias);
592 const QString relTableField = d->fullyQualifiedFieldName(relTableAlias, relation.indexColumn());
593 const QString cond = SqlrTm::eq(tableField, relTableField);
594 if (d->joinMode == QSqlRelationalTableModel::InnerJoin) {
597 from = SqlrTm::comma(from, tblexpr);
598 conditions = SqlrTm::et(conditions, cond);
600 from = SqlrTm::concat(from, SqlrTm::leftJoin(tblexpr));
601 from = SqlrTm::concat(from, SqlrTm::on(cond));
604 fList = SqlrTm::comma(fList, tableField);
611 const QString stmt = SqlrTm::concat(SqlrTm::select(fList), from);
612 const QString where = SqlrTm::where(SqlrTm::et(SqlrTm::paren(conditions), SqlrTm::paren(filter())));
613 return SqlrTm::concat(SqlrTm::concat(stmt, where), orderByClause());