From 225d3437e073b388623d26c31f9bd59076917583 Mon Sep 17 00:00:00 2001 From: Martin Kleusberg Date: Thu, 18 Aug 2016 20:33:39 +0200 Subject: [PATCH] Add parsing support for UNIQUE table constraints See issue #540. --- src/sqlitetypes.cpp | 53 +++++++++++++++++++++++++++++++++++---------- src/sqlitetypes.h | 7 +++++- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/sqlitetypes.cpp b/src/sqlitetypes.cpp index 1aed29e7..7431d6ac 100644 --- a/src/sqlitetypes.cpp +++ b/src/sqlitetypes.cpp @@ -127,6 +127,27 @@ void Table::setFields(const FieldVector &fields) m_fields = fields; } +void Table::setField(int index, FieldPtr f) +{ + FieldPtr oldField = m_fields[index]; + m_fields[index] = f; + + // Update unique constraints. If an existing field is updated but was used in a unique constraint, the pointer in the + // unique constraint needs to be updated to the new field, too. + if(oldField) + { + for(int i=0;iname())); + sql += QString(",\n\tUNIQUE(%1)").arg(fieldnames.join(",")); + } + // foreign keys foreach(FieldPtr f, m_fields) { @@ -247,6 +277,11 @@ QString Table::sql() const return sql + ";"; } +void Table::addUniqueConstraint(FieldVector fields) +{ + m_uniqueConstraints.push_back(fields); +} + namespace { QString identifier(antlr::RefAST ident) @@ -386,13 +421,12 @@ Table CreateTableWalker::table() { tc = tc->getNextSibling(); // skip UNIQUE tc = tc->getNextSibling(); // skip LPAREN - QVector uniquefieldsindex; + FieldVector fields; do { QString col = columnname(tc); - int fieldindex = tab.findField(col); - if(fieldindex != -1) - uniquefieldsindex.append(fieldindex); + FieldPtr field = tab.field(tab.findField(col)); + fields.push_back(field); tc = tc->getNextSibling(); if(tc != antlr::nullAST @@ -410,15 +444,10 @@ Table CreateTableWalker::table() } } while(tc != antlr::nullAST && tc->getType() != sqlite3TokenTypes::RPAREN); - if(uniquefieldsindex.size() == 1) - { - tab.fields().at(uniquefieldsindex[0])->setUnique(true); - } + if(fields.size() == 1) + fields[0]->setUnique(true); else - { - // else save on table a unique with more than one field - m_bModifySupported = false; - } + tab.addUniqueConstraint(fields); } break; case sqlite3TokenTypes::FOREIGN: diff --git a/src/sqlitetypes.h b/src/sqlitetypes.h index c65956da..6b3ffc9e 100644 --- a/src/sqlitetypes.h +++ b/src/sqlitetypes.h @@ -106,6 +106,7 @@ private: typedef QSharedPointer FieldPtr; typedef QVector< FieldPtr > FieldVector; + class Table { public: @@ -126,13 +127,16 @@ public: void addField(const FieldPtr& f); bool removeField(const QString& sFieldName); void setFields(const FieldVector& fields); - void setField(int index, FieldPtr f) { m_fields[index] = f; } + void setField(int index, FieldPtr f); + const FieldPtr& field(int index) { return m_fields[index]; } QStringList fieldNames() const; void setRowidColumn(const QString& rowid) { m_rowidColumn = rowid; } const QString& rowidColumn() const { return m_rowidColumn; } bool isWithoutRowidTable() const { return m_rowidColumn != "_rowid_"; } void clear(); + void addUniqueConstraint(FieldVector fields); + /** * @brief findField Finds a field and returns the index. * @param sname @@ -159,6 +163,7 @@ private: QString m_name; FieldVector m_fields; QString m_rowidColumn; + QVector m_uniqueConstraints; }; /**