1 #include "daq/slc/database/DBObjectLoader.h"
3 #include <daq/slc/system/LogFile.h>
5 #include <daq/slc/base/StringUtil.h>
6 #include <daq/slc/base/ConfigFile.h>
7 #include <daq/slc/database/DBHandlerException.h>
14 #include <daq/slc/system/LockGuard.h>
18 Mutex DBObjectLoader::m_mutex;
20 DBObject DBObjectLoader::load(
const std::string& filename)
28 const std::string nodename = config.get(
"nodename");
29 const std::string configname = config.get(
"config");
31 if (nodename.size() > 0)
32 obj.setName(nodename +
"@" + configname);
34 obj.setName(configname);
35 for (StringList::iterator it = config.getLabels().begin();
36 it != config.getLabels().end(); it++) {
37 const std::string name = *it;
38 StringList str = StringUtil::split(name,
'.');
39 if (str[0] ==
"config")
continue;
40 if (str[0] ==
"nodename")
continue;
41 std::string value = config.get(name);
42 std::string::size_type pos = value.find_first_of(
"(");
43 DBField::Type type = DBField::TEXT;
44 if (pos != std::string::npos) {
45 std::string type_s = value.substr(0, pos);
46 if (type_s ==
"bool") type = DBField::BOOL;
47 else if (type_s ==
"int") type = DBField::INT;
48 else if (type_s ==
"float") type = DBField::FLOAT;
49 else if (type_s ==
"double") type = DBField::DOUBLE;
50 else if (type_s ==
"object") type = DBField::OBJECT;
51 if (type != DBField::TEXT) {
52 value = StringUtil::replace(value.substr(pos + 1),
")",
"");
56 if (StringUtil::tolower(value) ==
"true") {
58 }
else if (StringUtil::tolower(value) ==
"false") {
60 }
else if ((value.size() >= 2 && value.at(0) ==
'0' && value.at(1) ==
'x') ||
61 StringUtil::isdigit(value)) {
63 }
else if (StringUtil::split(value,
'.').size() < 3 &&
64 StringUtil::isdigit(StringUtil::replace(value,
".",
"")) &&
65 sscanf(value.c_str(),
"%f", &vf) == 1) {
66 type = DBField::DOUBLE;
71 if (!setObject(obj, str, type, value)) {
72 LogFile::error(
"error : %s : %s", name.c_str(), value.c_str());
79 const std::string& tablename,
80 const std::string& config_in,
bool isfull)
82 std::string configname = config_in;
83 if (!db.isConnected()) {
87 StringList list = DBObjectLoader::getDBlist(db, tablename, configname);
88 if (list.size() == 0)
return obj;
89 StringList s = StringUtil::split(list[0],
',');
90 DBRecordList record_v;
92 ss <<
"select * from " << s[1] <<
" where pid =" << s[2] <<
" order by id";
96 record_v = db.loadRecords();
101 if (list.size() > 0) {
103 timestamp = atoi(s[4].c_str());
106 ss <<
" config : " << configname << std::endl;
107 for (
size_t i = 0; i < record_v.size(); i++) {
109 if (record.hasField(
"value_b")) {
110 ss << record.get(
"name") <<
" : " <<
111 (record.getBool(
"value_b") ?
"true" :
"false") << std::endl;
112 }
else if (record.hasField(
"value_i")) {
113 ss << record.get(
"name") <<
" : int(" << record.get(
"value_i") <<
")" << std::endl;
114 }
else if (record.hasField(
"value_f")) {
115 ss << record.get(
"name") <<
" : double(" << record.get(
"value_f") <<
")" << std::endl;
116 }
else if (record.hasField(
"value_t")) {
117 ss << record.get(
"name") <<
" : \"" << record.get(
"value_t") <<
"\"" << std::endl;
121 obj = DBObjectLoader::load(conf);
122 obj.setDate(timestamp);
126 bool DBObjectLoader::add(
DBObject& obj, StringList& str,
127 const std::string& name_in,
const DBObject& cobj)
129 std::string name = str[0];
131 StringList sstr = StringUtil::split(str[0],
'[');
132 if (sstr.size() > 1) {
133 index = atoi(sstr[1].c_str());
139 if (str.size() > 1) {
140 str.erase(str.begin());
141 if (obj.hasObject(name)) {
142 return add(obj.getObject(name, index), str, name_in, cobj);
144 throw (std::out_of_range(StringUtil::form(
"%s:%d %s", __FILE__, __LINE__,
147 if (obj.hasObject(name) && obj.getNObjects(name) > index) {
148 obj.getObject(name, index).addObject(name_in, cobj);
151 obj.addObject(name, cobj);
154 throw (std::out_of_range(StringUtil::form(
"%s:%d %s", __FILE__, __LINE__,
155 StringUtil::join(str,
".").c_str())));
158 bool DBObjectLoader::setObject(
DBObject& obj, StringList& str,
159 DBField::Type type,
const std::string& value,
160 const std::string& table_in,
const std::string& config_in,
165 if (str.size() > 0) {
166 StringList sstr = StringUtil::split(str[0],
'[');
167 if (sstr.size() > 1) {
168 index = atoi(sstr[1].c_str());
177 if (str.size() > 1) {
178 str.erase(str.begin());
179 bool found = obj.hasObject(name);
181 DBObjectList& objs(obj.getObjects(name));
182 for (DBObjectList::iterator it = objs.begin();
183 it != objs.end(); it++) {
184 if (it->getIndex() == index) {
194 cobj.setIndex(index);
195 obj.addObject(name, cobj);
197 DBObjectList& objs(obj.getObjects(name));
198 for (DBObjectList::iterator it = objs.begin();
199 it != objs.end(); it++) {
201 if (cobj.getIndex() == index) {
202 return setObject(cobj, str, type, value, table_in, config_in, db);
207 case DBField::BOOL: obj.addBool(name,
false);
break;
208 case DBField::INT: obj.addInt(name, 0);
break;
209 case DBField::FLOAT: obj.addFloat(name, 0);
break;
210 case DBField::DOUBLE: obj.addDouble(name, 0);
break;
211 case DBField::TEXT: obj.addText(name, value);
break;
212 case DBField::OBJECT: {
214 std::string config_out = config_in;
217 StringList list = DBObjectLoader::getDBlist(*db, table_in, config_out);
218 if (list.size() > 0) {
221 for (
size_t i = 0; i < list.size(); i++) {
222 if (config_out == list[0]) {
228 cobj = DBObjectLoader::load(*db, table_in, config_out,
true);
230 if (list.size() > 0) {
231 config_out = list[0];
232 cobj = DBObjectLoader::load(*db, table_in, config_out,
true);
237 if (cobj.hasObject(name)) {
238 cobj.getObject(name).setPath(table_in +
"/" + config_out);
239 obj.addObjects(name, cobj.getObjects(name));
242 obj.addObject(name, cobj);
245 default :
return false;
247 obj.setValueText(name, value);
254 const std::string& tablename,
257 std::string tablename_date = tablename +
"_" +
Date().toString(
"%Y");
258 std::string tablename_id = tablename +
"_id";
260 if (!db.isConnected()) db.connect();
262 LogFile::error(
e.what());
266 if (obj.getName().size() == 0) {
267 LogFile::error(
"Configname is null. createDB canceled.");
270 if (!db.checkTable(
"daqconfig")) {
271 db.execute(
"create table daqconfig \n"
272 "(name text not null, \n"
273 "id bigserial, lastupdate timestamp, \n"
275 db.execute(
"create index daqconfig_id_index on daqconfig(id);",
276 tablename.c_str(), tablename.c_str());
278 if (!db.checkTable(tablename_id)) {
280 db.execute(
"insert into daqconfig (name, lastupdate) values "
281 "('%s', current_timestamp);", tablename_id.c_str());
282 }
catch (
const std::exception& e) {
283 db.execute(
"update daqconfig set lastupdate = current_timestamp where name = '%s';",
284 tablename_id.c_str());
286 db.execute(
"create table %s \n"
287 "(name text not null \n"
288 "check (replace(name, '.', '') = name) not null, \n"
291 "record_time timestamp with time zone default current_timestamp, \n"
292 "UNIQUE (name)); ", tablename_id.c_str());
294 if (!db.checkTable(tablename_date)) {
296 db.execute(
"insert into daqconfig (name, lastupdate) values "
297 "('%s', current_timestamp);", tablename_date.c_str());
298 }
catch (
const std::exception& e) {
299 db.execute(
"update daqconfig set lastupdate = current_timestamp where name = '%s';",
300 tablename_date.c_str());
302 db.execute(
"create table %s \n"
303 "(name text not null,\n"
306 "value_b boolean default NULL, \n"
307 "value_i int default NULL, \n"
308 "value_f float default NULL, \n"
309 "value_t text default NULL \n"
310 "); ", tablename_date.c_str());
311 db.execute(
"create index %s_index on %s(id);",
312 tablename_date.c_str(), tablename_date.c_str());
315 LogFile::warning(
e.what());
318 db.execute(
"begin;");
322 db.execute(
"insert into %s (name, content) values ('%s','%s') returning id;",
323 tablename_id.c_str(), obj.getName().c_str(), tablename_date.c_str());
325 DBRecordList record(db.loadRecords());
326 if (record.size() > 0) {
327 id = record[0].getInt(
"id");
330 LogFile::error(
e.what());
332 db.execute(
"commit;");
333 if (failed)
return false;
334 std::string s = obj.printSQL(tablename_date,
id);
337 LogFile::error(
e.what());
343 StringList DBObjectLoader::getDBlist(
DBInterface& db,
344 const std::string& tablename,
345 const std::string& grep,
int max)
349 if (!db.isConnected()) db.connect();
350 std::stringstream ss;
351 if (grep.size() > 0) {
352 const char* prefix = grep.c_str();
353 ss <<
"select id,name,content,to_char(record_time,'DD/MM HH24:MI:SS') as tdate, extract(epoch from record_time) as utime from " <<
354 tablename <<
"_id where "
355 <<
"(name like '" << prefix <<
"_%' or "
356 <<
"name like '" << prefix <<
"') order by id desc";
357 if (max > 0) ss <<
" limit " << max;
360 ss <<
"select id,name,content,to_char(record_time,'DD/MM HH24:MI:SS') as tdate, extract(epoch from record_time) as utime from " <<
361 tablename <<
"_id order by id desc";
362 if (max > 0) ss <<
" limit " << max;
366 db.execute(ss.str());
367 DBRecordList record_v(db.loadRecords());
368 for (
size_t i = 0; i < record_v.size(); i++) {
370 str.push_back(record.get(
"name") +
"," + record.get(
"content") +
"," +
371 record.get(
"id") +
"," + record.get(
"tdate") +
"," + record.get(
"utime"));
374 LogFile::error(
e.what());