8#include "daq/slc/database/DBObject.h"
10#include <daq/slc/base/StringUtil.h>
11#include <daq/slc/base/Reader.h>
12#include <daq/slc/base/Writer.h>
26DBObject::DBObject(
const std::string& path)
32DBObject::DBObject(
const DBObject& obj)
44void DBObject::copy(
const DBObject& obj)
47 setDate(obj.getDate());
48 setIndex(obj.getIndex());
50 setPath(obj.getPath());
51 setName(obj.getName());
52 for (DBField::NameList::const_iterator it = obj.getFieldNames().begin();
53 it != obj.getFieldNames().end(); ++it) {
54 const std::string& name(*it);
55 DBField::Type type = obj.getProperty(name).getType();
57 case DBField::BOOL: addBool(name, obj.getBool(name));
break;
58 case DBField::CHAR: addChar(name, obj.getChar(name));
break;
59 case DBField::SHORT: addShort(name, obj.getShort(name));
break;
60 case DBField::INT: addInt(name, obj.getInt(name));
break;
61 case DBField::LONG: addLong(name, obj.getLong(name));
break;
62 case DBField::FLOAT: addFloat(name, obj.getFloat(name));
break;
63 case DBField::DOUBLE: addDouble(name, obj.getDouble(name));
break;
64 case DBField::TEXT: addText(name, obj.getText(name));
break;
65 case DBField::OBJECT: addObjects(name, obj.getObjects(name));
break;
76int DBObject::getNObjects(
const std::string& name)
const
78 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
79 if (it != m_obj_v_m.end())
return it->second.size();
83DBObjectList& DBObject::getObjects(
const std::string& name)
85 FieldObjectList::iterator it = m_obj_v_m.find(name);
86 if (it != m_obj_v_m.end())
return it->second;
87 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
88 name.c_str(), getName().c_str(),
89 __FILE__, __LINE__)));
92const DBObjectList& DBObject::getObjects(
const std::string& name)
const
94 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
95 if (it != m_obj_v_m.end())
return it->second;
96 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
97 name.c_str(), getName().c_str(),
98 __FILE__, __LINE__)));
101DBObject& DBObject::getObject(
const std::string& name,
int i)
103 FieldObjectList::iterator it = m_obj_v_m.find(name);
104 if (it != m_obj_v_m.end())
return it->second[i];
105 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
106 name.c_str(), getName().c_str(),
107 __FILE__, __LINE__)));
110const DBObject& DBObject::getObject(
const std::string& name,
int i)
const
112 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
113 if (it != m_obj_v_m.end())
return it->second[i];
114 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
115 name.c_str(), getName().c_str(),
116 __FILE__, __LINE__)));
119void DBObject::reset()
121 const DBField::NameList& name_v(getFieldNames());
122 for (
size_t ii = 0; ii < name_v.size(); ii++) {
123 const std::string& name(name_v[ii]);
124 if (hasObject(name)) {
125 size_t nobj = getNObjects(name);
126 for (
size_t i = 0; i < nobj; i++) getObject(name, i).reset();
129 for (FieldValueList::iterator it = m_value_m.begin();
130 it != m_value_m.end(); ++it) {
133 m_value_m = FieldValueList();
134 m_text_m = FieldTextList();
135 m_obj_v_m = FieldObjectList();
136 AbstractDBObject::reset();
139void DBObject::readObject(
Reader& reader)
142 setPath(reader.readString());
143 setName(reader.readString());
144 setDate(reader.readInt());
145 int npar = reader.readInt();
146 for (
int i = 0; i < npar; i++) {
147 std::string name = reader.readString();
148 DBField::Type type = (DBField::Type)reader.readInt();
150 case DBField::BOOL: addBool(name, reader.readBool());
break;
151 case DBField::CHAR: addChar(name, reader.readChar());
break;
152 case DBField::SHORT: addShort(name, reader.readShort());
break;
153 case DBField::INT: addInt(name, reader.readInt());
break;
154 case DBField::LONG: addLong(name, reader.readLong());
break;
155 case DBField::FLOAT: addFloat(name, reader.readFloat());
break;
156 case DBField::DOUBLE: addDouble(name, reader.readDouble());
break;
157 case DBField::TEXT: addText(name, reader.readString());
break;
158 case DBField::OBJECT: {
160 int nobj = reader.readInt();
161 for (
int n = 0; n < nobj; n++) {
163 obj.readObject(reader);
165 obj_v.push_back(obj);
167 addObjects(name, obj_v);
174void DBObject::writeObject(
Writer& writer)
const
176 writer.writeString(getPath());
177 writer.writeString(getName());
178 writer.writeInt(getDate());
179 const DBField::NameList& name_v(getFieldNames());
180 writer.writeInt(name_v.size());
181 for (DBField::NameList::const_iterator iname = name_v.begin();
182 iname != name_v.end(); ++iname) {
183 const std::string name = *iname;
184 DBField::Type type = getProperty(name).getType();
185 writer.writeString(name);
186 writer.writeInt(type);
188 case DBField::BOOL: writer.writeBool(getBool(name));
break;
189 case DBField::CHAR: writer.writeChar(getChar(name));
break;
190 case DBField::SHORT: writer.writeShort(getShort(name));
break;
191 case DBField::INT: writer.writeInt(getInt(name));
break;
192 case DBField::LONG: writer.writeLong(getLong(name));
break;
193 case DBField::FLOAT: writer.writeFloat(getFloat(name));
break;
194 case DBField::DOUBLE: writer.writeDouble(getDouble(name));
break;
195 case DBField::TEXT: writer.writeString(getText(name));
break;
196 case DBField::OBJECT: {
197 const DBObjectList& obj_v(getObjects(name));
198 writer.writeInt(obj_v.size());
199 for (DBObjectList::const_iterator iobj = obj_v.begin();
200 iobj != obj_v.end(); ++iobj) {
201 iobj->writeObject(writer);
209const void* DBObject::getValue(
const std::string& name)
const
211 if (!hasValue(name))
return NULL;
212 FieldValueList::const_iterator it = m_value_m.find(name);
213 if (it != m_value_m.end())
return it->second;
214 else throw (std::out_of_range(StringUtil::form(
"value %s not found", name.c_str())));
217const std::string& DBObject::getText(
const std::string& name)
const
219 if (!hasText(name))
return m_empty;
220 FieldTextList::const_iterator it = m_text_m.find(name);
221 if (it != m_text_m.end())
return it->second;
222 else throw (std::out_of_range(StringUtil::form(
"text %s not found", name.c_str())));
225void DBObject::addValue(
const std::string& name,
const void* value,
226 DBField::Type type,
int)
229 int size = pro.getTypeSize();
230 if (size <= 0)
return;
231 if (!hasValue(name)) {
233 void* v = malloc(size);
234 memcpy(v, value, size);
235 m_value_m.insert(FieldValueList::value_type(name, v));
237 memcpy(m_value_m[name], value, size);
241void DBObject::setValue(
const std::string& name,
242 const void* value,
int)
245 int size = pro.getTypeSize();
246 if (hasField(name) && size > 0) {
247 memcpy(m_value_m[name], value, size);
251void DBObject::addText(
const std::string& name,
252 const std::string& value)
254 if (!hasField(name)) {
256 m_text_m.insert(FieldTextList::value_type(name, value));
258 m_text_m[name] = value;
262void DBObject::addObject(
const std::string& name,
265 if (!hasField(name)) {
267 m_obj_v_m.insert(FieldObjectList::value_type(name, DBObjectList()));
269 m_obj_v_m[name].push_back(obj);
270 getProperty(name).setLength(m_obj_v_m[name].size());
273void DBObject::addObjects(
const std::string& name,
274 const DBObjectList& obj_v)
276 if (!hasField(name)) {
278 m_obj_v_m.insert(FieldObjectList::value_type(name, obj_v));
280 m_obj_v_m[name] = obj_v;
284void DBObject::print(
bool isfull)
const
286 const std::string& name_in =
"";
288 search(map, name_in, isfull);
290 for (NameValueList::iterator it = map.begin();
291 it != map.end(); ++it) {
292 if (it->name.size() > length) length = it->name.size();
295 printf(
"# DB object (confname = %s) stored at %s\n", getName().c_str(),
Date(getDate()).toString());
298 StringList s = StringUtil::split(getName(),
'@');
300 printf(
"%*s : %s\n",
int(-length),
"nodename", s[0].c_str());
301 printf(
"%*s : %s\n",
int(-length),
"config", s[1].c_str());
303 printf(
"%*s : %s\n",
int(-length),
"config", getName().c_str());
306 for (NameValueList::iterator it = map.begin();
307 it != map.end(); ++it) {
308 printf(
"%*s : %s\n",
int(-length), it->name.c_str(), it->value.c_str());
316const std::string DBObject::sprint(
bool isfull)
const
318 std::stringstream ss;
319 const std::string& name_in =
"";
321 search(map, name_in, isfull);
323 for (NameValueList::iterator it = map.begin();
324 it != map.end(); ++it) {
325 if (it->name.size() > length) length = it->name.size();
327 ss <<
"#" << std::endl;
328 ss <<
"# DB object (confname = " << getName() <<
")" << std::endl;
329 ss <<
"#" << std::endl;
330 ss <<
"" << std::endl;
331 StringList s = StringUtil::split(getName(),
'@');
333 ss << StringUtil::form(
"%*s : %s\n", -length,
"nodename", s[0].c_str())
335 ss << StringUtil::form(
"%*s : %s\n", -length,
"config", s[1].c_str())
338 ss << StringUtil::form(
"%*s : %s\n", -length,
"config", getName().c_str())
341 ss <<
"" << std::endl;
342 for (NameValueList::iterator it = map.begin();
343 it != map.end(); ++it) {
344 ss << StringUtil::form(
"%*s : %s\n", -length, it->name.c_str(), it->value.c_str())
347 ss <<
"" << std::endl;
348 ss <<
"#" << std::endl;
349 ss <<
"#" << std::endl;
350 ss <<
"#" << std::endl;
354void DBObject::printHTML(
bool isfull)
const
356 const std::string& name_in =
"";
358 search(map, name_in, isfull);
360 printf(
"<caption><strong>%s</strong></caption>\n", getName().c_str());
361 printf(
"<thead><tr><th>Name</th><th>Value</th>\n</tr></thead>\n");
363 StringList s = StringUtil::split(getName(),
'@');
365 printf(
"<tr><td>nodename</td><td>%s</td>\n", s[0].c_str());
366 printf(
"<tr><td>config</td><td>%s</td>\n", s[1].c_str());
368 printf(
"<tr><td>config</td><td>%s</td>\n", getName().c_str());
370 std::string rcconfig, dbtable, nodename;
371 for (NameValueList::iterator it = map.begin();
372 it != map.end(); ++it) {
373 if (it->name.find(
"name") != std::string::npos) {
374 nodename = it->value;
375 printf(
"<tr><td>%s</td><td>%s</td>\n", it->name.c_str(), it->value.c_str());
376 }
else if (it->name.find(
"rcconfig") != std::string::npos) {
377 rcconfig = it->value;
378 }
else if (it->name.find(
"dbtable") != std::string::npos) {
380 printf(
"<tr><td>%s</td><td><a href=\"./daqconfig.php?db=%s&config=%s@%s\" >%s/%s</a></td>\n",
381 it->name.c_str(), dbtable.c_str(), nodename.c_str(), rcconfig.c_str(),
382 dbtable.c_str(), rcconfig.c_str());
384 printf(
"<tr><td>%s</td><td>%s</td>\n", it->name.c_str(), it->value.c_str());
387 printf(
"</tbody>\n");
388 printf(
"</table>\n");
391StringList DBObject::getNameList(
bool isfull)
const
393 const std::string& name_in =
"";
395 search(map, name_in, isfull);
397 for (NameValueList::iterator it = map.begin();
398 it != map.end(); ++it) {
399 str.push_back(it->name);
404void DBObject::search(NameValueList& map,
const std::string& name_in,
bool isfull)
407 const DBField::NameList& name_v(getFieldNames());
408 for (DBField::NameList::const_iterator it = name_v.begin();
409 it != name_v.end(); ++it) {
410 const std::string& name(*it);
412 std::string name_out = name_in;
413 if (name_in.size() > 0) name_out +=
".";
416 switch (pro.getType()) {
417 case DBField::BOOL: ptype =
"bool";
break;
418 case DBField::INT: ptype =
"int";
break;
419 case DBField::FLOAT: ptype =
"float";
break;
420 case DBField::DOUBLE: ptype =
"double";
break;
423 if (pro.getType() == DBField::OBJECT) {
424 int length = getNObjects(name);
425 if (!isfull && getObject(name).getPath().size() > 0) {
426 const DBObjectList& objs(getObjects(name));
427 if (length == 1 || objs[1].getPath().size() == 0 || objs[0].getPath() == objs[1].getPath()) {
428 std::string value = objs[0].getPath();
429 value =
"object(" + value +
")";
431 nv.name = name_out.c_str();
433 nv.type = pro.getType();
436 for (
int i = 0; i < length; i++) {
437 std::string value = objs[i].getPath();
438 value =
"object(" + value +
")";
440 nv.name = StringUtil::form(
"%s[%d].%s", name.c_str(), i, name_out.c_str());
442 nv.type = pro.getType();
447 size_t lengthCur = getNObjects(name);
449 const DBObjectList& objs(getObjects(name));
450 for (
size_t i = 0; i < lengthCur; i++) {
451 objs[i].search(map, StringUtil::form(
"%s[%d]", name_out.c_str(), i), isfull);
454 const DBObject& obj(getObject(name));
455 obj.search(map, name_out, isfull);
459 std::string value = getValueText(name);
460 if (ptype.size() > 0) value = ptype +
"(" + value +
")";
464 nv.type = pro.getType();
465 if (pro.getType() != DBField::TEXT) {
466 nv.buf = (
void*)getValue(name);
468 nv.buf = (
void*)&getText(name);
475const std::string DBObject::printSQL(
const std::string& table,
int id)
const
477 std::stringstream ss;
479 const std::string& name_in =
"";
482 search(map, name_in, isfull);
483 for (NameValueList::iterator it = map.begin();
484 it != map.end(); ++it) {
486 std::string value = nv.value;
487 std::string::size_type pos = value.find_first_of(
"(");
488 DBField::Type type = DBField::TEXT;
489 if (pos != std::string::npos) {
490 std::string type_s = value.substr(0, pos);
491 if (type_s ==
"bool") type = DBField::BOOL;
492 else if (type_s ==
"char") type = DBField::CHAR;
493 else if (type_s ==
"short") type = DBField::SHORT;
494 else if (type_s ==
"int") type = DBField::INT;
495 else if (type_s ==
"float") type = DBField::FLOAT;
496 else if (type_s ==
"double") type = DBField::DOUBLE;
497 else if (type_s ==
"object") type = DBField::OBJECT;
498 if (type != DBField::TEXT) {
499 value = StringUtil::replace(value.substr(pos + 1),
")",
"");
505 ss <<
"insert into " << table <<
" (pid,name,value_b) values "
506 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
509 ss <<
"insert into " << table <<
" (pid,name,value_i) values "
510 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
513 case DBField::DOUBLE:
514 ss <<
"insert into " << table <<
" (pid,name,value_f) values "
515 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
518 ss <<
"insert into " << table <<
" (pid,name,value_t) values "
519 <<
"(" <<
id <<
",'" << nv.name <<
"','" << value <<
"');" << std::endl;
Abstract base class for different kinds of events.