mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-02 20:30:11 +01:00
4529 sql logger shutdown (#4530)
* enh(ThreadTest): add join test * enh(SQLLogger): #4529 (wip) * enh(SQLChannel): just few C++17 modernisations. * enh(SQLiteTest): extend unit test to destroy SQL channel while it has pending messages. (#4529) * enh(ODBC): improve exception descriptions and add string/batch size tests * feat(SQLChannel): add store-and-forward mode * fix(DataTest): SQLChannel *nix build and test run #4529 * fix(DataTest): CodeQL warning #4529 * chore(ODBCTest): lower the number of max statements in big batch * feat(SQLChannel): add flush property #4529 * enh(SQLChannel): use event for interruptible sleep; reduce code duplication with lambda; update comments #4529 * fix(SQLChannel): flush time determination #4529 --------- Co-authored-by: Matej Kenda <matejken@gmail.com>
This commit is contained in:
parent
2442c66f84
commit
ed181d99dc
@ -651,10 +651,6 @@
|
|||||||
RelativePath=".\include\Poco\Data\SimpleRowFormatter.h"
|
RelativePath=".\include\Poco\Data\SimpleRowFormatter.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\include\Poco\Data\SQLChannel.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\include\Poco\Data\SQLParser.h"
|
RelativePath=".\include\Poco\Data\SQLParser.h"
|
||||||
>
|
>
|
||||||
@ -791,10 +787,6 @@
|
|||||||
RelativePath=".\src\SimpleRowFormatter.cpp"
|
RelativePath=".\src\SimpleRowFormatter.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
|
||||||
RelativePath=".\src\SQLChannel.cpp"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
<File
|
||||||
RelativePath=".\src\Statement.cpp"
|
RelativePath=".\src\Statement.cpp"
|
||||||
>
|
>
|
||||||
|
@ -180,9 +180,6 @@
|
|||||||
<ClInclude Include="include\Poco\Data\SimpleRowFormatter.h">
|
<ClInclude Include="include\Poco\Data\SimpleRowFormatter.h">
|
||||||
<Filter>DataCore\Header Files</Filter>
|
<Filter>DataCore\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="include\Poco\Data\SQLChannel.h">
|
|
||||||
<Filter>DataCore\Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="include\Poco\Data\SQLParser.h">
|
<ClInclude Include="include\Poco\Data\SQLParser.h">
|
||||||
<Filter>DataCore\Header Files</Filter>
|
<Filter>DataCore\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -297,6 +294,9 @@
|
|||||||
<ClInclude Include="include\Poco\Data\ArchiveStrategy.h">
|
<ClInclude Include="include\Poco\Data\ArchiveStrategy.h">
|
||||||
<Filter>Logging\Header Files</Filter>
|
<Filter>Logging\Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="include\Poco\Data\SQLChannel.h">
|
||||||
|
<Filter>Logging\Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\AbstractBinder.cpp">
|
<ClCompile Include="src\AbstractBinder.cpp">
|
||||||
@ -374,9 +374,6 @@
|
|||||||
<ClCompile Include="src\SimpleRowFormatter.cpp">
|
<ClCompile Include="src\SimpleRowFormatter.cpp">
|
||||||
<Filter>DataCore\Source Files</Filter>
|
<Filter>DataCore\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="src\SQLChannel.cpp">
|
|
||||||
<Filter>DataCore\Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="src\Statement.cpp">
|
<ClCompile Include="src\Statement.cpp">
|
||||||
<Filter>DataCore\Source Files</Filter>
|
<Filter>DataCore\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -440,6 +437,9 @@
|
|||||||
<ClCompile Include="src\ArchiveStrategy.cpp">
|
<ClCompile Include="src\ArchiveStrategy.cpp">
|
||||||
<Filter>Logging\Source Files</Filter>
|
<Filter>Logging\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\SQLChannel.cpp">
|
||||||
|
<Filter>Logging\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\DLLVersion.rc" />
|
<ResourceCompile Include="..\DLLVersion.rc" />
|
||||||
|
@ -999,7 +999,7 @@ private:
|
|||||||
{
|
{
|
||||||
std::size_t sz = it->size() * typeSize;
|
std::size_t sz = it->size() * typeSize;
|
||||||
if (sz > _maxFieldSize)
|
if (sz > _maxFieldSize)
|
||||||
throw LengthExceededException();
|
throw LengthExceededException("ODBC::Binder::getMinValueSize(%s, %d)", std::string(typeid(T).name()), static_cast<int>(size));
|
||||||
|
|
||||||
if (sz == _maxFieldSize)
|
if (sz == _maxFieldSize)
|
||||||
{
|
{
|
||||||
|
@ -528,8 +528,8 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
|||||||
|
|
||||||
if (actualSize > colSize)
|
if (actualSize > colSize)
|
||||||
{
|
{
|
||||||
throw LengthExceededException(Poco::format("Error binding column %z size=%z, max size=%ld)",
|
throw LengthExceededException(Poco::format("ODBC::Binder::getColSizeAndPrecision();%d: Error binding column %z size=%z, max size=%ld)",
|
||||||
pos, actualSize, static_cast<long>(colSize)));
|
__LINE__, pos, actualSize, static_cast<long>(colSize)));
|
||||||
}
|
}
|
||||||
foundPrec = _pTypeInfo->tryGetInfo(cDataType, "MAXIMUM_SCALE", tmp);
|
foundPrec = _pTypeInfo->tryGetInfo(cDataType, "MAXIMUM_SCALE", tmp);
|
||||||
if (foundPrec) decDigits = tmp;
|
if (foundPrec) decDigits = tmp;
|
||||||
@ -565,8 +565,8 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
|
|||||||
// last check, just in case
|
// last check, just in case
|
||||||
if ((0 != colSize) && (actualSize > colSize))
|
if ((0 != colSize) && (actualSize > colSize))
|
||||||
{
|
{
|
||||||
throw LengthExceededException(Poco::format("Error binding column %z size=%z, max size=%ld)",
|
throw LengthExceededException(Poco::format("ODBC::Binder::getColSizeAndPrecision();%d: Error binding column %z size=%z, max size=%ld)",
|
||||||
pos, actualSize, static_cast<long>(colSize)));
|
__LINE__, pos, actualSize, static_cast<long>(colSize)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
using namespace Poco::Data::Keywords;
|
using namespace Poco::Data::Keywords;
|
||||||
using Poco::Data::DataException;
|
using Poco::Data::DataException;
|
||||||
using Poco::Data::Statement;
|
using Poco::Data::Statement;
|
||||||
@ -216,6 +217,76 @@ void ODBCSQLServerTest::testBLOB()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::testBigString()
|
||||||
|
{
|
||||||
|
std::string lastName(8000, 'l');
|
||||||
|
std::string firstName(8000, 'f');
|
||||||
|
std::string address("Address");
|
||||||
|
int age = 42;
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreatePersonBigStringTable();
|
||||||
|
session().setFeature("autoBind", bindValue(i));
|
||||||
|
session().setFeature("autoExtract", bindValue(i + 1));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
session() << "INSERT INTO Person VALUES (?,?,?,?)"s,
|
||||||
|
use(lastName), use(firstName), use(address), use(age), now;
|
||||||
|
}
|
||||||
|
catch (DataException& ce)
|
||||||
|
{
|
||||||
|
std::cout << ce.displayText() << std::endl;
|
||||||
|
failmsg(__func__);
|
||||||
|
}
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::testBigBatch()
|
||||||
|
{
|
||||||
|
const std::string query("INSERT INTO Person VALUES('L', 'N', 'A', %d);");
|
||||||
|
std::string bigQuery;
|
||||||
|
// TODO: see what exactly the limits are here
|
||||||
|
int rows = 316, cnt = 0;
|
||||||
|
for (int i = 0; i < rows; ++i)
|
||||||
|
{
|
||||||
|
bigQuery += Poco::format(query, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 8;)
|
||||||
|
{
|
||||||
|
recreatePersonBigStringTable();
|
||||||
|
session().setFeature("autoBind", bindValue(i));
|
||||||
|
session().setFeature("autoExtract", bindValue(i + 1));
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
session() << bigQuery, now;
|
||||||
|
}
|
||||||
|
catch (DataException& ce)
|
||||||
|
{
|
||||||
|
std::cout << ce.displayText() << std::endl;
|
||||||
|
failmsg(__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
session() << "SELECT COUNT(*) FROM Person", into(cnt), now;
|
||||||
|
assertEqual(rows, cnt);
|
||||||
|
}
|
||||||
|
catch (DataException& ce)
|
||||||
|
{
|
||||||
|
std::cout << ce.displayText() << std::endl;
|
||||||
|
failmsg(__func__);
|
||||||
|
}
|
||||||
|
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::testNull()
|
void ODBCSQLServerTest::testNull()
|
||||||
{
|
{
|
||||||
// test for NOT NULL violation exception
|
// test for NOT NULL violation exception
|
||||||
@ -706,6 +777,15 @@ void ODBCSQLServerTest::recreatePersonBLOBTable()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ODBCSQLServerTest::recreatePersonBigStringTable()
|
||||||
|
{
|
||||||
|
dropObject("TABLE", "Person");
|
||||||
|
try { session() << "CREATE TABLE Person (LastName VARCHAR(MAX), FirstName VARCHAR(8000), Address VARCHAR(30), Age INTEGER)", now; }
|
||||||
|
catch (ConnectionException& ce) { std::cout << ce.toString() << std::endl; fail("recreatePersonBLOBTable()"); }
|
||||||
|
catch (StatementException& se) { std::cout << se.toString() << std::endl; fail("recreatePersonBLOBTable()"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ODBCSQLServerTest::recreatePersonDateTimeTable()
|
void ODBCSQLServerTest::recreatePersonDateTimeTable()
|
||||||
{
|
{
|
||||||
dropObject("TABLE", "Person");
|
dropObject("TABLE", "Person");
|
||||||
@ -939,6 +1019,8 @@ CppUnit::Test* ODBCSQLServerTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSingleSelect);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSingleSelect);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testEmptyDB);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testEmptyDB);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOB);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOB);
|
||||||
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBigString);
|
||||||
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBigBatch);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOBContainer);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOBContainer);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOBStmt);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBLOBStmt);
|
||||||
CppUnit_addTest(pSuite, ODBCSQLServerTest, testRecordSet);
|
CppUnit_addTest(pSuite, ODBCSQLServerTest, testRecordSet);
|
||||||
|
@ -47,6 +47,8 @@ public:
|
|||||||
void testTempTable();
|
void testTempTable();
|
||||||
|
|
||||||
void testBLOB();
|
void testBLOB();
|
||||||
|
void testBigString();
|
||||||
|
void testBigBatch();
|
||||||
void testNull();
|
void testNull();
|
||||||
void testBulk();
|
void testBulk();
|
||||||
|
|
||||||
@ -65,6 +67,7 @@ private:
|
|||||||
void recreateNullableTable();
|
void recreateNullableTable();
|
||||||
void recreatePersonTable();
|
void recreatePersonTable();
|
||||||
void recreatePersonBLOBTable();
|
void recreatePersonBLOBTable();
|
||||||
|
void recreatePersonBigStringTable();
|
||||||
void recreatePersonDateTimeTable();
|
void recreatePersonDateTimeTable();
|
||||||
void recreatePersonDateTable() { /* no-op */ };
|
void recreatePersonDateTable() { /* no-op */ };
|
||||||
void recreatePersonTimeTable() { /* no-op */ };
|
void recreatePersonTimeTable() { /* no-op */ };
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
<ProjectConfiguration Include="debug_shared|ARM64">
|
<ProjectConfiguration Include="debug_shared|ARM64">
|
||||||
@ -81,7 +81,7 @@
|
|||||||
<RootNamespace>TestSuite</RootNamespace>
|
<RootNamespace>TestSuite</RootNamespace>
|
||||||
<Keyword>Win32Proj</Keyword>
|
<Keyword>Win32Proj</Keyword>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
@ -172,63 +172,63 @@
|
|||||||
<CharacterSet>MultiByte</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings"/>
|
<ImportGroup Label="ExtensionSettings" />
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|ARM64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|ARM64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
|
||||||
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
|
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros"/>
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<_ProjectFileVersion>17.0.34714.143</_ProjectFileVersion>
|
<_ProjectFileVersion>17.0.34714.143</_ProjectFileVersion>
|
||||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|ARM64'">TestSuited</TargetName>
|
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|ARM64'">TestSuited</TargetName>
|
||||||
@ -352,7 +352,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -388,9 +388,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -421,7 +421,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -457,9 +457,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -490,7 +490,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -526,9 +526,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -559,7 +559,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -595,9 +595,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -628,7 +628,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -664,9 +664,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -697,7 +697,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -733,9 +733,9 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -757,8 +757,8 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@ -766,7 +766,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -794,17 +794,17 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -826,8 +826,8 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||||
@ -835,7 +835,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -863,17 +863,17 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -895,8 +895,8 @@
|
|||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
@ -904,7 +904,7 @@
|
|||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
@ -932,17 +932,17 @@
|
|||||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
|
||||||
<OmitFramePointers>true</OmitFramePointers>
|
<OmitFramePointers>true</OmitFramePointers>
|
||||||
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\Foundation\include;..\..\..\Data\include;..\..\..\Data\SQLParser;..\..\..\Data\SQLParser\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_CRT_SECURE_NO_WARNINGS;NDEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<StringPooling>true</StringPooling>
|
<StringPooling>true</StringPooling>
|
||||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
<BufferSecurityCheck>false</BufferSecurityCheck>
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||||
<PrecompiledHeader/>
|
<PrecompiledHeader />
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<DebugInformationFormat/>
|
<DebugInformationFormat />
|
||||||
<CompileAs>Default</CompileAs>
|
<CompileAs>Default</CompileAs>
|
||||||
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
<ProgramDataBaseFileName>$(OutDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||||
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
<AdditionalOptions>/Zc:__cplusplus %(AdditionalOptions)</AdditionalOptions>
|
||||||
@ -962,8 +962,8 @@
|
|||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\SQLiteTest.h"/>
|
<ClInclude Include="src\SQLiteTest.h" />
|
||||||
<ClInclude Include="src\SQLiteTestSuite.h"/>
|
<ClInclude Include="src\SQLiteTestSuite.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\Driver.cpp">
|
<ClCompile Include="src\Driver.cpp">
|
||||||
@ -982,6 +982,6 @@
|
|||||||
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
<LanguageStandard_C>stdc11</LanguageStandard_C>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets"/>
|
<ImportGroup Label="ExtensionTargets" />
|
||||||
</Project>
|
</Project>
|
@ -2480,7 +2480,7 @@ void SQLiteTest::testSQLChannel()
|
|||||||
{
|
{
|
||||||
Thread::sleep(10);
|
Thread::sleep(10);
|
||||||
if (sw.elapsedSeconds() > 3)
|
if (sw.elapsedSeconds() > 3)
|
||||||
fail ("SQLExecutor::sqlLogger(): SQLChannel timed out");
|
fail ("SQLChannel timed out");
|
||||||
}
|
}
|
||||||
// bulk binding mode is not suported by SQLite, but SQLChannel should handle it internally
|
// bulk binding mode is not suported by SQLite, but SQLChannel should handle it internally
|
||||||
pChannel->setProperty("bulk", "true");
|
pChannel->setProperty("bulk", "true");
|
||||||
@ -2537,6 +2537,17 @@ void SQLiteTest::testSQLChannel()
|
|||||||
rs2.moveNext();
|
rs2.moveNext();
|
||||||
assertTrue("WarningSource" == rs2["Source"]);
|
assertTrue("WarningSource" == rs2["Source"]);
|
||||||
assertTrue("f Warning sync message" == rs2["Text"]);
|
assertTrue("f Warning sync message" == rs2["Text"]);
|
||||||
|
|
||||||
|
pChannel->setProperty("minBatch", "1024");
|
||||||
|
constexpr int mcount { 2000 };
|
||||||
|
for (int i = 0; i < mcount; i++)
|
||||||
|
{
|
||||||
|
Message msgInfG("InformationSource", "g Informational sync message", Message::PRIO_INFORMATION);
|
||||||
|
pChannel->log(msgInfG);
|
||||||
|
}
|
||||||
|
pChannel.reset();
|
||||||
|
RecordSet rsl(tmp, "SELECT * FROM T_POCO_LOG");
|
||||||
|
assertEquals(2+mcount, rsl.rowCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3513,7 +3524,7 @@ void SQLiteTest::testIllegalFilePath()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SQLiteTest::testTransactionTypeProperty()
|
void SQLiteTest::testTransactionTypeProperty()
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
using namespace Poco::Data::SQLite;
|
using namespace Poco::Data::SQLite;
|
||||||
|
@ -31,7 +31,9 @@
|
|||||||
#include "Poco/String.h"
|
#include "Poco/String.h"
|
||||||
#include "Poco/NotificationQueue.h"
|
#include "Poco/NotificationQueue.h"
|
||||||
#include "Poco/Thread.h"
|
#include "Poco/Thread.h"
|
||||||
#include "Poco/Mutex.h"
|
#include "Poco/Stopwatch.h"
|
||||||
|
#include "Poco/Event.h"
|
||||||
|
#include <atomic>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
|
||||||
@ -56,15 +58,21 @@ class Data_API SQLChannel: public Poco::Channel, Poco::Runnable
|
|||||||
///
|
///
|
||||||
/// The table name is configurable through "table" property.
|
/// The table name is configurable through "table" property.
|
||||||
/// Other than DateTime filed name used for optional time-based archiving purposes, currently the
|
/// Other than DateTime filed name used for optional time-based archiving purposes, currently the
|
||||||
/// field names are not mandated. However, it is recomended to use names as specified above.
|
/// field names are not mandated. However, it is recommended to use names as specified above.
|
||||||
///
|
///
|
||||||
/// To provide as non-intrusive operation as possbile, the log entries are cached and
|
/// To provide as non-intrusive operation as possible, the log entries are cached and
|
||||||
/// inserted into the target database asynchronously by default. The blocking, however, will occur
|
/// inserted into the target database asynchronously by default. The blocking, however, will occur
|
||||||
/// before the next entry insertion with default timeout of 1 second. The default settings can be
|
/// before the next entry insertion with default timeout of 1 second. The default settings can be
|
||||||
/// overridden (see async, timeout and throw properties for details).
|
/// overridden (see async, timeout and throw properties for details).
|
||||||
/// If throw property is false, insertion timeouts are ignored, otherwise a TimeoutException is thrown.
|
/// If throw property is false, insertion timeouts are ignored, otherwise a TimeoutException is thrown.
|
||||||
/// To force insertion of every entry, set timeout to 0. This setting, however, introduces
|
/// To force insertion of every entry, set timeout to 0. This setting, however, introduces
|
||||||
/// a risk of long blocking periods in case of remote server communication delays.
|
/// a risk of long blocking periods in case of remote server communication delays.
|
||||||
|
///
|
||||||
|
/// A default-constructed SQLChannel operates without an active DB connection, in a store-and-forward
|
||||||
|
/// mode. For this mode of operation, a separate service is required to consume and execute the SQL
|
||||||
|
/// statements from the stored files and insert the log entries into the database. Since this setup
|
||||||
|
/// stores SQL inserts in the OS file system, it is strongly recommended to take the necessary
|
||||||
|
/// precautions to limit and secure the access to those files.
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class LogNotification : public Poco::Notification
|
class LogNotification : public Poco::Notification
|
||||||
@ -88,9 +96,15 @@ public:
|
|||||||
|
|
||||||
static const int DEFAULT_MIN_BATCH_SIZE = 1;
|
static const int DEFAULT_MIN_BATCH_SIZE = 1;
|
||||||
static const int DEFAULT_MAX_BATCH_SIZE = 1000;
|
static const int DEFAULT_MAX_BATCH_SIZE = 1000;
|
||||||
|
static const int DEFAULT_MAX_SQL_SIZE = 65536;
|
||||||
|
static const int DEFAULT_FLUSH_SECONDS = 10;
|
||||||
|
|
||||||
SQLChannel();
|
SQLChannel();
|
||||||
/// Creates SQLChannel.
|
/// Creates SQLChannel.
|
||||||
|
/// An SQLChannel without DB connector and local file name
|
||||||
|
/// only logs SQL inserts into local files. A separate file
|
||||||
|
/// is created for each insert batch; files are named
|
||||||
|
/// <YYYYMMDDHH24MISSmmm>.<UUID>.log.sql.
|
||||||
|
|
||||||
SQLChannel(const std::string& connector,
|
SQLChannel(const std::string& connector,
|
||||||
const std::string& connect,
|
const std::string& connect,
|
||||||
@ -98,27 +112,28 @@ public:
|
|||||||
const std::string& table = "T_POCO_LOG",
|
const std::string& table = "T_POCO_LOG",
|
||||||
int timeout = 1000,
|
int timeout = 1000,
|
||||||
int minBatch = DEFAULT_MIN_BATCH_SIZE,
|
int minBatch = DEFAULT_MIN_BATCH_SIZE,
|
||||||
int maxBatch = DEFAULT_MAX_BATCH_SIZE);
|
int maxBatch = DEFAULT_MAX_BATCH_SIZE,
|
||||||
|
int maxSQL = DEFAULT_MAX_SQL_SIZE);
|
||||||
/// Creates an SQLChannel with the given connector, connect string, timeout, table and name.
|
/// Creates an SQLChannel with the given connector, connect string, timeout, table and name.
|
||||||
/// The connector must be already registered.
|
/// The connector must be already registered.
|
||||||
|
|
||||||
void open();
|
void open() override;
|
||||||
/// Opens the SQLChannel.
|
/// Opens the SQLChannel.
|
||||||
/// Returns true if succesful.
|
/// Returns true if succesful.
|
||||||
|
|
||||||
void close();
|
void close() override;
|
||||||
/// Closes the SQLChannel.
|
/// Closes the SQLChannel.
|
||||||
|
|
||||||
void run();
|
void run() override;
|
||||||
/// Dequeues and sends the logs to the DB.
|
/// Dequeues and sends the logs to the DB.
|
||||||
|
|
||||||
bool isRunning() const;
|
bool isRunning() const;
|
||||||
/// Returns true if the logging thread is running.
|
/// Returns true if the logging thread is running.
|
||||||
|
|
||||||
void log(const Message& msg);
|
void log(const Message& msg) override;
|
||||||
/// Writes the log message to the database.
|
/// Writes the log message to the database.
|
||||||
|
|
||||||
void setProperty(const std::string& name, const std::string& value);
|
void setProperty(const std::string& name, const std::string& value) override;
|
||||||
/// Sets the property with the given value.
|
/// Sets the property with the given value.
|
||||||
///
|
///
|
||||||
/// The following properties are supported:
|
/// The following properties are supported:
|
||||||
@ -149,8 +164,7 @@ public:
|
|||||||
/// is asynchronous since the 1.13.0. release.
|
/// is asynchronous since the 1.13.0. release.
|
||||||
///
|
///
|
||||||
/// * timeout: Timeout (ms) to wait for previous log operation completion.
|
/// * timeout: Timeout (ms) to wait for previous log operation completion.
|
||||||
/// Values "0" and "" mean no timeout. Only valid when logging
|
/// Values "0" and "" mean no timeout.
|
||||||
/// is asynchronous, otherwise ignored.
|
|
||||||
///
|
///
|
||||||
/// * throw: Boolean value indicating whether to throw in case of timeout.
|
/// * throw: Boolean value indicating whether to throw in case of timeout.
|
||||||
/// Setting this property to false may result in log entries being lost.
|
/// Setting this property to false may result in log entries being lost.
|
||||||
@ -166,13 +180,23 @@ public:
|
|||||||
/// reaches this size, log entries are silently discarded.
|
/// reaches this size, log entries are silently discarded.
|
||||||
/// Defaults to 100, can't be zero or larger than 1000.
|
/// Defaults to 100, can't be zero or larger than 1000.
|
||||||
///
|
///
|
||||||
|
/// * maxSQL: Maximum total length of the SQL statement. Defaults to 65536.
|
||||||
|
///
|
||||||
/// * bulk: Do bulk execute (on most DBMS systems, this can speed up things
|
/// * bulk: Do bulk execute (on most DBMS systems, this can speed up things
|
||||||
/// drastically).
|
/// drastically).
|
||||||
///
|
///
|
||||||
/// * file Destination file name for the backup FileChannel, used when DB
|
/// * file Destination file name for the backup FileChannel, used when DB
|
||||||
/// connection is not present to log not executed SQL statements.
|
/// connection is not present to log not executed SQL statements.
|
||||||
|
///
|
||||||
|
/// * flush Time in seconds to flush outstanding log entries; since logging
|
||||||
|
/// is performed in batches of entries, the entries that do not make
|
||||||
|
/// it into the last logged batch may remain unlogged for a long time
|
||||||
|
/// during an extened period of inactivity. This setting ensures that
|
||||||
|
/// unlogged entries are flushed in such circumstances, even when the
|
||||||
|
/// minimum batch size was not reached.
|
||||||
|
/// Zero value means no flushing.
|
||||||
|
|
||||||
std::string getProperty(const std::string& name) const;
|
std::string getProperty(const std::string& name) const override;
|
||||||
/// Returns the value of the property with the given name.
|
/// Returns the value of the property with the given name.
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
@ -198,42 +222,55 @@ public:
|
|||||||
static const std::string PROP_TIMEOUT;
|
static const std::string PROP_TIMEOUT;
|
||||||
static const std::string PROP_MIN_BATCH;
|
static const std::string PROP_MIN_BATCH;
|
||||||
static const std::string PROP_MAX_BATCH;
|
static const std::string PROP_MAX_BATCH;
|
||||||
|
static const std::string PROP_MAX_SQL;
|
||||||
static const std::string PROP_BULK;
|
static const std::string PROP_BULK;
|
||||||
static const std::string PROP_THROW;
|
static const std::string PROP_THROW;
|
||||||
|
static const std::string PROP_DIRECTORY;
|
||||||
static const std::string PROP_FILE;
|
static const std::string PROP_FILE;
|
||||||
|
static const std::string PROP_FLUSH;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
~SQLChannel();
|
~SQLChannel() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const std::string SQL_INSERT_STMT;
|
static const std::string SQL_INSERT_STMT;
|
||||||
|
|
||||||
typedef Poco::SharedPtr<Session> SessionPtr;
|
using SessionPtr = Poco::SharedPtr<Session>;
|
||||||
typedef Poco::SharedPtr<Statement> StatementPtr;
|
using StatementPtr = Poco::SharedPtr<Statement>;
|
||||||
typedef Poco::Message::Priority Priority;
|
using Priority = Poco::Message::Priority;
|
||||||
typedef Poco::SharedPtr<ArchiveStrategy> StrategyPtr;
|
using StrategyPtr = Poco::SharedPtr<ArchiveStrategy>;
|
||||||
|
|
||||||
void reconnect();
|
void reconnect();
|
||||||
/// Closes and opens the DB connection.
|
/// Closes and opens the DB connection.
|
||||||
|
|
||||||
bool processOne(int minBatch = 0);
|
bool processBatch(int minBatch = 0);
|
||||||
/// Processes one message.
|
/// Processes a batch of messages.
|
||||||
/// If the number of acummulated messages is greater
|
/// If the number of acummulated messages is greater
|
||||||
/// than minBatch, sends logs to the destination.
|
/// than minBatch, sends logs to the destination.
|
||||||
/// Returns true if log entry was processed.
|
/// Returns true if at least one log entry was sent
|
||||||
|
/// to the destination.
|
||||||
|
|
||||||
size_t execSQL();
|
size_t execSQL(bool flush = false);
|
||||||
/// Executes the log statement.
|
/// Executes the log statement.
|
||||||
|
|
||||||
size_t logSync();
|
size_t logSync(bool flush = false);
|
||||||
/// Inserts entries into the target database.
|
/// Inserts entries into the target database.
|
||||||
|
|
||||||
bool isTrue(const std::string& value) const;
|
bool isTrue(const std::string& value) const;
|
||||||
/// Returns true is value is "true", "t", "yes" or "y".
|
/// Returns true is value is "true", "t", "yes" or "y".
|
||||||
/// Case insensitive.
|
/// Case insensitive.
|
||||||
|
|
||||||
size_t logTofile(AutoPtr<FileChannel>& pFileChannel, const std::string& fileName, bool clear = false);
|
size_t logToDB(bool flush = false);
|
||||||
/// Logs cached entries to a file. Called in case DB insertions fail.
|
/// Logs cached entries to the DB.
|
||||||
|
|
||||||
|
size_t logToFile(bool flush = false);
|
||||||
|
/// Logs cached entries to a file.
|
||||||
|
/// Called in case DB insertions fail or
|
||||||
|
/// in the store-and-forward mode of operation.
|
||||||
|
|
||||||
|
void logLocal(const std::string&, Message::Priority prio = Message::PRIO_ERROR);
|
||||||
|
/// Adds the message to the local SQLChannel log queue, and logs it to the file.
|
||||||
|
/// Typically used to log DB connection/execution erors.
|
||||||
|
|
||||||
std::string maskPwd();
|
std::string maskPwd();
|
||||||
/// Masks the password in the connection
|
/// Masks the password in the connection
|
||||||
@ -241,38 +278,46 @@ private:
|
|||||||
/// bullet-proof method; if not succesful,
|
/// bullet-proof method; if not succesful,
|
||||||
/// empty string is returned.
|
/// empty string is returned.
|
||||||
|
|
||||||
|
bool shouldFlush() const;
|
||||||
|
/// Returns true if there are unflushed log entries
|
||||||
|
/// and the flush timer has expired.
|
||||||
|
|
||||||
mutable Poco::FastMutex _mutex;
|
mutable Poco::FastMutex _mutex;
|
||||||
|
|
||||||
std::string _connector;
|
std::string _connector;
|
||||||
std::string _connect;
|
std::string _connect;
|
||||||
SessionPtr _pSession;
|
SessionPtr _pSession;
|
||||||
std::string _sql;
|
std::string _sql;
|
||||||
std::string _name;
|
std::string _name;
|
||||||
std::string _table;
|
std::string _table;
|
||||||
bool _tableChanged;
|
std::atomic<bool> _tableChanged;
|
||||||
int _timeout;
|
std::atomic<int> _timeout;
|
||||||
std::atomic<int> _minBatch;
|
std::atomic<int> _minBatch;
|
||||||
int _maxBatch;
|
std::atomic<int> _maxBatch;
|
||||||
bool _bulk;
|
std::atomic<int> _maxSQL;
|
||||||
|
std::atomic<bool> _bulk;
|
||||||
std::atomic<bool> _throw;
|
std::atomic<bool> _throw;
|
||||||
|
std::atomic<int> _flush;
|
||||||
|
|
||||||
// members for log entry cache
|
// members for log entry cache
|
||||||
std::vector<std::string> _source;
|
std::deque<std::string> _source;
|
||||||
std::vector<long> _pid;
|
std::deque<long> _pid;
|
||||||
std::vector<std::string> _thread;
|
std::deque<std::string> _thread;
|
||||||
std::vector<long> _tid;
|
std::deque<long> _tid;
|
||||||
std::vector<int> _priority;
|
std::deque<int> _priority;
|
||||||
std::vector<std::string> _text;
|
std::deque<std::string> _text;
|
||||||
std::vector<DateTime> _dateTime;
|
std::deque<DateTime> _dateTime;
|
||||||
Poco::NotificationQueue _logQueue;
|
Poco::NotificationQueue _logQueue;
|
||||||
std::unique_ptr<Poco::Thread> _pDBThread;
|
std::unique_ptr<Poco::Thread> _pLogThread;
|
||||||
std::atomic<bool> _reconnect;
|
std::atomic<bool> _reconnect;
|
||||||
std::atomic<bool> _running;
|
|
||||||
std::atomic<bool> _stop;
|
std::atomic<bool> _stop;
|
||||||
std::atomic<size_t> _logged;
|
std::atomic<size_t> _logged;
|
||||||
StrategyPtr _pArchiveStrategy;
|
StrategyPtr _pArchiveStrategy;
|
||||||
std::string _file;
|
std::string _file;
|
||||||
|
std::string _directory;
|
||||||
AutoPtr<FileChannel> _pFileChannel;
|
AutoPtr<FileChannel> _pFileChannel;
|
||||||
|
Poco::Stopwatch _flushTimer;
|
||||||
|
Poco::Event _event;
|
||||||
Poco::Logger& _logger = Poco::Logger::get("SQLChannel");
|
Poco::Logger& _logger = Poco::Logger::get("SQLChannel");
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -293,7 +338,7 @@ inline bool SQLChannel::isTrue(const std::string& value) const
|
|||||||
|
|
||||||
inline bool SQLChannel::isRunning() const
|
inline bool SQLChannel::isRunning() const
|
||||||
{
|
{
|
||||||
return _running;
|
return _pLogThread && _pLogThread->isRunning();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -303,6 +348,13 @@ inline size_t SQLChannel::logged() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline bool SQLChannel::shouldFlush() const
|
||||||
|
{
|
||||||
|
return (_flush > 0 && _source.size() &&
|
||||||
|
(_flushTimer.elapsedSeconds() >= _flush));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} } // namespace Poco::Data
|
} } // namespace Poco::Data
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,10 +22,13 @@
|
|||||||
#include "Poco/Instantiator.h"
|
#include "Poco/Instantiator.h"
|
||||||
#include "Poco/NumberParser.h"
|
#include "Poco/NumberParser.h"
|
||||||
#include "Poco/NumberFormatter.h"
|
#include "Poco/NumberFormatter.h"
|
||||||
#include "Poco/Stopwatch.h"
|
|
||||||
#include "Poco/Format.h"
|
#include "Poco/Format.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/UUID.h"
|
||||||
|
#include "Poco/UUIDGenerator.h"
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
|
||||||
namespace Poco {
|
namespace Poco {
|
||||||
@ -45,9 +48,12 @@ const std::string SQLChannel::PROP_ASYNC("async");
|
|||||||
const std::string SQLChannel::PROP_TIMEOUT("timeout");
|
const std::string SQLChannel::PROP_TIMEOUT("timeout");
|
||||||
const std::string SQLChannel::PROP_MIN_BATCH("minBatch");
|
const std::string SQLChannel::PROP_MIN_BATCH("minBatch");
|
||||||
const std::string SQLChannel::PROP_MAX_BATCH("maxBatch");
|
const std::string SQLChannel::PROP_MAX_BATCH("maxBatch");
|
||||||
|
const std::string SQLChannel::PROP_MAX_SQL("maxSQL");
|
||||||
const std::string SQLChannel::PROP_BULK("bulk");
|
const std::string SQLChannel::PROP_BULK("bulk");
|
||||||
const std::string SQLChannel::PROP_THROW("throw");
|
const std::string SQLChannel::PROP_THROW("throw");
|
||||||
|
const std::string SQLChannel::PROP_DIRECTORY("directory");
|
||||||
const std::string SQLChannel::PROP_FILE("file");
|
const std::string SQLChannel::PROP_FILE("file");
|
||||||
|
const std::string SQLChannel::PROP_FLUSH("flush");
|
||||||
|
|
||||||
|
|
||||||
const std::string SQLChannel::SQL_INSERT_STMT = "INSERT INTO %s " \
|
const std::string SQLChannel::SQL_INSERT_STMT = "INSERT INTO %s " \
|
||||||
@ -56,22 +62,23 @@ const std::string SQLChannel::SQL_INSERT_STMT = "INSERT INTO %s " \
|
|||||||
|
|
||||||
|
|
||||||
SQLChannel::SQLChannel():
|
SQLChannel::SQLChannel():
|
||||||
_name("-"),
|
_name("SQLChannel"),
|
||||||
_table("T_POCO_LOG"),
|
|
||||||
_tableChanged(true),
|
_tableChanged(true),
|
||||||
_timeout(1000),
|
_timeout(1000),
|
||||||
_minBatch(DEFAULT_MIN_BATCH_SIZE),
|
_minBatch(DEFAULT_MIN_BATCH_SIZE),
|
||||||
_maxBatch(DEFAULT_MAX_BATCH_SIZE),
|
_maxBatch(DEFAULT_MAX_BATCH_SIZE),
|
||||||
|
_maxSQL(DEFAULT_MAX_SQL_SIZE),
|
||||||
_bulk(true),
|
_bulk(true),
|
||||||
_throw(false),
|
_throw(false),
|
||||||
_pid(),
|
_pid(),
|
||||||
_tid(),
|
_tid(),
|
||||||
_priority(),
|
_priority(),
|
||||||
|
_pLogThread(new Thread),
|
||||||
_reconnect(false),
|
_reconnect(false),
|
||||||
_running(false),
|
|
||||||
_stop(false),
|
_stop(false),
|
||||||
_logged(0)
|
_logged(0)
|
||||||
{
|
{
|
||||||
|
_pLogThread->start(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -81,7 +88,8 @@ SQLChannel::SQLChannel(const std::string& connector,
|
|||||||
const std::string& table,
|
const std::string& table,
|
||||||
int timeout,
|
int timeout,
|
||||||
int minBatch,
|
int minBatch,
|
||||||
int maxBatch) :
|
int maxBatch,
|
||||||
|
int maxSQL) :
|
||||||
_connector(connector),
|
_connector(connector),
|
||||||
_connect(connect),
|
_connect(connect),
|
||||||
_name(name),
|
_name(name),
|
||||||
@ -90,18 +98,18 @@ SQLChannel::SQLChannel(const std::string& connector,
|
|||||||
_timeout(timeout),
|
_timeout(timeout),
|
||||||
_minBatch(minBatch),
|
_minBatch(minBatch),
|
||||||
_maxBatch(maxBatch),
|
_maxBatch(maxBatch),
|
||||||
|
_maxSQL(maxSQL),
|
||||||
_bulk(false),
|
_bulk(false),
|
||||||
_throw(false),
|
_throw(false),
|
||||||
_pid(),
|
_pid(),
|
||||||
_tid(),
|
_tid(),
|
||||||
_priority(),
|
_priority(),
|
||||||
_pDBThread(new Thread),
|
_pLogThread(new Thread),
|
||||||
_reconnect(true),
|
_reconnect(true),
|
||||||
_running(false),
|
|
||||||
_stop(false),
|
_stop(false),
|
||||||
_logged(0)
|
_logged(0)
|
||||||
{
|
{
|
||||||
_pDBThread->start(*this);
|
_pLogThread->start(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -157,12 +165,13 @@ void SQLChannel::open()
|
|||||||
_pSession = new Session(_connector, _connect, _timeout / 1000);
|
_pSession = new Session(_connector, _connect, _timeout / 1000);
|
||||||
if (_pSession->hasProperty("maxFieldSize")) _pSession->setProperty("maxFieldSize", 8192);
|
if (_pSession->hasProperty("maxFieldSize")) _pSession->setProperty("maxFieldSize", 8192);
|
||||||
if (_pSession->hasProperty("autoBind")) _pSession->setFeature("autoBind", true);
|
if (_pSession->hasProperty("autoBind")) _pSession->setFeature("autoBind", true);
|
||||||
_logger.information("Connected to %s: %s", _connector, maskPwd());
|
if (!_stop) _logger.information("Connected to %s: %s", _connector, maskPwd());
|
||||||
|
else logLocal(Poco::format("Connected to %s: %s", _connector, maskPwd()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
catch (DataException& ex)
|
catch (const DataException& ex)
|
||||||
{
|
{
|
||||||
_logger.error(ex.displayText());
|
logLocal(ex.displayText());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_pSession = nullptr;
|
_pSession = nullptr;
|
||||||
@ -173,23 +182,35 @@ void SQLChannel::open()
|
|||||||
void SQLChannel::close()
|
void SQLChannel::close()
|
||||||
{
|
{
|
||||||
wait(_timeout);
|
wait(_timeout);
|
||||||
_pSession = nullptr;
|
if (_pSession)
|
||||||
|
{
|
||||||
|
_pSession->close();
|
||||||
|
_pSession = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SQLChannel::logLocal(const std::string& message, Message::Priority prio)
|
||||||
|
{
|
||||||
|
Message msg("SQLChannel"s, message, prio);
|
||||||
|
log(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLChannel::log(const Message& msg)
|
void SQLChannel::log(const Message& msg)
|
||||||
{
|
{
|
||||||
_logQueue.enqueueNotification(new LogNotification(msg));
|
_logQueue.enqueueNotification(new LogNotification(msg));
|
||||||
|
_event.set();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t SQLChannel::logSync()
|
size_t SQLChannel::logSync(bool flush)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return execSQL();
|
return execSQL(flush);
|
||||||
}
|
}
|
||||||
catch (Exception&)
|
catch (...)
|
||||||
{
|
{
|
||||||
if (_throw) throw;
|
if (_throw) throw;
|
||||||
}
|
}
|
||||||
@ -198,10 +219,10 @@ size_t SQLChannel::logSync()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SQLChannel::processOne(int minBatch)
|
bool SQLChannel::processBatch(int minBatch)
|
||||||
{
|
{
|
||||||
bool ret = false;
|
bool ret = false, flush = (minBatch == 0);
|
||||||
if (_logQueue.size())
|
while (_logQueue.size())
|
||||||
{
|
{
|
||||||
Notification::Ptr pN = _logQueue.dequeueNotification();
|
Notification::Ptr pN = _logQueue.dequeueNotification();
|
||||||
LogNotification::Ptr pLN = pN.cast<LogNotification>();
|
LogNotification::Ptr pLN = pN.cast<LogNotification>();
|
||||||
@ -218,11 +239,13 @@ bool SQLChannel::processOne(int minBatch)
|
|||||||
_priority.push_back(msg.getPriority());
|
_priority.push_back(msg.getPriority());
|
||||||
_text.push_back(msg.getText());
|
_text.push_back(msg.getText());
|
||||||
Poco::replaceInPlace(_text.back(), "'", "''");
|
Poco::replaceInPlace(_text.back(), "'", "''");
|
||||||
_dateTime.push_back(msg.getTime());
|
_dateTime.emplace_back(msg.getTime());
|
||||||
|
if ((_source.size() >= minBatch) || flush)
|
||||||
|
logSync(flush);
|
||||||
|
ret = true;
|
||||||
}
|
}
|
||||||
ret = true;
|
|
||||||
}
|
}
|
||||||
if (_source.size() >= _minBatch) logSync();
|
if (flush) logSync(flush);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -230,6 +253,7 @@ bool SQLChannel::processOne(int minBatch)
|
|||||||
|
|
||||||
void SQLChannel::run()
|
void SQLChannel::run()
|
||||||
{
|
{
|
||||||
|
_flushTimer.start();
|
||||||
long sleepTime = 100; // milliseconds
|
long sleepTime = 100; // milliseconds
|
||||||
while (!_stop)
|
while (!_stop)
|
||||||
{
|
{
|
||||||
@ -239,53 +263,286 @@ void SQLChannel::run()
|
|||||||
{
|
{
|
||||||
close();
|
close();
|
||||||
open();
|
open();
|
||||||
_reconnect = _pSession.isNull();
|
_reconnect = !_connector.empty() && _pSession.isNull();
|
||||||
if (_reconnect && sleepTime < 12800)
|
if (_reconnect && sleepTime < 12800)
|
||||||
sleepTime *= 2;
|
sleepTime *= 2;
|
||||||
}
|
}
|
||||||
processOne(_minBatch);
|
|
||||||
sleepTime = 100;
|
if (!_reconnect)
|
||||||
|
{
|
||||||
|
if (_logQueue.size()) processBatch(_minBatch);
|
||||||
|
if (shouldFlush()) processBatch();
|
||||||
|
sleepTime = 100;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Poco::Exception& ex)
|
catch (const Poco::Exception& ex)
|
||||||
{
|
{
|
||||||
_logger.error(ex.displayText());
|
if (!_stop)
|
||||||
|
_logger.error(ex.displayText());
|
||||||
|
else
|
||||||
|
logLocal(ex.displayText());
|
||||||
}
|
}
|
||||||
catch (std::exception& ex)
|
catch (const std::exception& ex)
|
||||||
{
|
{
|
||||||
_logger.error(ex.what());
|
if (!_stop)
|
||||||
|
_logger.error(ex.what());
|
||||||
|
else
|
||||||
|
logLocal(ex.what());
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
_logger.error("SQLChannel::run(): unknown exception");
|
if (!_stop)
|
||||||
|
_logger.error("SQLChannel::run(): unknown exception"s);
|
||||||
|
else
|
||||||
|
logLocal("SQLChannel::run(): unknown exception"s);
|
||||||
}
|
}
|
||||||
_running = true;
|
if (_stop)
|
||||||
Thread::sleep(100);
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_event.tryWait(sleepTime);
|
||||||
}
|
}
|
||||||
_running = false;
|
while (_logQueue.size() || _source.size())
|
||||||
|
processBatch();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLChannel::stop()
|
void SQLChannel::stop()
|
||||||
{
|
{
|
||||||
if (_pDBThread)
|
if (_pLogThread)
|
||||||
{
|
{
|
||||||
_reconnect = false;
|
_reconnect = false;
|
||||||
_stop = true;
|
_stop = true;
|
||||||
_pDBThread->join();
|
while (_pLogThread->isRunning())
|
||||||
while (_logQueue.size())
|
Thread::sleep(10);
|
||||||
processOne();
|
_pLogThread->join();
|
||||||
|
_pLogThread.reset();
|
||||||
|
_event.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SQLChannel::reconnect()
|
void SQLChannel::reconnect()
|
||||||
{
|
{
|
||||||
if (!_pDBThread)
|
|
||||||
{
|
|
||||||
_pDBThread.reset(new Thread);
|
|
||||||
_pDBThread->start(*this);
|
|
||||||
}
|
|
||||||
_reconnect = true;
|
_reconnect = true;
|
||||||
|
if (!_pLogThread)
|
||||||
|
{
|
||||||
|
_pLogThread = std::make_unique<Thread>();
|
||||||
|
_pLogThread->start(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t SQLChannel::logToFile(bool flush)
|
||||||
|
{
|
||||||
|
if (_source.empty()) return 0u;
|
||||||
|
|
||||||
|
static std::vector<std::string> names;
|
||||||
|
if (names.size() != _source.size())
|
||||||
|
names.resize(_source.size(), Poco::replace(_name, "'", "''"));
|
||||||
|
|
||||||
|
std::size_t n = 0, batch = 0;
|
||||||
|
|
||||||
|
AutoPtr<FileChannel> pFileChannel;
|
||||||
|
std::string file = _file;
|
||||||
|
if (!_pFileChannel && !_file.empty())
|
||||||
|
{
|
||||||
|
if (!Path(File(file).path()).isAbsolute())
|
||||||
|
file = _directory + file;
|
||||||
|
|
||||||
|
_pFileChannel = new FileChannel(file);
|
||||||
|
pFileChannel = _pFileChannel;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UUID uuid = UUIDGenerator::defaultGenerator().createRandom();
|
||||||
|
std::string filename(_directory);
|
||||||
|
filename.append(DateTimeFormatter::format(LocalDateTime(), "%Y%m%d%H%M%S%i.").append(uuid.toString()).append(".log.sql"s));
|
||||||
|
pFileChannel = new FileChannel(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream os;
|
||||||
|
auto doLog = [&]
|
||||||
|
{
|
||||||
|
Message msg(_source[0], os.str(), Message::PRIO_FATAL);
|
||||||
|
pFileChannel->log(msg);
|
||||||
|
n += batch;
|
||||||
|
_logged += batch;
|
||||||
|
_source.erase(_source.begin(), _source.begin()+batch);
|
||||||
|
_pid.erase(_pid.begin(), _pid.begin() + batch);
|
||||||
|
_thread.erase(_thread.begin(), _thread.begin() + batch);
|
||||||
|
_tid.erase(_tid.begin(), _tid.begin() + batch);
|
||||||
|
_priority.erase(_priority.begin(), _priority.begin() + batch);
|
||||||
|
_text.erase(_text.begin(), _text.begin() + batch);
|
||||||
|
_dateTime.erase(_dateTime.begin(), _dateTime.begin() + batch);
|
||||||
|
_flushTimer.restart();
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pFileChannel)
|
||||||
|
{
|
||||||
|
std::string sql;
|
||||||
|
Poco::format(sql, SQL_INSERT_STMT, _table, std::string());
|
||||||
|
std::stringstream tmp;
|
||||||
|
os << sql << '\n';
|
||||||
|
auto it = _source.begin();
|
||||||
|
auto end = _source.end();
|
||||||
|
int idx = 0;
|
||||||
|
for (; it != end; ++idx)
|
||||||
|
{
|
||||||
|
std::string dt = DateTimeFormatter::format(_dateTime[idx], "%Y-%m-%d %H:%M:%S.%i");
|
||||||
|
tmp.str("");
|
||||||
|
tmp << "('" << *it << "','" <<
|
||||||
|
names[idx] << "'," <<
|
||||||
|
_pid[idx] << ",'" <<
|
||||||
|
_thread[idx] << "'," <<
|
||||||
|
_tid[idx] << ',' <<
|
||||||
|
_priority[idx] << ",'" <<
|
||||||
|
_text[idx] << "','" <<
|
||||||
|
dt << "')";
|
||||||
|
|
||||||
|
if (++batch == _maxBatch || (os.str().length() + tmp.str().length()) >= _maxSQL)
|
||||||
|
{
|
||||||
|
os << ";\n";
|
||||||
|
doLog();
|
||||||
|
os.str(""); sql.clear();
|
||||||
|
Poco::format(sql, SQL_INSERT_STMT, _table, std::string());
|
||||||
|
os << sql << '\n' << tmp.str();
|
||||||
|
batch = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << tmp.str();
|
||||||
|
|
||||||
|
if (++it == end)
|
||||||
|
{
|
||||||
|
os << ";\n";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
os << ",\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((batch >= _minBatch) || flush) doLog();
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t SQLChannel::logToDB(bool flush)
|
||||||
|
{
|
||||||
|
if (_source.empty()) return 0u;
|
||||||
|
|
||||||
|
static std::vector<std::string> names;
|
||||||
|
if (names.size() != _source.size())
|
||||||
|
names.resize(_source.size(), Poco::replace(_name, "'", "''"));
|
||||||
|
static std::string placeholders = "(?,?,?,?,?,?,?,?)";
|
||||||
|
|
||||||
|
Poco::FastMutex::ScopedLock l(_mutex);
|
||||||
|
|
||||||
|
if (_tableChanged)
|
||||||
|
{
|
||||||
|
Poco::format(_sql, SQL_INSERT_STMT, _table, placeholders);
|
||||||
|
_tableChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t n = 0;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (_bulk)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
(*_pSession) << _sql,
|
||||||
|
use(_source, bulk),
|
||||||
|
use(names, bulk),
|
||||||
|
use(_pid, bulk),
|
||||||
|
use(_thread, bulk),
|
||||||
|
use(_tid, bulk),
|
||||||
|
use(_priority, bulk),
|
||||||
|
use(_text, bulk),
|
||||||
|
use(_dateTime, bulk), now;
|
||||||
|
}
|
||||||
|
// most likely bulk mode not supported, try again
|
||||||
|
catch (const Poco::InvalidAccessException&)
|
||||||
|
{
|
||||||
|
(*_pSession) << _sql,
|
||||||
|
use(_source),
|
||||||
|
use(names),
|
||||||
|
use(_pid),
|
||||||
|
use(_thread),
|
||||||
|
use(_tid),
|
||||||
|
use(_priority),
|
||||||
|
use(_text),
|
||||||
|
use(_dateTime), now;
|
||||||
|
_bulk = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(*_pSession) << _sql,
|
||||||
|
use(_source),
|
||||||
|
use(names),
|
||||||
|
use(_pid),
|
||||||
|
use(_thread),
|
||||||
|
use(_tid),
|
||||||
|
use(_priority),
|
||||||
|
use(_text),
|
||||||
|
use(_dateTime), now;
|
||||||
|
}
|
||||||
|
n = _source.size();
|
||||||
|
}
|
||||||
|
catch (const Poco::Exception& ex)
|
||||||
|
{
|
||||||
|
logLocal(ex.displayText());
|
||||||
|
close();
|
||||||
|
_reconnect = true;
|
||||||
|
}
|
||||||
|
catch (const std::exception& ex)
|
||||||
|
{
|
||||||
|
logLocal(ex.what());
|
||||||
|
close();
|
||||||
|
_reconnect = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n)
|
||||||
|
{
|
||||||
|
_logged += n;
|
||||||
|
_source.erase(_source.begin(), _source.begin() + n);
|
||||||
|
_pid.erase(_pid.begin(), _pid.begin() + n);
|
||||||
|
_thread.erase(_thread.begin(), _thread.begin() + n);
|
||||||
|
_tid.erase(_tid.begin(), _tid.begin() + n);
|
||||||
|
_priority.erase(_priority.begin(), _priority.begin() + n);
|
||||||
|
_text.erase(_text.begin(), _text.begin() + n);
|
||||||
|
_dateTime.erase(_dateTime.begin(), _dateTime.begin() + n);
|
||||||
|
_flushTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t SQLChannel::execSQL(bool flush)
|
||||||
|
{
|
||||||
|
if (!_connector.empty() && (!_pSession || !_pSession->isConnected())) open();
|
||||||
|
if (_pArchiveStrategy) _pArchiveStrategy->archive();
|
||||||
|
|
||||||
|
size_t n = _pSession ? logToDB(flush) : logToFile(flush);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::size_t SQLChannel::wait(int ms)
|
||||||
|
{
|
||||||
|
Stopwatch sw;
|
||||||
|
sw.start();
|
||||||
|
while (_logQueue.size())
|
||||||
|
{
|
||||||
|
Thread::sleep(10);
|
||||||
|
if (ms && sw.elapsed() * 1000 > ms)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return _logQueue.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -319,7 +576,7 @@ void SQLChannel::setProperty(const std::string& name, const std::string& value)
|
|||||||
{
|
{
|
||||||
if (value.empty())
|
if (value.empty())
|
||||||
{
|
{
|
||||||
_pArchiveStrategy = 0;
|
_pArchiveStrategy = nullptr;
|
||||||
}
|
}
|
||||||
else if (_pArchiveStrategy)
|
else if (_pArchiveStrategy)
|
||||||
{
|
{
|
||||||
@ -336,7 +593,7 @@ void SQLChannel::setProperty(const std::string& name, const std::string& value)
|
|||||||
{
|
{
|
||||||
if (value.empty() || "forever" == value)
|
if (value.empty() || "forever" == value)
|
||||||
{
|
{
|
||||||
_pArchiveStrategy = 0;
|
_pArchiveStrategy = nullptr;
|
||||||
}
|
}
|
||||||
else if (_pArchiveStrategy)
|
else if (_pArchiveStrategy)
|
||||||
{
|
{
|
||||||
@ -374,6 +631,11 @@ void SQLChannel::setProperty(const std::string& name, const std::string& value)
|
|||||||
throw Poco::InvalidArgumentException(Poco::format("SQLChannel::setProperty(%s,%s)", name, value));
|
throw Poco::InvalidArgumentException(Poco::format("SQLChannel::setProperty(%s,%s)", name, value));
|
||||||
_maxBatch = maxBatch;
|
_maxBatch = maxBatch;
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_MAX_SQL)
|
||||||
|
{
|
||||||
|
int maxSQL = NumberParser::parse(value);
|
||||||
|
_maxSQL = maxSQL;
|
||||||
|
}
|
||||||
else if (name == PROP_BULK)
|
else if (name == PROP_BULK)
|
||||||
{
|
{
|
||||||
_bulk = isTrue(value);
|
_bulk = isTrue(value);
|
||||||
@ -382,10 +644,24 @@ void SQLChannel::setProperty(const std::string& name, const std::string& value)
|
|||||||
{
|
{
|
||||||
_throw = isTrue(value);
|
_throw = isTrue(value);
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_DIRECTORY)
|
||||||
|
{
|
||||||
|
std::string dir = value;
|
||||||
|
if (!Path(File(dir).path()).isAbsolute())
|
||||||
|
{
|
||||||
|
Path d(dir);
|
||||||
|
dir = d.makeDirectory().makeAbsolute().toString();
|
||||||
|
}
|
||||||
|
_directory = dir;
|
||||||
|
}
|
||||||
else if (name == PROP_FILE)
|
else if (name == PROP_FILE)
|
||||||
{
|
{
|
||||||
_file = value;
|
_file = value;
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_FLUSH)
|
||||||
|
{
|
||||||
|
_flush.store(NumberParser::parse(value));
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Channel::setProperty(name, value);
|
Channel::setProperty(name, value);
|
||||||
@ -434,6 +710,10 @@ std::string SQLChannel::getProperty(const std::string& name) const
|
|||||||
{
|
{
|
||||||
return std::to_string(_maxBatch);
|
return std::to_string(_maxBatch);
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_MAX_SQL)
|
||||||
|
{
|
||||||
|
return std::to_string(_maxSQL);
|
||||||
|
}
|
||||||
else if (name == PROP_BULK)
|
else if (name == PROP_BULK)
|
||||||
{
|
{
|
||||||
if (_bulk) return "true";
|
if (_bulk) return "true";
|
||||||
@ -444,10 +724,18 @@ std::string SQLChannel::getProperty(const std::string& name) const
|
|||||||
if (_throw) return "true";
|
if (_throw) return "true";
|
||||||
else return "false";
|
else return "false";
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_DIRECTORY)
|
||||||
|
{
|
||||||
|
return _directory;
|
||||||
|
}
|
||||||
else if (name == PROP_FILE)
|
else if (name == PROP_FILE)
|
||||||
{
|
{
|
||||||
return _file;
|
return _file;
|
||||||
}
|
}
|
||||||
|
else if (name == PROP_FLUSH)
|
||||||
|
{
|
||||||
|
return std::to_string(_flush);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return Channel::getProperty(name);
|
return Channel::getProperty(name);
|
||||||
@ -455,189 +743,6 @@ std::string SQLChannel::getProperty(const std::string& name) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t SQLChannel::logTofile(AutoPtr<FileChannel>& pFileChannel, const std::string& fileName, bool clear)
|
|
||||||
{
|
|
||||||
static std::vector<std::string> names;
|
|
||||||
if (names.size() != _source.size())
|
|
||||||
names.resize(_source.size(), Poco::replace(_name, "'", "''"));
|
|
||||||
|
|
||||||
std::size_t n = 0;
|
|
||||||
|
|
||||||
if (!pFileChannel) pFileChannel = new FileChannel(fileName);
|
|
||||||
if (pFileChannel)
|
|
||||||
{
|
|
||||||
std::string sql;
|
|
||||||
Poco::format(sql, SQL_INSERT_STMT, _table, std::string());
|
|
||||||
std::stringstream os;
|
|
||||||
os << sql << '\n';
|
|
||||||
auto it = _source.begin();
|
|
||||||
auto end = _source.end();
|
|
||||||
int idx = 0, batch = 0;
|
|
||||||
for (; it != end; ++idx)
|
|
||||||
{
|
|
||||||
std::string dt = Poco::DateTimeFormatter::format(_dateTime[idx], "%Y-%m-%d %H:%M:%S.%i");
|
|
||||||
os << "('" << *it << "','" <<
|
|
||||||
names[idx] << "'," <<
|
|
||||||
_pid[idx] << ",'" <<
|
|
||||||
_thread[idx] << "'," <<
|
|
||||||
_tid[idx] << ',' <<
|
|
||||||
_priority[idx] << ",'" <<
|
|
||||||
_text[idx] << "','" <<
|
|
||||||
dt << "')";
|
|
||||||
if (++batch == _maxBatch)
|
|
||||||
{
|
|
||||||
os << ";\n";
|
|
||||||
Message msg(_source[0], os.str(), Message::PRIO_ERROR);
|
|
||||||
pFileChannel->log(msg);
|
|
||||||
os.str(""); sql.clear();
|
|
||||||
Poco::format(sql, SQL_INSERT_STMT, _table, std::string());
|
|
||||||
batch = 0;
|
|
||||||
}
|
|
||||||
if (++it == end)
|
|
||||||
{
|
|
||||||
os << ";\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
os << ",\n";
|
|
||||||
}
|
|
||||||
Message msg(_source[0], os.str(), Message::PRIO_ERROR);
|
|
||||||
pFileChannel->log(msg);
|
|
||||||
n = _source.size();
|
|
||||||
if (clear && n)
|
|
||||||
{
|
|
||||||
_source.clear();
|
|
||||||
_pid.clear();
|
|
||||||
_thread.clear();
|
|
||||||
_tid.clear();
|
|
||||||
_priority.clear();
|
|
||||||
_text.clear();
|
|
||||||
_dateTime.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
size_t SQLChannel::execSQL()
|
|
||||||
{
|
|
||||||
static std::vector<std::string> names;
|
|
||||||
if (names.size() != _source.size())
|
|
||||||
names.resize(_source.size(), Poco::replace(_name, "'", "''"));
|
|
||||||
static std::string placeholders = "(?,?,?,?,?,?,?,?)";
|
|
||||||
|
|
||||||
Poco::FastMutex::ScopedLock l(_mutex);
|
|
||||||
|
|
||||||
if (_tableChanged)
|
|
||||||
{
|
|
||||||
Poco::format(_sql, SQL_INSERT_STMT, _table, placeholders);
|
|
||||||
_tableChanged = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_pSession || !_pSession->isConnected()) open();
|
|
||||||
if (_pArchiveStrategy) _pArchiveStrategy->archive();
|
|
||||||
|
|
||||||
size_t n = 0;
|
|
||||||
if (_pSession)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (_bulk)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
(*_pSession) << _sql,
|
|
||||||
use(_source, bulk),
|
|
||||||
use(names, bulk),
|
|
||||||
use(_pid, bulk),
|
|
||||||
use(_thread, bulk),
|
|
||||||
use(_tid, bulk),
|
|
||||||
use(_priority, bulk),
|
|
||||||
use(_text, bulk),
|
|
||||||
use(_dateTime, bulk), now;
|
|
||||||
}
|
|
||||||
// most likely bulk mode not supported,
|
|
||||||
// log and try again
|
|
||||||
catch (Poco::InvalidAccessException& ex)
|
|
||||||
{
|
|
||||||
_logger.log(ex);
|
|
||||||
(*_pSession) << _sql,
|
|
||||||
use(_source),
|
|
||||||
use(names),
|
|
||||||
use(_pid),
|
|
||||||
use(_thread),
|
|
||||||
use(_tid),
|
|
||||||
use(_priority),
|
|
||||||
use(_text),
|
|
||||||
use(_dateTime), now;
|
|
||||||
_bulk = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
(*_pSession) << _sql,
|
|
||||||
use(_source),
|
|
||||||
use(names),
|
|
||||||
use(_pid),
|
|
||||||
use(_thread),
|
|
||||||
use(_tid),
|
|
||||||
use(_priority),
|
|
||||||
use(_text),
|
|
||||||
use(_dateTime), now;
|
|
||||||
}
|
|
||||||
n = _source.size();
|
|
||||||
}
|
|
||||||
catch (Poco::Exception& ex)
|
|
||||||
{
|
|
||||||
_logger.error(ex.displayText());
|
|
||||||
if (!_file.empty())
|
|
||||||
n = logTofile(_pFileChannel, _file);
|
|
||||||
close();
|
|
||||||
_reconnect = true;
|
|
||||||
}
|
|
||||||
catch (std::exception& ex)
|
|
||||||
{
|
|
||||||
_logger.error(ex.what());
|
|
||||||
if (!_file.empty())
|
|
||||||
n = logTofile(_pFileChannel, _file);
|
|
||||||
close();
|
|
||||||
_reconnect = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!_file.empty())
|
|
||||||
n = logTofile(_pFileChannel, _file);
|
|
||||||
}
|
|
||||||
if (n)
|
|
||||||
{
|
|
||||||
_logged += n;
|
|
||||||
_source.clear();
|
|
||||||
_pid.clear();
|
|
||||||
_thread.clear();
|
|
||||||
_tid.clear();
|
|
||||||
_priority.clear();
|
|
||||||
_text.clear();
|
|
||||||
_dateTime.clear();
|
|
||||||
}
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::size_t SQLChannel::wait(int ms)
|
|
||||||
{
|
|
||||||
Stopwatch sw;
|
|
||||||
sw.start();
|
|
||||||
int processed = _logQueue.size();
|
|
||||||
while (_logQueue.size())
|
|
||||||
{
|
|
||||||
Thread::sleep(10);
|
|
||||||
if (ms && sw.elapsed() * 1000 > ms)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return processed - _logQueue.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SQLChannel::registerChannel()
|
void SQLChannel::registerChannel()
|
||||||
{
|
{
|
||||||
Poco::LoggingFactory::defaultFactory().registerChannelClass("SQLChannel",
|
Poco::LoggingFactory::defaultFactory().registerChannelClass("SQLChannel",
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "Poco/Data/Column.h"
|
#include "Poco/Data/Column.h"
|
||||||
#include "Poco/Data/Date.h"
|
#include "Poco/Data/Date.h"
|
||||||
#include "Poco/Data/Time.h"
|
#include "Poco/Data/Time.h"
|
||||||
|
#include "Poco/Data/SQLChannel.h"
|
||||||
#include "Poco/Data/SimpleRowFormatter.h"
|
#include "Poco/Data/SimpleRowFormatter.h"
|
||||||
#include "Poco/Data/JSONRowFormatter.h"
|
#include "Poco/Data/JSONRowFormatter.h"
|
||||||
#include "Poco/Data/DataException.h"
|
#include "Poco/Data/DataException.h"
|
||||||
@ -27,12 +28,18 @@
|
|||||||
#include "Poco/BinaryReader.h"
|
#include "Poco/BinaryReader.h"
|
||||||
#include "Poco/BinaryWriter.h"
|
#include "Poco/BinaryWriter.h"
|
||||||
#include "Poco/DateTime.h"
|
#include "Poco/DateTime.h"
|
||||||
|
#include "Poco/Stopwatch.h"
|
||||||
#include "Poco/Types.h"
|
#include "Poco/Types.h"
|
||||||
#include "Poco/Dynamic/Var.h"
|
#include "Poco/Dynamic/Var.h"
|
||||||
#include "Poco/Data/DynamicLOB.h"
|
#include "Poco/Data/DynamicLOB.h"
|
||||||
#include "Poco/Data/DynamicDateTime.h"
|
#include "Poco/Data/DynamicDateTime.h"
|
||||||
#include "Poco/Latin1Encoding.h"
|
#include "Poco/Latin1Encoding.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
|
#include "Poco/DirectoryIterator.h"
|
||||||
|
#include "Poco/Glob.h"
|
||||||
|
#include "Poco/File.h"
|
||||||
|
#include "Poco/Path.h"
|
||||||
|
#include <string>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
@ -40,46 +47,10 @@
|
|||||||
|
|
||||||
|
|
||||||
using namespace Poco;
|
using namespace Poco;
|
||||||
|
using Poco::Dynamic::Var;
|
||||||
using namespace Poco::Data;
|
using namespace Poco::Data;
|
||||||
using namespace Poco::Data::Keywords;
|
using namespace Poco::Data::Keywords;
|
||||||
|
using namespace std::string_literals;
|
||||||
|
|
||||||
using Poco::BinaryReader;
|
|
||||||
using Poco::BinaryWriter;
|
|
||||||
using Poco::UInt32;
|
|
||||||
using Poco::Int64;
|
|
||||||
using Poco::UInt64;
|
|
||||||
using Poco::DateTime;
|
|
||||||
using Poco::Latin1Encoding;
|
|
||||||
using Poco::Dynamic::Var;
|
|
||||||
using Poco::InvalidAccessException;
|
|
||||||
using Poco::IllegalStateException;
|
|
||||||
using Poco::RangeException;
|
|
||||||
using Poco::NotFoundException;
|
|
||||||
using Poco::InvalidArgumentException;
|
|
||||||
using Poco::NotImplementedException;
|
|
||||||
using Poco::Data::Session;
|
|
||||||
using Poco::Data::SessionFactory;
|
|
||||||
using Poco::Data::Statement;
|
|
||||||
using Poco::Data::NotSupportedException;
|
|
||||||
using Poco::Data::CLOB;
|
|
||||||
using Poco::Data::CLOBInputStream;
|
|
||||||
using Poco::Data::CLOBOutputStream;
|
|
||||||
using Poco::Data::MetaColumn;
|
|
||||||
using Poco::Data::Column;
|
|
||||||
using Poco::Data::Row;
|
|
||||||
using Poco::Data::RowFormatter;
|
|
||||||
using Poco::Data::SimpleRowFormatter;
|
|
||||||
using Poco::Data::JSONRowFormatter;
|
|
||||||
using Poco::Data::Date;
|
|
||||||
using Poco::Data::Time;
|
|
||||||
using Poco::Data::AbstractExtractor;
|
|
||||||
using Poco::Data::AbstractExtraction;
|
|
||||||
using Poco::Data::AbstractExtractionVec;
|
|
||||||
using Poco::Data::AbstractExtractionVecVec;
|
|
||||||
using Poco::Data::AbstractBinding;
|
|
||||||
using Poco::Data::AbstractBindingVec;
|
|
||||||
using Poco::Data::NotConnectedException;
|
|
||||||
|
|
||||||
|
|
||||||
DataTest::DataTest(const std::string& name): CppUnit::TestCase(name)
|
DataTest::DataTest(const std::string& name): CppUnit::TestCase(name)
|
||||||
@ -1570,6 +1541,65 @@ void DataTest::testSQLParse()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DataTest::testSQLChannel()
|
||||||
|
{
|
||||||
|
std::string dir = Path::tempHome();
|
||||||
|
AutoPtr<SQLChannel> pChannel = new SQLChannel();
|
||||||
|
pChannel->setProperty("directory", dir);
|
||||||
|
Stopwatch sw; sw.start();
|
||||||
|
while (!pChannel->isRunning())
|
||||||
|
{
|
||||||
|
Thread::sleep(10);
|
||||||
|
if (sw.elapsedSeconds() > 3)
|
||||||
|
fail("SQLChannel timed out");
|
||||||
|
}
|
||||||
|
|
||||||
|
Glob g("*.log.sql");
|
||||||
|
{
|
||||||
|
DirectoryIterator it(dir);
|
||||||
|
DirectoryIterator end;
|
||||||
|
while (it != end)
|
||||||
|
{
|
||||||
|
if (g.match(it->path()))
|
||||||
|
{
|
||||||
|
File(it->path()).remove();
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
constexpr int mcount{10};
|
||||||
|
constexpr int batch{3};
|
||||||
|
pChannel->setProperty("minBatch", std::to_string(batch));
|
||||||
|
constexpr int flush{1};
|
||||||
|
pChannel->setProperty("flush", std::to_string(flush));
|
||||||
|
assertEqual(flush, NumberParser::parse(pChannel->getProperty("flush")));
|
||||||
|
for (int i = 0; i < mcount; i++)
|
||||||
|
{
|
||||||
|
Message msgInfA("InformationSource", Poco::format("%d Informational sync message", i), Message::PRIO_INFORMATION);
|
||||||
|
pChannel->log(msgInfA);
|
||||||
|
}
|
||||||
|
Thread::sleep(2000*flush); // give it time to flush
|
||||||
|
auto logged = pChannel->logged();
|
||||||
|
assertEqual(mcount, logged);
|
||||||
|
pChannel.reset();
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
DirectoryIterator it(dir);
|
||||||
|
DirectoryIterator end;
|
||||||
|
while (it != end)
|
||||||
|
{
|
||||||
|
if (g.match(it->path()))
|
||||||
|
{
|
||||||
|
++count;
|
||||||
|
File(it->path()).remove();
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
assertEqual(count, (mcount / batch) + (mcount % batch));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DataTest::setUp()
|
void DataTest::setUp()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -1603,6 +1633,7 @@ CppUnit::Test* DataTest::suite()
|
|||||||
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
CppUnit_addTest(pSuite, DataTest, testExternalBindingAndExtraction);
|
||||||
CppUnit_addTest(pSuite, DataTest, testTranscode);
|
CppUnit_addTest(pSuite, DataTest, testTranscode);
|
||||||
CppUnit_addTest(pSuite, DataTest, testSQLParse);
|
CppUnit_addTest(pSuite, DataTest, testSQLParse);
|
||||||
|
CppUnit_addTest(pSuite, DataTest, testSQLChannel);
|
||||||
|
|
||||||
return pSuite;
|
return pSuite;
|
||||||
}
|
}
|
||||||
|
@ -46,6 +46,7 @@ public:
|
|||||||
void testExternalBindingAndExtraction();
|
void testExternalBindingAndExtraction();
|
||||||
void testTranscode();
|
void testTranscode();
|
||||||
void testSQLParse();
|
void testSQLParse();
|
||||||
|
void testSQLChannel();
|
||||||
|
|
||||||
void setUp();
|
void setUp();
|
||||||
void tearDown();
|
void tearDown();
|
||||||
|
@ -122,6 +122,37 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class JoinRunnable : public Runnable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
JoinRunnable() : _stop(false), _running(false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
_running = true;
|
||||||
|
while (!_stop)
|
||||||
|
Thread::sleep(100);
|
||||||
|
_running = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop()
|
||||||
|
{
|
||||||
|
_stop = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool running() const
|
||||||
|
{
|
||||||
|
return _running;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic<bool> _stop;
|
||||||
|
std::atomic<bool> _running;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class TrySleepRunnable : public Runnable
|
class TrySleepRunnable : public Runnable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -268,7 +299,7 @@ void ThreadTest::testThreads()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadTest::testJoin()
|
void ThreadTest::testTryJoin()
|
||||||
{
|
{
|
||||||
Thread thread;
|
Thread thread;
|
||||||
MyRunnable r;
|
MyRunnable r;
|
||||||
@ -283,6 +314,22 @@ void ThreadTest::testJoin()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ThreadTest::testJoin()
|
||||||
|
{
|
||||||
|
Thread thread;
|
||||||
|
JoinRunnable r;
|
||||||
|
assertTrue(!thread.isRunning());
|
||||||
|
thread.start(r);
|
||||||
|
Thread::sleep(200);
|
||||||
|
assertTrue(thread.isRunning());
|
||||||
|
assertTrue(!thread.tryJoin(100));
|
||||||
|
r.stop();
|
||||||
|
thread.join();
|
||||||
|
assertTrue(!thread.isRunning());
|
||||||
|
assertTrue(!r.running());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void ThreadTest::testNotJoin()
|
void ThreadTest::testNotJoin()
|
||||||
{
|
{
|
||||||
Thread thread;
|
Thread thread;
|
||||||
@ -512,6 +559,7 @@ CppUnit::Test* ThreadTest::suite()
|
|||||||
CppUnit_addTest(pSuite, ThreadTest, testNamedThread);
|
CppUnit_addTest(pSuite, ThreadTest, testNamedThread);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testCurrent);
|
CppUnit_addTest(pSuite, ThreadTest, testCurrent);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testThreads);
|
CppUnit_addTest(pSuite, ThreadTest, testThreads);
|
||||||
|
CppUnit_addTest(pSuite, ThreadTest, testTryJoin);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testJoin);
|
CppUnit_addTest(pSuite, ThreadTest, testJoin);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testNotJoin);
|
CppUnit_addTest(pSuite, ThreadTest, testNotJoin);
|
||||||
CppUnit_addTest(pSuite, ThreadTest, testNotRun);
|
CppUnit_addTest(pSuite, ThreadTest, testNotRun);
|
||||||
|
@ -28,6 +28,7 @@ public:
|
|||||||
void testNamedThread();
|
void testNamedThread();
|
||||||
void testCurrent();
|
void testCurrent();
|
||||||
void testThreads();
|
void testThreads();
|
||||||
|
void testTryJoin();
|
||||||
void testJoin();
|
void testJoin();
|
||||||
void testNotJoin();
|
void testNotJoin();
|
||||||
void testNotRun();
|
void testNotRun();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user