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;
408QVariant QSqlRelationalTableModel::data(
const QModelIndex &index,
int role)
const
410 Q_D(
const QSqlRelationalTableModel);
412 if (role == Qt::DisplayRole && index.column() >= 0 && index.column() < d->relations.size() &&
413 d->relations.at(index.column())->isValid()) {
414 auto relation = d->relations.at(index.column());
415 if (!relation->isDictionaryInitialized())
416 relation->populateDictionary();
422 if (d->strategy != OnFieldChange) {
423 const QSqlTableModelPrivate::ModifiedRow row = d->cache.value(index.row());
424 if (row.op() != QSqlTableModelPrivate::None && row.rec().isGenerated(index.column())) {
425 if (d->strategy == OnManualSubmit || row.op() != QSqlTableModelPrivate::Delete) {
426 QVariant v = row.rec().value(index.column());
428 return relation->dictionary[v.toString()];
433 return QSqlTableModel::data(index, role);
452bool QSqlRelationalTableModel::setData(
const QModelIndex &index,
const QVariant &value,
455 Q_D(QSqlRelationalTableModel);
456 if ( role == Qt::EditRole && index.column() > 0 && index.column() < d->relations.size()
457 && d->relations.at(index.column())->isValid()) {
458 auto relation = d->relations.at(index.column());
459 if (!relation->isDictionaryInitialized())
460 relation->populateDictionary();
461 if (value.isValid() && !relation->dictionary.contains(value.toString()))
464 return QSqlTableModel::setData(index, value, role);
524QString QSqlRelationalTableModel::selectStatement()
const
526 Q_D(
const QSqlRelationalTableModel);
528 if (tableName().isEmpty())
530 if (d->relations.isEmpty())
531 return QSqlTableModel::selectStatement();
534 QHash<QString,
int> fieldNames;
535 QStringList fieldList;
536 for (
int i = 0; i < d->baseRec.count(); ++i) {
537 QSqlRelation relation = d->relations.value(i) ? d->relations.at(i)->rel : QSqlRelation();
539 if (relation.isValid()) {
541 name = relation.displayColumn();
542 if (d->db.driver()->isIdentifierEscaped(name, QSqlDriver::FieldName))
543 name = d->db.driver()->stripDelimiters(name, QSqlDriver::FieldName);
545 const QSqlRecord rec = database().record(relation.tableName());
546 for (
int i = 0; i < rec.count(); ++i) {
547 if (name.compare(rec.fieldName(i), Qt::CaseInsensitive) == 0) {
548 name = rec.fieldName(i);
554 name = d->baseRec.fieldName(i);
556 fieldNames[name] = fieldNames.value(name, 0) + 1;
557 fieldList.append(name);
562 QString from = SqlrTm::from(tableName());
563 for (
int i = 0; i < d->baseRec.count(); ++i) {
564 QSqlRelation relation = d->relations.value(i) ? d->relations.at(i)->rel : QSqlRelation();
565 const QString tableField = d->fullyQualifiedFieldName(tableName(), d->db.driver()->escapeIdentifier(d->baseRec.fieldName(i), QSqlDriver::FieldName));
566 if (relation.isValid()) {
567 const QString relTableAlias = SqlrTm::relTablePrefix(i);
568 QString displayTableField = d->fullyQualifiedFieldName(relTableAlias, relation.displayColumn());
571 if (fieldNames.value(fieldList[i]) > 1) {
572 QString relTableName = relation.tableName().section(QChar::fromLatin1(
'.'), -1, -1);
573 if (d->db.driver()->isIdentifierEscaped(relTableName, QSqlDriver::TableName))
574 relTableName = d->db.driver()->stripDelimiters(relTableName, QSqlDriver::TableName);
575 QString displayColumn = relation.displayColumn();
576 if (d->db.driver()->isIdentifierEscaped(displayColumn, QSqlDriver::FieldName))
577 displayColumn = d->db.driver()->stripDelimiters(displayColumn, QSqlDriver::FieldName);
578 QString alias = QString::fromLatin1(
"%1_%2_%3")
579 .arg(relTableName, displayColumn, QString::number(fieldNames.value(fieldList[i])));
580 alias.truncate(d->db.driver()->maximumIdentifierLength(QSqlDriver::FieldName));
581 alias = d->db.driver()->escapeIdentifier(alias, QSqlDriver::FieldName);
582 displayTableField = SqlrTm::as(displayTableField, alias);
583 --fieldNames[fieldList[i]];
586 fList = SqlrTm::comma(fList, displayTableField);
589 const QString tblexpr = SqlrTm::concat(relation.tableName(), relTableAlias);
590 const QString relTableField = d->fullyQualifiedFieldName(relTableAlias, relation.indexColumn());
591 const QString cond = SqlrTm::eq(tableField, relTableField);
592 if (d->joinMode == QSqlRelationalTableModel::InnerJoin) {
595 from = SqlrTm::comma(from, tblexpr);
596 conditions = SqlrTm::et(conditions, cond);
598 from = SqlrTm::concat(from, SqlrTm::leftJoin(tblexpr));
599 from = SqlrTm::concat(from, SqlrTm::on(cond));
602 fList = SqlrTm::comma(fList, tableField);
609 const QString stmt = SqlrTm::concat(SqlrTm::select(fList), from);
610 const QString where = SqlrTm::where(SqlrTm::et(SqlrTm::paren(conditions), SqlrTm::paren(filter())));
611 return SqlrTm::concat(SqlrTm::concat(stmt, where), orderByClause());