Merge remote-tracking branch 'origin/4.14'

Change-Id: I214b8d59e8ff7fe0511cd6116ec7725ddc4376ee
This commit is contained in:
Eike Ziller
2021-02-18 09:26:22 +01:00
11 changed files with 235 additions and 11 deletions

View File

@@ -37,9 +37,10 @@
#include <utils/span.h>
#include <cstdint>
#include <functional>
#include <memory>
#include <type_traits>
#include <tuple>
#include <type_traits>
using std::int64_t;
@@ -319,6 +320,40 @@ public:
return statement.template fetchValue<Type>(0);
}
template<int ResultTypeCount = 1, typename Callable, typename... QueryTypes>
void readCallback(Callable &&callable, const QueryTypes &...queryValues)
{
BaseStatement::checkColumnCount(ResultTypeCount);
Resetter resetter{*this};
bindValues(queryValues...);
while (BaseStatement::next()) {
auto control = callCallable<ResultTypeCount>(callable);
if (control == CallbackControl::Abort)
break;
}
resetter.reset();
}
template<int ResultTypeCount = 1, typename Container, typename... QueryTypes>
void readTo(Container &container, const QueryTypes &...queryValues)
{
BaseStatement::checkColumnCount(ResultTypeCount);
Resetter resetter{*this};
bindValues(queryValues...);
while (BaseStatement::next())
pushBackToContainer<ResultTypeCount>(container);
resetter.reset();
}
protected:
~StatementImplementation() = default;
@@ -401,6 +436,30 @@ private:
return assignValue<ResultOptionalType>(std::make_integer_sequence<int, ResultTypeCount>{});
}
template<typename Callable, int... ColumnIndices>
CallbackControl callCallable(Callable &&callable, std::integer_sequence<int, ColumnIndices...>)
{
return std::invoke(callable, ValueGetter(*this, ColumnIndices)...);
}
template<int ResultTypeCount, typename Callable>
CallbackControl callCallable(Callable &&callable)
{
return callCallable(callable, std::make_integer_sequence<int, ResultTypeCount>{});
}
template<typename Container, int... ColumnIndices>
void pushBackToContainer(Container &container, std::integer_sequence<int, ColumnIndices...>)
{
container.push_back(Container::value_type(ValueGetter(*this, ColumnIndices)...));
}
template<int ResultTypeCount, typename Container>
void pushBackToContainer(Container &container)
{
pushBackToContainer(container, std::make_integer_sequence<int, ResultTypeCount>{});
}
template<typename ValueType>
void bindValuesByIndex(int index, const ValueType &value)
{

View File

@@ -68,4 +68,6 @@ enum class ChangeType : int { Delete = 9, Insert = 18, Update = 23 };
enum class byte : unsigned char {};
enum class CallbackControl : unsigned char { Continue, Abort };
} // namespace Sqlite

View File

@@ -34,9 +34,11 @@ class SQLITE_EXPORT ReadStatement final : protected StatementImplementation<Base
public:
explicit ReadStatement(Utils::SmallStringView sqlStatement, Database &database);
using StatementImplementation::readCallback;
using StatementImplementation::readTo;
using StatementImplementation::toValue;
using StatementImplementation::value;
using StatementImplementation::values;
using StatementImplementation::toValue;
protected:
void checkIsReadOnlyStatement();

View File

@@ -37,9 +37,11 @@ public:
ReadWriteStatement(Utils::SmallStringView sqlStatement, Database &database);
using StatementImplementation::execute;
using StatementImplementation::readCallback;
using StatementImplementation::readTo;
using StatementImplementation::toValue;
using StatementImplementation::value;
using StatementImplementation::values;
using StatementImplementation::toValue;
using StatementImplementation::write;
};

View File

@@ -216,9 +216,8 @@ bool FileUtils::copyRecursively(const FilePath &srcFilePath,
const QFileInfo srcFileInfo = srcFilePath.toFileInfo();
if (srcFileInfo.isDir()) {
if (!tgtFilePath.exists()) {
QDir targetDir(tgtFilePath.toString());
targetDir.cdUp();
if (!targetDir.mkdir(tgtFilePath.fileName())) {
const QDir targetDir(tgtFilePath.parentDir().toString());
if (!targetDir.mkpath(tgtFilePath.fileName())) {
if (error) {
*error = QCoreApplication::translate("Utils::FileUtils",
"Failed to create directory \"%1\".")

View File

@@ -64,7 +64,7 @@ struct Data
{
FilePath sourcePath;
FilePath extractedPath;
bool installIntoApplication;
bool installIntoApplication = false;
};
static QStringList libraryNameFilter()
@@ -354,7 +354,7 @@ public:
vlayout->addSpacing(10);
auto localInstall = new QRadioButton(PluginInstallWizard::tr("User plugins"));
localInstall->setChecked(true);
localInstall->setChecked(!m_data->installIntoApplication);
auto localLabel = new QLabel(
PluginInstallWizard::tr("The plugin will be available to all compatible %1 "
"installations, but only for the current user.")
@@ -368,6 +368,7 @@ public:
auto appInstall = new QRadioButton(
PluginInstallWizard::tr("%1 installation").arg(Constants::IDE_DISPLAY_NAME));
appInstall->setChecked(m_data->installIntoApplication);
auto appLabel = new QLabel(
PluginInstallWizard::tr("The plugin will be available only to this %1 "
"installation, but for all users that can access it.")

View File

@@ -38,6 +38,7 @@
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
#include <utils/environment.h>
#include <utils/qtcassert.h>
#include <QLoggingCategory>
@@ -411,7 +412,9 @@ ProjectImporter::findOrCreateToolChains(const ToolChainDescription &tcd) const
{
ToolChainData result;
result.tcs = ToolChainManager::toolChains([&tcd](const ToolChain *tc) {
return tc->language() == tcd.language && tc->compilerCommand() == tcd.compilerPath;
return tc->language() == tcd.language &&
Utils::Environment::systemEnvironment().isSameExecutable(
tc->compilerCommand().toString(), tcd.compilerPath.toString());
});
for (const ToolChain *tc : qAsConst(result.tcs)) {
const QByteArray tcId = tc->id();

View File

@@ -33,6 +33,7 @@
#include "bindingproperty.h"
#include "variantproperty.h"
#include "rewritertransaction.h"
#include "signalhandlerproperty.h"
#include <rewritingexception.h>
#include <QUrl>
@@ -78,6 +79,13 @@ static void syncBindingProperties(ModelNode &outputNode, const ModelNode &inputN
}
}
static void syncSignalHandlerProperties(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash)
{
foreach (const SignalHandlerProperty &signalProperty, inputNode.signalProperties()) {
outputNode.signalHandlerProperty(signalProperty.name()).setSource(fixExpression(signalProperty.source(), idRenamingHash));
}
}
static void syncId(ModelNode &outputNode, const ModelNode &inputNode, const QHash<QString, QString> &idRenamingHash)
{
if (!inputNode.id().isEmpty())
@@ -152,6 +160,7 @@ static ModelNode createNodeFromNode(const ModelNode &modelNode,const QHash<QStri
propertyList, variantPropertyList, modelNode.nodeSource(), modelNode.nodeSourceType()));
syncAuxiliaryProperties(newNode, modelNode);
syncBindingProperties(newNode, modelNode, idRenamingHash);
syncSignalHandlerProperties(newNode, modelNode, idRenamingHash);
syncId(newNode, modelNode, idRenamingHash);
syncNodeProperties(newNode, modelNode, idRenamingHash, view);
syncNodeListProperties(newNode, modelNode, idRenamingHash, view);

View File

@@ -41,8 +41,10 @@ public:
MOCK_CONST_METHOD1(fetchLongValue, long (int));
MOCK_CONST_METHOD1(fetchLongLongValue, long long (int));
MOCK_CONST_METHOD1(fetchDoubleValue, double (int));
MOCK_CONST_METHOD1(fetchSmallStringValue, Utils::SmallString (int));
MOCK_CONST_METHOD1(fetchSmallStringValue, Utils::SmallString(int));
MOCK_CONST_METHOD1(fetchSmallStringViewValue, Utils::SmallStringView(int));
MOCK_CONST_METHOD1(fetchPathStringValue, Utils::PathString (int));
MOCK_CONST_METHOD1(fetchValueView, Sqlite::ValueView(int));
template<typename Type>
Type fetchValue(int column) const;

View File

@@ -37,6 +37,7 @@
#include <QDir>
#include <deque>
#include <vector>
namespace {
@@ -958,4 +959,148 @@ TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForToManyArgumentsForToValues)
Sqlite::ColumnCountDoesNotMatch);
}
TEST_F(SqliteStatement, ReadCallback)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
ReadStatement statement("SELECT name, value FROM test", database);
EXPECT_CALL(callbackMock, Call(Eq("bar"), Eq(1)));
EXPECT_CALL(callbackMock, Call(Eq("foo"), Eq(2)));
EXPECT_CALL(callbackMock, Call(Eq("poo"), Eq(3)));
statement.readCallback<2>(callbackMock.AsStdFunction());
}
TEST_F(SqliteStatement, ReadCallbackCalledWithArguments)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
ReadStatement statement("SELECT name, value FROM test WHERE value=?", database);
EXPECT_CALL(callbackMock, Call(Eq("foo"), Eq(2)));
statement.readCallback<2>(callbackMock.AsStdFunction(), 2);
}
TEST_F(SqliteStatement, ReadCallbackAborts)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
ReadStatement statement("SELECT name, value FROM test ORDER BY name", database);
EXPECT_CALL(callbackMock, Call(Eq("bar"), Eq(1)));
EXPECT_CALL(callbackMock, Call(Eq("foo"), Eq(2))).WillOnce(Return(Sqlite::CallbackControl::Abort));
EXPECT_CALL(callbackMock, Call(Eq("poo"), Eq(3))).Times(0);
statement.readCallback<2>(callbackMock.AsStdFunction());
}
TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForToManyArgumentsForReadCallback)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView)> callbackMock;
SqliteTestStatement statement("SELECT name, number FROM test", database);
ASSERT_THROW(statement.readCallback<1>(callbackMock.AsStdFunction()),
Sqlite::ColumnCountDoesNotMatch);
}
TEST_F(SqliteStatement, ReadCallbackCallsResetAfterCallbacks)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
MockSqliteStatement mockStatement;
EXPECT_CALL(mockStatement, reset());
mockStatement.readCallback<2>(callbackMock.AsStdFunction());
}
TEST_F(SqliteStatement, ReadCallbackCallsResetAfterCallbacksAborts)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
MockSqliteStatement mockStatement;
ON_CALL(callbackMock, Call(_, _)).WillByDefault(Return(Sqlite::CallbackControl::Abort));
EXPECT_CALL(mockStatement, reset());
mockStatement.readCallback<2>(callbackMock.AsStdFunction());
}
TEST_F(SqliteStatement, ReadCallbackThrowsForError)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
MockSqliteStatement mockStatement;
ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));
ASSERT_THROW(mockStatement.readCallback<2>(callbackMock.AsStdFunction()),
Sqlite::StatementHasError);
}
TEST_F(SqliteStatement, ReadCallbackCallsResetIfExceptionIsThrown)
{
MockFunction<Sqlite::CallbackControl(Utils::SmallStringView, long long)> callbackMock;
MockSqliteStatement mockStatement;
ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));
EXPECT_CALL(mockStatement, reset());
EXPECT_THROW(mockStatement.readCallback<2>(callbackMock.AsStdFunction()),
Sqlite::StatementHasError);
}
TEST_F(SqliteStatement, ReadToContainer)
{
std::deque<FooValue> values;
ReadStatement statement("SELECT number FROM test", database);
statement.readTo<1>(values);
ASSERT_THAT(values, UnorderedElementsAre(Eq("blah"), Eq(23.3), Eq(40)));
}
TEST_F(SqliteStatement, ReadToContainerCallCallbackWithArguments)
{
std::deque<FooValue> values;
ReadStatement statement("SELECT number FROM test WHERE value=?", database);
statement.readTo(values, 2);
ASSERT_THAT(values, ElementsAre(Eq(23.3)));
}
TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForToManyArgumentsForReadTo)
{
std::deque<FooValue> values;
SqliteTestStatement statement("SELECT name, number FROM test", database);
ASSERT_THROW(statement.readTo<1>(values, 2), Sqlite::ColumnCountDoesNotMatch);
}
TEST_F(SqliteStatement, ReadToCallsResetAfterPushingAllValuesBack)
{
std::deque<FooValue> values;
MockSqliteStatement mockStatement;
EXPECT_CALL(mockStatement, reset());
mockStatement.readTo(values);
}
TEST_F(SqliteStatement, ReadToThrowsForError)
{
std::deque<FooValue> values;
MockSqliteStatement mockStatement;
ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));
ASSERT_THROW(mockStatement.readTo(values), Sqlite::StatementHasError);
}
TEST_F(SqliteStatement, ReadToCallsResetIfExceptionIsThrown)
{
std::deque<FooValue> values;
MockSqliteStatement mockStatement;
ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));
EXPECT_CALL(mockStatement, reset());
EXPECT_THROW(mockStatement.readTo(values), Sqlite::StatementHasError);
}
} // namespace