1 //
2 // ArchiveStrategy.cpp
3 //
4 // Library: Data
5 // Package: Logging
6 // Module:  ArchiveStrategy
7 //
8 // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
9 // and Contributors.
10 //
11 // SPDX-License-Identifier:	BSL-1.0
12 //
13 
14 
15 #include "Poco/Data/ArchiveStrategy.h"
16 #include "Poco/Ascii.h"
17 
18 namespace Poco {
19 namespace Data {
20 
21 
22 using namespace Keywords;
23 
24 //
25 // ArchiveStrategy
26 //
27 
28 
29 const std::string ArchiveStrategy::DEFAULT_ARCHIVE_DESTINATION = "T_POCO_LOG_ARCHIVE";
30 
31 
ArchiveStrategy(const std::string & connector,const std::string & connect,const std::string & source,const std::string & destination)32 ArchiveStrategy::ArchiveStrategy(const std::string& connector,
33 	const std::string& connect,
34 	const std::string& source,
35 	const std::string& destination):
36 	_connector(connector),
37 	_connect(connect),
38 	_source(source),
39 	_destination(destination)
40 {
41 	open();
42 }
43 
44 
~ArchiveStrategy()45 ArchiveStrategy::~ArchiveStrategy()
46 {
47 }
48 
49 
open()50 void ArchiveStrategy::open()
51 {
52 	if (_connector.empty() || _connect.empty())
53 		throw IllegalStateException("Connector and connect string must be non-empty.");
54 
55 	_pSession = new Session(_connector, _connect);
56 }
57 
58 
59 //
60 // ArchiveByAgeStrategy
61 //
62 
63 
ArchiveByAgeStrategy(const std::string & connector,const std::string & connect,const std::string & sourceTable,const std::string & destinationTable)64 ArchiveByAgeStrategy::ArchiveByAgeStrategy(const std::string& connector,
65 	const std::string& connect,
66 	const std::string& sourceTable,
67 	const std::string& destinationTable):
68 	ArchiveStrategy(connector, connect, sourceTable, destinationTable)
69 {
70 	initStatements();
71 }
72 
73 
~ArchiveByAgeStrategy()74 ArchiveByAgeStrategy::~ArchiveByAgeStrategy()
75 {
76 }
77 
78 
archive()79 void ArchiveByAgeStrategy::archive()
80 {
81 	if (!session().isConnected()) open();
82 
83 	DateTime now;
84 	_archiveDateTime = now - _maxAge;
85 	getCountStatement().execute();
86 	if (_archiveCount > 0)
87 	{
88 		getCopyStatement().execute();
89 		getDeleteStatement().execute();
90 	}
91 }
92 
93 
initStatements()94 void ArchiveByAgeStrategy::initStatements()
95 {
96 	std::string src = getSource();
97 	std::string dest = getDestination();
98 
99 	setCountStatement();
100 	_archiveCount = 0;
101 	std::string sql;
102 	Poco::format(sql, "SELECT COUNT(*) FROM %s WHERE DateTime < ?", src);
103 	getCountStatement() << sql, into(_archiveCount), use(_archiveDateTime);
104 
105 	setCopyStatement();
106 	sql.clear();
107 	Poco::format(sql, "INSERT INTO %s SELECT * FROM %s WHERE DateTime < ?", dest, src);
108 	getCopyStatement() << sql, use(_archiveDateTime);
109 
110 	setDeleteStatement();
111 	sql.clear();
112 	Poco::format(sql, "DELETE FROM %s WHERE DateTime < ?", src);
113 	getDeleteStatement() << sql, use(_archiveDateTime);
114 }
115 
116 
setThreshold(const std::string & age)117 void ArchiveByAgeStrategy::setThreshold(const std::string& age)
118 {
119 	std::string::const_iterator it  = age.begin();
120 	std::string::const_iterator end = age.end();
121 	int n = 0;
122 	while (it != end && Ascii::isSpace(*it)) ++it;
123 	while (it != end && Ascii::isDigit(*it)) { n *= 10; n += *it++ - '0'; }
124 	while (it != end && Ascii::isSpace(*it)) ++it;
125 	std::string unit;
126 	while (it != end && Ascii::isAlpha(*it)) unit += *it++;
127 
128 	Timespan::TimeDiff factor = Timespan::SECONDS;
129 	if (unit == "minutes")
130 		factor = Timespan::MINUTES;
131 	else if (unit == "hours")
132 		factor = Timespan::HOURS;
133 	else if (unit == "days")
134 		factor = Timespan::DAYS;
135 	else if (unit == "weeks")
136 		factor = 7*Timespan::DAYS;
137 	else if (unit == "months")
138 		factor = 30*Timespan::DAYS;
139 	else if (unit != "seconds")
140 		throw InvalidArgumentException("setMaxAge", age);
141 
142 	_maxAge = factor * n;
143 }
144 
145 
146 } } // namespace Poco::Data
147