11 #pragma managed(push, off)
22 static SECURITY_ATTRIBUTES sec_attr = {
sizeof(SECURITY_ATTRIBUTES), NULL, FALSE };
25 db_mutex = CreateMutex(&sec_attr, FALSE,
"icpsqlitemutex");
29 throw(std::exception(
"error creating mutex"));
31 if (WaitForSingleObject(
db_mutex, INFINITE) != WAIT_OBJECT_0)
33 throw(std::exception(
"error waiting on mutex"));
40 throw(std::exception(
"error releasing mutex"));
49 static char buffer[256];
50 sprintf(buffer,
"ISISDB schema rev %d using SQLITE %s",
db_schema_version, SQLITE_VERSION);
59 db_list.push_back(m_db);
70 int rc = sqlite3_close(m_db);
74 _snprintf_s(last_error,
sizeof(last_error), _TRUNCATE,
"SELOGGER: SQLITE error code %d from close", rc);
75 throw(std::exception(last_error));
85 #define SQLITE_CHECK_RC(__rc) \
86 if (__rc != SQLITE_OK) \
88 _snprintf_s(last_error, sizeof(last_error), _TRUNCATE, "SELOGGER: SQLITE error %s at %s:%d", errmsg, __FILE__, __LINE__); \
89 sqlite3_free(errmsg); \
91 throw std::exception(last_error); \
105 struct stat stat_struct;
107 bool new_file =
false;
108 if (stat(
db_file, &stat_struct) == -1)
113 if (sqlite3_threadsafe() == 0)
115 throw std::exception(
"sqlite3 not threadsafe");
118 rc = sqlite3_open_v2(
db_file, &
m_db, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_NOMUTEX, NULL);
121 _snprintf_s(last_error,
sizeof(last_error), _TRUNCATE,
"SELOGGER: Error opening database %s: %s",
db_file, sqlite3_errmsg(
m_db));
123 throw std::exception(last_error);
125 rc = sqlite3_busy_timeout(
m_db, 7 * 24 * 60 * 60 * 1000);
128 _snprintf_s(last_error,
sizeof(last_error), _TRUNCATE,
"SELOGGER: Error setting timeout");
130 throw std::exception(last_error);
133 char** pazResult = NULL;
136 rc = sqlite3_get_table(
m_db,
138 "PRAGMA quick_check;",
139 &pazResult, &pnRow, &pnColumn, &errmsg);
141 if (pnRow == 1 && !strcmp(pazResult[0],
"integrity_check"))
143 sqlite3_free_table(pazResult);
148 for(
int i=0; i<pnRow; i++)
150 s.append(pazResult[i]);
152 _snprintf_s(last_error,
sizeof(last_error), _TRUNCATE,
"SELOGGER: integrity check failed %s", s.c_str());
153 sqlite3_free_table(pazResult);
155 throw std::exception(last_error);
158 rc = sqlite3_exec(
m_db,
"PRAGMA cache_size = 40000; "
160 "PRAGMA auto_vacuum = FULL; "
161 "PRAGMA journal_mode = WAL; "
163 "PRAGMA temp_store = MEMORY; ", NULL, NULL, &errmsg);
168 rc = sqlite3_get_table(
m_db,
169 "SELECT * FROM config WHERE name = 'version';",
170 &pazResult, &pnRow, &pnColumn, &errmsg);
173 if (pnRow == 1 && pnColumn == 2)
175 version = atol(pazResult[pnColumn+1]);
177 sqlite3_free_table(pazResult);
181 sqlite3_free(errmsg);
192 rc = sqlite3_exec(
m_db,
193 "DROP TABLE IF EXISTS run; "
194 "DROP TRIGGER IF EXISTS on_selog; ", NULL, NULL, &errmsg);
197 rc = sqlite3_exec(
m_db,
198 "DROP TABLE IF EXISTS config;"
199 "CREATE TABLE config ("
200 "name TEXT PRIMARY KEY, "
201 "value TEXT );", NULL, NULL, &errmsg);
203 _snprintf_s(sql_line,
sizeof(sql_line), _TRUNCATE,
"INSERT INTO config VALUES ('version', %d);",
db_schema_version);
204 rc = sqlite3_exec(
m_db, sql_line, NULL, NULL, &errmsg);
206 rc = sqlite3_exec(
m_db,
207 "DROP TABLE IF EXISTS selog;"
208 "CREATE TABLE selog ("
209 "run_number INTEGER NOT NULL, "
210 "source TEXT DEFAULT 'UNKNOWN', "
211 "iso_time TEXT DEFAULT '1970-01-01T00:00:00', "
212 "unix_time INTEGER DEFAULT 0, "
213 "block_name TEXT NOT NULL, "
214 "block_value TEXT NOT NULL, "
215 "is_real INTEGER DEFAULT 0);", NULL, NULL, &errmsg);
217 rc = sqlite3_exec(
m_db,
218 "DROP TABLE IF EXISTS run_status;"
219 "CREATE TABLE run_status ("
220 "run_number INTEGER NOT NULL, "
223 "unix_time INTEGER, "
225 "run_status INTEGER, "
226 "is_running INTEGER, "
227 "is_waiting INTEGER, "
228 "good_frames INTEGER, "
229 "raw_frames INTEGER, "
232 "monitor1_sum INTEGER, "
233 "dae_beam_current REAL, "
234 "total_counts INTEGER, "
236 "np_ratio REAL );", NULL, NULL, &errmsg);
238 rc = sqlite3_exec(
m_db,
239 "DROP TABLE IF EXISTS seblocks;"
240 "CREATE TABLE seblocks ("
241 "run_number INTEGER NOT NULL, "
242 "block_name TEXT NOT NULL, "
243 "setpoint_value TEXT DEFAULT '0.0', "
244 "vi_name TEXT DEFAULT '', "
245 "read_control TEXT DEFAULT '', "
246 "set_control TEXT DEFAULT '', "
247 "button_control TEXT DEFAULT '', "
248 "options INTEGER DEFAULT 0, "
249 "nexus_name TEXT DEFAULT '', "
250 "low_limit REAL DEFAULT 0.0, "
251 "high_limit REAL DEFAULT 0.0, "
252 "units TEXT DEFAULT '', "
253 "block_value TEXT DEFAULT '0.0', "
254 "is_real INTEGER DEFAULT 0, "
255 "source TEXT DEFAULT 'UNKNOWN', "
256 "setpoint_time TEXT DEFAULT '1970-01-01T00:00:00', "
257 "value_time TEXT DEFAULT '1970-01-01T00:00:00', "
258 "PRIMARY KEY(run_number, block_name) );", NULL, NULL, &errmsg);
260 rc = sqlite3_exec(
m_db,
261 "DROP TABLE IF EXISTS seperiods;"
262 "CREATE TABLE seperiods ("
263 "run_number INTEGER NOT NULL, "
266 "unix_time INTEGER, "
268 "block_name TEXT NOT NULL, "
269 "block_setpoint TEXT, "
270 "block_value TEXT );", NULL, NULL, &errmsg);
272 rc = sqlite3_exec(
m_db,
273 "DROP TABLE IF EXISTS run_state;"
274 "CREATE TABLE run_state ("
275 "run_number INTEGER NOT NULL, "
279 "unix_time INTEGER );", NULL, NULL, &errmsg);
281 rc = sqlite3_exec(
m_db,
282 "DROP TABLE IF EXISTS measurement;"
283 "CREATE TABLE measurement ("
284 "uuid STRING PRIMARY KEY, "
285 "run_number INTEGER, "
287 "label STRING );", NULL, NULL, &errmsg);
290 rc = sqlite3_exec(
m_db,
291 "DROP INDEX IF EXISTS selog_index; "
292 "CREATE INDEX selog_index ON selog (run_number, block_name); "
293 "DROP INDEX IF EXISTS seperiods_index; "
294 "CREATE INDEX seperiods_index ON seperiods (run_number, block_name); "
295 "DROP INDEX IF EXISTS run_status_index; "
296 "CREATE INDEX run_status_index ON run_status (run_number); "
297 "DROP INDEX IF EXISTS run_state_index; "
298 "CREATE INDEX run_state_index ON run_state (run_number); ", NULL, NULL, &errmsg);
301 rc = sqlite3_exec(
m_db,
302 "DROP VIEW IF EXISTS c_period; "
303 "CREATE VIEW c_period AS SELECT value FROM config WHERE name='period'; "
304 "DROP VIEW IF EXISTS c_run_number; "
305 "CREATE VIEW c_run_number AS SELECT value FROM config WHERE name='run_number'; ",
306 NULL, NULL, &errmsg);
318 rc = sqlite3_exec(
m_db,
319 "DROP TRIGGER IF EXISTS on_config_update; "
320 "CREATE TRIGGER on_config_update AFTER UPDATE ON config FOR EACH ROW WHEN (NEW.name='run_number') BEGIN "
321 "INSERT OR IGNORE INTO seblocks SELECT NEW.value, block_name, setpoint_value, vi_name, read_control, "
322 "set_control, button_control, options, nexus_name, low_limit, high_limit, units, block_value, "
323 "is_real, source, setpoint_time, value_time FROM seblocks WHERE run_number=OLD.value; "
324 "END; ", NULL, NULL, &errmsg);
328 rc = sqlite3_exec(
m_db,
329 "DROP TRIGGER IF EXISTS on_config_insert; "
330 "CREATE TRIGGER on_config_insert AFTER INSERT ON config FOR EACH ROW WHEN (NEW.name='run_number') BEGIN "
331 "INSERT OR IGNORE INTO seblocks SELECT NEW.value, block_name, setpoint_value, vi_name, read_control, "
332 "set_control, button_control, options, nexus_name, low_limit, high_limit, units, block_value, "
333 "is_real, source, setpoint_time, value_time FROM seblocks WHERE run_number=-1; "
334 "END; ", NULL, NULL, &errmsg);
336 rc = sqlite3_exec(
m_db,
337 "DROP TRIGGER IF EXISTS on_run_state; "
338 "CREATE TRIGGER on_run_state AFTER INSERT ON run_state FOR EACH ROW BEGIN "
339 "INSERT INTO seperiods SELECT c_run_number.value,c_period.value,NEW.iso_time,NEW.unix_time,NEW.is_start,seblocks.block_name,seblocks.setpoint_value,seblocks.block_value FROM c_run_number,c_period,seblocks WHERE seblocks.run_number=NEW.run_number; "
340 "INSERT INTO selog SELECT c_run_number.value,'TRIGGER',NEW.iso_time,NEW.unix_time,seblocks.block_name,seblocks.block_value,seblocks.is_real FROM c_run_number,seblocks WHERE seblocks.run_number=NEW.run_number; "
341 "END; ", NULL, NULL, &errmsg);
static const char * db_file
ISISDB(bool integrity_check)
Poco::SingletonHolder< SQLITESessionPool > sqlite_session_pool
static const char * isisdb_per_session_sql
static std::list< sqlite3 * > db_list
static char last_error[1024]
static const int db_schema_version
update when you change database schema
static volatile HANDLE db_mutex
#define SQLITE_CHECK_RC(__rc)