diff options
Diffstat (limited to 'src/libs/sqlite/createtablesqlstatementbuilder.cpp')
-rw-r--r-- | src/libs/sqlite/createtablesqlstatementbuilder.cpp | 182 |
1 files changed, 168 insertions, 14 deletions
diff --git a/src/libs/sqlite/createtablesqlstatementbuilder.cpp b/src/libs/sqlite/createtablesqlstatementbuilder.cpp index 9a64d8e488..07008a9a1d 100644 --- a/src/libs/sqlite/createtablesqlstatementbuilder.cpp +++ b/src/libs/sqlite/createtablesqlstatementbuilder.cpp @@ -39,16 +39,26 @@ void CreateTableSqlStatementBuilder::setTableName(Utils::SmallString &&tableName this->m_tableName = std::move(tableName); } -void CreateTableSqlStatementBuilder::addColumn(Utils::SmallString &&columnName, +void CreateTableSqlStatementBuilder::addColumn(Utils::SmallStringView columnName, ColumnType columnType, - Contraint constraint) + Constraints &&constraints) { m_sqlStatementBuilder.clear(); - m_columns.emplace_back(std::move(columnName), columnType, constraint); + m_columns.emplace_back(Utils::SmallStringView{}, columnName, columnType, std::move(constraints)); } -void CreateTableSqlStatementBuilder::setColumns(const SqliteColumns &columns) +void CreateTableSqlStatementBuilder::addConstraint(TableConstraint &&constraint) +{ + m_tableConstraints.push_back(std::move(constraint)); +} + +void CreateTableSqlStatementBuilder::setConstraints(TableConstraints constraints) +{ + m_tableConstraints = std::move(constraints); +} + +void CreateTableSqlStatementBuilder::setColumns(SqliteColumns columns) { m_sqlStatementBuilder.clear(); @@ -97,20 +107,164 @@ bool CreateTableSqlStatementBuilder::isValid() const return m_tableName.hasContent() && !m_columns.empty(); } -void CreateTableSqlStatementBuilder::bindColumnDefinitions() const +namespace { +Utils::SmallStringView actionToText(ForeignKeyAction action) { - Utils::SmallStringVector columnDefinitionStrings; + switch (action) { + case ForeignKeyAction::NoAction: + return "NO ACTION"; + case ForeignKeyAction::Restrict: + return "RESTRICT"; + case ForeignKeyAction::SetNull: + return "SET NULL"; + case ForeignKeyAction::SetDefault: + return "SET DEFAULT"; + case ForeignKeyAction::Cascade: + return "CASCADE"; + } + + return ""; +} - for (const Column &columns : m_columns) { - Utils::SmallString columnDefinitionString = {columns.name(), " ", columns.typeString()}; +class ContraintsVisiter +{ +public: + ContraintsVisiter(Utils::SmallString &columnDefinitionString) + : columnDefinitionString(columnDefinitionString) + {} + + void operator()(const Unique &) { columnDefinitionString.append(" UNIQUE"); } - switch (columns.constraint()) { - case Contraint::PrimaryKey: columnDefinitionString.append(" PRIMARY KEY"); break; - case Contraint::Unique: columnDefinitionString.append(" UNIQUE"); break; - case Contraint::NoConstraint: break; + void operator()(const PrimaryKey &primaryKey) + { + columnDefinitionString.append(" PRIMARY KEY"); + if (primaryKey.autoincrement == AutoIncrement::Yes) + columnDefinitionString.append(" AUTOINCREMENT"); + } + + void operator()(const ForeignKey &foreignKey) + { + columnDefinitionString.append(" REFERENCES "); + columnDefinitionString.append(foreignKey.table); + + if (foreignKey.column.hasContent()) { + columnDefinitionString.append("("); + columnDefinitionString.append(foreignKey.column); + columnDefinitionString.append(")"); + } + + if (foreignKey.updateAction != ForeignKeyAction::NoAction) { + columnDefinitionString.append(" ON UPDATE "); + columnDefinitionString.append(actionToText(foreignKey.updateAction)); + } + + if (foreignKey.deleteAction != ForeignKeyAction::NoAction) { + columnDefinitionString.append(" ON DELETE "); + columnDefinitionString.append(actionToText(foreignKey.deleteAction)); } - columnDefinitionStrings.push_back(columnDefinitionString); + if (foreignKey.enforcement == Enforment::Deferred) + columnDefinitionString.append(" DEFERRABLE INITIALLY DEFERRED"); + } + + void operator()(const NotNull &) { columnDefinitionString.append(" NOT NULL"); } + + void operator()(const Check &check) + { + columnDefinitionString.append(" CHECK ("); + columnDefinitionString.append(check.expression); + columnDefinitionString.append(")"); + } + + void operator()(const DefaultValue &defaultValue) + { + columnDefinitionString.append(" DEFAULT "); + switch (defaultValue.value.type()) { + case Sqlite::ValueType::Integer: + columnDefinitionString.append( + Utils::SmallString::number(defaultValue.value.toInteger())); + break; + case Sqlite::ValueType::Float: + columnDefinitionString.append(Utils::SmallString::number(defaultValue.value.toFloat())); + break; + case Sqlite::ValueType::String: + columnDefinitionString.append("'"); + columnDefinitionString.append(defaultValue.value.toStringView()); + columnDefinitionString.append("'"); + break; + default: + break; + } + } + + void operator()(const DefaultExpression &defaultexpression) + { + columnDefinitionString.append(" DEFAULT ("); + columnDefinitionString.append(defaultexpression.expression); + columnDefinitionString.append(")"); + } + + void operator()(const Collate &collate) + { + columnDefinitionString.append(" COLLATE "); + columnDefinitionString.append(collate.collation); + } + + void operator()(const GeneratedAlways &generatedAlways) + { + columnDefinitionString.append(" GENERATED ALWAYS AS ("); + columnDefinitionString.append(generatedAlways.expression); + columnDefinitionString.append(")"); + + if (generatedAlways.storage == Sqlite::GeneratedAlwaysStorage::Virtual) + columnDefinitionString.append(" VIRTUAL"); + else + columnDefinitionString.append(" STORED"); + } + + Utils::SmallString &columnDefinitionString; +}; + +class TableContraintsVisiter +{ +public: + TableContraintsVisiter(Utils::SmallString &columnDefinitionString) + : columnDefinitionString(columnDefinitionString) + {} + + void operator()(const TablePrimaryKey &primaryKey) + { + columnDefinitionString.append("PRIMARY KEY("); + columnDefinitionString.append(primaryKey.columns.join(", ")); + columnDefinitionString.append(")"); + } + + Utils::SmallString &columnDefinitionString; +}; +} // namespace +void CreateTableSqlStatementBuilder::bindColumnDefinitionsAndTableConstraints() const +{ + Utils::SmallStringVector columnDefinitionStrings; + columnDefinitionStrings.reserve(m_columns.size()); + + for (const Column &column : m_columns) { + Utils::SmallString columnDefinitionString = {column.name, " ", column.typeString()}; + + ContraintsVisiter visiter{columnDefinitionString}; + + for (const Constraint &constraint : column.constraints) + Utils::visit(visiter, constraint); + + columnDefinitionStrings.push_back(std::move(columnDefinitionString)); + } + + for (const TableConstraint &constraint : m_tableConstraints) { + Utils::SmallString columnDefinitionString; + + TableContraintsVisiter visiter{columnDefinitionString}; + Utils::visit(visiter, constraint); + + columnDefinitionStrings.push_back(std::move(columnDefinitionString)); } m_sqlStatementBuilder.bind("$columnDefinitions", columnDefinitionStrings); @@ -122,7 +276,7 @@ void CreateTableSqlStatementBuilder::bindAll() const bindTemporary(); bindIfNotExists(); - bindColumnDefinitions(); + bindColumnDefinitionsAndTableConstraints(); bindWithoutRowId(); } |