53#define FREE(x) { if (x) free(x); (x) = NULL; }
67 const char*
sign =
"";
106 char c =
'0' + (
char)(
i%10);
131 const char* s = event_name;
132 for (
int j=0; s[
j];
j++) {
188 for (
int i=0; s[
i]!=0;
i++) {
205 for (
int i=0; s[
i]!=0;
i++) {
249 "xxxINVALIDxxxARRAY",
250 "xxxINVALIDxxxSTRUCT",
271 "xxxINVALIDxxxARRAY",
272 "xxxINVALIDxxxSTRUCT",
293 "xxxINVALIDxxxARRAY",
294 "xxxINVALIDxxxSTRUCT",
320 cm_msg(
MERROR,
"SqlHistory",
"Cannot use this SQL database, incompatible column names: created column type [%s] is reported with column type [%s]",
index_type,
col_type->c_str());
357 cm_msg(
MERROR,
"SqlHistory",
"Cannot use this SQL database, incompatible column names: created column type [%s] is reported with column type [%s]",
index_type,
col_type->c_str());
365 for (
int tid=0; tid<
TID_LAST; tid++)
369 printf(
"sql2midasType: Cannot convert SQL data type \'%s\' to a MIDAS data type!\n",
name);
384 printf(
"sql2midasType: Cannot convert SQL data type \'%s\' to a MIDAS data type!\n",
name);
439 time_t* last_written) = 0;
469 for (
size_t i=0;
i<
fData.size();
i++)
478 for (
size_t i=0;
i<
fData.size();
i++)
552 printf(
"find_event: All schema for event %s: (total %zu)\n", event_name,
fData.size());
554 for (
size_t i=0;
i<
fData.size();
i++) {
563 printf(
"find_event: Found %d schemas for event %s\n",
found, event_name);
569 for (
size_t i=0;
i<
fData.size();
i++) {
590 for (
size_t i=0;
i<
fData.size();
i++) {
652 virtual int Exec(
const char* table_name,
const char*
sql) = 0;
656 virtual int Prepare(
const char* table_name,
const char*
sql) = 0;
674 virtual std::string
QuoteId(
const char* s) = 0;
797 for (
size_t j=0;
j<
nv;
j++)
798 printf(
" %zu: name [%s], type [%s] tid %d, n_data %d, n_bytes %d, offset %d\n",
j, this->
fVariables[
j].name.c_str(),
rpc_tid_name(this->
fVariables[
j].
type), this->
fVariables[
j].type, this->
fVariables[
j].n_data, this->
fVariables[
j].n_bytes, this->
fOffsets[
j]);
804 printf(
"event [%s], sql_table [%s], time %s..%s, %zu variables, %zu bytes\n", this->
fEventName.c_str(),
this->fTableName.c_str(),
TimeToString(this->
fTimeFrom).
c_str(),
TimeToString(this->
fTimeTo).
c_str(), nv,
fNumBytes);
806 for (
size_t j=0;
j<
nv;
j++) {
818 printf(
"event [%s], file_name [%s], time %s..%s, %zu variables, %zu bytes, dat_offset %jd, record_size %zu\n", this->
fEventName.c_str(),
this->fFileName.c_str(),
TimeToString(this->
fTimeFrom).
c_str(),
TimeToString(this->
fTimeTo).
c_str(), nv,
fNumBytes, (
intmax_t)
fDataOffset,
fRecordSize);
820 for (
size_t j=0;
j<
nv;
j++)
821 printf(
" %zu: name [%s], type [%s] tid %d, n_data %d, n_bytes %d, offset %d\n",
j, this->
fVariables[
j].name.c_str(),
rpc_tid_name(this->
fVariables[
j].
type), this->
fVariables[
j].type, this->
fVariables[
j].n_data, this->
fVariables[
j].n_bytes, this->
fOffsets[
j]);
843 std::string fConnectString;
870 int Exec(
const char* table_name,
const char*
sql);
873 int Prepare(
const char* table_name,
const char*
sql);
887 std::string
QuoteId(
const char* s);
901 fTransactionPerTable =
false;
930 std::string user_name;
945 char* s =
fgets(buf,
sizeof(buf),
fp);
982 printf(
"Mysql::Connect: connecting to server [%s] port %d, unix socket [%s], database [%s], user [%s], password [%s], buffer [%zu]\n",
host_name.c_str(),
tcp_port,
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
user_password.c_str(),
fMaxDisconnected);
994 cm_msg(
MERROR,
"Mysql::Connect",
"mysql_real_connect() to host [%s], port %d, unix socket [%s], database [%s], user [%s], password [%s]: error %d (%s)",
host_name.c_str(),
tcp_port,
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
"xxx",
mysql_errno(
fMysql),
mysql_error(
fMysql));
1005 status = Exec(
"(notable)",
"SET SESSION sql_mode='ANSI'");
1007 cm_msg(
MERROR,
"Mysql::Connect",
"Cannot set ANSI mode, nothing will work");
1013 cm_msg(
MINFO,
"Mysql::Connect",
"Connected to a MySQL database on host [%s], port %d, unix socket [%s], database [%s], user [%s], password [%s], buffer %zu",
host_name.c_str(),
tcp_port,
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
"xxx",
fMaxDisconnected);
1017 fIsConnected =
true;
1040int Mysql::Disconnect()
1056 fIsConnected =
false;
1060bool Mysql::IsConnected()
1062 return fIsConnected;
1065int Mysql::OpenTransaction(
const char* table_name)
1067 return Exec(table_name,
"START TRANSACTION");
1071int Mysql::CommitTransaction(
const char* table_name)
1073 Exec(table_name,
"COMMIT");
1077int Mysql::RollbackTransaction(
const char* table_name)
1079 Exec(table_name,
"ROLLBACK");
1083int Mysql::ListTables(std::vector<std::string> *
plist)
1089 printf(
"Mysql::ListTables!\n");
1106 std::string
tn = GetText(0);
1115int Mysql::ListColumns(
const char* table_name, std::vector<std::string> *
plist)
1121 printf(
"Mysql::ListColumns for table \'%s\'\n", table_name);
1126 cmd +=
"SHOW COLUMNS FROM ";
1127 cmd += QuoteId(table_name);
1130 status = Prepare(table_name, cmd.c_str());
1140 std::string
cn = GetText(0);
1141 std::string
ct = GetText(1);
1154int Mysql::Exec(
const char* table_name,
const char*
sql)
1157 printf(
"Mysql::Exec(%s, %s)\n", table_name,
sql);
1184 return ExecDisconnected(table_name,
sql);
1192int Mysql::ExecDisconnected(
const char* table_name,
const char*
sql)
1195 printf(
"Mysql::ExecDisconnected(%s, %s)\n", table_name,
sql);
1200 cm_msg(
MERROR,
"Mysql::ExecDisconnected",
"Error: Disconnected database buffer overflow, size %zu, subsequent events are lost",
fDisconnectedBuffer.size());
1209 int status = Connect(fConnectString.c_str());
1230int Mysql::Prepare(
const char* table_name,
const char*
sql)
1233 printf(
"Mysql::Prepare(%s, %s)\n", table_name,
sql);
1252 status = Connect(fConnectString.c_str());
1257 cm_msg(
MERROR,
"Mysql::Prepare",
"mysql_query(%s) - MySQL server has gone away, and couldn't reconnect - %d",
sql,
status);
1265 cm_msg(
MINFO,
"Mysql::Prepare",
"Reconnected to MySQL after long inactivity.");
1286 printf(
"Mysql::Step()\n");
1304const char* Mysql::GetText(
int column)
1317double Mysql::GetDouble(
int column)
1327int Mysql::Finalize()
1340const char* Mysql::ColumnType(
int midas_tid)
1377 printf(
"type mismatch!\n");
1382std::string Mysql::QuoteId(
const char* s)
1391std::string Mysql::QuoteString(
const char* s)
1397 while (
int c = *s++) {
1425#include <libpq-fe.h>
1430 std::string fConnectString;
1449 int Connect(
const char* path);
1458 int Exec(
const char* table_name,
const char*
sql);
1461 int Prepare(
const char* table_name,
const char*
sql);
1476 std::string
QuoteId(
const char* s);
1491 fTransactionPerTable =
false;
1520 std::string user_name;
1535 char* s =
fgets(buf,
sizeof(buf),
fp);
1572 printf(
"Pgsql::Connect: connecting to server [%s] port %s, unix socket [%s], database [%s], user [%s], password [%s], buffer [%zu]\n",
host_name.c_str(),
tcp_port.c_str(),
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
user_password.c_str(),
fMaxDisconnected);
1577 msg.erase(std::remove(msg.begin(), msg.end(),
'\n'), msg.end());
1578 cm_msg(
MERROR,
"Pgsql::Connect",
"PQsetdbLogin() to host [%s], port %s, unix socket [%s], database [%s], user [%s], password [%s]: error (%s)",
host_name.c_str(),
tcp_port.c_str(),
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
"xxx", msg.c_str());
1586 cm_msg(
MINFO,
"Pgsql::Connect",
"Connected to a PostgreSQL database on host [%s], port %s, unix socket [%s], database [%s], user [%s], password [%s], buffer %zu",
host_name.c_str(),
tcp_port.c_str(),
unix_socket.c_str(),
db_name.c_str(), user_name.c_str(),
"xxx",
fMaxDisconnected);
1590 fIsConnected =
true;
1611 status = Prepare(
"pg_extensions",
"select extname from pg_extension where extname = 'timescaledb';");
1614 cm_msg(
MERROR,
"Pgsql::Connect",
"TimescaleDB extension not installed");
1619 status = Prepare(
"pg_extensions",
"select extname from pg_extension where extname = 'timescaledb_toolkit';");
1622 cm_msg(
MERROR,
"Pgsql::Connect",
"TimescaleDB_toolkit extension not installed");
1627 cm_msg(
MINFO,
"Pgsql::Connect",
"TimescaleDB extensions found - downsampling enabled");
1633int Pgsql::Disconnect()
1641 fIsConnected =
false;
1645bool Pgsql::IsConnected()
1647 return fIsConnected;
1650int Pgsql::OpenTransaction(
const char* table_name)
1652 return Exec(table_name,
"BEGIN TRANSACTION;");
1655int Pgsql::CommitTransaction(
const char* table_name)
1657 return Exec(table_name,
"COMMIT;");
1660int Pgsql::RollbackTransaction(
const char* table_name)
1662 return Exec(table_name,
"ROLLBACK;");
1665int Pgsql::ListTables(std::vector<std::string> *
plist)
1671 printf(
"Pgsql::ListTables!\n");
1673 int status = Prepare(
"pg_tables",
"select tablename from pg_tables where schemaname = 'public';");
1683 std::string
tn = GetText(0);
1692int Pgsql::ListColumns(
const char* table_name, std::vector<std::string> *
plist)
1698 printf(
"Pgsql::ListColumns for table \'%s\'\n", table_name);
1701 cmd +=
"SELECT column_name, data_type FROM information_schema.columns WHERE table_name = ";
1702 cmd += QuoteString(table_name);
1705 int status = Prepare(table_name, cmd.c_str());
1714 std::string
cn = GetText(0);
1715 std::string
ct = GetText(1);
1725int Pgsql::Exec(
const char* table_name,
const char*
sql)
1728 printf(
"Pgsql::Exec(%s, %s)\n", table_name,
sql);
1748 return ExecDisconnected(table_name,
sql);
1755int Pgsql::ExecDisconnected(
const char* table_name,
const char*
sql)
1758 printf(
"Pgsql::ExecDisconnected(%s, %s)\n", table_name,
sql);
1763 cm_msg(
MERROR,
"Pgsql::ExecDisconnected",
"Error: Disconnected database buffer overflow, size %zu, subsequent events are lost",
fDisconnectedBuffer.size());
1772 int status = Connect(fConnectString.c_str());
1793int Pgsql::Prepare(
const char* table_name,
const char*
sql)
1796 printf(
"Pgsql::Prepare(%s, %s)\n", table_name,
sql);
1808 int status = Connect(fConnectString.c_str());
1813 cm_msg(
MERROR,
"Pgsql::Prepare",
"PQexec(%s) PostgreSQL server has gone away, and couldn't reconnect - %d",
sql,
status);
1820 cm_msg(
MINFO,
"Pgsql::Prepare",
"Reconnected to PostgreSQL after long inactivity.");
1828std::string Pgsql::BuildDownsampleQuery(
const time_t start_time,
const time_t end_time,
const int npoints,
1829 const char* table_name,
const char* column_name)
1832 cmd +=
"SELECT extract(epoch from time::TIMESTAMPTZ) as _i_time, value ";
1834 cmd +=
" FROM unnest(( SELECT lttb";
1835 cmd +=
"(_t_time, ";
1838 cmd += std::to_string(
npoints);
1841 cmd += QuoteId(table_name);
1842 cmd +=
" WHERE _t_time BETWEEN ";
1843 cmd +=
"to_timestamp(";
1845 cmd +=
") AND to_timestamp(";
1847 cmd +=
") )) ORDER BY time;";
1865const char* Pgsql::GetText(
int column)
1876double Pgsql::GetDouble(
int column)
1886int Pgsql::Finalize()
1897const char* Pgsql::ColumnType(
int midas_tid)
1930 printf(
"type mismatch!\n");
1935std::string Pgsql::QuoteId(
const char* s)
1944std::string Pgsql::QuoteString(
const char* s)
1963typedef std::map<std::string, sqlite3*>
DbMap;
1979 int Connect(
const char* path);
1989 int Exec(
const char* table_name,
const char*
sql);
1992 int Prepare(
const char* table_name,
const char*
sql);
2006 std::string
QuoteId(
const char* s);
2010std::string Sqlite::QuoteId(
const char* s)
2019std::string Sqlite::QuoteString(
const char* s)
2028const char* Sqlite::ColumnType(
int midas_tid)
2053const char* Sqlite::GetText(
int column)
2063double Sqlite::GetDouble(
int column)
2070 fIsConnected =
false;
2087int Sqlite::ConnectTable(
const char* table_name)
2089 std::string
fname = fPath +
"mh_" + table_name +
".sqlite3";
2102#if SQLITE_VERSION_NUMBER >= 3006020
2108#warning Missing sqlite3_extended_result_codes()!
2113 Exec(table_name,
"PRAGMA journal_mode=persist;");
2114 Exec(table_name,
"PRAGMA synchronous=normal;");
2116 Exec(table_name,
"PRAGMA journal_size_limit=-1;");
2119 Exec(table_name,
"PRAGMA legacy_file_format;");
2120 Exec(table_name,
"PRAGMA synchronous;");
2121 Exec(table_name,
"PRAGMA journal_mode;");
2122 Exec(table_name,
"PRAGMA journal_size_limit;");
2125#ifdef SQLITE_LIMIT_COLUMN
2133 cm_msg(
MINFO,
"Sqlite::Connect",
"Table %s: connected to Sqlite file \'%s\'", table_name,
fname.c_str());
2138sqlite3* Sqlite::GetTable(
const char* table_name)
2149 return fMap[table_name];
2152int Sqlite::Connect(
const char* path)
2160 if (fPath.length() > 0) {
2166 cm_msg(
MINFO,
"Sqlite::Connect",
"Connected to Sqlite database in \'%s\'", fPath.c_str());
2168 fIsConnected =
true;
2173int Sqlite::Disconnect()
2179 const char* table_name =
iter->first.c_str();
2189 fIsConnected =
false;
2194bool Sqlite::IsConnected()
2196 return fIsConnected;
2199int Sqlite::OpenTransaction(
const char* table_name)
2201 int status = Exec(table_name,
"BEGIN TRANSACTION");
2205int Sqlite::CommitTransaction(
const char* table_name)
2207 int status = Exec(table_name,
"COMMIT TRANSACTION");
2211int Sqlite::RollbackTransaction(
const char* table_name)
2213 int status = Exec(table_name,
"ROLLBACK TRANSACTION");
2217int Sqlite::Prepare(
const char* table_name,
const char*
sql)
2224 printf(
"Sqlite::Prepare(%s, %s)\n", table_name,
sql);
2229#if SQLITE_VERSION_NUMBER >= 3006020
2232#warning Missing sqlite3_prepare_v2()!
2250 printf(
"Sqlite::Step()\n");
2268int Sqlite::Finalize()
2271 printf(
"Sqlite::Finalize()\n");
2292int Sqlite::ListTables(std::vector<std::string> *
plist)
2298 printf(
"Sqlite::ListTables at path [%s]\n", fPath.c_str());
2302 const char* cmd =
"SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;";
2315 const char*
dn =
de->d_name;
2330 char table_name[256];
2331 mstrlcpy(table_name,
dn+3,
sizeof(table_name));
2333 char*
ss =
strstr(table_name,
".sqlite3");
2340 status = Prepare(table_name, cmd);
2349 const char*
tn = GetText(0);
2363int Sqlite::ListColumns(
const char* table, std::vector<std::string> *
plist)
2369 printf(
"Sqlite::ListColumns for table \'%s\'\n", table);
2372 cmd =
"PRAGMA table_info(";
2378 status = Prepare(table, cmd.c_str());
2387 const char*
colname = GetText(1);
2388 const char*
coltype = GetText(2);
2403 printf(
"history_sqlite::callback---->\n");
2411int Sqlite::Exec(
const char* table_name,
const char*
sql)
2426 printf(
"Sqlite::Exec(%s, %s)\n", table_name,
sql);
2448int Sqlite::ExecDisconnected(
const char* table_name,
const char*
sql)
2450 cm_msg(
MERROR,
"Sqlite::Exec",
"sqlite driver does not support disconnected operations");
2485 if (file_size < 0) {
2505 cm_msg(
MERROR,
"FileHistory::write_event",
"File \'%s\' may be truncated, data offset %jd, record size %zu, file size: %jd, should be %jd, making it so", s->
fFileName.c_str(), (
intmax_t)s->
fDataOffset, s->
fRecordSize, (
intmax_t)file_size, (
intmax_t)
data_end);
2559 if ((
size_t)
wr != size) {
2611 cm_msg(
MERROR,
"FileHistory::ReadRecord",
"Cannot read \'%s\', unexpected end of file on read()",
file_name);
2623static int FindTime(
const char*
file_name,
int fd,
off64_t offset,
size_t recsize,
off64_t nrec,
time_t timestamp,
off64_t*
i1p,
time_t*
t1p,
off64_t*
i2p,
time_t*
t2p,
time_t* tstart,
time_t* tend,
int debug)
2644 char* buf =
new char[
recsize];
2662 if (timestamp <=
t1) {
2672 assert(
t1 < timestamp);
2695 if (
t2 < timestamp) {
2704 assert(
t1 < timestamp);
2705 assert(timestamp <=
t2);
2726 if (timestamp <= t) {
2742 assert(
t1 < timestamp);
2743 assert(timestamp <=
t2);
2776 if (file_size < 0) {
2822 if (
lw >= timestamp) {
2830 status =
FindTime(s->
fFileName.c_str(), fd, s->
fDataOffset, s->
fRecordSize,
nrec, timestamp, &
irec, &
trec, &
iunused, &
tunused, &tstart, &tend, 0*
debug);
2836 assert(
trec < timestamp);
2847 assert(
lw < timestamp);
2890 if (file_size < 0) {
2921 int istatus =
FindTime(s->
fFileName.c_str(), fd, s->
fDataOffset, s->
fRecordSize,
nrec, start_time, &
iunused, &
tunused, &
irec, &
trec, &tstart, &tend, 0*
debug);
2929 printf(
"FindTime %d, nrec %jd, (%jd, %s) (%jd, %s), tstart %s, tend %s, want %s\n",
istatus, (
intmax_t)
nrec, (
intmax_t)
iunused,
TimeToString(
tunused).
c_str(), (
intmax_t)
irec,
TimeToString(
trec).
c_str(),
TimeToString(tstart).
c_str(),
TimeToString(tend).
c_str(),
TimeToString(start_time).
c_str());
2938 printf(
"FileHistory::read: file %s, schema time %s..%s, read time %s..%s, file time %s..%s, data in this file is too old\n", s->
fFileName.c_str(),
TimeToString(s->
fTimeFrom).c_str(),
TimeToString(s->
fTimeTo).c_str(),
TimeToString(start_time).
c_str(),
TimeToString(end_time).
c_str(),
TimeToString(tstart).
c_str(),
TimeToString(tend).
c_str());
3039 char*
data = buf + 4;
3058 int ii = var_index[
i];
3068 v = ((
unsigned char*)ptr)[
ii];
3071 v = ((
signed char *)ptr)[
ii];
3074 v = ((
char*)ptr)[
ii];
3077 v = ((
unsigned short *)ptr)[
ii];
3080 v = ((
signed short *)ptr)[
ii];
3083 v = ((
unsigned int *)ptr)[
ii];
3086 v = ((
int *)ptr)[
ii];
3089 v = ((
unsigned int *)ptr)[
ii];
3092 v = ((
float*)ptr)[
ii];
3095 v = ((
double*)ptr)[
ii];
3099 buffer[
i]->
Add(t, v);
3118 printf(
"FileHistory::read: file %s, schema time %s..%s, read time %s..%s, %d vars, read %d rows\n", s->
fFileName.c_str(),
TimeToString(s->
fTimeFrom).c_str(),
TimeToString(s->
fTimeTo).c_str(),
TimeToString(start_time).
c_str(),
TimeToString(end_time).
c_str(),
num_var,
count);
3188 int hs_write_event(
const char* event_name,
time_t timestamp,
int buffer_size,
const char* buffer);
3200 int num_var,
const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
3277 (*fTimeBuffer)[pos] = t;
3278 (*fDataBuffer)[pos] = v;
3280 (*fNumEntries) = pos + 1;
3296 const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
3304 int num_var,
const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
3473 printf(
"hs_define_event: event name [%s] with %d tags\n", event_name,
ntags);
3483 printf(
"deleting exising event %s\n", event_name);
3492 cm_msg(
MERROR,
"hs_define_event",
"Error: History event \'%s\' has empty name at index %d", event_name,
i);
3495 if (tags[
i].
name[0] ==
' ') {
3496 cm_msg(
MERROR,
"hs_define_event",
"Error: History event \'%s\' has name \'%s\' starting with a blank", event_name, tags[
i].
name);
3500 cm_msg(
MERROR,
"hs_define_event",
"Error: History event \'%s\' tag \'%s\' at index %d has invalid type %d",
3506 "Error: History event \'%s\' tag \'%s\' at index %d has forbidden type TID_STRING", event_name,
3510 if (tags[
i].n_data <= 0) {
3511 cm_msg(
MERROR,
"hs_define_event",
"Error: History event \'%s\' tag \'%s\' at index %d has invalid n_data %d",
3512 event_name, tags[
i].
name,
i, tags[
i].n_data);
3518 std::vector<std::string>
names;
3528 "Error: History event \'%s\' has duplicate tag name \'%s\'", event_name,
3560 printf(
"hs_write_event: write event \'%s\', time %d, size %d\n", event_name, (
int)timestamp,
xbuffer_size);
3602 cm_msg(
MERROR,
"hs_write_event",
"Event \'%s\' data size mismatch: expected %zu bytes, got %zu bytes", s->
fEventName.c_str(), s->
fNumBytes, buffer_size);
3612 cm_msg(
MERROR,
"hs_write_event",
"Event \'%s\' data size mismatch: expected %zu bytes, got %zu bytes", s->
fEventName.c_str(), s->
fNumBytes, buffer_size);
3632 cm_msg(
MERROR,
"hs_write_event",
"Event \'%s\' disabled after write error %d", event_name,
status);
3644 printf(
"hs_flush_buffers!\n");
3663 printf(
"SchemaHistoryBase::hs_clear_cache!\n");
3681 printf(
"hs_get_events: available schema:\n");
3705 printf(
"hs_get_events: returning %zu events\n",
pevents->size());
3742 for (
size_t k=0;
k<
ptags->size();
k++)
3754 ptags->push_back(t);
3763 printf(
"hs_get_tags: event [%s], returning %zu tags\n", event_name,
ptags->size());
3764 for (
size_t i=0;
i<
ptags->size();
i++) {
3779 last_written[
j] = 0;
3814 if (
lw > last_written[
j])
3815 last_written[
j] =
lw;
3832 int num_var,
const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
3885 cm_msg(
MERROR,
"SchemaHistoryBase::hs_read_buffer",
"History internal error, schema is not ordered by time. Please report this error to the midas forum.");
3892 std::vector<HsSchema*>
slist;
3893 std::vector<std::vector<int>>
smap;
3904 std::vector<int>
sm;
3928 printf(
"Found %zu matching schema:\n",
slist.size());
3930 for (
size_t i=0;
i<
slist.size();
i++) {
3951 printf(
"Check schema %zu/%zu: prev from %s, this from %s to %s, compare %d\n",
ss,
slist.size(),
3960 cm_msg(
MERROR,
"SchemaHistoryBase::hs_read_buffer",
"History internal error, selected schema is not ordered by time. Please report this error to the midas forum.");
3971 for (
size_t i=
slist.size()-1; ;
i--) {
3992 const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
4040 int num_var,
const char*
const event_name[],
const char*
const var_name[],
const int var_index[],
4160 for (
size_t i=0;
i<
sv->size();
i++) {
4211 cm_msg(
MERROR,
"NewSqlSchema",
"Error: Unexpected ordering of schema for table \'%s\', good luck!", table_name);
4225 cm_msg(
MERROR,
"NewSqlSchema",
"Error: Cannot clone schema for table \'%s\', good luck!", table_name);
4306 cm_msg(
MERROR,
"HsSqlSchema::write_event",
"Internal error, unexpected inactive column %zu",
i);
4317 cm_msg(
MERROR,
"HsSqlSchema::write_event",
"Internal error, unexpected negative offset %d for column %zu",
offset,
i);
4322 assert(n_data == 1);
4323 assert(
strlen(column_name) > 0);
4325 assert((
size_t)
offset < data_size);
4342 sprintf(buf,
"%u",((
unsigned char *)ptr)[
j]);
4345 sprintf(buf,
"%d",((
signed char*)ptr)[
j]);
4349 sprintf(buf,
"\'%c\'",((
char*)ptr)[
j]);
4352 sprintf(buf,
"%u",((
unsigned short *)ptr)[
j]);
4355 sprintf(buf,
"%d",((
short *)ptr)[
j]);
4358 sprintf(buf,
"%u",((
unsigned int *)ptr)[
j]);
4361 sprintf(buf,
"%d",((
int *)ptr)[
j]);
4364 sprintf(buf,
"%u",((
unsigned int *)ptr)[
j]);
4368 sprintf(buf,
"\'%.8g\'",((
float*)ptr)[
j]);
4372 sprintf(buf,
"\'%.16g\'",((
double*)ptr)[
j]);
4383 strftime(buf,
sizeof(buf)-1,
"%Y-%m-%d %H:%M:%S.0", &
tms);
4386 cmd =
"INSERT INTO ";
4388 cmd +=
" (_t_time, _i_time";
4390 cmd +=
") VALUES (";
4436 cmd +=
"SELECT _i_time FROM ";
4438 cmd +=
" WHERE _i_time < ";
4440 cmd +=
" ORDER BY _i_time DESC LIMIT 2;";
4499 cmd +=
"SELECT _i_time, ";
4503 cmd +=
" WHERE _i_time>=";
4505 cmd +=
" and _i_time<=";
4507 cmd +=
" ORDER BY _i_time;";
4544 buffer[
i]->
Add(t, v);
4597 int status =
sql->OpenTransaction(table_name);
4615 cmd =
"CREATE TABLE ";
4616 cmd +=
sql->QuoteId(table_name);
4618 cmd +=
" (_t_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4620 cmd +=
" (_t_time TIMESTAMP NOT NULL, _i_time INTEGER NOT NULL);";
4623 status =
sql->Exec(table_name, cmd.c_str());
4627 cm_msg(
MINFO,
"CreateSqlTable",
"Adding SQL table \"%s\", but it already exists", table_name);
4633 cm_msg(
MINFO,
"CreateSqlTable",
"Adding SQL table \"%s\", error status %d", table_name,
status);
4638 cm_msg(
MINFO,
"CreateSqlTable",
"Adding SQL table \"%s\"", table_name);
4649 cmd =
"CREATE INDEX ";
4652 cmd +=
sql->QuoteId(table_name);
4653 cmd +=
" (_i_time ASC);";
4655 status =
sql->Exec(table_name, cmd.c_str());
4659 cmd =
"CREATE INDEX ";
4662 cmd +=
sql->QuoteId(table_name);
4663 cmd +=
" (_t_time);";
4665 status =
sql->Exec(table_name, cmd.c_str());
4681 cmd =
"CREATE TABLE ";
4682 cmd +=
sql->QuoteId(table_name);
4683 cmd +=
" (_t_time TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP, _i_time INTEGER NOT NULL DEFAULT 0);";
4685 status =
sql->Exec(table_name, cmd.c_str());
4688 cm_msg(
MINFO,
"CreateSqlHyperTable",
"Adding SQL table \"%s\", but it already exists", table_name);
4694 cm_msg(
MINFO,
"CreateSqlHyperTable",
"Adding SQL table \"%s\", error status %d", table_name,
status);
4699 cm_msg(
MINFO,
"CreateSqlHyperTable",
"Adding SQL table \"%s\"", table_name);
4702 cmd =
"SELECT create_hypertable(";
4703 cmd +=
sql->QuoteString(table_name);
4704 cmd +=
", '_t_time');";
4707 status =
sql->Exec(table_name, cmd.c_str());
4710 cm_msg(
MINFO,
"CreateSqlHyperTable",
"Converting SQL table to hypertable \"%s\", error status %d", table_name,
status);
4723 cmd =
"CREATE INDEX ";
4726 cmd +=
sql->QuoteId(table_name);
4727 cmd +=
" (_i_time ASC);";
4729 status =
sql->Exec(table_name, cmd.c_str());
4733 cmd =
"CREATE INDEX ";
4736 cmd +=
sql->QuoteId(table_name);
4737 cmd +=
" (_t_time);";
4739 status =
sql->Exec(table_name, cmd.c_str());
4749 printf(
"CreateSqlColumn: table [%s], column [%s], type [%s]\n", table_name, column_name,
column_type);
4756 cmd =
"ALTER TABLE ";
4757 cmd +=
sql->QuoteId(table_name);
4758 cmd +=
" ADD COLUMN ";
4759 cmd +=
sql->QuoteId(column_name);
4764 status =
sql->Exec(table_name, cmd.c_str());
4766 cm_msg(
MINFO,
"CreateSqlColumn",
"Adding column \"%s\" to SQL table \"%s\", status %d", column_name, table_name,
status);
4852 printf(
"hs_disconnect!\n");
4888 cm_msg(
MERROR,
"SqlHistory::new_event",
"Error: Cannot create schema for event \'%s\', see previous messages", event_name);
4903 cm_msg(
MERROR,
"SqlHistory::new_event",
"Error: Cannot update schema database for event \'%s\', see previous messages", event_name);
4908 printf(
"SqlHistory::new_event: schema for [%s] is %p\n", event_name, s);
4915 cm_msg(
MERROR,
"SqlHistory::new_event",
"Error: Cannot create schema for event \'%s\', see previous messages", event_name);
4926 cm_msg(
MERROR,
"SqlHistory::new_event",
"Error: Cannot update schema database for event \'%s\', see previous messages", event_name);
4931 printf(
"SqlHistory::new_event: schema for [%s] is %p\n", event_name, s);
4940 cm_msg(
MERROR,
"SqlHistory::new_event",
"Error: Cannot create schema for event \'%s\', see previous messages", event_name);
4957 printf(
"SqlHistory::read_schema: loading schema for event [%s] at time %s\n", event_name,
TimeToString(timestamp).
c_str());
4961 if (
sv->size() == 0) {
4969 if (event_name ==
NULL)
4972 for (
size_t i=0;
i<
sv->size();
i++) {
4981 size_t nn =
sv->size();
4986 if (
sv->size() !=
nn)
5024 printf(
"update_schema1\n");
5032 for (
unsigned int j=0;
j<tags[
i].
n_data;
j++) {
5037 if (tags[
i].n_data > 1) {
5067 printf(
"Incompatible column!\n");
5130 for (
int t=0; t<20; t++) {
5174 cm_msg(
MERROR,
"SqlHistory::update_schema",
"Duplicate tags or SQL columns for history event \"%s\" tag \"%s\"", s->
fEventName.c_str(),
tagname.c_str());
5187 for (
unsigned int j=0;
j<tags[
i].
n_data;
j++) {
5190 if (tags[
i].n_data > 1) {
5225 printf(
"Return error!\n");
5239 printf(
"ReadSqliteTableNames: table [%s]\n", table_name);
5245 cmd =
"SELECT event_name, _i_time FROM \'_event_name_";
5247 cmd +=
"\' WHERE table_name='";
5251 status =
sql->Prepare(table_name, cmd.c_str());
5284 printf(
"ReadSqliteTableSchema: table [%s]\n", table_name);
5324 printf(
"SqliteHistory::read_table_and_event_names!\n");
5328 std::vector<std::string>
tables;
5333 for (
size_t i=0;
i<
tables.size();
i++) {
5334 const char* table_name =
tables[
i].c_str();
5337 s =
strstr(table_name,
"_event_name_");
5338 if (s == table_name)
5340 s =
strstr(table_name,
"_column_names_");
5341 if (s == table_name)
5353 printf(
"SqliteHistory::read_column_names: table [%s], event [%s]\n", table_name, event_name);
5357 std::vector<std::string>
columns;
5362 for (
size_t i=0;
i<
sv->size();
i++) {
5409 tn +=
"_column_names_";
5413 cmd =
"SELECT column_name, tag_name, tag_type, _i_time FROM ";
5415 cmd +=
" WHERE table_name=";
5417 cmd +=
" ORDER BY _i_time ASC;";
5447 for (
size_t i=0;
i<
sv->size();
i++) {
5475 printf(
"SqliteHistory::create_table: event [%s], timestamp %s\n", event_name,
TimeToString(timestamp).
c_str());
5497 en +=
"_event_name_";
5500 cmd =
"CREATE TABLE ";
5502 cmd +=
" (table_name TEXT NOT NULL, event_name TEXT NOT NULL, _i_time INTEGER NOT NULL);";
5506 cmd =
"INSERT INTO ";
5508 cmd +=
" (table_name, event_name, _i_time) VALUES (";
5519 cn +=
"_column_names_";
5522 cmd =
"CREATE TABLE ";
5524 cmd +=
" (table_name TEXT NOT NULL, column_name TEXT NOT NULL, tag_name TEXT NOT NULL, tag_type TEXT NOT NULL, column_type TEXT NOT NULL, _i_time INTEGER NOT NULL);";
5539 printf(
"SqliteHistory::update_column: event [%s], table [%s], column [%s], new name [%s], timestamp %s\n", event_name, table_name, column_name, tag_name,
TimeToString(timestamp).
c_str());
5547 cmd =
"INSERT INTO \'_column_names_";
5549 cmd +=
"\' (table_name, column_name, tag_name, tag_type, column_type, _i_time) VALUES (\'";
5595 cmd =
"SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name='";
5599 cmd =
"SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';";
5600 table_name =
"_history_index";
5603 status =
sql->Prepare(table_name, cmd.c_str());
5653 cm_msg(
MERROR,
"ReadMysqlTableNames",
"Error: Cannot continue, nothing will work after this error\n");
5671 printf(
"MysqlHistory::read_column_names: table [%s], event [%s]\n", table_name, event_name);
5675 std::vector<std::string>
columns;
5680 for (
size_t i=0;
i<
sv->size();
i++) {
5729 cmd =
"SELECT column_name, column_type, tag_name, tag_type, itimestamp, active FROM _history_index WHERE event_name=";
5767 for (
size_t i=0;
i<
sv->size();
i++) {
5811 printf(
"ReadMysqlTableSchema: table [%s]\n", table_name);
5833 printf(
"MysqlHistory::read_table_and_event_names!\n");
5837 std::vector<std::string>
tables;
5842 for (
size_t i=0;
i<
tables.size();
i++) {
5843 const char* table_name =
tables[
i].c_str();
5846 s =
strstr(table_name,
"_history_index");
5847 if (s == table_name)
5864 printf(
"read_table_and_event_names:\n");
5876 printf(
"MysqlHistory::create_table: event [%s], timestamp %s\n", event_name,
TimeToString(timestamp).
c_str());
5882 if (table_name.length() > 40) {
5883 table_name.resize(40);
5923 cm_msg(
MERROR,
"MysqlHistory::create_table",
"Could not create table [%s] for event [%s], timestamp %s, please fix the SQL database configuration and try again", table_name.c_str(), event_name,
TimeToString(timestamp).
c_str());
5931 for (
int j=0;
j<2;
j++) {
5933 cmd +=
"INSERT INTO _history_index (event_name, table_name, itimestamp, active) VALUES (";
5939 sprintf(buf,
"%.0f", (
double)timestamp);
5969 cm_msg(
MERROR,
"MysqlHistory::create_table",
"Could not create table [%s] for event [%s], timestamp %s, after %d attempts", table_name.c_str(), event_name,
TimeToString(timestamp).
c_str(),
max_attempts);
5977 printf(
"MysqlHistory::update_column: event [%s], table [%s], column [%s], type [%s] new name [%s], timestamp %s\n", event_name, table_name, column_name,
column_type, tag_name,
TimeToString(timestamp).
c_str());
5980 cmd +=
"INSERT INTO _history_index (event_name, table_name, tag_name, tag_type, column_name, column_type, itimestamp, active) VALUES (";
5994 sprintf(buf,
"%.0f", (
double)timestamp);
6041 cmd =
"SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name='";
6045 cmd =
"SELECT event_name, table_name, itimestamp FROM _history_index WHERE table_name!='';";
6046 table_name =
"_history_index";
6049 status =
sql->Prepare(table_name, cmd.c_str());
6099 cm_msg(
MERROR,
"ReadPgsqlTableNames",
"Error: Cannot continue, nothing will work after this error\n");
6114int PgsqlHistory::read_column_names(
HsSchemaVector *
sv,
const char* table_name,
const char* event_name)
6117 printf(
"PgsqlHistory::read_column_names: table [%s], event [%s]\n", table_name, event_name);
6121 std::vector<std::string>
columns;
6122 fSql->ListColumns(table_name, &
columns);
6126 for (
size_t i=0;
i<
sv->size();
i++) {
6173 cmd =
"SELECT column_name, column_type, tag_name, tag_type, itimestamp, active FROM _history_index WHERE event_name=";
6174 cmd += fSql->QuoteString(event_name);
6177 int status = fSql->Prepare(table_name, cmd.c_str());
6189 const char*
col_name = fSql->GetText(0);
6190 const char*
col_type = fSql->GetText(1);
6191 const char* tag_name = fSql->GetText(2);
6192 const char* tag_type = fSql->GetText(3);
6194 const char* active = fSql->GetText(5);
6210 for (
size_t i=0;
i<
sv->size();
i++) {
6245 status = fSql->Finalize();
6255 printf(
"PgsqlHistory::read_table_and_event_names!\n");
6259 std::vector<std::string>
tables;
6264 for (
size_t i=0;
i<
tables.size();
i++) {
6265 const char* table_name =
tables[
i].c_str();
6268 s =
strstr(table_name,
"_history_index");
6269 if (s == table_name)
6286 printf(
"read_table_and_event_names:\n");
6298 printf(
"PgsqlHistory::create_table: event [%s], timestamp %s\n", event_name,
TimeToString(timestamp).
c_str());
6304 if (table_name.length() > 40) {
6305 table_name.resize(40);
6313 status = fSql->OpenTransaction(table_name.c_str());
6342 fSql->RollbackTransaction(table_name.c_str());
6347 fSql->RollbackTransaction(table_name.c_str());
6351 fSql->Exec(table_name.c_str(),
"SAVEPOINT t0");
6353 for (
int j=0;
j<2;
j++) {
6355 cmd +=
"INSERT INTO _history_index (event_name, table_name, itimestamp, active) VALUES (";
6356 cmd += fSql->QuoteString(event_name);
6361 sprintf(buf,
"%.0f", (
double)timestamp);
6364 cmd += fSql->QuoteString(
"1");
6367 int status = fSql->Exec(table_name.c_str(), cmd.c_str());
6373 fSql->Exec(table_name.c_str(),
"ROLLBACK TO SAVEPOINT t0");
6385 status = fSql->CommitTransaction(table_name.c_str());
6395 cm_msg(
MERROR,
"PgsqlHistory::create_table",
"Could not create table [%s] for event [%s], timestamp %s, after %d attempts", table_name.c_str(), event_name,
TimeToString(timestamp).
c_str(),
max_attempts);
6400int PgsqlHistory::update_column(
const char* event_name,
const char* table_name,
const char* column_name,
const char*
column_type,
const char* tag_name,
const char* tag_type,
const time_t timestamp,
bool active,
bool*
have_transaction)
6403 printf(
"PgsqlHistory::update_column: event [%s], table [%s], column [%s], type [%s] new name [%s], timestamp %s\n", event_name, table_name, column_name,
column_type, tag_name,
TimeToString(timestamp).
c_str());
6406 cmd +=
"INSERT INTO _history_index (event_name, table_name, tag_name, tag_type, column_name, column_type, itimestamp, active) VALUES (";
6407 cmd += fSql->QuoteString(event_name);
6409 cmd += fSql->QuoteString(table_name);
6411 cmd += fSql->QuoteString(tag_name);
6413 cmd += fSql->QuoteString(tag_type);
6415 cmd += fSql->QuoteString(column_name);
6420 sprintf(buf,
"%.0f", (
double)timestamp);
6424 cmd += fSql->QuoteString(
"1");
6426 cmd += fSql->QuoteString(
"0");
6429 int status = fSql->Exec(table_name, cmd.c_str());
6491 if (
fPath.length() > 0) {
6502 printf(
"FileHistory::hs_clear_cache!\n");
6510 printf(
"FileHistory::hs_disconnect!\n");
6544 printf(
"FileHistory::read_file_list: history directory \"%s\" mtime %d did not change\n",
fPath.c_str(),
int(
stat_buf.st_mtime));
6551 printf(
"FileHistory::read_file_list: reading list of history files in \"%s\"\n",
fPath.c_str());
6553 std::vector<std::string>
flist;
6569 printf(
"file names sorted by time:\n");
6570 for (
size_t i=0;
i<
flist.size();
i++) {
6576 std::vector<bool>
fread;
6584 for (
size_t i=0;
i<
flist.size();
i++) {
6607 if (
sv->size() == 0) {
6609 printf(
"FileHistory::read_schema: schema is empty, do a full reload from disk\n");
6628 if ((*sv).find_event(event_name, timestamp)) {
6630 printf(
"FileHistory::read_schema: event [%s] at time %s, no new history files, already have this schema\n", event_name,
TimeToString(timestamp).
c_str());
6677 cm_msg(
MINFO,
"FileHistory::read_schema",
"Loading schema for event \"%s\" timestamp %s, reading %d history files took %.1f sec", event_name,
TimeToString(timestamp).
c_str(), count_read,
read_elapsed);
6693 e.tag_name = tags[
i].
name;
6748 printf(
"CCC: event [%s] index %zu: name [%s] -> [%s]!\n", event_name,
i, s->
fVariables[
i].name.c_str(), tags[
i].
name);
6768 printf(
"*** Schema for event %s has changed!\n", event_name);
6772 printf(
"*** New tags:\n");
6777 printf(
"FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema mismatch, starting a new file.\n", event_name,
TimeToString(timestamp).
c_str(),
ntags);
6789 printf(
"FileHistory::new_event: event [%s], timestamp %s, ntags %d: schema is too old, age %.1f months, starting a new file.\n", event_name,
TimeToString(timestamp).
c_str(),
ntags, (
double)
age/(
double)
kMonth);
6802 printf(
"FileHistory::new_event: event [%s], timestamp %s, ntags %d: file too big, size %.1f MiBytes, max size %.1f MiBytes, starting a new file.\n", event_name,
TimeToString(timestamp).
c_str(),
ntags, size/
MiB,
fConfMaxFileSize/
MiB);
6810 std::string filename;
6812 std::vector<HsSchemaEntry> vars;
6822 cm_msg(
MERROR,
"FileHistory::new_event",
"Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6831 cm_msg(
MERROR,
"FileHistory::new_event",
"Error: Cannot create schema for event \'%s\', see previous messages", event_name);
6845 printf(
"schema for [%s] is %p\n", event_name, s);
6861 printf(
"FileHistory::create_file: event [%s]\n", event_name);
6873 std::string filename;
6912 cm_msg(
MERROR,
"FileHistory::create_file",
"Error: Cannot create file \'%s\' for event \'%s\'", filename.c_str(), event_name);
6918 ss +=
"version: 2.0\n";
6919 ss +=
"event_name: ";
6928 ss +=
"tag: /DWORD 1 4 /timestamp\n";
6936 for (
size_t i=0;
i<vars.size();
i++) {
6938 int n_bytes = vars[
i].n_data*
tsize;
6985 ss +=
"record_size: ";
6996 ss +=
"data_offset: ";
7018 printf(
"FileHistory::read_file_schema: file %s\n", filename);
7020 FILE*
fp =
fopen(filename,
"r");
7044 char* b =
fgets(buf,
sizeof(buf),
fp);
7110 cm_msg(
MERROR,
"FileHistory::read_file_schema",
"Unknown MIDAS data type \'%s\' in history file \'%s\'",
midas_type, filename);
7160 cm_msg(
MERROR,
"FileHistory::read_file_schema",
"Malformed history schema in \'%s\', maybe it is not a history file", filename);
7165 cm_msg(
MERROR,
"FileHistory::read_file_schema",
"Record size mismatch in history schema from \'%s\', file says %zu while total of all tags is %zu", filename, s->
fRecordSize,
rd_recsize);
7172 cm_msg(
MERROR,
"FileHistory::read_file_schema",
"Could not read history schema from \'%s\', maybe it is not a history file", filename);
7198 printf(
"FileHistory::maybe_reopen: reopen file \"%s\", size %jd, max size %jd\n",
fs->fFileName.c_str(),
fs->fFileSize,
fConfMaxFileSize);
7253 cm_msg(
MERROR,
"MakeMidasHistorySqlite",
"Error: Cannot initialize SQLITE history - this MIDAS was built without SQLITE support - HAVE_SQLITE is not defined");
7263 cm_msg(
MERROR,
"MakeMidasHistoryMysql",
"Error: Cannot initialize MySQL history - this MIDAS was built without MySQL support - HAVE_MYSQL is not defined");
7273 cm_msg(
MERROR,
"MakeMidasHistoryPgsql",
"Error: Cannot initialize PgSQL history - this MIDAS was built without PostgreSQL support - HAVE_PGSQL is not defined");
HsSchema * maybe_reopen(const char *event_name, time_t timestamp, HsSchema *s)
HsFileSchema * read_file_schema(const char *filename)
std::vector< std::string > fSortedFiles
HsSchema * new_event(const char *event_name, time_t timestamp, int ntags, const TAG tags[])
std::vector< bool > fSortedRead
int hs_connect(const char *connect_string)
returns HS_SUCCESS
void tags_to_variables(int ntags, const TAG tags[], std::vector< HsSchemaEntry > &variables)
int create_file(const char *event_name, time_t timestamp, const std::vector< HsSchemaEntry > &vars, std::string *filenamep)
int hs_clear_cache()
clear internal cache, returns HS_SUCCESS
int read_schema(HsSchemaVector *sv, const char *event_name, const time_t timestamp)
int read_file_list(bool *pchanged)
int hs_disconnect()
disconnect from history, returns HS_SUCCESS
void remove_inactive_columns()
int read_data(const time_t start_time, const time_t end_time, const int num_var, const std::vector< int > &var_schema_index, const int var_index[], const int debug, std::vector< time_t > &last_time, MidasHistoryBufferInterface *buffer[])
void print(bool print_tags=true) const
int write_event(const time_t t, const char *data, const size_t data_size)
int read_last_written(const time_t timestamp, const int debug, time_t *last_written)
virtual void print(bool print_tags=true) const
std::vector< int > fOffsets
virtual void remove_inactive_columns()=0
std::vector< HsSchemaEntry > fVariables
virtual int read_data(const time_t start_time, const time_t end_time, const int num_var, const std::vector< int > &var_schema_index, const int var_index[], const int debug, std::vector< time_t > &last_time, MidasHistoryBufferInterface *buffer[])=0
virtual int write_event(const time_t t, const char *data, const size_t data_size)=0
virtual int read_last_written(const time_t timestamp, const int debug, time_t *last_written)=0
virtual int flush_buffers()=0
virtual int match_event_var(const char *event_name, const char *var_name, const int var_index)
void print(bool print_tags=true) const
std::vector< HsSchema * > fData
HsSchema * find_event(const char *event_name, const time_t timestamp, int debug=0)
HsSchema * operator[](int index) const
int get_transaction_count()
int read_last_written(const time_t timestamp, const int debug, time_t *last_written)
int read_data(const time_t start_time, const time_t end_time, const int num_var, const std::vector< int > &var_schema_index, const int var_index[], const int debug, std::vector< time_t > &last_time, MidasHistoryBufferInterface *buffer[])
std::vector< std::string > fColumnNames
void print(bool print_tags=true) const
void remove_inactive_columns()
std::vector< std::string > fColumnTypes
int fTableTransactionCount
std::vector< bool > fColumnInactive
void increment_transaction_count()
int match_event_var(const char *event_name, const char *var_name, const int var_index)
static std::map< SqlBase *, int > gfTransactionCount
void reset_transaction_count()
int write_event(const time_t t, const char *data, const size_t data_size)
MidasHistoryBinnedBuffer(time_t first_time, time_t last_time, int num_bins)
~MidasHistoryBinnedBuffer()
void Add(time_t t, double v)
virtual void Add(time_t time, double value)=0
char type[NAME_LENGTH]
history channel name
int update_column(const char *event_name, const char *table_name, const char *column_name, const char *column_type, const char *tag_name, const char *tag_type, const time_t timestamp, bool active, bool *have_transaction)
int read_table_and_event_names(HsSchemaVector *sv)
int create_table(HsSchemaVector *sv, const char *event_name, time_t timestamp)
int read_column_names(HsSchemaVector *sv, const char *table_name, const char *event_name)
void Add(time_t t, double v)
ReadBuffer(time_t first_time, time_t last_time, time_t interval)
void Realloc(int wantalloc)
int hs_get_tags(const char *event_name, time_t t, std::vector< TAG > *ptags)
get list of history variables for given event (use event names returned by hs_get_events()) that exis...
virtual int hs_connect(const char *connect_string)=0
returns HS_SUCCESS
virtual ~SchemaHistoryBase()
int hs_write_event(const char *event_name, time_t timestamp, int buffer_size, const char *buffer)
see hs_write_event(), returns HS_SUCCESS or HS_FILE_ERROR
int hs_read_buffer(time_t start_time, time_t end_time, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], MidasHistoryBufferInterface *buffer[], int hs_status[])
returns HS_SUCCESS
virtual HsSchema * maybe_reopen(const char *event_name, time_t timestamp, HsSchema *s)=0
int hs_define_event(const char *event_name, time_t timestamp, int ntags, const TAG tags[])
see hs_define_event(), returns HS_SUCCESS or HS_FILE_ERROR
int hs_read_binned(time_t start_time, time_t end_time, int num_bins, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], int *count_bins[], double *mean_bins[], double *rms_bins[], double *min_bins[], double *max_bins[], time_t *bins_first_time[], double *bins_first_value[], time_t *bins_last_time[], double *bins_last_value[], time_t last_time[], double last_value[], int st[])
returns HS_SUCCESS
HsSchemaVector fWriterSchema
virtual HsSchema * new_event(const char *event_name, time_t timestamp, int ntags, const TAG tags[])=0
int hs_get_events(time_t t, std::vector< std::string > *pevents)
get list of events that exist(ed) at given time and later (value 0 means "return all events from begi...
std::vector< HsSchema * > fWriterEvents
int hs_get_last_written(time_t timestamp, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], time_t last_written[])
virtual int hs_set_debug(int debug)
set debug level, returns previous debug level
virtual int hs_disconnect()=0
disconnect from history, returns HS_SUCCESS
HsSchemaVector fReaderSchema
int hs_read(time_t start_time, time_t end_time, time_t interval, int num_var, const char *const event_name[], const char *const var_name[], const int var_index[], int num_entries[], time_t *time_buffer[], double *data_buffer[], int st[])
see hs_read(), returns HS_SUCCESS
int hs_clear_cache()
clear internal cache, returns HS_SUCCESS
std::string fConnectString
int hs_flush_buffers()
flush buffered data to storage where it is visible to mhttpd
virtual int read_schema(HsSchemaVector *sv, const char *event_name, const time_t timestamp)=0
virtual int ListColumns(const char *table_name, std::vector< std::string > *plist)=0
virtual int Connect(const char *path)=0
virtual int ListColumns(const char *table, std::vector< std::string > *plist)=0
virtual double GetDouble(int column)=0
virtual int RollbackTransaction(const char *table_name)=0
virtual bool IsConnected()=0
virtual int CommitTransaction(const char *table_name)=0
virtual int ListTables(std::vector< std::string > *plist)=0
virtual std::string QuoteId(const char *s)=0
virtual int Disconnect()=0
virtual bool TypesCompatible(int midas_tid, const char *sql_type)=0
virtual int Prepare(const char *table_name, const char *sql)=0
virtual int Exec(const char *sql)=0
virtual int Connect(const char *dsn=0)=0
virtual int Exec(const char *table_name, const char *sql)=0
virtual std::string QuoteString(const char *s)=0
bool fTransactionPerTable
virtual time_t GetTime(int column)=0
virtual const char * GetText(int column)=0
virtual int ExecDisconnected(const char *table_name, const char *sql)=0
virtual int OpenTransaction(const char *table_name)=0
virtual const char * ColumnType(int midas_tid)=0
int update_schema1(HsSqlSchema *s, const time_t timestamp, const int ntags, const TAG tags[], bool write_enable, bool *have_transaction)
int hs_disconnect()
disconnect from history, returns HS_SUCCESS
int hs_set_debug(int debug)
set debug level, returns previous debug level
int read_schema(HsSchemaVector *sv, const char *event_name, const time_t timestamp)
HsSchema * maybe_reopen(const char *event_name, time_t timestamp, HsSchema *s)
virtual ~SqlHistoryBase()
virtual int create_table(HsSchemaVector *sv, const char *event_name, time_t timestamp)=0
virtual int update_column(const char *event_name, const char *table_name, const char *column_name, const char *column_type, const char *tag_name, const char *tag_type, const time_t timestamp, bool active, bool *have_transaction)=0
virtual int read_column_names(HsSchemaVector *sv, const char *table_name, const char *event_name)=0
virtual int read_table_and_event_names(HsSchemaVector *sv)=0
int hs_connect(const char *connect_string)
returns HS_SUCCESS
HsSchema * new_event(const char *event_name, time_t timestamp, int ntags, const TAG tags[])
int update_schema(HsSqlSchema *s, const time_t timestamp, const int ntags, const TAG tags[], bool write_enable)
int update_column(const char *event_name, const char *table_name, const char *column_name, const char *column_type, const char *tag_name, const char *tag_type, const time_t timestamp, bool active, bool *have_transaction)
int read_column_names(HsSchemaVector *sv, const char *table_name, const char *event_name)
int create_table(HsSchemaVector *sv, const char *event_name, time_t timestamp)
int read_table_and_event_names(HsSchemaVector *sv)
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
#define DB_NO_MORE_SUBKEYS
#define HS_UNDEFINED_EVENT
double ss_file_size(const char *path)
INT ss_file_find(const char *path, const char *pattern, char **plist)
INT cm_msg_flush_buffer()
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
const char * rpc_tid_name(INT id)
int rpc_name_tid(const char *name)
static std::string q(const char *s)
static const int tid_size[]
static const char * sql_type_mysql[]
static const char ** sql_type
static std::string MidasNameToSqlName(const char *s)
static int CreateSqlColumn(SqlBase *sql, const char *table_name, const char *column_name, const char *column_type, bool *have_transaction, int debug)
static int ReadSqliteTableNames(SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug)
void DoctorPgsqlColumnType(std::string *col_type, const char *index_type)
static int ReadRecord(const char *file_name, int fd, off64_t offset, size_t recsize, off64_t irec, char *rec)
static int CreateSqlHyperTable(SqlBase *sql, const char *table_name, bool *have_transaction)
void DoctorSqlColumnType(std::string *col_type, const char *index_type)
static bool MatchTagName(const char *tag_name, int n_data, const char *var_tag_name, const int var_tag_index)
static int var_name_cmp(const std::string &v1, const char *v2)
static std::string TimeToString(time_t t)
MidasHistoryInterface * MakeMidasHistorySqlite()
static void PrintTags(int ntags, const TAG tags[])
static char * skip_spaces(char *s)
static bool MatchEventName(const char *event_name, const char *var_event_name)
static HsSqlSchema * NewSqlSchema(HsSchemaVector *sv, const char *table_name, time_t t)
static int StartSqlTransaction(SqlBase *sql, const char *table_name, bool *have_transaction)
MidasHistoryInterface * MakeMidasHistoryMysql()
static int ReadSqliteTableSchema(SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug)
static int event_name_cmp(const std::string &e1, const char *e2)
MidasHistoryInterface * MakeMidasHistoryPgsql()
MidasHistoryInterface * MakeMidasHistoryFile()
static int ReadMysqlTableNames(SqlBase *sql, HsSchemaVector *sv, const char *table_name, int debug, const char *must_have_event_name, const char *must_have_table_name)
static std::string SmallIntToString(int i)
static int CreateSqlTable(SqlBase *sql, const char *table_name, bool *have_transaction, bool set_default_timestamp=false)
static std::string MidasNameToFileName(const char *s)
static int FindTime(const char *file_name, int fd, off64_t offset, size_t recsize, off64_t nrec, time_t timestamp, off64_t *i1p, time_t *t1p, off64_t *i2p, time_t *t2p, time_t *tstart, time_t *tend, int debug)
BOOL debug
debug printouts
char host_name[HOST_NAME_LENGTH]
#define DIR_SEPARATOR_STR
#define write(n, a, f, d)
struct callback_addr callback
BOOL match(char *pat, char *str)
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)