forked from qt-creator/qt-creator
Sqlite: Improve SqliteStatement
There are now only value and values methods. value returns an optional and values are returning a vector. The result value count has now be specified instead of the result value list. Change-Id: I17a0741d5e838b4bf4b9486825c870ada1722584 Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
@@ -420,7 +420,7 @@ Type DatabaseBackend::toValue(Utils::SmallStringView sqlStatement)
|
||||
|
||||
statement.next();
|
||||
|
||||
return statement.value<Type>(0);
|
||||
return statement.fetchValue<Type>(0);
|
||||
}
|
||||
|
||||
} // namespace Sqlite
|
||||
|
||||
@@ -34,8 +34,7 @@ class SQLITE_EXPORT ReadStatement final : private Statement
|
||||
public:
|
||||
explicit ReadStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
using Statement::structValues;
|
||||
using Statement::tupleValues;
|
||||
using Statement::value;
|
||||
using Statement::values;
|
||||
using Statement::toValue;
|
||||
using Statement::database;
|
||||
|
||||
@@ -37,9 +37,8 @@ public:
|
||||
ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
using Statement::execute;
|
||||
using Statement::value;
|
||||
using Statement::values;
|
||||
using Statement::structValues;
|
||||
using Statement::tupleValues;
|
||||
using Statement::toValue;
|
||||
using Statement::database;
|
||||
using Statement::write;
|
||||
|
||||
@@ -445,8 +445,7 @@ static StringType convertToTextForColumn(sqlite3_stmt *sqlStatment, int column)
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
template<>
|
||||
int Statement::value<int>(int column) const
|
||||
int Statement::fetchIntValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
@@ -454,13 +453,23 @@ int Statement::value<int>(int column) const
|
||||
}
|
||||
|
||||
template<>
|
||||
long Statement::value<long>(int column) const
|
||||
int Statement::fetchValue<int>(int column) const
|
||||
{
|
||||
return long(value<long long>(column));
|
||||
return fetchIntValue(column);
|
||||
}
|
||||
|
||||
long Statement::fetchLongValue(int column) const
|
||||
{
|
||||
return long(fetchValue<long long>(column));
|
||||
}
|
||||
|
||||
template<>
|
||||
long long Statement::value<long long>(int column) const
|
||||
long Statement::fetchValue<long>(int column) const
|
||||
{
|
||||
return fetchLongValue(column);
|
||||
}
|
||||
|
||||
long long Statement::fetchLongLongValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
@@ -468,27 +477,48 @@ long long Statement::value<long long>(int column) const
|
||||
}
|
||||
|
||||
template<>
|
||||
double Statement::value<double>(int column) const
|
||||
long long Statement::fetchValue<long long>(int column) const
|
||||
{
|
||||
return fetchLongLongValue(column);
|
||||
}
|
||||
|
||||
double Statement::fetchDoubleValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return sqlite3_column_double(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template<>
|
||||
double Statement::fetchValue<double>(int column) const
|
||||
{
|
||||
return fetchDoubleValue(column);
|
||||
}
|
||||
|
||||
template<typename StringType>
|
||||
StringType Statement::value(int column) const
|
||||
StringType Statement::fetchValue(int column) const
|
||||
{
|
||||
checkIfIsReadyToFetchValues();
|
||||
checkColumnIsValid(column);
|
||||
return convertToTextForColumn<StringType>(m_compiledStatement.get(), column);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT Utils::SmallString Statement::value<Utils::SmallString>(int column) const;
|
||||
template SQLITE_EXPORT Utils::PathString Statement::value<Utils::PathString>(int column) const;
|
||||
Utils::SmallString Statement::fetchSmallStringValue(int column) const
|
||||
{
|
||||
return fetchValue<Utils::SmallString>(column);
|
||||
}
|
||||
|
||||
Utils::PathString Statement::fetchPathStringValue(int column) const
|
||||
{
|
||||
return fetchValue<Utils::PathString>(column);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
|
||||
template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
|
||||
|
||||
Utils::SmallString Statement::text(int column) const
|
||||
{
|
||||
return value<Utils::SmallString>(column);
|
||||
return fetchValue<Utils::SmallString>(column);
|
||||
}
|
||||
|
||||
template <typename ContainerType>
|
||||
@@ -498,7 +528,7 @@ ContainerType Statement::columnValues(const std::vector<int> &columnIndices) con
|
||||
ContainerType valueContainer;
|
||||
valueContainer.reserve(columnIndices.size());
|
||||
for (int columnIndex : columnIndices)
|
||||
valueContainer.push_back(value<ElementType>(columnIndex));
|
||||
valueContainer.push_back(fetchValue<ElementType>(columnIndex));
|
||||
|
||||
return valueContainer;
|
||||
}
|
||||
@@ -510,7 +540,7 @@ Type Statement::toValue(Utils::SmallStringView sqlStatement, Database &database)
|
||||
|
||||
statement.next();
|
||||
|
||||
return statement.value<Type>(0);
|
||||
return statement.fetchValue<Type>(0);
|
||||
}
|
||||
|
||||
template SQLITE_EXPORT int Statement::toValue<int>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
@@ -31,6 +31,8 @@
|
||||
|
||||
#include <utils/smallstringvector.h>
|
||||
|
||||
#include <utils/optional.h>
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
@@ -58,16 +60,22 @@ protected:
|
||||
void execute() const;
|
||||
void reset() const;
|
||||
|
||||
int fetchIntValue(int column) const;
|
||||
long fetchLongValue(int column) const;
|
||||
long long fetchLongLongValue(int column) const;
|
||||
double fetchDoubleValue(int column) const;
|
||||
Utils::SmallString fetchSmallStringValue(int column) const;
|
||||
Utils::PathString fetchPathStringValue(int column) const;
|
||||
template<typename Type>
|
||||
Type value(int column) const;
|
||||
Type fetchValue(int column) const;
|
||||
Utils::SmallString text(int column) const;
|
||||
int columnCount() const;
|
||||
Utils::SmallStringVector columnNames() const;
|
||||
|
||||
void bind(int index, int value);
|
||||
void bind(int index, long long value);
|
||||
void bind(int index, double value);
|
||||
void bind(int index, Utils::SmallStringView value);
|
||||
void bind(int index, int fetchValue);
|
||||
void bind(int index, long long fetchValue);
|
||||
void bind(int index, double fetchValue);
|
||||
void bind(int index, Utils::SmallStringView fetchValue);
|
||||
|
||||
void bind(int index, uint value)
|
||||
{
|
||||
@@ -110,138 +118,60 @@ protected:
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
void bind(Utils::SmallStringView name, Type value);
|
||||
void bind(Utils::SmallStringView name, Type fetchValue);
|
||||
|
||||
int bindingIndexForName(Utils::SmallStringView name) const;
|
||||
|
||||
void setBindingColumnNames(const Utils::SmallStringVector &bindingColumnNames);
|
||||
const Utils::SmallStringVector &bindingColumnNames() const;
|
||||
|
||||
template <typename... ResultTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize)
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1>
|
||||
std::vector<ResultType> values(std::size_t reserveSize)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
typename... QueryElementTypes>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename... ResultTypes,
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename QueryElementType>
|
||||
std::vector<std::tuple<ResultTypes...>> tupleValues(std::size_t reserveSize,
|
||||
const std::vector<QueryElementType> &queryValues)
|
||||
{
|
||||
using Container = std::vector<std::tuple<ResultTypes...>>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const QueryElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
emplaceTupleValues<Container, ResultTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
typename... QueryTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
typename QueryElementType>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<QueryElementType> &queryValues)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
Container resultValues;
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const QueryElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
@@ -250,9 +180,9 @@ protected:
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryTypes,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryElementTypes>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<QueryElementTypes...>> &queryTuples)
|
||||
{
|
||||
using Container = std::vector<ResultType>;
|
||||
@@ -263,62 +193,7 @@ protected:
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
pushBackStructValues<Container, ResultEntryTypes...>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ElementTypes>
|
||||
std::vector<ResultType> values(std::size_t reserveSize)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ElementType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<std::tuple<ElementType...>> &queryTuples)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const auto &queryTuple : queryTuples) {
|
||||
bindTupleValues(queryTuple);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
return resultValues;
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
typename ElementType>
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const std::vector<ElementType> &queryValues)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
|
||||
for (const ElementType &queryValue : queryValues) {
|
||||
bindValues(queryValue);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
emplaceBackValues<ResultTypeCount>(resultValues);
|
||||
|
||||
reset();
|
||||
}
|
||||
@@ -327,20 +202,20 @@ protected:
|
||||
}
|
||||
|
||||
template <typename ResultType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryTypes>
|
||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryTypes&... queryValues)
|
||||
Utils::optional<ResultType> value( const QueryTypes&... queryValues)
|
||||
{
|
||||
std::vector<ResultType> resultValues;
|
||||
resultValues.reserve(reserveSize);
|
||||
Utils::optional<ResultType> resultValue;
|
||||
|
||||
bindValues(queryValues...);
|
||||
|
||||
while (next())
|
||||
resultValues.push_back(value<ResultType>(0));
|
||||
if (next())
|
||||
resultValue = assignValue<Utils::optional<ResultType>, ResultTypeCount>();
|
||||
|
||||
reset();
|
||||
|
||||
return resultValues;
|
||||
return resultValue;
|
||||
}
|
||||
|
||||
template <typename Type>
|
||||
@@ -352,7 +227,6 @@ protected:
|
||||
sqlite3 *sqliteDatabaseHandle() const;
|
||||
TextEncoding databaseTextEncoding();
|
||||
|
||||
|
||||
bool checkForStepError(int resultCode) const;
|
||||
void checkForPrepareError(int resultCode) const;
|
||||
void checkForBindingError(int resultCode) const;
|
||||
@@ -388,35 +262,74 @@ protected:
|
||||
DatabaseBackend &databaseBackend);
|
||||
|
||||
private:
|
||||
class ValueGetter
|
||||
{
|
||||
public:
|
||||
ValueGetter(Statement &statement, int column)
|
||||
: statement(statement),
|
||||
column(column)
|
||||
{}
|
||||
|
||||
operator int()
|
||||
{
|
||||
return statement.fetchIntValue(column);
|
||||
}
|
||||
|
||||
operator long()
|
||||
{
|
||||
return statement.fetchLongValue(column);
|
||||
}
|
||||
|
||||
operator long long()
|
||||
{
|
||||
return statement.fetchLongLongValue(column);
|
||||
}
|
||||
|
||||
operator double()
|
||||
{
|
||||
return statement.fetchDoubleValue(column);
|
||||
}
|
||||
|
||||
operator Utils::SmallString()
|
||||
{
|
||||
return statement.fetchSmallStringValue(column);
|
||||
}
|
||||
|
||||
operator Utils::PathString()
|
||||
{
|
||||
return statement.fetchPathStringValue(column);
|
||||
}
|
||||
|
||||
Statement &statement;
|
||||
int column;
|
||||
};
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultTypes,
|
||||
int... ColumnIndices>
|
||||
void emplaceTupleValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
void emplaceBackValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
{
|
||||
container.emplace_back(value<ResultTypes>(ColumnIndices)...);
|
||||
container.emplace_back(ValueGetter(*this, ColumnIndices)...);
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultTypes>
|
||||
void emplaceTupleValues(ContainerType &container)
|
||||
template <int ResultTypeCount,
|
||||
typename ContainerType>
|
||||
void emplaceBackValues(ContainerType &container)
|
||||
{
|
||||
emplaceTupleValues<ContainerType, ResultTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultTypes)>{});
|
||||
emplaceBackValues(container, std::make_integer_sequence<int, ResultTypeCount>{});
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultEntryTypes,
|
||||
template <typename ResultOptionalType,
|
||||
int... ColumnIndices>
|
||||
void pushBackStructValues(ContainerType &container, std::integer_sequence<int, ColumnIndices...>)
|
||||
ResultOptionalType assignValue(std::integer_sequence<int, ColumnIndices...>)
|
||||
{
|
||||
using ResultType = typename ContainerType::value_type;
|
||||
container.push_back(ResultType{value<ResultEntryTypes>(ColumnIndices)...});
|
||||
return ResultOptionalType(Utils::in_place, ValueGetter(*this, ColumnIndices)...);
|
||||
}
|
||||
|
||||
template <typename ContainerType,
|
||||
typename... ResultEntryTypes>
|
||||
void pushBackStructValues(ContainerType &container)
|
||||
template <typename ResultOptionalType,
|
||||
int ResultTypeCount>
|
||||
ResultOptionalType assignValue()
|
||||
{
|
||||
pushBackStructValues<ContainerType, ResultEntryTypes...>(container, std::make_integer_sequence<int, sizeof...(ResultEntryTypes)>{});
|
||||
return assignValue<ResultOptionalType>(std::make_integer_sequence<int, ResultTypeCount>{});
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
@@ -478,10 +391,10 @@ extern template SQLITE_EXPORT long long Statement::toValue<long long>(Utils::Sma
|
||||
extern template SQLITE_EXPORT double Statement::toValue<double>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::toValue<Utils::SmallString>(Utils::SmallStringView sqlStatement, Database &database);
|
||||
|
||||
template <> SQLITE_EXPORT int Statement::value<int>(int column) const;
|
||||
template <> SQLITE_EXPORT long Statement::value<long>(int column) const;
|
||||
template <> SQLITE_EXPORT long long Statement::value<long long>(int column) const;
|
||||
template <> SQLITE_EXPORT double Statement::value<double>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::value<Utils::SmallString>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::PathString Statement::value<Utils::PathString>(int column) const;
|
||||
template <> SQLITE_EXPORT int Statement::fetchValue<int>(int column) const;
|
||||
template <> SQLITE_EXPORT long Statement::fetchValue<long>(int column) const;
|
||||
template <> SQLITE_EXPORT long long Statement::fetchValue<long long>(int column) const;
|
||||
template <> SQLITE_EXPORT double Statement::fetchValue<double>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::SmallString Statement::fetchValue<Utils::SmallString>(int column) const;
|
||||
extern template SQLITE_EXPORT Utils::PathString Statement::fetchValue<Utils::PathString>(int column) const;
|
||||
} // namespace Sqlite
|
||||
|
||||
@@ -39,24 +39,25 @@ class SourceLocations
|
||||
public:
|
||||
struct Location
|
||||
{
|
||||
qint64 sourceId;
|
||||
qint64 line;
|
||||
qint64 column;
|
||||
Location(qint64 sourceId, qint64 line, qint64 column)
|
||||
: sourceId(sourceId), line(line), column(column)
|
||||
{}
|
||||
|
||||
qint64 sourceId;
|
||||
qint64 line;
|
||||
qint64 column;
|
||||
};
|
||||
|
||||
struct Source
|
||||
{
|
||||
Source(qint64 sourceId, Utils::PathString &&sourcePath)
|
||||
: sourceId(sourceId), sourcePath(std::move(sourcePath))
|
||||
{}
|
||||
|
||||
qint64 sourceId;
|
||||
Utils::PathString sourcePath;
|
||||
};
|
||||
|
||||
enum LocationGetter
|
||||
{
|
||||
SourceId = 0,
|
||||
Line,
|
||||
Column
|
||||
};
|
||||
|
||||
std::vector<Location> locations;
|
||||
std::unordered_map<qint64, Utils::PathString> sources;
|
||||
};
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
|
||||
const std::size_t reserveSize = 128;
|
||||
|
||||
auto locations = locationsStatement.template structValues<Location, qint64, qint64, qint64>(
|
||||
auto locations = locationsStatement.template values<Location, 3>(
|
||||
reserveSize,
|
||||
filePath,
|
||||
line,
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
ReadStatement &sourcesStatement = m_statementFactory.selectSourcePathForId;
|
||||
|
||||
auto sources = sourcesStatement.template structValues<Source, qint64, Utils::PathString>(
|
||||
auto sources = sourcesStatement.template values<Source, 2>(
|
||||
reserveSize,
|
||||
sourceIds);
|
||||
|
||||
|
||||
@@ -25,31 +25,6 @@
|
||||
|
||||
#include "mocksqlitereadstatement.h"
|
||||
|
||||
template <typename ResultType,
|
||||
typename... QueryType>
|
||||
std::vector<ResultType> values(std::size_t, QueryType...)
|
||||
{
|
||||
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||
}
|
||||
|
||||
template <typename... ResultType>
|
||||
std::vector<std::tuple<ResultType...>> values(std::size_t,
|
||||
Utils::SmallStringView,
|
||||
uint,
|
||||
uint)
|
||||
{
|
||||
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||
}
|
||||
|
||||
template <typename... ResultType,
|
||||
template <typename...> class ContainerType,
|
||||
typename ElementType>
|
||||
std::vector<std::tuple<ResultType...>> tupleValues(std::size_t,
|
||||
const ContainerType<ElementType> &)
|
||||
{
|
||||
FAIL() << "MockSqliteReadStatement::value was instanciated implicitly. Please add an explicit overload.";
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<FilePathIndex> MockSqliteReadStatement::values<FilePathIndex>(std::size_t reserveSize)
|
||||
{
|
||||
@@ -58,20 +33,24 @@ std::vector<FilePathIndex> MockSqliteReadStatement::values<FilePathIndex>(std::s
|
||||
|
||||
template <>
|
||||
std::vector<Location>
|
||||
MockSqliteReadStatement::structValues<Location, qint64, qint64, qint64>(
|
||||
std::size_t reserveSize,
|
||||
const Utils::PathString &sourcePath,
|
||||
const uint &line,
|
||||
const uint &column)
|
||||
MockSqliteReadStatement::values<Location, 3>(std::size_t reserveSize,
|
||||
const Utils::PathString &sourcePath,
|
||||
const uint &line,
|
||||
const uint &column)
|
||||
{
|
||||
return structValuesReturnStdVectorLocation(reserveSize, sourcePath, line, column);
|
||||
return valuesReturnStdVectorLocation(reserveSize, sourcePath, line, column);
|
||||
}
|
||||
|
||||
template <>
|
||||
std::vector<Source>
|
||||
MockSqliteReadStatement::structValues<Source, qint64, Utils::PathString>(
|
||||
std::size_t reserveSize,
|
||||
const std::vector<qint64> &sourceIds)
|
||||
MockSqliteReadStatement::values<Source, 2>(std::size_t reserveSize, const std::vector<qint64> &sourceIds)
|
||||
{
|
||||
return structValuesReturnStdVectorSource(reserveSize, sourceIds);
|
||||
return valuesReturnStdVectorSource(reserveSize, sourceIds);
|
||||
}
|
||||
|
||||
template <>
|
||||
Utils::optional<uint32_t>
|
||||
MockSqliteReadStatement::value<uint32_t>(const Utils::SmallStringView &text)
|
||||
{
|
||||
return valueReturnUInt32(text);
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
|
||||
#include "mocksqlitedatabase.h"
|
||||
|
||||
#include <utils/optional.h>
|
||||
#include <utils/smallstring.h>
|
||||
|
||||
#include <cstdint>
|
||||
@@ -53,28 +54,31 @@ public:
|
||||
MOCK_CONST_METHOD1(valuesReturnStdVectorInt,
|
||||
std::vector<FilePathIndex>(std::size_t));
|
||||
|
||||
MOCK_CONST_METHOD4(structValuesReturnStdVectorLocation,
|
||||
MOCK_CONST_METHOD4(valuesReturnStdVectorLocation,
|
||||
std::vector<Location>(std::size_t, Utils::SmallStringView, qint64, qint64));
|
||||
|
||||
MOCK_CONST_METHOD2(structValuesReturnStdVectorSource,
|
||||
MOCK_CONST_METHOD2(valuesReturnStdVectorSource,
|
||||
std::vector<Source>(std::size_t, const std::vector<qint64> &));
|
||||
|
||||
template <typename ResultType,
|
||||
typename... QueryType>
|
||||
std::vector<ResultType> values(std::size_t, QueryType...);
|
||||
MOCK_CONST_METHOD1(valueReturnUInt32,
|
||||
Utils::optional<uint32_t>(Utils::SmallStringView));
|
||||
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryType,
|
||||
int ResultTypeCount = 1,
|
||||
typename... QueryType>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize, const QueryType&... queryValues);
|
||||
std::vector<ResultType> values(std::size_t reserveSize, const QueryType&... queryValues);
|
||||
|
||||
template <typename ResultType,
|
||||
typename... ResultEntryType,
|
||||
int ResultTypeCount = 1,
|
||||
template <typename...> class QueryContainerType,
|
||||
typename QueryElementType>
|
||||
std::vector<ResultType> structValues(std::size_t reserveSize,
|
||||
const QueryContainerType<QueryElementType> &queryValues);
|
||||
std::vector<ResultType> values(std::size_t reserveSize,
|
||||
const QueryContainerType<QueryElementType> &queryValues);
|
||||
|
||||
template <typename ResultType,
|
||||
typename... QueryTypes>
|
||||
Utils::optional<ResultType> value(const QueryTypes&... queryValues);
|
||||
|
||||
public:
|
||||
Utils::SmallString sqlStatement;
|
||||
@@ -85,7 +89,7 @@ std::vector<int> MockSqliteReadStatement::values<int>(std::size_t reserveSize);
|
||||
|
||||
template <>
|
||||
std::vector<Location>
|
||||
MockSqliteReadStatement::structValues<Location, qint64, qint64, qint64>(
|
||||
MockSqliteReadStatement::values<Location, 3>(
|
||||
std::size_t reserveSize,
|
||||
const Utils::PathString &sourcePath,
|
||||
const uint &line,
|
||||
@@ -93,8 +97,11 @@ MockSqliteReadStatement::structValues<Location, qint64, qint64, qint64>(
|
||||
|
||||
template <>
|
||||
std::vector<Source>
|
||||
MockSqliteReadStatement::structValues<Source, qint64, Utils::PathString>(
|
||||
MockSqliteReadStatement::values<Source, 2>(
|
||||
std::size_t reserveSize,
|
||||
const std::vector<qint64> &);
|
||||
|
||||
|
||||
template <>
|
||||
Utils::optional<uint32_t>
|
||||
MockSqliteReadStatement::value<uint32_t>(const Utils::SmallStringView&);
|
||||
|
||||
@@ -75,6 +75,10 @@ protected:
|
||||
|
||||
struct Output
|
||||
{
|
||||
Output(Utils::SmallString name, Utils::SmallString number, long long value)
|
||||
: name(name), number(number), value(value)
|
||||
{}
|
||||
|
||||
Utils::SmallString name;
|
||||
Utils::SmallString number;
|
||||
long long value;
|
||||
@@ -124,13 +128,13 @@ TEST_F(SqliteStatement, Value)
|
||||
|
||||
statement.next();
|
||||
|
||||
ASSERT_THAT(statement.value<int>(0), 0);
|
||||
ASSERT_THAT(statement.value<int64_t>(0), 0);
|
||||
ASSERT_THAT(statement.value<double>(0), 0.0);
|
||||
ASSERT_THAT(statement.fetchValue<int>(0), 0);
|
||||
ASSERT_THAT(statement.fetchValue<int64_t>(0), 0);
|
||||
ASSERT_THAT(statement.fetchValue<double>(0), 0.0);
|
||||
ASSERT_THAT(statement.text(0), "foo");
|
||||
ASSERT_THAT(statement.value<int>(1), 23);
|
||||
ASSERT_THAT(statement.value<int64_t>(1), 23);
|
||||
ASSERT_THAT(statement.value<double>(1), 23.3);
|
||||
ASSERT_THAT(statement.fetchValue<int>(1), 23);
|
||||
ASSERT_THAT(statement.fetchValue<int64_t>(1), 23);
|
||||
ASSERT_THAT(statement.fetchValue<double>(1), 23.3);
|
||||
ASSERT_THAT(statement.text(1), "23.3");
|
||||
}
|
||||
|
||||
@@ -138,7 +142,7 @@ TEST_F(SqliteStatement, ThrowNoValuesToFetchForNotSteppedStatement)
|
||||
{
|
||||
SqliteTestStatement statement("SELECT name, number FROM test", database);
|
||||
|
||||
ASSERT_THROW(statement.value<int>(0), Sqlite::NoValuesToFetch);
|
||||
ASSERT_THROW(statement.fetchValue<int>(0), Sqlite::NoValuesToFetch);
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, ThrowNoValuesToFetchForDoneStatement)
|
||||
@@ -146,7 +150,7 @@ TEST_F(SqliteStatement, ThrowNoValuesToFetchForDoneStatement)
|
||||
SqliteTestStatement statement("SELECT name, number FROM test", database);
|
||||
while (statement.next()) {}
|
||||
|
||||
ASSERT_THROW(statement.value<int>(0), Sqlite::NoValuesToFetch);
|
||||
ASSERT_THROW(statement.fetchValue<int>(0), Sqlite::NoValuesToFetch);
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNegativeColumn)
|
||||
@@ -154,7 +158,7 @@ TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNegativeColumn)
|
||||
SqliteTestStatement statement("SELECT name, number FROM test", database);
|
||||
statement.next();
|
||||
|
||||
ASSERT_THROW(statement.value<int>(-1), Sqlite::InvalidColumnFetched);
|
||||
ASSERT_THROW(statement.fetchValue<int>(-1), Sqlite::InvalidColumnFetched);
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNotExistingColumn)
|
||||
@@ -162,7 +166,7 @@ TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNotExistingColumn)
|
||||
SqliteTestStatement statement("SELECT name, number FROM test", database);
|
||||
statement.next();
|
||||
|
||||
ASSERT_THROW(statement.value<int>(2), Sqlite::InvalidColumnFetched);
|
||||
ASSERT_THROW(statement.fetchValue<int>(2), Sqlite::InvalidColumnFetched);
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, ToIntergerValue)
|
||||
@@ -206,7 +210,7 @@ TEST_F(SqliteStatement, BindString)
|
||||
statement.next();
|
||||
|
||||
ASSERT_THAT(statement.text(0), "foo");
|
||||
ASSERT_THAT(statement.value<double>(1), 23.3);
|
||||
ASSERT_THAT(statement.fetchValue<double>(1), 23.3);
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, BindInteger)
|
||||
@@ -356,7 +360,7 @@ TEST_F(SqliteStatement, GetTupleValuesWithoutArguments)
|
||||
using Tuple = std::tuple<Utils::SmallString, double, int>;
|
||||
ReadStatement statement("SELECT name, number, value FROM test", database);
|
||||
|
||||
auto values = statement.tupleValues<Utils::SmallString, double, int>(3);
|
||||
auto values = statement.values<Tuple, 3>(3);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Tuple{"bar", 0, 1},
|
||||
Tuple{"foo", 23.3, 2},
|
||||
@@ -376,7 +380,7 @@ TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
|
||||
{
|
||||
ReadStatement statement("SELECT name, number, value FROM test", database);
|
||||
|
||||
auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3);
|
||||
auto values = statement.values<Output, 3>(3);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1},
|
||||
Output{"foo", "23.3", 2},
|
||||
@@ -399,7 +403,7 @@ TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryValues)
|
||||
std::vector<double> queryValues = {40, 23.3};
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
|
||||
|
||||
auto values = statement.tupleValues<Utils::SmallString, double, double>(3, queryValues);
|
||||
auto values = statement.values<Tuple, 3>(3, queryValues);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Tuple{"poo", 40, 3.},
|
||||
Tuple{"foo", 23.3, 2.}));
|
||||
@@ -418,14 +422,14 @@ TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryValues)
|
||||
TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryTupleValues)
|
||||
{
|
||||
using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, int>;
|
||||
using Tuple2 = std::tuple<Utils::SmallString, double, int>;
|
||||
using ResultTuple = std::tuple<Utils::SmallString, double, int>;
|
||||
std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
|
||||
|
||||
auto values = statement.tupleValues<Utils::SmallString, double, int>(3, queryValues);
|
||||
auto values = statement.values<ResultTuple, 3>(3, queryValues);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Tuple2{"poo", 40, 3},
|
||||
Tuple2{"bar", 0, 1}));
|
||||
ASSERT_THAT(values, ElementsAre(ResultTuple{"poo", 40, 3},
|
||||
ResultTuple{"bar", 0, 1}));
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryTupleValues)
|
||||
@@ -444,7 +448,7 @@ TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndMultipleQueryValue)
|
||||
using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
|
||||
|
||||
auto values = statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah", 1);
|
||||
auto values = statement.values<Tuple, 3>(3, "bar", "blah", 1);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
|
||||
}
|
||||
@@ -453,9 +457,9 @@ TEST_F(SqliteStatement, CallGetValuesForMultipleOutputValuesAndMultipleQueryValu
|
||||
{
|
||||
using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=?", database);
|
||||
statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah");
|
||||
statement.values<Tuple, 3>(3, "bar", "blah");
|
||||
|
||||
auto values = statement.tupleValues<Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah");
|
||||
auto values = statement.values<Tuple, 3>(3, "bar", "blah");
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
|
||||
}
|
||||
@@ -464,7 +468,7 @@ TEST_F(SqliteStatement, GetStructOutputValuesAndMultipleQueryValue)
|
||||
{
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
|
||||
|
||||
auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, "bar", "blah", 1);
|
||||
auto values = statement.values<Output, 3>(3, "bar", "blah", 1);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1}));
|
||||
}
|
||||
@@ -474,7 +478,7 @@ TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryValues)
|
||||
std::vector<double> queryValues = {40, 23.3};
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
|
||||
|
||||
auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, queryValues);
|
||||
auto values = statement.values<Output, 3>(3, queryValues);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
|
||||
Output{"foo", "23.3", 2}));
|
||||
@@ -486,12 +490,41 @@ TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryTupleValues)
|
||||
std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
|
||||
|
||||
auto values = statement.structValues<Output, Utils::SmallString, Utils::SmallString, long long>(3, queryValues);
|
||||
auto values = statement.values<Output, 3>(3, queryValues);
|
||||
|
||||
ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
|
||||
Output{"bar", "blah", 1}));
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, GetOptionalSingleValueAndMultipleQueryValue)
|
||||
{
|
||||
ReadStatement statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", database);
|
||||
|
||||
auto value = statement.value<Utils::SmallString>("bar", "blah", 1);
|
||||
|
||||
ASSERT_THAT(value.value(), Eq("bar"));
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, GetOptionalOutputValueAndMultipleQueryValue)
|
||||
{
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
|
||||
|
||||
auto value = statement.value<Output, 3>("bar", "blah", 1);
|
||||
|
||||
ASSERT_THAT(value.value(), Eq(Output{"bar", "blah", 1}));
|
||||
}
|
||||
|
||||
TEST_F(SqliteStatement, GetOptionalTupleValueAndMultipleQueryValue)
|
||||
{
|
||||
using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
|
||||
ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
|
||||
|
||||
auto value = statement.value<Tuple, 3>("bar", "blah", 1);
|
||||
|
||||
ASSERT_THAT(value.value(), Eq(Tuple{"bar", "blah", 1}));
|
||||
}
|
||||
|
||||
|
||||
void SqliteStatement::SetUp()
|
||||
{
|
||||
database.setJournalMode(JournalMode::Memory);
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
using Statement::execute;
|
||||
using Statement::next;
|
||||
using Statement::text;
|
||||
using Statement::value;
|
||||
using Statement::fetchValue;
|
||||
|
||||
protected:
|
||||
void checkIsWritableStatement();
|
||||
|
||||
@@ -63,9 +63,9 @@ protected:
|
||||
|
||||
TEST_F(SymbolQuery, LocationsAt)
|
||||
{
|
||||
EXPECT_CALL(selectLocationsForSymbolLocation, structValuesReturnStdVectorLocation(_, Eq("/path/to/file.cpp"), 14, 7))
|
||||
EXPECT_CALL(selectLocationsForSymbolLocation, valuesReturnStdVectorLocation(_, Eq("/path/to/file.cpp"), 14, 7))
|
||||
.WillRepeatedly(Return(locations));
|
||||
EXPECT_CALL(selectSourcePathForId, structValuesReturnStdVectorSource(_, ElementsAre(1, 2, 4)));
|
||||
EXPECT_CALL(selectSourcePathForId, valuesReturnStdVectorSource(_, ElementsAre(1, 2, 4)));
|
||||
|
||||
query.locationsAt("/path/to/file.cpp", 14, 7);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user