diff --git a/.github/actions/spelling/expect.txt b/.github/actions/spelling/expect.txt index dce7008fed..0f72b5feba 100644 --- a/.github/actions/spelling/expect.txt +++ b/.github/actions/spelling/expect.txt @@ -291,6 +291,7 @@ NX objbase objidl ofile +openmode Outptr packageinuse PACL diff --git a/src/AppInstallerCommonCore/FileLogger.cpp b/src/AppInstallerCommonCore/FileLogger.cpp index c0fe6de1b6..77c6be0704 100644 --- a/src/AppInstallerCommonCore/FileLogger.cpp +++ b/src/AppInstallerCommonCore/FileLogger.cpp @@ -15,6 +15,7 @@ namespace AppInstaller::Logging static constexpr std::string_view s_fileLoggerDefaultFilePrefix = "WinGet"sv; static constexpr std::string_view s_fileLoggerDefaultFileExt = ".log"sv; + static constexpr std::ios_base::openmode s_fileLoggerDefaultOpenMode = std::ios_base::out | std::ios_base::app; FileLogger::FileLogger() : FileLogger(s_fileLoggerDefaultFilePrefix) {} @@ -23,7 +24,7 @@ namespace AppInstaller::Logging m_name = GetNameForPath(filePath); m_filePath = filePath; - m_stream.open(m_filePath); + m_stream.open(m_filePath, s_fileLoggerDefaultOpenMode); } FileLogger::FileLogger(const std::string_view fileNamePrefix) @@ -32,7 +33,7 @@ namespace AppInstaller::Logging m_filePath = Runtime::GetPathTo(Runtime::PathName::DefaultLogLocation); m_filePath /= fileNamePrefix.data() + ('-' + Utility::GetCurrentTimeForFilename() + s_fileLoggerDefaultFileExt.data()); - m_stream.open(m_filePath); + m_stream.open(m_filePath, s_fileLoggerDefaultOpenMode); } FileLogger::~FileLogger() diff --git a/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp b/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp index 26e8726354..38b88d6982 100644 --- a/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp +++ b/src/AppInstallerRepositoryCore/SQLiteWrapper.cpp @@ -37,6 +37,12 @@ namespace AppInstaller::Repository::SQLite namespace { + size_t GetNextConnectionId() + { + static std::atomic_size_t connectionId(0); + return ++connectionId; + } + size_t GetNextStatementId() { static std::atomic_size_t statementId(0); @@ -141,7 +147,8 @@ namespace AppInstaller::Repository::SQLite Connection::Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags) { - AICLI_LOG(SQL, Info, << "Opening SQLite connection: '" << target << "' [" << std::hex << static_cast(disposition) << ", " << std::hex << static_cast(flags) << "]"); + m_id = GetNextConnectionId(); + AICLI_LOG(SQL, Info, << "Opening SQLite connection #" << m_id << ": '" << target << "' [" << std::hex << static_cast(disposition) << ", " << std::hex << static_cast(flags) << "]"); // Always force connection serialization until we determine that there are situations where it is not needed int resultingFlags = static_cast(disposition) | static_cast(flags) | SQLITE_OPEN_FULLMUTEX; THROW_IF_SQLITE_FAILED(sqlite3_open_v2(target.c_str(), &m_dbconn, resultingFlags, nullptr), nullptr); @@ -172,10 +179,16 @@ namespace AppInstaller::Repository::SQLite return sqlite3_changes(m_dbconn.get()); } + size_t Connection::GetID() const + { + return m_id; + } + Statement::Statement(const Connection& connection, std::string_view sql) { + m_connectionId = connection.GetID(); m_id = GetNextStatementId(); - AICLI_LOG(SQL, Verbose, << "Preparing statement #" << m_id << ": " << sql); + AICLI_LOG(SQL, Verbose, << "Preparing statement #" << m_connectionId << '-' << m_id << ": " << sql); // SQL string size should include the null terminator (https://www.sqlite.org/c3ref/prepare.html) assert(sql.data()[sql.size()] == '\0'); THROW_IF_SQLITE_FAILED(sqlite3_prepare_v2(connection, sql.data(), static_cast(sql.size() + 1), &m_stmt, nullptr), connection); @@ -241,18 +254,18 @@ namespace AppInstaller::Repository::SQLite bool Statement::Step(bool failFastOnError) { - AICLI_LOG(SQL, Verbose, << "Stepping statement #" << m_id); + AICLI_LOG(SQL, Verbose, << "Stepping statement #" << m_connectionId << '-' << m_id); int result = sqlite3_step(m_stmt.get()); if (result == SQLITE_ROW) { - AICLI_LOG(SQL, Verbose, << "Statement #" << m_id << " has data"); + AICLI_LOG(SQL, Verbose, << "Statement #" << m_connectionId << '-' << m_id << " has data"); m_state = State::HasRow; return true; } else if (result == SQLITE_DONE) { - AICLI_LOG(SQL, Verbose, << "Statement #" << m_id << " has completed"); + AICLI_LOG(SQL, Verbose, << "Statement #" << m_connectionId << '-' << m_id << " has completed"); m_state = State::Completed; return false; } @@ -283,7 +296,7 @@ namespace AppInstaller::Repository::SQLite void Statement::Reset() { - AICLI_LOG(SQL, Verbose, << "Reset statement #" << m_id); + AICLI_LOG(SQL, Verbose, << "Reset statement #" << m_connectionId << '-' << m_id); // Ignore return value from reset, as if it is an error, it was the error from the last call to step. sqlite3_reset(m_stmt.get()); m_state = State::Prepared; diff --git a/src/AppInstallerRepositoryCore/SQLiteWrapper.h b/src/AppInstallerRepositoryCore/SQLiteWrapper.h index 0b66dacbb4..3a5913ce95 100644 --- a/src/AppInstallerRepositoryCore/SQLiteWrapper.h +++ b/src/AppInstallerRepositoryCore/SQLiteWrapper.h @@ -177,11 +177,15 @@ namespace AppInstaller::Repository::SQLite // Gets the count of changed rows for the last executed statement. int GetChanges() const; + //. Gets the (fixed but arbitrary) identifier for this connection. + size_t GetID() const; + operator sqlite3* () const { return m_dbconn.get(); } private: Connection(const std::string& target, OpenDisposition disposition, OpenFlags flags); + size_t m_id = 0; wil::unique_any m_dbconn; }; @@ -223,7 +227,7 @@ namespace AppInstaller::Repository::SQLite template void Bind(int index, Value&& v) { - AICLI_LOG(SQL, Verbose, << "Binding statement #" << m_id << ": " << index << " => " << details::ParameterSpecifics::ToLog(std::forward(v))); + AICLI_LOG(SQL, Verbose, << "Binding statement #" << m_connectionId << '-' << m_id << ": " << index << " => " << details::ParameterSpecifics::ToLog(std::forward(v))); details::ParameterSpecifics::Bind(m_stmt.get(), index, std::forward(v)); } @@ -278,6 +282,7 @@ namespace AppInstaller::Repository::SQLite return std::make_tuple(details::ParameterSpecifics::GetColumn(m_stmt.get(), I)...); } + size_t m_connectionId = 0; size_t m_id = 0; wil::unique_any m_stmt; State m_state = State::Prepared;