diff --git a/src/libs/sqlite/sqliteindex.h b/src/libs/sqlite/sqliteindex.h index 11d83541af1..d8f4d7c61da 100644 --- a/src/libs/sqlite/sqliteindex.h +++ b/src/libs/sqlite/sqliteindex.h @@ -43,14 +43,16 @@ enum class IndexType class Index { public: - Index(Utils::SmallString &&tableName, + Index(Utils::SmallStringView tableName, Utils::SmallStringVector &&columnNames, - IndexType indexType=IndexType::Normal) - : m_tableName(std::move(tableName)), - m_columnNames(std::move(columnNames)), - m_indexType(indexType) - { - } + IndexType indexType = IndexType::Normal, + Utils::SmallStringView condition = {}) + : m_tableName(std::move(tableName)) + , m_columnNames(std::move(columnNames)) + , m_indexType(indexType) + , m_condition{condition} + + {} Utils::SmallString sqlStatement() const { @@ -67,7 +69,9 @@ public: m_tableName, "(", m_columnNames.join(", "), - ")"}); + ")", + m_condition.hasContent() ? " WHERE " : "", + m_condition}); } void checkTableName() const @@ -86,6 +90,7 @@ private: Utils::SmallString m_tableName; Utils::SmallStringVector m_columnNames; IndexType m_indexType; + Utils::SmallString m_condition; }; using SqliteIndices = std::vector; diff --git a/src/libs/sqlite/sqlitetable.h b/src/libs/sqlite/sqlitetable.h index 5022400d88e..1c1f6869757 100644 --- a/src/libs/sqlite/sqlitetable.h +++ b/src/libs/sqlite/sqlitetable.h @@ -134,20 +134,21 @@ public: m_tableConstraints.emplace_back(TablePrimaryKey{std::move(columnNames)}); } - Index &addIndex(const SqliteColumnConstReferences &columns) + Index &addIndex(const SqliteColumnConstReferences &columns, Utils::SmallStringView condition = {}) { - m_sqliteIndices.emplace_back(m_tableName.clone(), sqliteColumnNames(columns)); - - return m_sqliteIndices.back(); + return m_sqliteIndices.emplace_back(m_tableName, + sqliteColumnNames(columns), + IndexType::Normal, + condition); } - Index &addUniqueIndex(const SqliteColumnConstReferences &columns) + Index &addUniqueIndex(const SqliteColumnConstReferences &columns, + Utils::SmallStringView condition = {}) { - m_sqliteIndices.emplace_back(m_tableName.clone(), - sqliteColumnNames(columns), - IndexType::Unique); - - return m_sqliteIndices.back(); + return m_sqliteIndices.emplace_back(m_tableName, + sqliteColumnNames(columns), + IndexType::Unique, + condition); } const SqliteColumns &columns() const diff --git a/tests/unit/unittest/sqliteindex-test.cpp b/tests/unit/unittest/sqliteindex-test.cpp index f6fb4e8be30..c4fdeba439c 100644 --- a/tests/unit/unittest/sqliteindex-test.cpp +++ b/tests/unit/unittest/sqliteindex-test.cpp @@ -73,4 +73,15 @@ TEST(Index, UniqueIndex) ASSERT_THAT(sqlStatement, Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)")); } + +TEST(Index, Condition) +{ + Index index{"tableName", {"column1"}, IndexType::Normal, "column1 IS NOT NULL"}; + + auto sqlStatement = index.sqlStatement(); + + ASSERT_THAT(sqlStatement, + Eq("CREATE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1) WHERE " + "column1 IS NOT NULL")); +} } diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp index 2faebd844cd..20aa0680be9 100644 --- a/tests/unit/unittest/sqlitetable-test.cpp +++ b/tests/unit/unittest/sqlitetable-test.cpp @@ -107,11 +107,34 @@ TEST_F(SqliteTable, InitializeTableWithIndex) auto &column = table.addColumn("name"); auto &column2 = table.addColumn("value"); table.addIndex({column}); - table.addIndex({column2}); + table.addIndex({column2}, "value IS NOT NULL"); EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name, value)"))); EXPECT_CALL(databaseMock, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); - EXPECT_CALL(databaseMock, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value)"))); + EXPECT_CALL(databaseMock, + execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " + "WHERE value IS NOT NULL"))); + + table.initialize(databaseMock); +} + +TEST_F(SqliteTable, InitializeTableWithUniqueIndex) +{ + InSequence sequence; + table.setName(tableName.clone()); + auto &column = table.addColumn("name"); + auto &column2 = table.addColumn("value"); + table.addUniqueIndex({column}); + table.addUniqueIndex({column2}, "value IS NOT NULL"); + + EXPECT_CALL(databaseMock, execute(Eq("CREATE TABLE testTable(name, value)"))); + EXPECT_CALL(databaseMock, + execute(Eq( + "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); + EXPECT_CALL(databaseMock, + execute(Eq( + "CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_value ON testTable(value) " + "WHERE value IS NOT NULL"))); table.initialize(databaseMock); }