diff --git a/src/libs/sqlite/sqlitebasestatement.cpp b/src/libs/sqlite/sqlitebasestatement.cpp index 459913060f4..932828a625f 100644 --- a/src/libs/sqlite/sqlitebasestatement.cpp +++ b/src/libs/sqlite/sqlitebasestatement.cpp @@ -51,12 +51,8 @@ namespace Sqlite { BaseStatement::BaseStatement(Utils::SmallStringView sqlStatement, Database &database) : m_compiledStatement(nullptr, deleteCompiledStatement) , m_database(database) - , m_bindingParameterCount(0) - , m_columnCount(0) { prepare(sqlStatement); - setBindingParameterCount(); - setColumnCount(); } void BaseStatement::deleteCompiledStatement(sqlite3_stmt *compiledStatement) @@ -141,11 +137,6 @@ void BaseStatement::step() const next(); } -int BaseStatement::columnCount() const -{ - return m_columnCount; -} - void BaseStatement::bind(int index, NullValue) { int resultCode = sqlite3_bind_null(m_compiledStatement.get(), index); @@ -512,34 +503,16 @@ void BaseStatement::checkForBindingError(int resultCode) const throwUnknowError("SqliteStatement::bind: unknown error has happened"); } +void BaseStatement::checkBindingParameterCount(int bindingParameterCount) const +{ + if (bindingParameterCount != sqlite3_bind_parameter_count(m_compiledStatement.get())) + throw WrongBindingParameterCount{"Sqlite: wrong binding parameter count!"}; +} + void BaseStatement::checkColumnCount(int columnCount) const { - if (columnCount != m_columnCount) - throw ColumnCountDoesNotMatch("SqliteStatement::values: column count does not match!"); -} - -void BaseStatement::checkBindingName(int index) const -{ - if (index <= 0 || index > m_bindingParameterCount) - throwWrongBingingName("SqliteStatement::bind: binding name are not exists in this statement!"); -} - -void BaseStatement::setBindingParameterCount() -{ - m_bindingParameterCount = sqlite3_bind_parameter_count(m_compiledStatement.get()); -} - -Utils::SmallStringView chopFirstLetter(const char *rawBindingName) -{ - if (rawBindingName != nullptr) - return Utils::SmallStringView(++rawBindingName); - - return Utils::SmallStringView(""); -} - -void BaseStatement::setColumnCount() -{ - m_columnCount = sqlite3_column_count(m_compiledStatement.get()); + if (columnCount != sqlite3_column_count(m_compiledStatement.get())) + throw WrongColumnCount{"Sqlite: wrong column count!"}; } bool BaseStatement::isReadOnlyStatement() const @@ -582,11 +555,6 @@ void BaseStatement::throwBindingIndexIsOutOfRange(const char *whatHasHappened) c throw BindingIndexIsOutOfRange(whatHasHappened, sqlite3_errmsg(sqliteDatabaseHandle())); } -void BaseStatement::throwWrongBingingName(const char *whatHasHappened) const -{ - throw WrongBindingName(whatHasHappened); -} - void BaseStatement::throwUnknowError(const char *whatHasHappened) const { if (sqliteDatabaseHandle()) diff --git a/src/libs/sqlite/sqlitebasestatement.h b/src/libs/sqlite/sqlitebasestatement.h index 8ba9de09e89..aa7fb11c7eb 100644 --- a/src/libs/sqlite/sqlitebasestatement.h +++ b/src/libs/sqlite/sqlitebasestatement.h @@ -80,7 +80,6 @@ public: BlobView fetchBlobValue(int column) const; template Type fetchValue(int column) const; - int columnCount() const; void bind(int index, NullValue); void bind(int index, int value); @@ -112,10 +111,9 @@ public: [[noreturn]] void checkForPrepareError(int resultCode) const; [[noreturn]] void checkForBindingError(int resultCode) const; void setIfIsReadyToFetchValues(int resultCode) const; - void checkColumnCount(int columnCount) const; void checkBindingName(int index) const; - void setBindingParameterCount(); - void setColumnCount(); + void checkBindingParameterCount(int bindingParameterCount) const; + void checkColumnCount(int columnCount) const; bool isReadOnlyStatement() const; [[noreturn]] void throwStatementIsBusy(const char *whatHasHappened) const; [[noreturn]] void throwStatementHasError(const char *whatHasHappened) const; @@ -149,8 +147,6 @@ protected: private: std::unique_ptr m_compiledStatement; Database &m_database; - int m_bindingParameterCount; - int m_columnCount; }; template <> SQLITE_EXPORT int BaseStatement::fetchValue(int column) const; @@ -161,7 +157,7 @@ extern template SQLITE_EXPORT Utils::SmallStringView BaseStatement::fetchValue(int column) const; extern template SQLITE_EXPORT Utils::PathString BaseStatement::fetchValue(int column) const; -template +template class StatementImplementation : public BaseStatement { struct Resetter; @@ -175,11 +171,11 @@ public: BaseStatement::next(); } - void bindValues() {} - template - void bindValues(const ValueType&... values) + void bindValues(const ValueType &...values) { + static_assert(BindParameterCount == sizeof...(values), "Wrong binding parameter count!"); + int index = 0; (BaseStatement::bind(++index, values), ...); } @@ -344,10 +340,9 @@ public: using const_iterator = iterator; template - BaseSqliteResultRange(StatementImplementation &statement, const QueryTypes &...queryValues) + BaseSqliteResultRange(StatementImplementation &statement) : m_statement{statement} { - statement.bindValues(queryValues...); } BaseSqliteResultRange(BaseSqliteResultRange &) = delete; @@ -376,7 +371,6 @@ public: SqliteResultRange(StatementImplementation &statement, const QueryTypes &...queryValues) : BaseSqliteResultRange{statement} , resetter{&statement} - { statement.bindValues(queryValues...); } diff --git a/src/libs/sqlite/sqlitedatabase.h b/src/libs/sqlite/sqlitedatabase.h index 588cabf3749..b379e2f80f1 100644 --- a/src/libs/sqlite/sqlitedatabase.h +++ b/src/libs/sqlite/sqlitedatabase.h @@ -45,10 +45,11 @@ namespace Sqlite { using namespace std::chrono_literals; -template +template class ReadStatement; +template class WriteStatement; -template +template class ReadWriteStatement; class SQLITE_EXPORT Database final : public TransactionInterface, public DatabaseInterface @@ -59,11 +60,12 @@ class SQLITE_EXPORT Database final : public TransactionInterface, public Databas public: using MutexType = std::mutex; - template - using ReadStatement = Sqlite::ReadStatement; - using WriteStatement = Sqlite::WriteStatement; - template - using ReadWriteStatement = Sqlite::ReadWriteStatement; + template + using ReadStatement = Sqlite::ReadStatement; + template + using WriteStatement = Sqlite::WriteStatement; + template + using ReadWriteStatement = Sqlite::ReadWriteStatement; using BusyHandler = DatabaseBackend::BusyHandler; Database(); diff --git a/src/libs/sqlite/sqliteexception.h b/src/libs/sqlite/sqliteexception.h index 6dbf92951ae..44f7806662f 100644 --- a/src/libs/sqlite/sqliteexception.h +++ b/src/libs/sqlite/sqliteexception.h @@ -104,12 +104,6 @@ public: using Exception::Exception; }; -class ColumnCountDoesNotMatch : public Exception -{ -public: - using Exception::Exception; -}; - class BindingIndexIsOutOfRange : public ExceptionWithMessage { public: @@ -326,4 +320,10 @@ public: using Exception::Exception; }; +class WrongColumnCount : public Exception +{ +public: + using Exception::Exception; +}; + } // namespace Sqlite diff --git a/src/libs/sqlite/sqlitereadstatement.h b/src/libs/sqlite/sqlitereadstatement.h index 09906a3d902..58eafc3e424 100644 --- a/src/libs/sqlite/sqlitereadstatement.h +++ b/src/libs/sqlite/sqlitereadstatement.h @@ -29,16 +29,18 @@ namespace Sqlite { -template -class ReadStatement final : protected StatementImplementation +template +class ReadStatement final + : protected StatementImplementation { - using Base = StatementImplementation; + using Base = StatementImplementation; public: ReadStatement(Utils::SmallStringView sqlStatement, Database &database) : Base{sqlStatement, database} { checkIsReadOnlyStatement(); + Base::checkBindingParameterCount(BindParameterCount); Base::checkColumnCount(ResultCount); } diff --git a/src/libs/sqlite/sqlitereadwritestatement.h b/src/libs/sqlite/sqlitereadwritestatement.h index e33b247f077..4ac9617996b 100644 --- a/src/libs/sqlite/sqlitereadwritestatement.h +++ b/src/libs/sqlite/sqlitereadwritestatement.h @@ -29,16 +29,18 @@ namespace Sqlite { -template -class ReadWriteStatement final : protected StatementImplementation +template +class ReadWriteStatement final + : protected StatementImplementation { friend class DatabaseBackend; - using Base = StatementImplementation; + using Base = StatementImplementation; public: ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database) : Base{sqlStatement, database} { + Base::checkBindingParameterCount(BindParameterCount); Base::checkColumnCount(ResultCount); } diff --git a/src/libs/sqlite/sqlitesessions.h b/src/libs/sqlite/sqlitesessions.h index da5fe336df6..0d1baeec477 100644 --- a/src/libs/sqlite/sqlitesessions.h +++ b/src/libs/sqlite/sqlitesessions.h @@ -88,7 +88,7 @@ private: public: Database &database; - WriteStatement insertSession; + WriteStatement<1> insertSession; Utils::SmallString databaseName; Utils::SmallStringVector tableNames; std::unique_ptr session; diff --git a/src/libs/sqlite/sqlitewritestatement.h b/src/libs/sqlite/sqlitewritestatement.h index 1a0bb5832ca..cbea0d5b3fd 100644 --- a/src/libs/sqlite/sqlitewritestatement.h +++ b/src/libs/sqlite/sqlitewritestatement.h @@ -28,21 +28,23 @@ #include "sqlitebasestatement.h" namespace Sqlite { - -class WriteStatement : protected StatementImplementation +template +class WriteStatement : protected StatementImplementation { - using Base = StatementImplementation; + using Base = StatementImplementation; public: WriteStatement(Utils::SmallStringView sqlStatement, Database &database) - : StatementImplementation(sqlStatement, database) + : Base(sqlStatement, database) { checkIsWritableStatement(); + Base::checkBindingParameterCount(BindParameterCount); + Base::checkColumnCount(0); } - using StatementImplementation::database; - using StatementImplementation::execute; - using StatementImplementation::write; + using Base::database; + using Base::execute; + using Base::write; protected: void checkIsWritableStatement() diff --git a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h b/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h index 3b320634da0..2f7e2eb93e6 100644 --- a/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h +++ b/src/plugins/qmldesigner/designercore/imagecache/imagecachestorage.h @@ -43,9 +43,10 @@ template class ImageCacheStorage : public ImageCacheStorageInterface { public: - template - using ReadStatement = typename DatabaseType::template ReadStatement; - using WriteStatement = typename DatabaseType::WriteStatement; + template + using ReadStatement = typename DatabaseType::template ReadStatement; + template + using WriteStatement = typename DatabaseType::template WriteStatement; ImageCacheStorage(DatabaseType &database) : database(database) @@ -273,18 +274,18 @@ public: DatabaseType &database; Initializer initializer{database}; Sqlite::ImmediateNonThrowingDestructorTransaction transaction{database}; - mutable ReadStatement<1> selectImageStatement{ + mutable ReadStatement<1, 2> selectImageStatement{ "SELECT image FROM images WHERE name=?1 AND mtime >= ?2", database}; - mutable ReadStatement<1> selectSmallImageStatement{ + mutable ReadStatement<1, 2> selectSmallImageStatement{ "SELECT smallImage FROM images WHERE name=?1 AND mtime >= ?2", database}; - mutable ReadStatement<1> selectIconStatement{ + mutable ReadStatement<1, 2> selectIconStatement{ "SELECT icon FROM icons WHERE name=?1 AND mtime >= ?2", database}; - WriteStatement upsertImageStatement{ + WriteStatement<4> upsertImageStatement{ "INSERT INTO images(name, mtime, image, smallImage) VALUES (?1, ?2, ?3, ?4) ON " "CONFLICT(name) DO UPDATE SET mtime=excluded.mtime, image=excluded.image, " "smallImage=excluded.smallImage", database}; - WriteStatement upsertIconStatement{ + WriteStatement<3> upsertIconStatement{ "INSERT INTO icons(name, mtime, icon) VALUES (?1, ?2, ?3) ON " "CONFLICT(name) DO UPDATE SET mtime=excluded.mtime, icon=excluded.icon", database}; diff --git a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h index 3f10cbe8175..92b189e8629 100644 --- a/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h +++ b/src/plugins/qmldesigner/designercore/projectstorage/projectstorage.h @@ -47,11 +47,12 @@ template class ProjectStorage final : public ProjectStorageInterface { public: - template - using ReadStatement = typename Database::template ReadStatement; - template - using ReadWriteStatement = typename Database::template ReadWriteStatement; - using WriteStatement = typename Database::WriteStatement; + template + using ReadStatement = typename Database::template ReadStatement; + template + using ReadWriteStatement = typename Database::template ReadWriteStatement; + template + using WriteStatement = typename Database::template WriteStatement; ProjectStorage(Database &database, bool isInitialized) : database{database} @@ -2137,18 +2138,18 @@ public: Database &database; Initializer initializer; ModuleCache moduleCache{ModuleStorageAdapter{*this}}; - ReadWriteStatement<1> upsertTypeStatement{ + ReadWriteStatement<1, 3> upsertTypeStatement{ "INSERT INTO types(sourceId, name, accessSemantics) VALUES(?1, ?2, ?3) ON CONFLICT DO " "UPDATE SET accessSemantics=excluded.accessSemantics WHERE accessSemantics IS NOT " "excluded.accessSemantics RETURNING typeId", database}; - WriteStatement updatePrototypeStatement{ + WriteStatement<3> updatePrototypeStatement{ "UPDATE types SET prototypeId=?2, prototypeNameId=?3 WHERE typeId=?1 AND (prototypeId IS " "NOT ?2 OR prototypeNameId IS NOT ?3)", database}; - mutable ReadStatement<1> selectTypeIdByExportedNameStatement{ + mutable ReadStatement<1, 1> selectTypeIdByExportedNameStatement{ "SELECT typeId FROM exportedTypeNames WHERE name=?1", database}; - mutable ReadStatement<1> selectPrototypeIdStatement{ + mutable ReadStatement<1, 2> selectPrototypeIdStatement{ "WITH RECURSIVE " " typeSelection(typeId) AS (" " VALUES(?1) " @@ -2157,7 +2158,7 @@ public: " IS NOT NULL)" "SELECT typeId FROM typeSelection WHERE typeId=?2 LIMIT 1", database}; - mutable ReadStatement<1> selectPropertyDeclarationIdByTypeIdAndNameStatement{ + mutable ReadStatement<1, 2> selectPropertyDeclarationIdByTypeIdAndNameStatement{ "WITH RECURSIVE " " typeSelection(typeId, level) AS (" " VALUES(?1, 0) " @@ -2167,7 +2168,7 @@ public: "SELECT propertyDeclarationId FROM propertyDeclarations JOIN typeSelection USING(typeId) " " WHERE name=?2 ORDER BY level LIMIT 1", database}; - mutable ReadStatement<3> selectPropertyDeclarationByTypeIdAndNameStatement{ + mutable ReadStatement<3, 2> selectPropertyDeclarationByTypeIdAndNameStatement{ "WITH RECURSIVE " " typeSelection(typeId, level) AS (" " VALUES(?1, 0) " @@ -2178,7 +2179,7 @@ public: " FROM propertyDeclarations JOIN typeSelection USING(typeId) " " WHERE name=?2 ORDER BY level LIMIT 1", database}; - mutable ReadStatement<1> selectPrototypeIdsStatement{ + mutable ReadStatement<1, 1> selectPrototypeIdsStatement{ "WITH RECURSIVE " " typeSelection(typeId, level) AS (" " VALUES(?1, 0) " @@ -2187,69 +2188,69 @@ public: " USING(typeId) WHERE prototypeId IS NOT NULL) " "SELECT typeId FROM typeSelection ORDER BY level DESC", database}; - mutable ReadStatement<1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{ + mutable ReadStatement<1, 1> selectSourceContextIdFromSourceContextsBySourceContextPathStatement{ "SELECT sourceContextId FROM sourceContexts WHERE sourceContextPath = ?", database}; - mutable ReadStatement<1> selectSourceContextPathFromSourceContextsBySourceContextIdStatement{ + mutable ReadStatement<1, 1> selectSourceContextPathFromSourceContextsBySourceContextIdStatement{ "SELECT sourceContextPath FROM sourceContexts WHERE sourceContextId = ?", database}; mutable ReadStatement<2> selectAllSourceContextsStatement{ "SELECT sourceContextPath, sourceContextId FROM sourceContexts", database}; - WriteStatement insertIntoSourceContextsStatement{ + WriteStatement<1> insertIntoSourceContextsStatement{ "INSERT INTO sourceContexts(sourceContextPath) VALUES (?)", database}; - mutable ReadStatement<1> selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement{ + mutable ReadStatement<1, 2> selectSourceIdFromSourcesBySourceContextIdAndSourceNameStatement{ "SELECT sourceId FROM sources WHERE sourceContextId = ? AND sourceName = ?", database}; - mutable ReadStatement<2> selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement{ + mutable ReadStatement<2, 1> selectSourceNameAndSourceContextIdFromSourcesBySourceIdStatement{ "SELECT sourceName, sourceContextId FROM sources WHERE sourceId = ?", database}; - mutable ReadStatement<1> selectSourceContextIdFromSourcesBySourceIdStatement{ + mutable ReadStatement<1, 1> selectSourceContextIdFromSourcesBySourceIdStatement{ "SELECT sourceContextId FROM sources WHERE sourceId = ?", database}; - WriteStatement insertIntoSourcesStatement{ + WriteStatement<2> insertIntoSourcesStatement{ "INSERT INTO sources(sourceContextId, sourceName) VALUES (?,?)", database}; mutable ReadStatement<3> selectAllSourcesStatement{ "SELECT sourceName, sourceContextId, sourceId FROM sources", database}; - mutable ReadStatement<4> selectTypeByTypeIdStatement{ + mutable ReadStatement<4, 1> selectTypeByTypeIdStatement{ "SELECT sourceId, name, prototypeId, accessSemantics FROM types WHERE typeId=?", database}; - mutable ReadStatement<4> selectExportedTypesByTypeIdStatement{ + mutable ReadStatement<4, 1> selectExportedTypesByTypeIdStatement{ "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1) FROM " "exportedTypeNames WHERE typeId=?", database}; mutable ReadStatement<5> selectTypesStatement{ "SELECT sourceId, name, typeId, ifnull(prototypeId, -1), accessSemantics FROM types", database}; - ReadStatement<1> selectNotUpdatedTypesInSourcesStatement{ + ReadStatement<1, 2> selectNotUpdatedTypesInSourcesStatement{ "SELECT DISTINCT typeId FROM types WHERE (sourceId IN carray(?1) AND typeId NOT IN " "carray(?2))", database}; - WriteStatement deleteTypeNamesByTypeIdStatement{"DELETE FROM exportedTypeNames WHERE typeId=?", - database}; - WriteStatement deleteEnumerationDeclarationByTypeIdStatement{ + WriteStatement<1> deleteTypeNamesByTypeIdStatement{ + "DELETE FROM exportedTypeNames WHERE typeId=?", database}; + WriteStatement<1> deleteEnumerationDeclarationByTypeIdStatement{ "DELETE FROM enumerationDeclarations WHERE typeId=?", database}; - WriteStatement deletePropertyDeclarationByTypeIdStatement{ + WriteStatement<1> deletePropertyDeclarationByTypeIdStatement{ "DELETE FROM propertyDeclarations WHERE typeId=?", database}; - WriteStatement deleteFunctionDeclarationByTypeIdStatement{ + WriteStatement<1> deleteFunctionDeclarationByTypeIdStatement{ "DELETE FROM functionDeclarations WHERE typeId=?", database}; - WriteStatement deleteSignalDeclarationByTypeIdStatement{ + WriteStatement<1> deleteSignalDeclarationByTypeIdStatement{ "DELETE FROM signalDeclarations WHERE typeId=?", database}; - WriteStatement deleteTypeStatement{"DELETE FROM types WHERE typeId=?", database}; - mutable ReadStatement<4> selectPropertyDeclarationsByTypeIdStatement{ + WriteStatement<1> deleteTypeStatement{"DELETE FROM types WHERE typeId=?", database}; + mutable ReadStatement<4, 1> selectPropertyDeclarationsByTypeIdStatement{ "SELECT name, nullif(propertyTypeId, -1), propertyTraits, (SELECT name FROM " "propertyDeclarations WHERE propertyDeclarationId=pd.aliasPropertyDeclarationId) FROM " "propertyDeclarations AS pd WHERE typeId=?", database}; - ReadStatement<6> selectPropertyDeclarationsForTypeIdStatement{ + ReadStatement<6, 1> selectPropertyDeclarationsForTypeIdStatement{ "SELECT name, propertyTraits, propertyTypeId, propertyImportedTypeNameId, " "propertyDeclarationId, ifnull(aliasPropertyDeclarationId, -1) FROM propertyDeclarations " "WHERE typeId=? ORDER BY name", database}; - ReadWriteStatement<1> insertPropertyDeclarationStatement{ + ReadWriteStatement<1, 5> insertPropertyDeclarationStatement{ "INSERT INTO propertyDeclarations(typeId, name, propertyTypeId, propertyTraits, " "propertyImportedTypeNameId, aliasPropertyDeclarationId) VALUES(?1, ?2, ?3, ?4, ?5, NULL) " "RETURNING propertyDeclarationId", database}; - WriteStatement updatePropertyDeclarationStatement{ + WriteStatement<4> updatePropertyDeclarationStatement{ "UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, " "propertyImportedTypeNameId=?4, aliasPropertyDeclarationId=NULL WHERE " "propertyDeclarationId=?1", database}; - WriteStatement updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement{ + WriteStatement<3> updatePropertyAliasDeclarationRecursivelyWithTypeAndTraitsStatement{ "WITH RECURSIVE " " properties(aliasPropertyDeclarationId) AS ( " " SELECT propertyDeclarationId FROM propertyDeclarations WHERE " @@ -2262,7 +2263,7 @@ public: "FROM properties AS p " "WHERE pd.propertyDeclarationId=p.aliasPropertyDeclarationId", database}; - WriteStatement updatePropertyAliasDeclarationRecursivelyStatement{ + WriteStatement<1> updatePropertyAliasDeclarationRecursivelyStatement{ "WITH RECURSIVE " " propertyValues(propertyTypeId, propertyTraits) AS (" " SELECT propertyTypeId, propertyTraits FROM propertyDeclarations " @@ -2278,120 +2279,120 @@ public: "FROM properties AS p, propertyValues AS pv " "WHERE pd.propertyDeclarationId=p.aliasPropertyDeclarationId", database}; - WriteStatement deletePropertyDeclarationStatement{ + WriteStatement<1> deletePropertyDeclarationStatement{ "DELETE FROM propertyDeclarations WHERE propertyDeclarationId=?", database}; - ReadStatement<3> selectPropertyDeclarationsWithAliasForTypeIdStatement{ + ReadStatement<3, 1> selectPropertyDeclarationsWithAliasForTypeIdStatement{ "SELECT name, propertyDeclarationId, aliasPropertyDeclarationId FROM propertyDeclarations " "WHERE typeId=? AND aliasPropertyDeclarationId IS NOT NULL ORDER BY name", database}; - WriteStatement updatePropertyDeclarationWithAliasAndTypeStatement{ + WriteStatement<5> updatePropertyDeclarationWithAliasAndTypeStatement{ "UPDATE propertyDeclarations SET propertyTypeId=?2, propertyTraits=?3, " "propertyImportedTypeNameId=?4, aliasPropertyDeclarationId=?5 WHERE " "propertyDeclarationId=?1", database}; - ReadWriteStatement<1> insertAliasPropertyDeclarationStatement{ + ReadWriteStatement<1, 2> insertAliasPropertyDeclarationStatement{ "INSERT INTO propertyDeclarations(typeId, name) VALUES(?1, ?2) RETURNING " "propertyDeclarationId", database}; - mutable ReadStatement<4> selectFunctionDeclarationsForTypeIdStatement{ + mutable ReadStatement<4, 1> selectFunctionDeclarationsForTypeIdStatement{ "SELECT name, returnTypeName, signature, functionDeclarationId FROM " "functionDeclarations WHERE typeId=? ORDER BY name", database}; - mutable ReadStatement<3> selectFunctionDeclarationsForTypeIdWithoutSignatureStatement{ + mutable ReadStatement<3, 1> selectFunctionDeclarationsForTypeIdWithoutSignatureStatement{ "SELECT name, returnTypeName, functionDeclarationId FROM " "functionDeclarations WHERE typeId=? ORDER BY name", database}; - mutable ReadStatement<3> selectFunctionParameterDeclarationsStatement{ + mutable ReadStatement<3, 1> selectFunctionParameterDeclarationsStatement{ "SELECT json_extract(json_each.value, '$.n'), json_extract(json_each.value, '$.tn'), " "json_extract(json_each.value, '$.tr') FROM functionDeclarations, " "json_each(functionDeclarations.signature) WHERE functionDeclarationId=?", database}; - WriteStatement insertFunctionDeclarationStatement{ + WriteStatement<4> insertFunctionDeclarationStatement{ "INSERT INTO functionDeclarations(typeId, name, returnTypeName, signature) VALUES(?1, ?2, " "?3, ?4)", database}; - WriteStatement updateFunctionDeclarationStatement{ + WriteStatement<3> updateFunctionDeclarationStatement{ "UPDATE functionDeclarations SET returnTypeName=?2, signature=?3 WHERE " "functionDeclarationId=?1", database}; - WriteStatement deleteFunctionDeclarationStatement{ + WriteStatement<1> deleteFunctionDeclarationStatement{ "DELETE FROM functionDeclarations WHERE functionDeclarationId=?", database}; - mutable ReadStatement<3> selectSignalDeclarationsForTypeIdStatement{ + mutable ReadStatement<3, 1> selectSignalDeclarationsForTypeIdStatement{ "SELECT name, signature, signalDeclarationId FROM signalDeclarations WHERE typeId=? ORDER " "BY name", database}; - mutable ReadStatement<2> selectSignalDeclarationsForTypeIdWithoutSignatureStatement{ + mutable ReadStatement<2, 1> selectSignalDeclarationsForTypeIdWithoutSignatureStatement{ "SELECT name, signalDeclarationId FROM signalDeclarations WHERE typeId=? ORDER BY name", database}; - mutable ReadStatement<3> selectSignalParameterDeclarationsStatement{ + mutable ReadStatement<3, 1> selectSignalParameterDeclarationsStatement{ "SELECT json_extract(json_each.value, '$.n'), json_extract(json_each.value, '$.tn'), " "json_extract(json_each.value, '$.tr') FROM signalDeclarations, " "json_each(signalDeclarations.signature) WHERE signalDeclarationId=?", database}; - WriteStatement insertSignalDeclarationStatement{ + WriteStatement<3> insertSignalDeclarationStatement{ "INSERT INTO signalDeclarations(typeId, name, signature) VALUES(?1, ?2, ?3)", database}; - WriteStatement updateSignalDeclarationStatement{ + WriteStatement<2> updateSignalDeclarationStatement{ "UPDATE signalDeclarations SET signature=?2 WHERE signalDeclarationId=?1", database}; - WriteStatement deleteSignalDeclarationStatement{ + WriteStatement<1> deleteSignalDeclarationStatement{ "DELETE FROM signalDeclarations WHERE signalDeclarationId=?", database}; - mutable ReadStatement<3> selectEnumerationDeclarationsForTypeIdStatement{ + mutable ReadStatement<3, 1> selectEnumerationDeclarationsForTypeIdStatement{ "SELECT name, enumeratorDeclarations, enumerationDeclarationId FROM " "enumerationDeclarations WHERE typeId=? ORDER BY name", database}; - mutable ReadStatement<2> selectEnumerationDeclarationsForTypeIdWithoutEnumeratorDeclarationsStatement{ + mutable ReadStatement<2, 1> selectEnumerationDeclarationsForTypeIdWithoutEnumeratorDeclarationsStatement{ "SELECT name, enumerationDeclarationId FROM enumerationDeclarations WHERE typeId=? ORDER " "BY name", database}; - mutable ReadStatement<3> selectEnumeratorDeclarationStatement{ + mutable ReadStatement<3, 1> selectEnumeratorDeclarationStatement{ "SELECT json_each.key, json_each.value, json_each.type!='null' FROM " "enumerationDeclarations, json_each(enumerationDeclarations.enumeratorDeclarations) WHERE " "enumerationDeclarationId=?", database}; - WriteStatement insertEnumerationDeclarationStatement{ + WriteStatement<3> insertEnumerationDeclarationStatement{ "INSERT INTO enumerationDeclarations(typeId, name, enumeratorDeclarations) VALUES(?1, ?2, " "?3)", database}; - WriteStatement updateEnumerationDeclarationStatement{ + WriteStatement<2> updateEnumerationDeclarationStatement{ "UPDATE enumerationDeclarations SET enumeratorDeclarations=?2 WHERE " "enumerationDeclarationId=?1", database}; - WriteStatement deleteEnumerationDeclarationStatement{ + WriteStatement<1> deleteEnumerationDeclarationStatement{ "DELETE FROM enumerationDeclarations WHERE enumerationDeclarationId=?", database}; - mutable ReadStatement<1> selectModuleIdByNameStatement{ + mutable ReadStatement<1, 1> selectModuleIdByNameStatement{ "SELECT moduleId FROM modules WHERE name=? LIMIT 1", database}; - mutable ReadWriteStatement<1> insertModuleNameStatement{ + mutable ReadWriteStatement<1, 1> insertModuleNameStatement{ "INSERT INTO modules(name) VALUES(?1) RETURNING moduleId", database}; - mutable ReadStatement<1> selectModuleNameStatement{ + mutable ReadStatement<1, 1> selectModuleNameStatement{ "SELECT name FROM modules WHERE moduleId =?1", database}; mutable ReadStatement<2> selectAllModulesStatement{"SELECT name, moduleId FROM modules", database}; - mutable ReadStatement<1> selectTypeIdBySourceIdAndNameStatement{ + mutable ReadStatement<1, 2> selectTypeIdBySourceIdAndNameStatement{ "SELECT typeId FROM types WHERE sourceId=?1 and name=?2", database}; - mutable ReadStatement<1> selectTypeIdByModuleIdsAndExportedNameStatement{ + mutable ReadStatement<1, 3> selectTypeIdByModuleIdsAndExportedNameStatement{ "SELECT typeId FROM exportedTypeNames WHERE moduleId IN carray(?1, ?2, 'int32') AND " "name=?3", database}; - mutable ReadStatement<5> selectDocumentImportForSourceIdStatement{ + mutable ReadStatement<5, 1> selectDocumentImportForSourceIdStatement{ "SELECT importId, sourceId, moduleId, ifnull(majorVersion, -1), ifnull(minorVersion, -1) " "FROM documentImports WHERE sourceId IN carray(?1) ORDER BY sourceId, moduleId, " "majorVersion, minorVersion", database}; - WriteStatement insertDocumentImportWithoutVersionStatement{ + WriteStatement<2> insertDocumentImportWithoutVersionStatement{ "INSERT INTO documentImports(sourceId, moduleId) " "VALUES (?1, ?2)", database}; - WriteStatement insertDocumentImportWithMajorVersionStatement{ + WriteStatement<3> insertDocumentImportWithMajorVersionStatement{ "INSERT INTO documentImports(sourceId, moduleId, majorVersion) " "VALUES (?1, ?2, ?3)", database}; - WriteStatement insertDocumentImportWithVersionStatement{ + WriteStatement<4> insertDocumentImportWithVersionStatement{ "INSERT INTO documentImports(sourceId, moduleId, majorVersion, minorVersion) " "VALUES (?1, ?2, ?3, ?4)", database}; - WriteStatement deleteDocumentImportStatement{"DELETE FROM documentImports WHERE importId=?1", - database}; - WriteStatement deleteDocumentImportsWithSourceIdsStatement{ + WriteStatement<1> deleteDocumentImportStatement{"DELETE FROM documentImports WHERE importId=?1", + database}; + WriteStatement<1> deleteDocumentImportsWithSourceIdsStatement{ "DELETE FROM documentImports WHERE sourceId IN carray(?1)", database}; - ReadStatement<1> selectPropertyDeclarationIdPrototypeChainDownStatement{ + ReadStatement<1, 2> selectPropertyDeclarationIdPrototypeChainDownStatement{ "WITH RECURSIVE " " typeSelection(typeId, level) AS (" " SELECT prototypeId, 0 FROM types WHERE typeId=?1 AND prototypeId IS NOT NULL" @@ -2401,22 +2402,22 @@ public: "SELECT propertyDeclarationId FROM typeSelection JOIN propertyDeclarations " " USING(typeId) WHERE name=?2 ORDER BY level LIMIT 1", database}; - WriteStatement updateAliasIdPropertyDeclarationStatement{ + WriteStatement<2> updateAliasIdPropertyDeclarationStatement{ "UPDATE propertyDeclarations SET aliasPropertyDeclarationId=?2 WHERE " "aliasPropertyDeclarationId=?1", database}; - WriteStatement updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement{ + WriteStatement<2> updateAliasPropertyDeclarationByAliasPropertyDeclarationIdStatement{ "UPDATE propertyDeclarations SET propertyTypeId=new.propertyTypeId, " "propertyTraits=new.propertyTraits, aliasPropertyDeclarationId=?1 FROM (SELECT " "propertyTypeId, propertyTraits FROM propertyDeclarations WHERE propertyDeclarationId=?1) " "AS new WHERE aliasPropertyDeclarationId=?2", database}; - WriteStatement updateAliasPropertyDeclarationToNullStatement{ + WriteStatement<1> updateAliasPropertyDeclarationToNullStatement{ "UPDATE propertyDeclarations SET aliasPropertyDeclarationId=NULL, propertyTypeId=NULL, " "propertyTraits=NULL WHERE propertyDeclarationId=? AND (aliasPropertyDeclarationId IS NOT " "NULL OR propertyTypeId IS NOT NULL OR propertyTraits IS NOT NULL)", database}; - ReadStatement<4> selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement{ + ReadStatement<4, 1> selectAliasPropertiesDeclarationForPropertiesWithTypeIdStatement{ "SELECT alias.typeId, alias.propertyDeclarationId, alias.propertyImportedTypeNameId, " "target.propertyDeclarationId FROM propertyDeclarations AS alias JOIN propertyDeclarations " "AS target ON alias.aliasPropertyDeclarationId=target.propertyDeclarationId WHERE " @@ -2424,7 +2425,7 @@ public: "(SELECT importedTypeNameId FROM exportedTypeNames JOIN importedTypeNames USING(name) " "WHERE typeId=?1)", database}; - ReadStatement<3> selectAliasPropertiesDeclarationForPropertiesWithAliasIdStatement{ + ReadStatement<3, 1> selectAliasPropertiesDeclarationForPropertiesWithAliasIdStatement{ "WITH RECURSIVE " " properties(propertyDeclarationId, propertyImportedTypeNameId, typeId, " " aliasPropertyDeclarationId) AS (" @@ -2438,22 +2439,22 @@ public: "SELECT propertyDeclarationId, propertyImportedTypeNameId, aliasPropertyDeclarationId " " FROM properties", database}; - ReadWriteStatement<3> updatesPropertyDeclarationPropertyTypeToNullStatement{ + ReadWriteStatement<3, 1> updatesPropertyDeclarationPropertyTypeToNullStatement{ "UPDATE propertyDeclarations SET propertyTypeId=NULL WHERE propertyTypeId=?1 AND " "aliasPropertyDeclarationId IS NULL RETURNING typeId, propertyDeclarationId, " "propertyImportedTypeNameId", database}; - ReadStatement<1> selectPropertyNameStatement{ + ReadStatement<1, 1> selectPropertyNameStatement{ "SELECT name FROM propertyDeclarations WHERE propertyDeclarationId=?", database}; - WriteStatement updatePropertyDeclarationTypeStatement{ + WriteStatement<2> updatePropertyDeclarationTypeStatement{ "UPDATE propertyDeclarations SET propertyTypeId=?2 WHERE propertyDeclarationId=?1", database}; - ReadWriteStatement<2> updatePrototypeIdToNullStatement{ + ReadWriteStatement<2, 1> updatePrototypeIdToNullStatement{ "UPDATE types SET prototypeId=NULL WHERE prototypeId=?1 RETURNING " "typeId, prototypeNameId", database}; - WriteStatement updateTypePrototypeStatement{"UPDATE types SET prototypeId=?2 WHERE typeId=?1", - database}; - mutable ReadStatement<1> selectTypeIdsForPrototypeChainIdStatement{ + WriteStatement<2> updateTypePrototypeStatement{ + "UPDATE types SET prototypeId=?2 WHERE typeId=?1", database}; + mutable ReadStatement<1, 1> selectTypeIdsForPrototypeChainIdStatement{ "WITH RECURSIVE " " prototypes(typeId) AS (" " SELECT prototypeId FROM types WHERE typeId=? AND prototypeId IS NOT NULL" @@ -2462,12 +2463,12 @@ public: " IS NOT NULL)" "SELECT typeId FROM prototypes", database}; - WriteStatement updatePropertyDeclarationAliasIdAndTypeNameIdStatement{ + WriteStatement<3> updatePropertyDeclarationAliasIdAndTypeNameIdStatement{ "UPDATE propertyDeclarations SET aliasPropertyDeclarationId=?2, " "propertyImportedTypeNameId=?3 WHERE propertyDeclarationId=?1 AND " "(aliasPropertyDeclarationId IS NOT ?2 OR propertyImportedTypeNameId IS NOT ?3)", database}; - WriteStatement updatetPropertiesDeclarationValuesOfAliasStatement{ + WriteStatement<1> updatetPropertiesDeclarationValuesOfAliasStatement{ "WITH RECURSIVE " " properties(propertyDeclarationId, propertyTypeId, propertyTraits) AS ( " " SELECT aliasPropertyDeclarationId, propertyTypeId, propertyTraits FROM " @@ -2482,11 +2483,11 @@ public: " (pd.propertyTypeId IS NOT p.propertyTypeId OR pd.propertyTraits IS NOT " " p.propertyTraits)", database}; - WriteStatement updatePropertyDeclarationAliasIdToNullStatement{ + WriteStatement<1> updatePropertyDeclarationAliasIdToNullStatement{ "UPDATE propertyDeclarations SET aliasPropertyDeclarationId=NULL WHERE " "propertyDeclarationId=?1", database}; - mutable ReadStatement<1> selectPropertyDeclarationIdsForAliasChainStatement{ + mutable ReadStatement<1, 1> selectPropertyDeclarationIdsForAliasChainStatement{ "WITH RECURSIVE " " properties(propertyDeclarationId) AS ( " " SELECT aliasPropertyDeclarationId FROM propertyDeclarations WHERE " @@ -2498,43 +2499,44 @@ public: database}; mutable ReadStatement<3> selectAllFileStatusesStatement{ "SELECT sourceId, size, lastModified FROM fileStatuses ORDER BY sourceId", database}; - mutable ReadStatement<3> selectFileStatusesForSourceIdsStatement{ + mutable ReadStatement<3, 1> selectFileStatusesForSourceIdsStatement{ "SELECT sourceId, size, lastModified FROM fileStatuses WHERE sourceId IN carray(?1) ORDER " "BY sourceId", database}; - mutable ReadStatement<3> selectFileStatusesForSourceIdStatement{ + mutable ReadStatement<3, 1> selectFileStatusesForSourceIdStatement{ "SELECT sourceId, size, lastModified FROM fileStatuses WHERE sourceId=?1 ORDER BY sourceId", database}; - WriteStatement insertFileStatusStatement{ + WriteStatement<3> insertFileStatusStatement{ "INSERT INTO fileStatuses(sourceId, size, lastModified) VALUES(?1, ?2, ?3)", database}; - WriteStatement deleteFileStatusStatement{"DELETE FROM fileStatuses WHERE sourceId=?1", database}; - WriteStatement updateFileStatusStatement{ + WriteStatement<1> deleteFileStatusStatement{"DELETE FROM fileStatuses WHERE sourceId=?1", + database}; + WriteStatement<3> updateFileStatusStatement{ "UPDATE fileStatuses SET size=?2, lastModified=?3 WHERE sourceId=?1", database}; - ReadStatement<1> selectTypeIdBySourceIdStatement{"SELECT typeId FROM types WHERE sourceId=?", - database}; - mutable ReadStatement<1> selectImportedTypeNameIdStatement{ + ReadStatement<1, 1> selectTypeIdBySourceIdStatement{"SELECT typeId FROM types WHERE sourceId=?", + database}; + mutable ReadStatement<1, 3> selectImportedTypeNameIdStatement{ "SELECT importedTypeNameId FROM importedTypeNames WHERE kind=?1 AND importOrSourceId=?2 " "AND name=?3 LIMIT 1", database}; - mutable ReadWriteStatement<1> insertImportedTypeNameIdStatement{ + mutable ReadWriteStatement<1, 3> insertImportedTypeNameIdStatement{ "INSERT INTO importedTypeNames(kind, importOrSourceId, name) VALUES (?1, ?2, ?3) " "RETURNING importedTypeNameId", database}; - mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdStatement{ + mutable ReadStatement<1, 2> selectImportIdBySourceIdAndModuleIdStatement{ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND majorVersion " "IS NULL AND minorVersion IS NULL LIMIT 1", database}; - mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement{ + mutable ReadStatement<1, 3> selectImportIdBySourceIdAndModuleIdAndMajorVersionStatement{ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND " "majorVersion=?3 AND minorVersion IS NULL LIMIT 1", database}; - mutable ReadStatement<1> selectImportIdBySourceIdAndModuleIdAndVersionStatement{ + mutable ReadStatement<1, 4> selectImportIdBySourceIdAndModuleIdAndVersionStatement{ "SELECT importId FROM documentImports WHERE sourceId=?1 AND moduleId=?2 AND " "majorVersion=?3 AND minorVersion=?4 LIMIT 1", database}; - mutable ReadStatement<1> selectKindFromImportedTypeNamesStatement{ + mutable ReadStatement<1, 1> selectKindFromImportedTypeNamesStatement{ "SELECT kind FROM importedTypeNames WHERE importedTypeNameId=?1", database}; - mutable ReadStatement<1> selectTypeIdForQualifiedImportedTypeNameNamesStatement{ + mutable ReadStatement<1, 1> selectTypeIdForQualifiedImportedTypeNameNamesStatement{ "SELECT typeId FROM importedTypeNames AS itn JOIN documentImports AS di ON " "importOrSourceId=importId JOIN exportedTypeNames AS etn USING(moduleId) WHERE " "itn.kind=2 AND importedTypeNameId=?1 AND itn.name=etn.name AND " @@ -2542,7 +2544,7 @@ public: "NULL OR di.minorVersion>=etn.minorVersion))) ORDER BY etn.majorVersion DESC NULLS FIRST, " "etn.minorVersion DESC NULLS FIRST LIMIT 1", database}; - mutable ReadStatement<1> selectTypeIdForImportedTypeNameNamesStatement{ + mutable ReadStatement<1, 1> selectTypeIdForImportedTypeNameNamesStatement{ "SELECT typeId FROM importedTypeNames AS itn JOIN documentImports AS di ON " "importOrSourceId=sourceId JOIN exportedTypeNames AS etn USING(moduleId) WHERE " "itn.kind=1 AND importedTypeNameId=?1 AND itn.name=etn.name AND " @@ -2550,44 +2552,45 @@ public: "NULL OR di.minorVersion>=etn.minorVersion))) ORDER BY etn.majorVersion DESC NULLS FIRST, " "etn.minorVersion DESC NULLS FIRST LIMIT 1", database}; - WriteStatement deleteAllSourcesStatement{"DELETE FROM sources", database}; - WriteStatement deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; - mutable ReadStatement<6> selectExportedTypesForSourceIdsStatement{ + WriteStatement<0> deleteAllSourcesStatement{"DELETE FROM sources", database}; + WriteStatement<0> deleteAllSourceContextsStatement{"DELETE FROM sourceContexts", database}; + mutable ReadStatement<6, 1> selectExportedTypesForSourceIdsStatement{ "SELECT moduleId, name, ifnull(majorVersion, -1), ifnull(minorVersion, -1), typeId, " "exportedTypeNameId FROM exportedTypeNames WHERE typeId in carray(?1) ORDER BY moduleId, " "name, majorVersion, minorVersion", database}; - WriteStatement insertExportedTypeNamesWithVersionStatement{ + WriteStatement<5> insertExportedTypeNamesWithVersionStatement{ "INSERT INTO exportedTypeNames(moduleId, name, majorVersion, minorVersion, typeId) " "VALUES(?1, ?2, ?3, ?4, ?5)", database}; - WriteStatement insertExportedTypeNamesWithMajorVersionStatement{ + WriteStatement<4> insertExportedTypeNamesWithMajorVersionStatement{ "INSERT INTO exportedTypeNames(moduleId, name, majorVersion, typeId) " "VALUES(?1, ?2, ?3, ?4)", database}; - WriteStatement insertExportedTypeNamesWithoutVersionStatement{ + WriteStatement<3> insertExportedTypeNamesWithoutVersionStatement{ "INSERT INTO exportedTypeNames(moduleId, name, typeId) VALUES(?1, ?2, ?3)", database}; - WriteStatement deleteExportedTypeNameStatement{ + WriteStatement<1> deleteExportedTypeNameStatement{ "DELETE FROM exportedTypeNames WHERE exportedTypeNameId=?", database}; - WriteStatement updateExportedTypeNameTypeIdStatement{ + WriteStatement<2> updateExportedTypeNameTypeIdStatement{ "UPDATE exportedTypeNames SET typeId=?2 WHERE exportedTypeNameId=?1", database}; - mutable ReadStatement<4> selectProjectDatasForModuleIdsStatement{ + mutable ReadStatement<4, 1> selectProjectDatasForModuleIdsStatement{ "SELECT projectSourceId, sourceId, moduleId, fileType FROM projectDatas WHERE " "projectSourceId IN carray(?1) ORDER BY projectSourceId, sourceId", database}; - WriteStatement insertProjectDataStatement{"INSERT INTO projectDatas(projectSourceId, sourceId, " - "moduleId, fileType) VALUES(?1, ?2, ?3, ?4)", - database}; - WriteStatement deleteProjectDataStatement{ + WriteStatement<4> insertProjectDataStatement{ + "INSERT INTO projectDatas(projectSourceId, sourceId, " + "moduleId, fileType) VALUES(?1, ?2, ?3, ?4)", + database}; + WriteStatement<2> deleteProjectDataStatement{ "DELETE FROM projectDatas WHERE projectSourceId=?1 AND sourceId=?2", database}; - WriteStatement updateProjectDataStatement{ + WriteStatement<4> updateProjectDataStatement{ "UPDATE projectDatas SET moduleId=?3, fileType=?4 WHERE projectSourceId=?1 AND sourceId=?2", database}; - mutable ReadStatement<4> selectProjectDatasForModuleIdStatement{ + mutable ReadStatement<4, 1> selectProjectDatasForModuleIdStatement{ "SELECT projectSourceId, sourceId, moduleId, fileType FROM projectDatas WHERE " "projectSourceId=?1", database}; - ReadStatement<1> selectTypeIdsForSourceIdsStatement{ + ReadStatement<1, 1> selectTypeIdsForSourceIdsStatement{ "SELECT typeId FROM types WHERE sourceId IN carray(?1)", database}; }; diff --git a/tests/unit/unittest/imagecachestorage-test.cpp b/tests/unit/unittest/imagecachestorage-test.cpp index 50995e6c407..73098c8cd5b 100644 --- a/tests/unit/unittest/imagecachestorage-test.cpp +++ b/tests/unit/unittest/imagecachestorage-test.cpp @@ -55,17 +55,19 @@ MATCHER_P2(IsIconEntry, class ImageCacheStorageTest : public testing::Test { protected: - template - using ReadStatement = QmlDesigner::ImageCacheStorage::ReadStatement; - using WriteStatement = QmlDesigner::ImageCacheStorage::WriteStatement; + template + using ReadStatement = QmlDesigner::ImageCacheStorage< + SqliteDatabaseMock>::ReadStatement; + template + using WriteStatement = QmlDesigner::ImageCacheStorage::WriteStatement; NiceMock databaseMock; QmlDesigner::ImageCacheStorage storage{databaseMock}; - ReadStatement<1> &selectImageStatement = storage.selectImageStatement; - ReadStatement<1> &selectSmallImageStatement = storage.selectSmallImageStatement; - ReadStatement<1> &selectIconStatement = storage.selectIconStatement; - WriteStatement &upsertImageStatement = storage.upsertImageStatement; - WriteStatement &upsertIconStatement = storage.upsertIconStatement; + ReadStatement<1, 2> &selectImageStatement = storage.selectImageStatement; + ReadStatement<1, 2> &selectSmallImageStatement = storage.selectSmallImageStatement; + ReadStatement<1, 2> &selectIconStatement = storage.selectIconStatement; + WriteStatement<4> &upsertImageStatement = storage.upsertImageStatement; + WriteStatement<3> &upsertIconStatement = storage.upsertIconStatement; QImage image1{10, 10, QImage::Format_ARGB32}; QImage smallImage1{10, 10, QImage::Format_ARGB32}; QIcon icon1{QPixmap::fromImage(image1)}; diff --git a/tests/unit/unittest/mocksqlitestatement.h b/tests/unit/unittest/mocksqlitestatement.h index a05c160371f..6e10384fbcc 100644 --- a/tests/unit/unittest/mocksqlitestatement.h +++ b/tests/unit/unittest/mocksqlitestatement.h @@ -64,6 +64,7 @@ public: MOCK_METHOD1(prepare, void(Utils::SmallStringView sqlStatement)); MOCK_METHOD1(checkColumnCount, void(int)); + MOCK_METHOD1(checkBindingParameterCount, void(int)); MOCK_CONST_METHOD0(isReadOnlyStatement, bool()); @@ -109,11 +110,11 @@ Utils::PathString BaseMockSqliteStatement::fetchValue(int col return fetchPathStringValue(column); } -template +template class MockSqliteStatement - : public Sqlite::StatementImplementation, ResultCount> + : public Sqlite::StatementImplementation, ResultCount, BindParameterCount> { - using Base = Sqlite::StatementImplementation, ResultCount>; + using Base = Sqlite::StatementImplementation, ResultCount, BindParameterCount>; public: explicit MockSqliteStatement(SqliteDatabaseMock &databaseMock) diff --git a/tests/unit/unittest/sqlitealgorithms-test.cpp b/tests/unit/unittest/sqlitealgorithms-test.cpp index 462814a67df..a1647979fa8 100644 --- a/tests/unit/unittest/sqlitealgorithms-test.cpp +++ b/tests/unit/unittest/sqlitealgorithms-test.cpp @@ -121,9 +121,10 @@ protected: database}; Sqlite::ReadStatement<2> selectValuesStatement{"SELECT key, value FROM data ORDER BY key", database}; - Sqlite::WriteStatement insertStatement{"INSERT INTO data(key, value) VALUES (?1, ?2)", database}; - Sqlite::WriteStatement updateStatement{"UPDATE data SET value = ?2 WHERE key=?1", database}; - Sqlite::WriteStatement deleteStatement{"DELETE FROM data WHERE key=?", database}; + Sqlite::WriteStatement<2> insertStatement{"INSERT INTO data(key, value) VALUES (?1, ?2)", + database}; + Sqlite::WriteStatement<2> updateStatement{"UPDATE data SET value = ?2 WHERE key=?1", database}; + Sqlite::WriteStatement<1> deleteStatement{"DELETE FROM data WHERE key=?", database}; std::function insert{ [&](const KeyValue &keyValue) { insertStatement.write(keyValue.key, keyValue.value); }}; std::function update{ diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp index 4c05fcd9b07..92cdf01961c 100644 --- a/tests/unit/unittest/sqlitedatabase-test.cpp +++ b/tests/unit/unittest/sqlitedatabase-test.cpp @@ -196,7 +196,7 @@ TEST_F(SqliteDatabase, DatabaseIsNotInitializedIfDatabasePathDoesNotExistAtOpeni TEST_F(SqliteDatabase, GetChangesCount) { - Sqlite::WriteStatement statement("INSERT INTO test(name) VALUES (?)", database); + Sqlite::WriteStatement<1> statement("INSERT INTO test(name) VALUES (?)", database); statement.write(42); ASSERT_THAT(database.changesCount(), 1); @@ -204,7 +204,7 @@ TEST_F(SqliteDatabase, GetChangesCount) TEST_F(SqliteDatabase, GetTotalChangesCount) { - Sqlite::WriteStatement statement("INSERT INTO test(name) VALUES (?)", database); + Sqlite::WriteStatement<1> statement("INSERT INTO test(name) VALUES (?)", database); statement.write(42); ASSERT_THAT(database.lastInsertedRowId(), 1); @@ -212,7 +212,7 @@ TEST_F(SqliteDatabase, GetTotalChangesCount) TEST_F(SqliteDatabase, GetLastInsertedRowId) { - Sqlite::WriteStatement statement("INSERT INTO test(name) VALUES (?)", database); + Sqlite::WriteStatement<1> statement("INSERT INTO test(name) VALUES (?)", database); statement.write(42); ASSERT_THAT(database.lastInsertedRowId(), 1); @@ -265,7 +265,7 @@ TEST_F(SqliteDatabase, SetUpdateHookSet) database.setUpdateHook(this, updateHookCallback); EXPECT_CALL(callbackMock, Call(_, _, _, _)); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, SetNullUpdateHook) @@ -275,7 +275,7 @@ TEST_F(SqliteDatabase, SetNullUpdateHook) database.setUpdateHook(nullptr, nullptr); EXPECT_CALL(callbackMock, Call(_, _, _, _)).Times(0); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, ResetUpdateHook) @@ -285,12 +285,12 @@ TEST_F(SqliteDatabase, ResetUpdateHook) database.resetUpdateHook(); EXPECT_CALL(callbackMock, Call(_, _, _, _)).Times(0); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, DeleteUpdateHookCall) { - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); database.setUpdateHook(this, updateHookCallback); EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Delete), _, _, _)); @@ -304,7 +304,7 @@ TEST_F(SqliteDatabase, InsertUpdateHookCall) EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Insert), _, _, _)); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, UpdateUpdateHookCall) @@ -313,7 +313,7 @@ TEST_F(SqliteDatabase, UpdateUpdateHookCall) EXPECT_CALL(callbackMock, Call(Eq(Sqlite::ChangeType::Insert), _, _, _)); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, RowIdUpdateHookCall) @@ -322,7 +322,7 @@ TEST_F(SqliteDatabase, RowIdUpdateHookCall) EXPECT_CALL(callbackMock, Call(_, _, _, Eq(42))); - Sqlite::WriteStatement("INSERT INTO test(rowid, name) VALUES (?,?)", database).write(42, "foo"); + Sqlite::WriteStatement<2>("INSERT INTO test(rowid, name) VALUES (?,?)", database).write(42, "foo"); } TEST_F(SqliteDatabase, DatabaseUpdateHookCall) @@ -331,7 +331,7 @@ TEST_F(SqliteDatabase, DatabaseUpdateHookCall) EXPECT_CALL(callbackMock, Call(_, StrEq("main"), _, _)); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, TableUpdateHookCall) @@ -340,20 +340,21 @@ TEST_F(SqliteDatabase, TableUpdateHookCall) EXPECT_CALL(callbackMock, Call(_, _, StrEq("test"), _)); - Sqlite::WriteStatement("INSERT INTO test(name) VALUES (?)", database).write(42); + Sqlite::WriteStatement<1>("INSERT INTO test(name) VALUES (?)", database).write(42); } TEST_F(SqliteDatabase, SessionsCommit) { database.setAttachedTables({"test"}); - Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); + Sqlite::WriteStatement<2>("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); database.unlock(); Sqlite::ImmediateSessionTransaction transaction{database}; - Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); + Sqlite::WriteStatement<2>("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); transaction.commit(); database.lock(); - Sqlite::WriteStatement("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database).write(2, "hoo"); + Sqlite::WriteStatement<2>("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database) + .write(2, "hoo"); database.applyAndUpdateSessions(); ASSERT_THAT(names(), ElementsAre("foo", "bar")); @@ -362,15 +363,16 @@ TEST_F(SqliteDatabase, SessionsCommit) TEST_F(SqliteDatabase, SessionsRollback) { database.setAttachedTables({"test"}); - Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); + Sqlite::WriteStatement<2>("INSERT INTO test(id, name) VALUES (?,?)", database).write(1, "foo"); database.unlock(); { Sqlite::ImmediateSessionTransaction transaction{database}; - Sqlite::WriteStatement("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); + Sqlite::WriteStatement<2>("INSERT INTO test(id, name) VALUES (?,?)", database).write(2, "bar"); } database.lock(); - Sqlite::WriteStatement("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database).write(2, "hoo"); + Sqlite::WriteStatement<2>("INSERT OR REPLACE INTO test(id, name) VALUES (?,?)", database) + .write(2, "hoo"); database.applyAndUpdateSessions(); ASSERT_THAT(names(), ElementsAre("foo", "hoo")); diff --git a/tests/unit/unittest/sqlitedatabasemock.h b/tests/unit/unittest/sqlitedatabasemock.h index 3314dd3a651..4ea83a46b40 100644 --- a/tests/unit/unittest/sqlitedatabasemock.h +++ b/tests/unit/unittest/sqlitedatabasemock.h @@ -41,11 +41,12 @@ class SqliteDatabaseMock : public SqliteTransactionBackendMock, public Sqlite::DatabaseInterface { public: - template - using ReadStatement = NiceMock>; - using WriteStatement = NiceMock; - template - using ReadWriteStatement = NiceMock>; + template + using ReadStatement = NiceMock>; + template + using WriteStatement = NiceMock>; + template + using ReadWriteStatement = NiceMock>; MOCK_METHOD(void, prepare, (Utils::SmallStringView sqlStatement), ()); diff --git a/tests/unit/unittest/sqlitereadstatementmock.h b/tests/unit/unittest/sqlitereadstatementmock.h index 9bde954ac91..225c83d5c95 100644 --- a/tests/unit/unittest/sqlitereadstatementmock.h +++ b/tests/unit/unittest/sqlitereadstatementmock.h @@ -273,7 +273,7 @@ public: Utils::SmallString sqlStatement; }; -template +template class SqliteReadStatementMock : public SqliteReadStatementMockBase { public: diff --git a/tests/unit/unittest/sqlitereadwritestatementmock.h b/tests/unit/unittest/sqlitereadwritestatementmock.h index 563731c02d4..5b85a67b681 100644 --- a/tests/unit/unittest/sqlitereadwritestatementmock.h +++ b/tests/unit/unittest/sqlitereadwritestatementmock.h @@ -87,7 +87,7 @@ public: Utils::SmallString sqlStatement; }; -template +template class SqliteReadWriteStatementMock : public SqliteReadWriteStatementMockBase { public: diff --git a/tests/unit/unittest/sqlitesessions-test.cpp b/tests/unit/unittest/sqlitesessions-test.cpp index 296dd0cb743..9288f3a2a3b 100644 --- a/tests/unit/unittest/sqlitesessions-test.cpp +++ b/tests/unit/unittest/sqlitesessions-test.cpp @@ -138,18 +138,19 @@ protected: "INITIALLY DEFERRED, tag NUMERIC)", database}; Sqlite::Sessions sessions{database, "main", "testsessions"}; - Sqlite::WriteStatement insertData{"INSERT INTO data(name, number, value) VALUES (?1, ?2, ?3) " - "ON CONFLICT (name) DO UPDATE SET (number, value) = (?2, ?3)", - database}; - Sqlite::WriteStatement insertOneDatum{"INSERT INTO data(value, name) VALUES (?1, ?2) " - "ON CONFLICT (name) DO UPDATE SET (value) = (?2)", - database}; - Sqlite::WriteStatement updateNumber{"UPDATE data SET number = ?002 WHERE name=?001", database}; - Sqlite::WriteStatement updateValue{"UPDATE data SET value = ?002 WHERE name=?001", database}; - Sqlite::WriteStatement deleteData{"DELETE FROM data WHERE name=?", database}; - Sqlite::WriteStatement deleteTag{ + Sqlite::WriteStatement<3> insertData{ + "INSERT INTO data(name, number, value) VALUES (?1, ?2, ?3) " + "ON CONFLICT (name) DO UPDATE SET (number, value) = (?2, ?3)", + database}; + Sqlite::WriteStatement<2> insertOneDatum{"INSERT INTO data(value, name) VALUES (?1, ?2) " + "ON CONFLICT (name) DO UPDATE SET (value) = (?2)", + database}; + Sqlite::WriteStatement<2> updateNumber{"UPDATE data SET number = ?2 WHERE name=?1", database}; + Sqlite::WriteStatement<2> updateValue{"UPDATE data SET value = ?2 WHERE name=?1", database}; + Sqlite::WriteStatement<1> deleteData{"DELETE FROM data WHERE name=?", database}; + Sqlite::WriteStatement<1> deleteTag{ "DELETE FROM tags WHERE dataId=(SELECT id FROM data WHERE name=?)", database}; - Sqlite::WriteStatement insertTag{ + Sqlite::WriteStatement<2> insertTag{ "INSERT INTO tags(dataId, tag) VALUES ((SELECT id FROM data WHERE name=?1), ?2) ", database}; Sqlite::ReadStatement<3> selectData{"SELECT name, number, value FROM data", database}; Sqlite::ReadStatement<2> selectTags{ @@ -599,7 +600,7 @@ TEST_F(SqliteSessions, ConvertAllValueTypesInChangeSet) TEST_F(SqliteSessions, InsertOneValueChangeSet) { sessions.create(); - insertOneDatum.write("foo"); + insertOneDatum.write("foo", Sqlite::NullValue{}); sessions.commit(); auto changeSets = sessions.changeSets(); auto &&changeSet = changeSets.front(); @@ -669,7 +670,7 @@ TEST_F(SqliteSessions, EmptyChangeSet) TEST_F(SqliteSessions, AccessInsertOneValueChangeSet) { sessions.create(); - insertOneDatum.write("foo"); + insertOneDatum.write("foo", Sqlite::NullValue{}); sessions.commit(); auto changeSets = sessions.changeSets(); auto &&changeSet = changeSets.front(); diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index ea37b502221..ff5348585a4 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -54,7 +54,7 @@ using Sqlite::Value; using Sqlite::WriteStatement; template -bool compareValue(SqliteTestStatement &statement, Type value, int column) +bool compareValue(SqliteTestStatement<2, 1> &statement, Type value, int column) { if constexpr (std::is_convertible_v && !std::is_same_v) return statement.fetchLongLongValue(column) == value; @@ -77,7 +77,7 @@ MATCHER_P3(HasValues, value1, value2, rowid, { Database &database = arg.database(); - SqliteTestStatement statement("SELECT name, number FROM test WHERE rowid=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE rowid=?", database); statement.bind(1, rowid); statement.next(); @@ -89,7 +89,7 @@ MATCHER_P(HasNullValues, rowid, std::string(negation ? "isn't null" : "is null") { Database &database = arg.database(); - SqliteTestStatement statement("SELECT name, number FROM test WHERE rowid=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE rowid=?", database); statement.bind(1, rowid); statement.next(); @@ -172,7 +172,7 @@ TEST_F(SqliteStatement, ThrowsNotReadonlySqlStatementForWritableSqlStatementInRe TEST_F(SqliteStatement, CountRows) { - SqliteTestStatement statement("SELECT * FROM test", database); + SqliteTestStatement<3> statement("SELECT * FROM test", database); int nextCount = 0; while (statement.next()) ++nextCount; @@ -184,7 +184,7 @@ TEST_F(SqliteStatement, CountRows) TEST_F(SqliteStatement, Value) { - SqliteTestStatement statement("SELECT name, number, value FROM test ORDER BY name", database); + SqliteTestStatement<3> statement("SELECT name, number, value FROM test ORDER BY name", database); statement.next(); statement.next(); @@ -235,7 +235,7 @@ TEST_F(SqliteStatement, ToStringValue) TEST_F(SqliteStatement, BindNull) { database.execute("INSERT INTO test VALUES (NULL, 323, 344)"); - SqliteTestStatement statement("SELECT name, number FROM test WHERE name IS ?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE name IS ?", database); statement.bind(1, Sqlite::NullValue{}); statement.next(); @@ -246,8 +246,7 @@ TEST_F(SqliteStatement, BindNull) TEST_F(SqliteStatement, BindString) { - - SqliteTestStatement statement("SELECT name, number FROM test WHERE name=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE name=?", database); statement.bind(1, Utils::SmallStringView("foo")); statement.next(); @@ -258,7 +257,7 @@ TEST_F(SqliteStatement, BindString) TEST_F(SqliteStatement, BindInteger) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=?", database); statement.bind(1, 40); statement.next(); @@ -268,7 +267,7 @@ TEST_F(SqliteStatement, BindInteger) TEST_F(SqliteStatement, BindLongInteger) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=?", database); statement.bind(1, int64_t(40)); statement.next(); @@ -278,7 +277,7 @@ TEST_F(SqliteStatement, BindLongInteger) TEST_F(SqliteStatement, BindDouble) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=?", database); statement.bind(1, 23.3); statement.next(); @@ -288,7 +287,7 @@ TEST_F(SqliteStatement, BindDouble) TEST_F(SqliteStatement, BindPointer) { - SqliteTestStatement statement("SELECT value FROM carray(?, 5, 'int64')", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?, 5, 'int64')", database); std::vector values{1, 1, 2, 3, 5}; statement.bind(1, values.data()); @@ -299,7 +298,7 @@ TEST_F(SqliteStatement, BindPointer) TEST_F(SqliteStatement, BindIntCarray) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3, 10, 20, 33, 55}; statement.bind(1, values); @@ -313,7 +312,7 @@ TEST_F(SqliteStatement, BindIntCarray) TEST_F(SqliteStatement, BindLongLongCarray) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3, 10, 20, 33, 55}; statement.bind(1, values); @@ -327,7 +326,7 @@ TEST_F(SqliteStatement, BindLongLongCarray) TEST_F(SqliteStatement, BindDoubleCarray) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3.3, 10.2, 20.54, 33.21, 55}; statement.bind(1, values); @@ -341,7 +340,7 @@ TEST_F(SqliteStatement, BindDoubleCarray) TEST_F(SqliteStatement, BindTextCarray) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{"yi", "er", "san", "se", "wu"}; statement.bind(1, values); @@ -355,7 +354,7 @@ TEST_F(SqliteStatement, BindTextCarray) TEST_F(SqliteStatement, BindBlob) { - SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); + SqliteTestStatement<1, 1> statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); const unsigned char chars[] = "aaafdfdlll"; auto bytePointer = reinterpret_cast(chars); Sqlite::BlobView bytes{bytePointer, sizeof(chars) - 1}; @@ -368,7 +367,7 @@ TEST_F(SqliteStatement, BindBlob) TEST_F(SqliteStatement, BindEmptyBlob) { - SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); + SqliteTestStatement<1, 1> statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); Sqlite::BlobView bytes; statement.bind(1, bytes); @@ -379,56 +378,56 @@ TEST_F(SqliteStatement, BindEmptyBlob) TEST_F(SqliteStatement, BindIndexIsZeroIsThrowingBindingIndexIsOutOfBoundInt) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(0, 40), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsZeroIsThrowingBindingIndexIsOutOfBoundNull) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(0, Sqlite::NullValue{}), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundLongLong) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(2, 40LL), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundStringView) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(2, "foo"), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundStringFloat) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(2, 2.), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundPointer) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(2, nullptr), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundValue) { - SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database); + SqliteTestStatement<2, 1> statement("SELECT name, number FROM test WHERE number=$1", database); ASSERT_THROW(statement.bind(2, Sqlite::Value{1}), Sqlite::BindingIndexIsOutOfRange); } TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundBlob) { - SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); + SqliteTestStatement<1, 1> statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); Sqlite::BlobView bytes{QByteArray{"XXX"}}; ASSERT_THROW(statement.bind(2, bytes), Sqlite::BindingIndexIsOutOfRange); @@ -436,7 +435,7 @@ TEST_F(SqliteStatement, BindIndexIsToLargeIsThrowingBindingIndexIsOutOfBoundBlob TEST_F(SqliteStatement, BindValues) { - SqliteTestStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + SqliteTestStatement<0, 3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.bindValues("see", 7.23, 1); statement.execute(); @@ -446,7 +445,7 @@ TEST_F(SqliteStatement, BindValues) TEST_F(SqliteStatement, BindNullValues) { - SqliteTestStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + SqliteTestStatement<0, 3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.bindValues(Sqlite::NullValue{}, Sqlite::Value{}, 1); statement.execute(); @@ -456,7 +455,7 @@ TEST_F(SqliteStatement, BindNullValues) TEST_F(SqliteStatement, WriteValues) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write("see", 7.23, 1); @@ -465,58 +464,57 @@ TEST_F(SqliteStatement, WriteValues) TEST_F(SqliteStatement, WritePointerValues) { - SqliteTestStatement statement("SELECT value FROM carray(?, ?, 'int64')", database); + SqliteTestStatement<1, 2> statement("SELECT value FROM carray(?, ?, 'int64')", database); std::vector values{1, 1, 2, 3, 5}; - statement.write(values.data(), int(values.size())); + auto results = statement.values(5, values.data(), int(values.size())); - ASSERT_THAT(statement.template values(5), ElementsAre(1, 1, 2, 3, 5)); + ASSERT_THAT(results, ElementsAre(1, 1, 2, 3, 5)); } TEST_F(SqliteStatement, WriteIntCarrayValues) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3, 10, 20, 33, 55}; - statement.write(Utils::span(values)); + auto results = statement.values(5, Utils::span(values)); - ASSERT_THAT(statement.template values(5), ElementsAre(3, 10, 20, 33, 55)); + ASSERT_THAT(results, ElementsAre(3, 10, 20, 33, 55)); } TEST_F(SqliteStatement, WriteLongLongCarrayValues) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3, 10, 20, 33, 55}; - statement.write(Utils::span(values)); + auto results = statement.values(5, Utils::span(values)); - ASSERT_THAT(statement.template values(5), ElementsAre(3, 10, 20, 33, 55)); + ASSERT_THAT(results, ElementsAre(3, 10, 20, 33, 55)); } TEST_F(SqliteStatement, WriteDoubleCarrayValues) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{3.3, 10.2, 20.54, 33.21, 55}; - statement.write(Utils::span(values)); + auto results = statement.values(5, Utils::span(values)); - ASSERT_THAT(statement.template values(5), ElementsAre(3.3, 10.2, 20.54, 33.21, 55)); + ASSERT_THAT(results, ElementsAre(3.3, 10.2, 20.54, 33.21, 55)); } TEST_F(SqliteStatement, WriteTextCarrayValues) { - SqliteTestStatement statement("SELECT value FROM carray(?)", database); + SqliteTestStatement<1, 1> statement("SELECT value FROM carray(?)", database); std::vector values{"yi", "er", "san", "se", "wu"}; - statement.write(Utils::span(values)); + auto results = statement.values(5, Utils::span(values)); - ASSERT_THAT(statement.template values(5), - ElementsAre("yi", "er", "san", "se", "wu")); + ASSERT_THAT(results, ElementsAre("yi", "er", "san", "se", "wu")); } TEST_F(SqliteStatement, WriteNullValues) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write(1, 1, 1); statement.write(Sqlite::NullValue{}, Sqlite::Value{}, 1); @@ -526,7 +524,7 @@ TEST_F(SqliteStatement, WriteNullValues) TEST_F(SqliteStatement, WriteSqliteIntegerValue) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write(1, 1, 1); statement.write("see", Sqlite::Value{33}, 1); @@ -536,7 +534,7 @@ TEST_F(SqliteStatement, WriteSqliteIntegerValue) TEST_F(SqliteStatement, WriteSqliteDoubeValue) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write("see", Value{7.23}, Value{1}); @@ -545,7 +543,7 @@ TEST_F(SqliteStatement, WriteSqliteDoubeValue) TEST_F(SqliteStatement, WriteSqliteStringValue) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write("see", Value{"foo"}, Value{1}); @@ -554,8 +552,8 @@ TEST_F(SqliteStatement, WriteSqliteStringValue) TEST_F(SqliteStatement, WriteSqliteBlobValue) { - SqliteTestStatement statement("INSERT INTO test VALUES ('blob', 40, ?)", database); - SqliteTestStatement readStatement("SELECT value FROM test WHERE name = 'blob'", database); + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('blob', 40, ?)", database); + SqliteTestStatement<1, 0> readStatement("SELECT value FROM test WHERE name = 'blob'", database); const unsigned char chars[] = "aaafdfdlll"; auto bytePointer = reinterpret_cast(chars); Sqlite::BlobView bytes{bytePointer, sizeof(chars) - 1}; @@ -568,7 +566,7 @@ TEST_F(SqliteStatement, WriteSqliteBlobValue) TEST_F(SqliteStatement, WriteNullValueView) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write(1, 1, 1); statement.write(Sqlite::NullValue{}, Sqlite::ValueView::create(Sqlite::NullValue{}), 1); @@ -578,7 +576,7 @@ TEST_F(SqliteStatement, WriteNullValueView) TEST_F(SqliteStatement, WriteSqliteIntegerValueView) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write(1, 1, 1); statement.write("see", Sqlite::ValueView::create(33), 1); @@ -588,7 +586,7 @@ TEST_F(SqliteStatement, WriteSqliteIntegerValueView) TEST_F(SqliteStatement, WriteSqliteDoubeValueView) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write("see", Sqlite::ValueView::create(7.23), 1); @@ -597,7 +595,7 @@ TEST_F(SqliteStatement, WriteSqliteDoubeValueView) TEST_F(SqliteStatement, WriteSqliteStringValueView) { - WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); + WriteStatement<3> statement("UPDATE test SET name=?, number=? WHERE rowid=?", database); statement.write("see", Sqlite::ValueView::create("foo"), 1); @@ -606,8 +604,8 @@ TEST_F(SqliteStatement, WriteSqliteStringValueView) TEST_F(SqliteStatement, WriteSqliteBlobValueView) { - SqliteTestStatement statement("INSERT INTO test VALUES ('blob', 40, ?)", database); - SqliteTestStatement readStatement("SELECT value FROM test WHERE name = 'blob'", database); + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('blob', 40, ?)", database); + SqliteTestStatement<1, 0> readStatement("SELECT value FROM test WHERE name = 'blob'", database); const unsigned char chars[] = "aaafdfdlll"; auto bytePointer = reinterpret_cast(chars); Sqlite::BlobView bytes{bytePointer, sizeof(chars) - 1}; @@ -620,7 +618,7 @@ TEST_F(SqliteStatement, WriteSqliteBlobValueView) TEST_F(SqliteStatement, WriteEmptyBlobs) { - SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); + SqliteTestStatement<1, 1> statement("WITH T(blob) AS (VALUES (?)) SELECT blob FROM T", database); Sqlite::BlobView bytes; @@ -631,8 +629,8 @@ TEST_F(SqliteStatement, WriteEmptyBlobs) TEST_F(SqliteStatement, EmptyBlobsAreNull) { - SqliteTestStatement statement("WITH T(blob) AS (VALUES (?)) SELECT ifnull(blob, 1) FROM T", - database); + SqliteTestStatement<1, 1> statement( + "WITH T(blob) AS (VALUES (?)) SELECT ifnull(blob, 1) FROM T", database); Sqlite::BlobView bytes; @@ -643,8 +641,8 @@ TEST_F(SqliteStatement, EmptyBlobsAreNull) TEST_F(SqliteStatement, WriteBlobs) { - SqliteTestStatement statement("INSERT INTO test VALUES ('blob', 40, ?)", database); - SqliteTestStatement readStatement("SELECT value FROM test WHERE name = 'blob'", database); + SqliteTestStatement<0, 1> statement("INSERT INTO test VALUES ('blob', 40, ?)", database); + SqliteTestStatement<1, 0> readStatement("SELECT value FROM test WHERE name = 'blob'", database); const unsigned char chars[] = "aaafdfdlll"; auto bytePointer = reinterpret_cast(chars); Sqlite::BlobView bytes{bytePointer, sizeof(chars) - 1}; @@ -918,7 +916,7 @@ TEST_F(SqliteStatement, GetStructRangeWithTransactionWithoutArguments) TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes) { - ReadStatement<1> statement("SELECT name FROM test WHERE number=?", database); + ReadStatement<1, 1> statement("SELECT name FROM test WHERE number=?", database); statement.values(3, 40); std::vector values = statement.values(3, 40); @@ -928,7 +926,7 @@ TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes) TEST_F(SqliteStatement, GetRangeForSingleOutputWithBindingMultipleTimes) { - ReadStatement<1> statement("SELECT name FROM test WHERE number=?", database); + ReadStatement<1, 1> statement("SELECT name FROM test WHERE number=?", database); statement.values(3, 40); auto range = statement.range(40); @@ -939,7 +937,7 @@ TEST_F(SqliteStatement, GetRangeForSingleOutputWithBindingMultipleTimes) TEST_F(SqliteStatement, GetRangeWithTransactionForSingleOutputWithBindingMultipleTimes) { - ReadStatement<1> statement("SELECT name FROM test WHERE number=?", database); + ReadStatement<1, 1> statement("SELECT name FROM test WHERE number=?", database); statement.values(3, 40); database.unlock(); @@ -953,7 +951,7 @@ TEST_F(SqliteStatement, GetRangeWithTransactionForSingleOutputWithBindingMultipl TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndMultipleQueryValue) { using Tuple = std::tuple; - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto values = statement.values(3, "bar", "blah", 1); @@ -964,7 +962,7 @@ TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndMultipleQueryValue) TEST_F(SqliteStatement, GetRangeForMultipleOutputValuesAndMultipleQueryValue) { using Tuple = std::tuple; - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto range = statement.range("bar", "blah", 1); @@ -976,7 +974,7 @@ TEST_F(SqliteStatement, GetRangeForMultipleOutputValuesAndMultipleQueryValue) TEST_F(SqliteStatement, GetRangeWithTransactionForMultipleOutputValuesAndMultipleQueryValue) { using Tuple = std::tuple; - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); database.unlock(); @@ -989,8 +987,8 @@ TEST_F(SqliteStatement, GetRangeWithTransactionForMultipleOutputValuesAndMultipl TEST_F(SqliteStatement, CallGetValuesForMultipleOutputValuesAndMultipleQueryValueMultipleTimes) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); statement.values(3, "bar", "blah"); auto values = statement.values(3, "bar", "blah"); @@ -1001,8 +999,8 @@ TEST_F(SqliteStatement, CallGetValuesForMultipleOutputValuesAndMultipleQueryValu TEST_F(SqliteStatement, CallGetRangeForMultipleOutputValuesAndMultipleQueryValueMultipleTimes) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); { auto range = statement.range("bar", "blah"); std::vector values1{range.begin(), range.end()}; @@ -1018,8 +1016,8 @@ TEST_F(SqliteStatement, CallGetRangeWithTransactionForMultipleOutputValuesAndMultipleQueryValueMultipleTimes) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); database.unlock(); std::vector values1 = toValues(statement.rangeWithTransaction("bar", "blah")); @@ -1031,7 +1029,7 @@ TEST_F(SqliteStatement, TEST_F(SqliteStatement, GetStructOutputValuesAndMultipleQueryValue) { - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto values = statement.values(3, "bar", "blah", 1); @@ -1081,8 +1079,8 @@ TEST_F(SqliteStatement, GetEmptyOptionalBlobValueForText) TEST_F(SqliteStatement, GetOptionalSingleValueAndMultipleQueryValue) { - ReadStatement<1> statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", - database); + ReadStatement<1, 3> statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", + database); auto value = statement.optionalValue("bar", "blah", 1); @@ -1091,7 +1089,7 @@ TEST_F(SqliteStatement, GetOptionalSingleValueAndMultipleQueryValue) TEST_F(SqliteStatement, GetOptionalOutputValueAndMultipleQueryValue) { - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto value = statement.optionalValue("bar", "blah", 1); @@ -1102,7 +1100,7 @@ TEST_F(SqliteStatement, GetOptionalOutputValueAndMultipleQueryValue) TEST_F(SqliteStatement, GetOptionalTupleValueAndMultipleQueryValue) { using Tuple = std::tuple; - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto value = statement.optionalValue("bar", "blah", 1); @@ -1112,7 +1110,7 @@ TEST_F(SqliteStatement, GetOptionalTupleValueAndMultipleQueryValue) TEST_F(SqliteStatement, GetOptionalValueCallsReset) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 1> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, reset()); @@ -1121,7 +1119,7 @@ TEST_F(SqliteStatement, GetOptionalValueCallsReset) TEST_F(SqliteStatement, GetOptionalValueCallsResetIfExceptionIsThrown) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 1> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); EXPECT_CALL(mockStatement, reset()); @@ -1131,8 +1129,8 @@ TEST_F(SqliteStatement, GetOptionalValueCallsResetIfExceptionIsThrown) TEST_F(SqliteStatement, GetSingleValueAndMultipleQueryValue) { - ReadStatement<1> statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", - database); + ReadStatement<1, 3> statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", + database); auto value = statement.value("bar", "blah", 1); @@ -1141,7 +1139,7 @@ TEST_F(SqliteStatement, GetSingleValueAndMultipleQueryValue) TEST_F(SqliteStatement, GetOutputValueAndMultipleQueryValue) { - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto value = statement.value("bar", "blah", 1); @@ -1152,7 +1150,7 @@ TEST_F(SqliteStatement, GetOutputValueAndMultipleQueryValue) TEST_F(SqliteStatement, GetTupleValueAndMultipleQueryValue) { using Tuple = std::tuple; - ReadStatement<3> statement( + ReadStatement<3, 3> statement( "SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database); auto value = statement.value("bar", "blah", 1); @@ -1166,7 +1164,7 @@ TEST_F(SqliteStatement, GetValueCallsReset) { int x = 0; }; - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 1> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, reset()); @@ -1179,7 +1177,7 @@ TEST_F(SqliteStatement, GetValueCallsResetIfExceptionIsThrown) { int x = 0; }; - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 1> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); EXPECT_CALL(mockStatement, reset()); @@ -1189,7 +1187,7 @@ TEST_F(SqliteStatement, GetValueCallsResetIfExceptionIsThrown) TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsReset) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, reset()); @@ -1198,7 +1196,7 @@ TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsReset) TEST_F(SqliteStatement, GetRangeWithoutArgumentsCallsReset) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, reset()); @@ -1208,7 +1206,7 @@ TEST_F(SqliteStatement, GetRangeWithoutArgumentsCallsReset) TEST_F(SqliteStatement, GetRangeWithTransactionWithoutArgumentsCalls) { InSequence s; - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; EXPECT_CALL(databaseMock, lock()); EXPECT_CALL(databaseMock, deferredBegin()); @@ -1221,7 +1219,7 @@ TEST_F(SqliteStatement, GetRangeWithTransactionWithoutArgumentsCalls) TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsResetIfExceptionIsThrown) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); EXPECT_CALL(mockStatement, reset()); @@ -1231,7 +1229,7 @@ TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsResetIfExceptionIsThrown) TEST_F(SqliteStatement, GetRangeWithoutArgumentsCallsResetIfExceptionIsThrown) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); auto range = mockStatement.range(); @@ -1243,7 +1241,7 @@ TEST_F(SqliteStatement, GetRangeWithoutArgumentsCallsResetIfExceptionIsThrown) TEST_F(SqliteStatement, GetRangeWithTransactionWithoutArgumentsCallsResetIfExceptionIsThrown) { InSequence s; - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); EXPECT_CALL(databaseMock, lock()); @@ -1262,7 +1260,7 @@ TEST_F(SqliteStatement, GetRangeWithTransactionWithoutArgumentsCallsResetIfExcep TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsReset) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 2> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, reset()); @@ -1271,7 +1269,7 @@ TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsReset) TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsResetIfExceptionIsThrown) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 2> mockStatement{databaseMock}; ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError(""))); EXPECT_CALL(mockStatement, reset()); @@ -1281,7 +1279,7 @@ TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsResetIfExceptionIsThrow TEST_F(SqliteStatement, ResetIfWriteIsThrowingException) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 1> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, bind(1, TypedEq("bar"))) .WillOnce(Throw(Sqlite::StatementIsBusy(""))); @@ -1292,7 +1290,7 @@ TEST_F(SqliteStatement, ResetIfWriteIsThrowingException) TEST_F(SqliteStatement, ResetIfExecuteThrowsException) { - MockSqliteStatement mockStatement{databaseMock}; + MockSqliteStatement<1, 0> mockStatement{databaseMock}; EXPECT_CALL(mockStatement, next()).WillOnce(Throw(Sqlite::StatementIsBusy(""))); EXPECT_CALL(mockStatement, reset()); @@ -1300,20 +1298,34 @@ TEST_F(SqliteStatement, ResetIfExecuteThrowsException) ASSERT_ANY_THROW(mockStatement.execute()); } -TEST_F(SqliteStatement, ReadStatementThrowsColumnCountDoesNotMatch) +TEST_F(SqliteStatement, ReadStatementThrowsWrongColumnCount) { - MockFunction callbackMock; - ASSERT_THROW(ReadStatement<1> statement("SELECT name, number FROM test", database), - Sqlite::ColumnCountDoesNotMatch); + Sqlite::WrongColumnCount); } -TEST_F(SqliteStatement, ReadWriteStatementThrowsColumnCountDoesNotMatch) +TEST_F(SqliteStatement, ReadWriteStatementThrowsWrongColumnCount) { - MockFunction callbackMock; - ASSERT_THROW(ReadWriteStatement<1> statement("SELECT name, number FROM test", database), - Sqlite::ColumnCountDoesNotMatch); + Sqlite::WrongColumnCount); +} + +TEST_F(SqliteStatement, WriteStatementThrowsWrongBindingParameterCount) +{ + ASSERT_THROW(WriteStatement<1>("INSERT INTO test(name, number) VALUES(?1, ?2)", database), + Sqlite::WrongBindingParameterCount); +} + +TEST_F(SqliteStatement, ReadWriteStatementThrowsWrongBindingParameterCount) +{ + ASSERT_THROW((ReadWriteStatement<0, 1>("INSERT INTO test(name, number) VALUES(?1, ?2)", database)), + Sqlite::WrongBindingParameterCount); +} + +TEST_F(SqliteStatement, ReadStatementThrowsWrongBindingParameterCount) +{ + ASSERT_THROW((ReadStatement<2, 0>("SELECT name, number FROM test WHERE name=?", database)), + Sqlite::WrongBindingParameterCount); } TEST_F(SqliteStatement, ReadCallback) @@ -1331,7 +1343,7 @@ TEST_F(SqliteStatement, ReadCallback) TEST_F(SqliteStatement, ReadCallbackCalledWithArguments) { MockFunction callbackMock; - ReadStatement<2> statement("SELECT name, value FROM test WHERE value=?", database); + ReadStatement<2, 1> statement("SELECT name, value FROM test WHERE value=?", database); EXPECT_CALL(callbackMock, Call(Eq("foo"), Eq(2))); @@ -1404,7 +1416,7 @@ TEST_F(SqliteStatement, ReadToContainer) TEST_F(SqliteStatement, ReadToContainerCallCallbackWithArguments) { std::deque values; - ReadStatement<1> statement("SELECT number FROM test WHERE value=?", database); + ReadStatement<1, 1> statement("SELECT number FROM test WHERE value=?", database); statement.readTo(values, 2); @@ -1444,8 +1456,8 @@ TEST_F(SqliteStatement, ReadToCallsResetIfExceptionIsThrown) TEST_F(SqliteStatement, ReadStatementValuesWithTransactions) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); database.unlock(); std::vector values = statement.valuesWithTransaction(1024, "bar", "blah"); @@ -1457,8 +1469,8 @@ TEST_F(SqliteStatement, ReadStatementValuesWithTransactions) TEST_F(SqliteStatement, ReadStatementValueWithTransactions) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); database.unlock(); auto value = statement.valueWithTransaction("bar", "blah"); @@ -1470,8 +1482,8 @@ TEST_F(SqliteStatement, ReadStatementValueWithTransactions) TEST_F(SqliteStatement, ReadStatementOptionalValueWithTransactions) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); database.unlock(); auto value = statement.optionalValueWithTransaction("bar", "blah"); @@ -1483,8 +1495,8 @@ TEST_F(SqliteStatement, ReadStatementOptionalValueWithTransactions) TEST_F(SqliteStatement, ReadStatementReadCallbackWithTransactions) { MockFunction callbackMock; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); database.unlock(); EXPECT_CALL(callbackMock, Call(Eq("bar"), Eq("blah"), Eq(1))); @@ -1496,8 +1508,8 @@ TEST_F(SqliteStatement, ReadStatementReadCallbackWithTransactions) TEST_F(SqliteStatement, ReadStatementReadToWithTransactions) { using Tuple = std::tuple; - ReadStatement<3> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", - database); + ReadStatement<3, 2> statement("SELECT name, number, value FROM test WHERE name=? AND number=?", + database); std::vector values; database.unlock(); @@ -1510,7 +1522,7 @@ TEST_F(SqliteStatement, ReadStatementReadToWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementValuesWithTransactions) { using Tuple = std::tuple; - ReadWriteStatement<3> statement( + ReadWriteStatement<3, 2> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); database.unlock(); @@ -1523,7 +1535,7 @@ TEST_F(SqliteStatement, ReadWriteStatementValuesWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementValueWithTransactions) { using Tuple = std::tuple; - ReadWriteStatement<3> statement( + ReadWriteStatement<3, 2> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); database.unlock(); @@ -1536,7 +1548,7 @@ TEST_F(SqliteStatement, ReadWriteStatementValueWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementOptionalValueWithTransactions) { using Tuple = std::tuple; - ReadWriteStatement<3> statement( + ReadWriteStatement<3, 2> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); database.unlock(); @@ -1549,7 +1561,7 @@ TEST_F(SqliteStatement, ReadWriteStatementOptionalValueWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementReadCallbackWithTransactions) { MockFunction callbackMock; - ReadWriteStatement<3> statement( + ReadWriteStatement<3, 2> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); database.unlock(); @@ -1562,7 +1574,7 @@ TEST_F(SqliteStatement, ReadWriteStatementReadCallbackWithTransactions) TEST_F(SqliteStatement, ReadWriteStatementReadToWithTransactions) { using Tuple = std::tuple; - ReadWriteStatement<3> statement( + ReadWriteStatement<3, 2> statement( "SELECT name, number, value FROM test WHERE name=? AND number=?", database); std::vector values; database.unlock(); diff --git a/tests/unit/unittest/sqliteteststatement.h b/tests/unit/unittest/sqliteteststatement.h index f2fe6ba2959..f90f319824c 100644 --- a/tests/unit/unittest/sqliteteststatement.h +++ b/tests/unit/unittest/sqliteteststatement.h @@ -26,10 +26,11 @@ #pragma once #include - -class SqliteTestStatement : public Sqlite::StatementImplementation +template +class SqliteTestStatement + : public Sqlite::StatementImplementation { - using Base = Sqlite::StatementImplementation; + using Base = Sqlite::StatementImplementation; public: explicit SqliteTestStatement(Utils::SmallStringView sqlStatement, Sqlite::Database &database) diff --git a/tests/unit/unittest/sqlitewritestatementmock.cpp b/tests/unit/unittest/sqlitewritestatementmock.cpp index a3612833b2e..0cfb6a677f2 100644 --- a/tests/unit/unittest/sqlitewritestatementmock.cpp +++ b/tests/unit/unittest/sqlitewritestatementmock.cpp @@ -27,8 +27,8 @@ #include "sqlitedatabasemock.h" -SqliteWriteStatementMock::SqliteWriteStatementMock(Utils::SmallStringView sqlStatement, - SqliteDatabaseMock &database) +SqliteWriteStatementMockBase::SqliteWriteStatementMockBase(Utils::SmallStringView sqlStatement, + SqliteDatabaseMock &database) : sqlStatement(sqlStatement) { database.prepare(sqlStatement); diff --git a/tests/unit/unittest/sqlitewritestatementmock.h b/tests/unit/unittest/sqlitewritestatementmock.h index 9031da67bbe..5dd939e7448 100644 --- a/tests/unit/unittest/sqlitewritestatementmock.h +++ b/tests/unit/unittest/sqlitewritestatementmock.h @@ -32,11 +32,11 @@ class SqliteDatabaseMock; -class SqliteWriteStatementMock +class SqliteWriteStatementMockBase { public: - SqliteWriteStatementMock() = default; - SqliteWriteStatementMock(Utils::SmallStringView sqlStatement, SqliteDatabaseMock &database); + SqliteWriteStatementMockBase() = default; + SqliteWriteStatementMockBase(Utils::SmallStringView sqlStatement, SqliteDatabaseMock &database); MOCK_METHOD(void, execute, (), ()); @@ -119,3 +119,10 @@ public: Utils::SmallString sqlStatement; }; + +template +class SqliteWriteStatementMock : public SqliteWriteStatementMockBase +{ +public: + using SqliteWriteStatementMockBase::SqliteWriteStatementMockBase; +};