1 #include "daq/slc/database/DBObject.h"
3 #include <daq/slc/base/StringUtil.h>
4 #include <daq/slc/base/Reader.h>
5 #include <daq/slc/base/Writer.h>
19 DBObject::DBObject(
const std::string& path)
25 DBObject::DBObject(
const DBObject& obj)
37 void DBObject::copy(
const DBObject& obj)
40 setDate(obj.getDate());
41 setIndex(obj.getIndex());
43 setPath(obj.getPath());
44 setName(obj.getName());
45 for (DBField::NameList::const_iterator it = obj.getFieldNames().begin();
46 it != obj.getFieldNames().end(); it++) {
47 const std::string& name(*it);
48 DBField::Type type = obj.getProperty(name).getType();
50 case DBField::BOOL: addBool(name, obj.getBool(name));
break;
51 case DBField::CHAR: addChar(name, obj.getChar(name));
break;
52 case DBField::SHORT: addShort(name, obj.getShort(name));
break;
53 case DBField::INT: addInt(name, obj.getInt(name));
break;
54 case DBField::LONG: addLong(name, obj.getLong(name));
break;
55 case DBField::FLOAT: addFloat(name, obj.getFloat(name));
break;
56 case DBField::DOUBLE: addDouble(name, obj.getDouble(name));
break;
57 case DBField::TEXT: addText(name, obj.getText(name));
break;
58 case DBField::OBJECT: addObjects(name, obj.getObjects(name));
break;
69 int DBObject::getNObjects(
const std::string& name)
const
71 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
72 if (it != m_obj_v_m.end())
return it->second.size();
76 DBObjectList& DBObject::getObjects(
const std::string& name)
78 FieldObjectList::iterator it = m_obj_v_m.find(name);
79 if (it != m_obj_v_m.end())
return it->second;
80 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
81 name.c_str(), getName().c_str(),
82 __FILE__, __LINE__)));
85 const DBObjectList& DBObject::getObjects(
const std::string& name)
const
87 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
88 if (it != m_obj_v_m.end())
return it->second;
89 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
90 name.c_str(), getName().c_str(),
91 __FILE__, __LINE__)));
94 DBObject& DBObject::getObject(
const std::string& name,
int i)
96 FieldObjectList::iterator it = m_obj_v_m.find(name);
97 if (it != m_obj_v_m.end())
return it->second[i];
98 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
99 name.c_str(), getName().c_str(),
100 __FILE__, __LINE__)));
103 const DBObject& DBObject::getObject(
const std::string& name,
int i)
const
105 FieldObjectList::const_iterator it = m_obj_v_m.find(name);
106 if (it != m_obj_v_m.end())
return it->second[i];
107 else throw (std::out_of_range(StringUtil::form(
"%s not found in %s (%s:%d)",
108 name.c_str(), getName().c_str(),
109 __FILE__, __LINE__)));
112 void DBObject::reset()
114 const DBField::NameList& name_v(getFieldNames());
115 for (
size_t ii = 0; ii < name_v.size(); ii++) {
116 const std::string& name(name_v[ii]);
117 if (hasObject(name)) {
118 size_t nobj = getNObjects(name);
119 for (
size_t i = 0; i < nobj; i++) getObject(name, i).reset();
122 for (FieldValueList::iterator it = m_value_m.begin();
123 it != m_value_m.end(); it++) {
126 m_value_m = FieldValueList();
127 m_text_m = FieldTextList();
128 m_obj_v_m = FieldObjectList();
129 AbstractDBObject::reset();
132 void DBObject::readObject(
Reader& reader)
135 setPath(reader.readString());
136 setName(reader.readString());
137 setDate(reader.readInt());
138 int npar = reader.readInt();
139 for (
int i = 0; i < npar; i++) {
140 std::string name = reader.readString();
141 DBField::Type type = (DBField::Type)reader.readInt();
143 case DBField::BOOL: addBool(name, reader.readBool());
break;
144 case DBField::CHAR: addChar(name, reader.readChar());
break;
145 case DBField::SHORT: addShort(name, reader.readShort());
break;
146 case DBField::INT: addInt(name, reader.readInt());
break;
147 case DBField::LONG: addLong(name, reader.readLong());
break;
148 case DBField::FLOAT: addFloat(name, reader.readFloat());
break;
149 case DBField::DOUBLE: addDouble(name, reader.readDouble());
break;
150 case DBField::TEXT: addText(name, reader.readString());
break;
151 case DBField::OBJECT: {
153 int nobj = reader.readInt();
154 for (
int n = 0; n < nobj; n++) {
156 obj.readObject(reader);
158 obj_v.push_back(obj);
160 addObjects(name, obj_v);
167 void DBObject::writeObject(
Writer& writer)
const
169 writer.writeString(getPath());
170 writer.writeString(getName());
171 writer.writeInt(getDate());
172 const DBField::NameList& name_v(getFieldNames());
173 writer.writeInt(name_v.size());
174 for (DBField::NameList::const_iterator iname = name_v.begin();
175 iname != name_v.end(); iname++) {
176 const std::string name = *iname;
177 DBField::Type type = getProperty(name).getType();
178 writer.writeString(name);
179 writer.writeInt(type);
181 case DBField::BOOL: writer.writeBool(getBool(name));
break;
182 case DBField::CHAR: writer.writeChar(getChar(name));
break;
183 case DBField::SHORT: writer.writeShort(getShort(name));
break;
184 case DBField::INT: writer.writeInt(getInt(name));
break;
185 case DBField::LONG: writer.writeLong(getLong(name));
break;
186 case DBField::FLOAT: writer.writeFloat(getFloat(name));
break;
187 case DBField::DOUBLE: writer.writeDouble(getDouble(name));
break;
188 case DBField::TEXT: writer.writeString(getText(name));
break;
189 case DBField::OBJECT: {
190 const DBObjectList& obj_v(getObjects(name));
191 writer.writeInt(obj_v.size());
192 for (DBObjectList::const_iterator iobj = obj_v.begin();
193 iobj != obj_v.end(); iobj++) {
194 iobj->writeObject(writer);
202 const void* DBObject::getValue(
const std::string& name)
const
204 if (!hasValue(name))
return NULL;
205 FieldValueList::const_iterator it = m_value_m.find(name);
206 if (it != m_value_m.end())
return it->second;
207 else throw (std::out_of_range(StringUtil::form(
"value %s not found", name.c_str())));
210 const std::string& DBObject::getText(
const std::string& name)
const
212 if (!hasText(name))
return m_empty;
213 FieldTextList::const_iterator it = m_text_m.find(name);
214 if (it != m_text_m.end())
return it->second;
215 else throw (std::out_of_range(StringUtil::form(
"text %s not found", name.c_str())));
218 void DBObject::addValue(
const std::string& name,
const void* value,
219 DBField::Type type,
int)
222 int size = pro.getTypeSize();
223 if (size <= 0)
return;
224 if (!hasValue(name)) {
226 void* v = malloc(size);
227 memcpy(v, value, size);
228 m_value_m.insert(FieldValueList::value_type(name, v));
230 memcpy(m_value_m[name], value, size);
234 void DBObject::setValue(
const std::string& name,
235 const void* value,
int)
238 int size = pro.getTypeSize();
239 if (hasField(name) && size > 0) {
240 memcpy(m_value_m[name], value, size);
244 void DBObject::addText(
const std::string& name,
245 const std::string& value)
247 if (!hasField(name)) {
249 m_text_m.insert(FieldTextList::value_type(name, value));
251 m_text_m[name] = value;
255 void DBObject::addObject(
const std::string& name,
258 if (!hasField(name)) {
260 m_obj_v_m.insert(FieldObjectList::value_type(name, DBObjectList()));
262 m_obj_v_m[name].push_back(obj);
263 getProperty(name).setLength(m_obj_v_m[name].size());
266 void DBObject::addObjects(
const std::string& name,
267 const DBObjectList& obj_v)
269 if (!hasField(name)) {
271 m_obj_v_m.insert(FieldObjectList::value_type(name, obj_v));
273 m_obj_v_m[name] = obj_v;
277 void DBObject::print(
bool isfull)
const
279 const std::string& name_in =
"";
281 search(map, name_in, isfull);
283 for (NameValueList::iterator it = map.begin();
284 it != map.end(); it++) {
285 if (it->name.size() > length) length = it->name.size();
288 printf(
"# DB object (confname = %s) stored at %s\n", getName().c_str(),
Date(getDate()).toString());
291 StringList s = StringUtil::split(getName(),
'@');
293 printf(
"%*s : %s\n",
int(-length),
"nodename", s[0].c_str());
294 printf(
"%*s : %s\n",
int(-length),
"config", s[1].c_str());
296 printf(
"%*s : %s\n",
int(-length),
"config", getName().c_str());
299 for (NameValueList::iterator it = map.begin();
300 it != map.end(); it++) {
301 printf(
"%*s : %s\n",
int(-length), it->name.c_str(), it->value.c_str());
309 const std::string DBObject::sprint(
bool isfull)
const
311 std::stringstream ss;
312 const std::string& name_in =
"";
314 search(map, name_in, isfull);
316 for (NameValueList::iterator it = map.begin();
317 it != map.end(); it++) {
318 if (it->name.size() > length) length = it->name.size();
320 ss <<
"#" << std::endl;
321 ss <<
"# DB object (confname = " << getName() <<
")" << std::endl;
322 ss <<
"#" << std::endl;
323 ss <<
"" << std::endl;
324 StringList s = StringUtil::split(getName(),
'@');
326 ss << StringUtil::form(
"%*s : %s\n", -length,
"nodename", s[0].c_str())
328 ss << StringUtil::form(
"%*s : %s\n", -length,
"config", s[1].c_str())
331 ss << StringUtil::form(
"%*s : %s\n", -length,
"config", getName().c_str())
334 ss <<
"" << std::endl;
335 for (NameValueList::iterator it = map.begin();
336 it != map.end(); it++) {
337 ss << StringUtil::form(
"%*s : %s\n", -length, it->name.c_str(), it->value.c_str())
340 ss <<
"" << std::endl;
341 ss <<
"#" << std::endl;
342 ss <<
"#" << std::endl;
343 ss <<
"#" << std::endl;
347 void DBObject::printHTML(
bool isfull)
const
349 const std::string& name_in =
"";
351 search(map, name_in, isfull);
353 printf(
"<caption><strong>%s</strong></caption>\n", getName().c_str());
354 printf(
"<thead><tr><th>Name</th><th>Value</th>\n</tr></thead>\n");
356 StringList s = StringUtil::split(getName(),
'@');
358 printf(
"<tr><td>nodename</td><td>%s</td>\n", s[0].c_str());
359 printf(
"<tr><td>config</td><td>%s</td>\n", s[1].c_str());
361 printf(
"<tr><td>config</td><td>%s</td>\n", getName().c_str());
363 std::string rcconfig, dbtable, nodename;
364 for (NameValueList::iterator it = map.begin();
365 it != map.end(); it++) {
366 if (it->name.find(
"name") != std::string::npos) {
367 nodename = it->value;
368 printf(
"<tr><td>%s</td><td>%s</td>\n", it->name.c_str(), it->value.c_str());
369 }
else if (it->name.find(
"rcconfig") != std::string::npos) {
370 rcconfig = it->value;
371 }
else if (it->name.find(
"dbtable") != std::string::npos) {
373 printf(
"<tr><td>%s</td><td><a href=\"./daqconfig.php?db=%s&config=%s@%s\" >%s/%s</a></td>\n",
374 it->name.c_str(), dbtable.c_str(), nodename.c_str(), rcconfig.c_str(),
375 dbtable.c_str(), rcconfig.c_str());
377 printf(
"<tr><td>%s</td><td>%s</td>\n", it->name.c_str(), it->value.c_str());
380 printf(
"</tbody>\n");
381 printf(
"</table>\n");
384 StringList DBObject::getNameList(
bool isfull)
const
386 const std::string& name_in =
"";
388 search(map, name_in, isfull);
390 for (NameValueList::iterator it = map.begin();
391 it != map.end(); it++) {
392 str.push_back(it->name);
397 void DBObject::search(NameValueList& map,
const std::string& name_in,
bool isfull)
400 const DBField::NameList& name_v(getFieldNames());
401 for (DBField::NameList::const_iterator it = name_v.begin();
402 it != name_v.end(); it++) {
403 const std::string& name(*it);
405 std::string name_out = name_in;
406 if (name_in.size() > 0) name_out +=
".";
409 switch (pro.getType()) {
410 case DBField::BOOL: ptype =
"bool";
break;
411 case DBField::INT: ptype =
"int";
break;
412 case DBField::FLOAT: ptype =
"float";
break;
413 case DBField::DOUBLE: ptype =
"double";
break;
416 if (pro.getType() == DBField::OBJECT) {
417 int length = getNObjects(name);
418 if (!isfull && getObject(name).getPath().size() > 0) {
419 const DBObjectList& objs(getObjects(name));
420 if (length == 1 || objs[1].getPath().size() == 0 || objs[0].getPath() == objs[1].getPath()) {
421 std::string value = objs[0].getPath();
422 value =
"object(" + value +
")";
424 nv.name = name_out.c_str();
426 nv.type = pro.getType();
429 for (
int i = 0; i < length; i++) {
430 std::string value = objs[i].getPath();
431 value =
"object(" + value +
")";
433 nv.name = StringUtil::form(
"%s[%d].%s", name.c_str(), i, name_out.c_str());
435 nv.type = pro.getType();
440 size_t length = getNObjects(name);
442 const DBObjectList& objs(getObjects(name));
443 for (
size_t i = 0; i < length; i++) {
444 objs[i].search(map, StringUtil::form(
"%s[%d]", name_out.c_str(), i), isfull);
447 const DBObject& obj(getObject(name));
448 obj.search(map, name_out, isfull);
452 std::string value = getValueText(name);
453 if (ptype.size() > 0) value = ptype +
"(" + value +
")";
457 nv.type = pro.getType();
458 if (pro.getType() != DBField::TEXT) {
459 nv.buf = (
void*)getValue(name);
461 nv.buf = (
void*)&getText(name);
468 const std::string DBObject::printSQL(
const std::string& table,
int id)
const
470 std::stringstream ss;
472 const std::string& name_in =
"";
475 search(map, name_in, isfull);
476 for (NameValueList::iterator it = map.begin();
477 it != map.end(); it++) {
480 std::string value = nv.value;
481 std::string::size_type pos = value.find_first_of(
"(");
482 DBField::Type type = DBField::TEXT;
483 if (pos != std::string::npos) {
484 std::string type_s = value.substr(0, pos);
485 if (type_s ==
"bool") type = DBField::BOOL;
486 else if (type_s ==
"char") type = DBField::CHAR;
487 else if (type_s ==
"short") type = DBField::SHORT;
488 else if (type_s ==
"int") type = DBField::INT;
489 else if (type_s ==
"float") type = DBField::FLOAT;
490 else if (type_s ==
"double") type = DBField::DOUBLE;
491 else if (type_s ==
"object") type = DBField::OBJECT;
492 if (type != DBField::TEXT) {
493 value = StringUtil::replace(value.substr(pos + 1),
")",
"");
499 ss <<
"insert into " << table <<
" (pid,name,value_b) values "
500 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
503 ss <<
"insert into " << table <<
" (pid,name,value_i) values "
504 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
507 case DBField::DOUBLE:
508 ss <<
"insert into " << table <<
" (pid,name,value_f) values "
509 <<
"(" <<
id <<
",'" << nv.name <<
"'," << value <<
");" << std::endl;
512 ss <<
"insert into " << table <<
" (pid,name,value_t) values "
513 <<
"(" <<
id <<
",'" << nv.name <<
"','" << value <<
"');" << std::endl;