Commit 7701b57a authored by Jonas Nylund's avatar Jonas Nylund

SevHistObject added and storage environment revisited

parent fa384bc6
......@@ -40,33 +40,7 @@
#include "pwr_baseclasses.h"
#define sev_cGarbageInterval 120
static int sev_comp_item(tree_sTable *tp, tree_sNode *x, tree_sNode *y)
{
sev_sItem *xp = (sev_sItem *) x;
sev_sItem *yp = (sev_sItem *) y;
if (xp->key.oid.vid > yp->key.oid.vid)
return 1;
if (xp->key.oid.vid < yp->key.oid.vid)
return -1;
if (xp->key.oid.oix > yp->key.oid.oix)
return 1;
if (xp->key.oid.oix < yp->key.oid.oix)
return -1;
if ( strcmp( xp->key.aname, yp->key.aname) > 0)
return 1;
if ( strcmp( xp->key.aname, yp->key.aname) < 0)
return -1;
return 0;
}
#define sev_cGarbageCycle 86400
int sev_server::init( int noneth)
{
......@@ -124,24 +98,18 @@ int sev_server::init( int noneth)
exit(0);
}
}
if( !env->checkAndUpdateVersion(constSevVersion) ) {
errh_Fatal("Failed to upgrade tables to sev version %d db:'%s'", constSevVersion, sev_dbms_env::dbName());
exit(0);
}
m_db = new sev_dbms( env);
errh_Info("Database opened '%s'", sev_dbms_env::dbName());
m_db->get_items( &m_sts);
m_item_key = tree_CreateTable(&sts, sizeof(sev_sItemKey), offsetof(sev_sItem, key), sizeof(sev_sItem), 100, sev_comp_item);
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
sev_sItemKey ik;
sev_sItem *ip;
ik.oid = m_db->m_items[i].oid;
strcpy( ik.aname, m_db->m_items[i].attr[0].aname);
ip = (sev_sItem *) tree_Insert(&sts, m_item_key, &ik);
ip->idx = i;
}
m_db->get_objectitems(&m_sts);
// Create a queue to server
qcom_sQattr attr;
......@@ -259,6 +227,8 @@ int sev_server::request_items( pwr_tNid nid)
int sev_server::send_itemlist( qcom_sQid tgt)
{
int item_cnt = 0;
int itemattr_cnt = 0;
qcom_sPut put;
pwr_tStatus sts, lsts;
int size;
......@@ -267,6 +237,7 @@ int sev_server::send_itemlist( qcom_sQid tgt)
if ( m_db->m_items[i].deleted)
continue;
item_cnt++;
itemattr_cnt += m_db->m_items[i].attrnum;
}
if ( !item_cnt)
......@@ -274,11 +245,82 @@ int sev_server::send_itemlist( qcom_sQid tgt)
size = sizeof(sev_sMsgHistItems) + (item_cnt - 1) * sizeof(sev_sHistItem);
size += itemattr_cnt * sizeof(sev_sHistAttr) - item_cnt * sizeof(sev_sHistAttr);
put.size = size;
put.data = qcom_Alloc(&lsts, put.size);
((sev_sMsgHistItems *)put.data)->Type = sev_eMsgType_HistItems;
((sev_sMsgHistItems *)put.data)->NumItems = item_cnt;
((sev_sMsgHistItems *)put.data)->NumAttributes = itemattr_cnt;
sev_sHistItem *itemPtr = ((sev_sMsgHistItems *)put.data)->Items;
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
if ( m_db->m_items[i].deleted)
continue;
itemPtr->oid = m_db->m_items[i].oid;
strcpy( itemPtr->oname, m_db->m_items[i].oname);
itemPtr->storagetime = net_DeltaTimeToNetTime(&m_db->m_items[i].storagetime);
itemPtr->creatime = net_TimeToNetTime( &m_db->m_items[i].creatime);
itemPtr->modtime = net_TimeToNetTime( &m_db->m_items[i].modtime);
strcpy( itemPtr->description, m_db->m_items[i].description);
itemPtr->attrnum = m_db->m_items[i].attrnum;
itemPtr->scantime = m_db->m_items[i].scantime;
itemPtr->deadband = m_db->m_items[i].deadband;
itemPtr->options = m_db->m_items[i].options;
size_t j = 0;
for( j = 0; j < m_db->m_items[i].attr.size(); j++ ) {
strcpy( itemPtr->attr[j].aname, m_db->m_items[i].attr[j].aname);
itemPtr->attr[j].type = m_db->m_items[i].attr[j].type;
itemPtr->attr[j].size = m_db->m_items[i].attr[j].size;
strcpy( itemPtr->attr[j].unit, m_db->m_items[i].attr[j].unit);
}
itemPtr = (sev_sHistItem *)&itemPtr->attr[j];
}
if ( !item_cnt)
((sev_sMsgHistItems *)put.data)->Status = SEV__NOITEMS;
else
((sev_sMsgHistItems *)put.data)->Status = SEV__SUCCESS;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevServer;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistItems;
put.msg_id = m_msg_id++;
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
return 0;
}
return 1;
}
/*
int sev_server::send_itemlist( qcom_sQid tgt)
{
int item_cnt = 0;
qcom_sPut put;
pwr_tStatus sts, lsts;
int size;
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
if ( m_db->m_items[i].deleted)
continue;
item_cnt++;
}
if ( !item_cnt)
return 1;
size = sizeof(sev_sMsgHistItems) + (item_cnt - 1) * sizeof(sev_sHistItem);
put.size = size;
put.data = qcom_Alloc(&lsts, put.size);
((sev_sMsgHistItems *)put.data)->Type = sev_eMsgType_HistItems;
((sev_sMsgHistItems *)put.data)->NumItems = item_cnt;
int idx = 0;
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
if ( m_db->m_items[i].deleted)
......@@ -320,6 +362,7 @@ int sev_server::send_itemlist( qcom_sQid tgt)
}
return 1;
}
*/
int sev_server::send_server_status( qcom_sQid tgt)
{
......@@ -417,44 +460,47 @@ int sev_server::mainloop()
continue;
switch (get.type.b) {
case sev_cMsgClass:
switch ( get.type.s) {
case sev_eMsgType_NodeUp:
errh_Info("Node up %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0));
request_items( get.reply.nid);
break;
case sev_eMsgType_HistItems:
errh_Info("Itemlist received %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0));
check_histitems( (sev_sMsgHistItems *) mp, get.size);
break;
case sev_eMsgType_HistDataStore:
receive_histdata( (sev_sMsgHistDataStore *) mp, get.size);
break;
case sev_eMsgType_HistDataGetRequest:
send_histdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size);
break;
case sev_eMsgType_HistItemsRequest:
send_itemlist( get.reply);
break;
case sev_eMsgType_HistItemDelete:
delete_item( get.reply, (sev_sMsgHistItemDelete *) mp);
break;
case sev_eMsgType_ServerStatusRequest:
send_server_status( get.reply);
break;
case sev_cMsgClass:
switch ( get.type.s) {
case sev_eMsgType_NodeUp:
errh_Info("Node up %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0));
request_items( get.reply.nid);
break;
case sev_eMsgType_HistItems:
errh_Info("Itemlist received %s", cdh_NodeIdToString( 0, get.reply.nid, 0, 0));
check_histitems( (sev_sMsgHistItems *) mp, get.size);
break;
case sev_eMsgType_HistDataStore:
receive_histdata( (sev_sMsgHistDataStore *) mp, get.size);
break;
case sev_eMsgType_HistDataGetRequest:
send_histdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size);
break;
case sev_eMsgType_HistItemsRequest:
send_itemlist( get.reply);
break;
case sev_eMsgType_HistItemDelete:
delete_item( get.reply, (sev_sMsgHistItemDelete *) mp);
break;
case sev_eMsgType_ServerStatusRequest:
send_server_status( get.reply);
break;
case sev_eMsgType_HistObjectDataGetRequest:
send_objecthistdata( get.reply, (sev_sMsgHistDataGetRequest *) mp, get.size);
break;
default: ;
}
break;
case qcom_eBtype_event: {
ini_mEvent new_event;
qcom_sEvent *ep = (qcom_sEvent*) get.data;
new_event.m = ep->mask;
if (new_event.b.terminate)
exit(0);
break;
}
default: ;
}
break;
case qcom_eBtype_event: {
ini_mEvent new_event;
qcom_sEvent *ep = (qcom_sEvent*) get.data;
new_event.m = ep->mask;
if (new_event.b.terminate)
exit(0);
break;
}
default: ;
}
qcom_Free( &sts, mp);
......@@ -463,7 +509,6 @@ int sev_server::mainloop()
int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
{
pwr_tStatus sts;
unsigned int idx;
pwr_tDeltaTime storagetime;
int item_cnt = (size - sizeof(sev_sMsgHistItems)) / sizeof(sev_sHistItem) + 1;
......@@ -487,6 +532,127 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
// printf( "Received: %s.%s\n", msg->Items[i].oname, msg->Items[i].attr[0].aname);
storagetime = net_NetTimeToDeltaTime( &msg->Items[i].storagetime);
if(msg->Items[i].attrnum > 1) {
//printf( "Received: %s.%s AttrNum:%d\n", msg->Items[i].oname, msg->Items[i].attr[0].aname, msg->Items[i].attrnum);
sev_sHistItem *buffP = &msg->Items[i];
while(buffP < &msg->Items[item_cnt-1]) {
//for(size_t j = 0; j < buffP->attrnum; j++) {
// printf( "Received: %s.%s\n", buffP->oname, buffP->attr[j].aname);
//}
char *s;
char tablename[400];
char tmpStr[400];
char attributeName[400];
strcpy( tmpStr, buffP->oname);
//Point out attribute name
s = strchr( tmpStr, '.');
if (s)
{
*s = 0;
strcpy( attributeName, s+1);
}
else
attributeName[0] = '\0';
storagetime = net_NetTimeToDeltaTime( &buffP->storagetime );
sprintf( tablename, "obj_%s", m_db->oid_to_table( buffP->oid, attributeName) );
if ( !m_db->check_objectitem( &m_sts,
tablename,
buffP->oid,
buffP->oname,
attributeName,
storagetime,
buffP->description,
buffP->scantime,
buffP->deadband,
buffP->options,
&idx)) {
m_db->add_objectitem( &m_sts,
tablename,
buffP->oid,
buffP->oname,
attributeName,
storagetime,
buffP->description,
buffP->scantime,
buffP->deadband,
buffP->options,
&idx);
if ( EVEN(m_sts)) return m_sts;
}
vector<sev_attr> oldattrVec = m_db->m_items[idx].attr;
vector<sev_attr> newattrVec;
m_db->m_items[idx].value_size = 0;
//Check if any new attributes is found if so add column
for(size_t j = 0; j < buffP->attrnum; j++) {
//printf( "Received: %s.%s\n", buffP->oname, buffP->attr[j].aname);
sev_attr newattr;
strncpy( newattr.aname, buffP->attr[j].aname, sizeof(newattr.aname));
newattr.type = buffP->attr[j].type;
newattr.size = buffP->attr[j].size;
m_db->m_items[idx].value_size += newattr.size;
newattr.elem = 0;
newattrVec.push_back(newattr);
if ( !m_db->check_objectitemattr( &m_sts,
tablename,
buffP->oid,
buffP->attr[j].aname,
buffP->oname,
buffP->attr[j].type,
buffP->attr[j].size,
&idx) ) {
m_db->add_objectitemattr( &m_sts,
tablename,
buffP->oid,
buffP->attr[j].aname,
buffP->oname,
buffP->attr[j].type,
buffP->attr[j].size,
&idx);
if ( EVEN(m_sts)) return m_sts;
}
}
//Be sure that we have the correct attribute order. Use the list from the client
m_db->m_items[idx].attr.clear();
m_db->m_items[idx].attr = newattrVec;
m_db->m_items[idx].attrnum = newattrVec.size();
//If node is coming up again we do not want deadband to be active due to init of old_value
m_db->m_items[idx].deadband_active = 0;
m_db->m_items[idx].first_storage = 1;
//TODO Check if some items in oldAttrVec no longer exists if so mark this item
//so that databaseadministrator knows which columns he can delete
//If something was wrong during checking of attributes we ignore this object
if ( ODD(m_sts) )
{
//Create space for the old values used if we have deadband active
if( m_db->m_items[idx].old_value != 0 ) {
free(m_db->m_items[idx].old_value);
m_db->m_items[idx].old_value = 0;
}
m_db->m_items[idx].old_value = malloc(m_db->m_items[idx].value_size);
m_db->m_items[idx].sevid = buffP->sevid;
sev_refid sevid(buffP->sevid);
m_refid[sevid] = idx;
}
int numberOfAttributes = buffP->attrnum;
//buffP points after the last attribute written
if(numberOfAttributes == 0) {
printf("Something is very strange at line:%d in file:%s\n", __LINE__, __FUNCTION__);
break;
}
buffP = (sev_sHistItem *)&buffP->attr[numberOfAttributes];
}
break;
}
if ( !m_db->check_item( &m_sts, msg->Items[i].oid, msg->Items[i].oname, msg->Items[i].attr[0].aname,
storagetime, msg->Items[i].attr[0].type, msg->Items[i].attr[0].size,
msg->Items[i].description, msg->Items[i].attr[0].unit, msg->Items[i].scantime,
......@@ -496,33 +662,26 @@ int sev_server::check_histitems( sev_sMsgHistItems *msg, unsigned int size)
msg->Items[i].description, msg->Items[i].attr[0].unit, msg->Items[i].scantime,
msg->Items[i].deadband, msg->Items[i].options, &idx);
if ( EVEN(m_sts)) return m_sts;
sev_sItemKey ik;
sev_sItem *ip;
ik.oid = msg->Items[i].oid;
strcpy( ik.aname, msg->Items[i].attr[0].aname);
ip = (sev_sItem *) tree_Insert(&sts, m_item_key, &ik);
ip->idx = idx;
}
//Create space for the old values used if we have deadband active
if ( m_db->m_items[idx].old_value != 0 ) {
free(m_db->m_items[idx].old_value);
m_db->m_items[idx].old_value = 0;
}
m_db->m_items[idx].value_size = msg->Items[i].attr[0].size;
m_db->m_items[idx].old_value = malloc(m_db->m_items[idx].value_size);
//If node is coming up again we do not want deadband to be active due to init of old_value
m_db->m_items[idx].deadband_active = 0;
m_db->m_items[idx].first_storage = 1;
m_db->m_items[idx].sevid = msg->Items[i].sevid;
sev_refid sevid(msg->Items[i].sevid);
m_refid[sevid] = idx;
}
#if 0
sev_sItem *ip = (sev_sItem *)tree_Minimum(&sts, m_item_key);
while ( ip) {
printf( "ItemKey: %d,%d Name %s idx: %d\n", ip->key.oid.vid, ip->key.oid.oix, ip->key.aname, ip->idx);
ip = (sev_sItem *)tree_Successor(&sts, m_item_key, ip);
}
#endif
printf( "---- Node up (%d) ----\n", nid);
// for ( iterator_refid it = m_refid.begin(); it != m_refid.end(); it++)
// printf( "Refid: %d,%d Name %s\n", it->first.id.nid, it->first.id.rix, m_db->m_items[it->second].oname);
for ( iterator_refid it = m_refid.begin(); it != m_refid.end(); it++)
printf( "Refid: %d,%d Idx: %d Name %s\n", it->first.id.nid, it->first.id.rix, it->second, m_db->m_items[it->second].oname);
return 1;
}
......@@ -539,16 +698,15 @@ int sev_server::receive_histdata( sev_sMsgHistDataStore *msg, unsigned int size)
continue;
}
unsigned int idx = it->second;
time = net_NetTimeToTime( &msg->Time);
m_db->store_value( &m_sts, idx, 0, time, &dp->data, dp->size);
dp = (sev_sHistData *)((char *)dp + sizeof( *dp) - sizeof(dp->data) + dp->size);
}
return 1;
}
int sev_server::send_histdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg, unsigned int size)
{
pwr_tTime *tbuf;
......@@ -559,32 +717,22 @@ int sev_server::send_histdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg,
qcom_sPut put;
pwr_tStatus sts, lsts;
pwr_tTime starttime, endtime;
sev_sItemKey ik;
sev_sItem *ip;
ik.oid = rmsg->Oid;
strcpy( ik.aname, rmsg->AName);
ip = (sev_sItem *) tree_Find(&sts, m_item_key, &ik);
if ( !ip)
m_sts = SEV__NOSUCHITEM;
else
m_sts = SEV__SUCCESS;
int idx = 0;
if ( ODD(m_sts)) {
idx = ip->idx;
starttime = net_NetTimeToTime( &rmsg->StartTime);
endtime = net_NetTimeToTime( &rmsg->EndTime);
m_db->get_values( &m_sts, rmsg->Oid, m_db->m_items[idx].options, m_db->m_items[idx].deadband,
rmsg->AName, m_db->m_items[idx].attr[0].type, m_db->m_items[idx].attr[0].size,
m_db->m_items[idx].scantime, &m_db->m_items[idx].creatime,
&starttime, &endtime, rmsg->NumPoints, &tbuf, &vbuf, &rows);
starttime = net_NetTimeToTime( &rmsg->StartTime);
endtime = net_NetTimeToTime( &rmsg->EndTime);
sev_item item;
char tablename[500];
strcpy( tablename, m_db->oid_to_table( rmsg->Oid, rmsg->AName) );
m_db->get_item(&m_sts, &item, tablename);
if(ODD(m_sts)) {
m_db->get_values( &m_sts, rmsg->Oid, item.options, item.deadband,
rmsg->AName, item.attr[0].type, item.attr[0].size,
item.scantime, &item.creatime,
&starttime, &endtime, rmsg->NumPoints, &tbuf, &vbuf, &rows);
}
if ( ODD(m_sts))
msize = rows * ( sizeof(pwr_tTime) + m_db->m_items[idx].attr[0].size) + sizeof(*msg) - sizeof(msg->Data);
msize = rows * ( sizeof(pwr_tTime) + item.attr[0].size) + sizeof(*msg) - sizeof(msg->Data);
else
msize = sizeof(*msg);
......@@ -603,14 +751,14 @@ int sev_server::send_histdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg,
strncpy( msg->AName, rmsg->AName, sizeof(msg->AName));
if ( ODD(m_sts)) {
msg->NumPoints = rows;
msg->VType = m_db->m_items[idx].attr[0].type;
msg->VSize = m_db->m_items[idx].attr[0].size;
msg->VType = item.attr[0].type;
msg->VSize = item.attr[0].size;
}
msg->Status = m_sts;
if ( ODD(m_sts) && rows) {
memcpy( &msg->Data, tbuf, sizeof(pwr_tTime) * rows);
memcpy( (char *)&msg->Data + sizeof(pwr_tTime) * rows, vbuf, m_db->m_items[idx].attr[0].size * rows);
memcpy( (char *)&msg->Data + sizeof(pwr_tTime) * rows, vbuf, item.attr[0].size * rows);
}
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
......@@ -619,22 +767,133 @@ int sev_server::send_histdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg,
return 1;
}
int sev_server::send_objecthistdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg, unsigned int size)
{
pwr_tTime *tbuf;
void *vbuf;
unsigned int rows;
sev_sMsgHistObjectDataGet *msg;
int msize;
qcom_sPut put;
pwr_tStatus sts, lsts;
pwr_tTime starttime, endtime;
starttime = net_NetTimeToTime( &rmsg->StartTime);
endtime = net_NetTimeToTime( &rmsg->EndTime);
sev_item item;
char tablename[500];
sprintf( tablename, "obj_%s", m_db->oid_to_table( rmsg->Oid, rmsg->AName) );
m_db->get_objectitem(&m_sts, &item, tablename);
if(ODD(m_sts)) {
m_db->get_objectvalues(&m_sts, &item, item.value_size, &starttime, &endtime, rmsg->NumPoints, &tbuf, &vbuf, &rows);
}
if ( ODD(m_sts)) {
msize = rows * ( sizeof(pwr_tTime) + item.value_size);
msize += item.attr.size() * sizeof(msg->Attr);
msize += sizeof(*msg) - sizeof(msg->Data) - sizeof(msg->Attr);
}
else
msize = sizeof(*msg);
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevServer;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistObjectDataGet;
put.msg_id = m_msg_id++;
put.size = msize;
msg = (sev_sMsgHistObjectDataGet *) qcom_Alloc(&lsts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_HistObjectDataGet;
msg->Oid = rmsg->Oid;
strncpy( msg->AName, rmsg->AName, sizeof(msg->AName));
msg->Status = m_sts;
msg->NumPoints = 0;
msg->NumAttributes = 0;
if ( ODD(m_sts)) {
msg->NumPoints = rows;
msg->NumAttributes = item.attr.size();
msg->TotalDataSize = rows * ( sizeof(pwr_tTime) + item.value_size);
for( size_t i = 0; i < item.attr.size(); i++ ) {
strncpy( msg->Attr[i].aname, item.attr[i].aname, sizeof(msg->Attr[0].aname));
msg->Attr[i].elem = 1; //Not used
msg->Attr[i].size = item.attr[i].size;
msg->Attr[i].type = item.attr[i].type;
}
if( rows ) {
void *ptr = &msg->Attr[item.attr.size()];
memcpy( ptr, tbuf, sizeof(pwr_tTime) * rows);
memcpy( (char *)ptr + sizeof(pwr_tTime) * rows, vbuf, item.value_size * rows);
}
}
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
}
return 1;
}
void sev_server::garbage_collector()
{
int item_size = m_db->m_items.size();
static int current = 0;
float items_per_scan;
int scan_per_items;
static int scan_cnt = 0;
int i;
if ( item_size == 0)
return;
items_per_scan = ((float)sev_cGarbageInterval) * item_size / sev_cGarbageCycle;
if ( items_per_scan >= 1) {
for ( i = 0; i < (int)items_per_scan; i++) {
garbage_item( current);
current++;
if ( current >= item_size)
current = 0;
}
}
else {
scan_per_items = (int)( 1.0 / items_per_scan);
scan_cnt++;
if ( scan_cnt >= scan_per_items) {
scan_cnt = 0;
garbage_item( current);
current++;
if ( current >= item_size)
current = 0;
}
}
}
void sev_server::garbage_item( int idx)
{
pwr_tTime currenttime, limit;
//clock_gettime( CLOCK_REALTIME, &currenttime);
time_GetTime( &currenttime);
for ( unsigned int i = 0; i < m_db->m_items.size(); i++) {
if ( m_db->m_items[i].deleted)
continue;
if ( m_db->m_items[i].storagetime.tv_sec == 0)
continue;
time_Asub( &limit, &currenttime, &m_db->m_items[i].storagetime);
if ( m_db->m_items[idx].deleted)
return;
if ( m_db->m_items[idx].storagetime.tv_sec == 0)
return;
m_db->delete_old_data( &m_sts, m_db->m_items[i].oid, m_db->m_items[i].attr[0].aname,
m_db->m_items[i].options, limit);
time_Asub( &limit, &currenttime, &m_db->m_items[idx].storagetime);
if( m_db->m_items[idx].attrnum > 1 ) {
m_db->delete_old_objectdata( &m_sts, m_db->m_items[idx].tablename,
m_db->m_items[idx].options, limit);
}
else {
m_db->delete_old_data( &m_sts, m_db->m_items[idx].oid, m_db->m_items[idx].attr[0].aname,
m_db->m_items[idx].options, limit);
}
}
......
......@@ -62,7 +62,10 @@ typedef struct {
class sev_server {
public:
sev_server() : m_server_status(0), m_item_key(0), m_msg_id(0) {}
//TODO should this really be in this file?
static const unsigned int constSevVersion = 2;
sev_server() : m_server_status(0), m_msg_id(0) {}
typedef map<sev_refid, unsigned int>::iterator iterator_refid;
......@@ -70,7 +73,6 @@ class sev_server {
pwr_tStatus m_server_status;
vector<sev_node> m_nodes;
map<sev_refid, unsigned int> m_refid;
tree_sTable *m_item_key;
unsigned int m_msg_id;
sev_db *m_db;
int m_noneth;
......@@ -82,9 +84,11 @@ class sev_server {
int check_histitems( sev_sMsgHistItems *msg, unsigned int size);
int receive_histdata( sev_sMsgHistDataStore *msg, unsigned int size);
int send_histdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *msg, unsigned int size);
int send_objecthistdata( qcom_sQid tgt, sev_sMsgHistDataGetRequest *rmsg, unsigned int size);
int send_itemlist( qcom_sQid tgt);
int send_server_status( qcom_sQid tgt);
int delete_item( qcom_sQid tgt, sev_sMsgHistItemDelete *rmsg);
void garbage_collector();
void garbage_item( int idx);
};
#endif
......@@ -202,7 +202,7 @@ void XttTblGtk::activate_list_layout( GtkWidget *w, gpointer data)
xtt->tblnav->show_list();
}
XttSevHist *XttTblGtk::sevhist_new( pwr_tOid oid, char *aname)
XttSevHist *XttTblGtk::sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject)
{
GtkWidget *w;
pwr_tStatus sts;
......@@ -214,7 +214,7 @@ XttSevHist *XttTblGtk::sevhist_new( pwr_tOid oid, char *aname)
strncpy( anamev[0], aname, sizeof(anamev[0]));
return new XttSevHistGtk( (void *)this, toplevel, "SevHist", &w, oidv, anamev,
sevcli, &sts);
sevcli, &sts, sevhistobject);
}
CoLogin *XttTblGtk::login_new( const char *name,
......
......@@ -49,7 +49,7 @@ class XttTblGtk : public XttTbl {
CoWowEntryGtk *cmd_entry;
void message( char severity, char *message);
XttSevHist *sevhist_new( pwr_tOid oid, char *aname);
XttSevHist *sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject);
CoLogin *login_new( const char *wl_name,
const char *wl_groupname,
void (* wl_bc_success)( void *),
......
......@@ -120,24 +120,41 @@ void XttTbl::activate_print()
void XttTbl::activate_opensevhist()
{
sevcli_sHistItem *hi;
// sevcli_sHistItem *hi;
TblNav_sevhistobject *hi;
if ( !tblnav->get_select( &hi)) {
message( 'E', "Select an storage item");
return;
}
sevhist_new( hi->oid, hi->attr[0].aname);
bool sevhistobject = hi->attrnum > 1;
if( !sevhistobject ) {
sevhist_new( hi->oid, hi->objectattrlist[0].aname, sevhistobject);
}
else {
char *s;
pwr_tAName aname;
s = strchr( hi->oname, '.');
if ( !s) {
//It is a complete object
aname[0] = '\0';
}
else {
strcpy( aname, s+1);
}
sevhist_new( hi->oid, aname, sevhistobject);
}
}
void XttTbl::delete_item_yes( void *ctx, void *data)
{
XttTbl *tbl = (XttTbl *)ctx;
sevcli_sHistItem *hi = (sevcli_sHistItem *)data;
// sevcli_sHistItem *hi = (sevcli_sHistItem *)data;
TblNav_sevhistobject *hi = (TblNav_sevhistobject *)data;
pwr_tStatus sts;
printf("Deleting %s\n", hi->oname);
sevcli_delete_item( &sts, tbl->sevcli, hi->oid, hi->attr[0].aname);
sevcli_delete_item( &sts, tbl->sevcli, hi->oid, hi->objectattrlist[0].aname);
if ( EVEN(sts)) {
tbl->message( 'E', "Delete error");
return;
......@@ -149,7 +166,8 @@ void XttTbl::delete_item_yes( void *ctx, void *data)
void XttTbl::activate_delete_item()
{
sevcli_sHistItem *hi;
//sevcli_sHistItem *hi;
TblNav_sevhistobject *hi;
char msg[300];
if ( !tblnav->get_select( &hi)) {
......@@ -157,7 +175,7 @@ void XttTbl::activate_delete_item()
return;
}
sprintf( msg, "Do you really wan't to delete all stored data for item\n\n%s.%s\n", hi->oname, hi->attr[0].aname);
sprintf( msg, "Do you really wan't to delete all stored data for item\n\n%s.%s\n", hi->oname, hi->objectattrlist[0].aname);
wow->DisplayQuestion( this, "Confirm Delete Item", msg, delete_item_yes, 0, hi);
}
......
......@@ -55,7 +55,7 @@ class XttTbl {
int quiet;
virtual void message( char severity, const char *message) {}
virtual XttSevHist *sevhist_new( pwr_tOid oid, char *aname) { return 0;}
virtual XttSevHist *sevhist_new( pwr_tOid oid, char *aname, bool sevhistobject) { return 0;}
virtual CoLogin *login_new( const char *wl_name,
const char *wl_groupname,
void (* wl_bc_success)( void *),
......
......@@ -132,6 +132,7 @@ TblNav::TblNav(
itemlist(xn_itemlist),item_cnt(xn_item_cnt),
message_cb(NULL), list_layout(0)
{
create_objectlist(xn_itemlist, xn_item_cnt, status);
*status = 1;
}
......@@ -438,16 +439,16 @@ int TblNav::create_items()
brow_SetNodraw( brow->ctx);
if ( list_layout) {
for ( i = 0; i < item_cnt; i++) {
new ItemLocal( this, &itemlist[i], NULL, flow_eDest_IntoLast);
for ( i = 0; i < (int)sevhistobjectlist.size(); i++) {
new ItemLocal( this, &sevhistobjectlist[i], NULL, flow_eDest_IntoLast);
}
}
else {
for ( int idx = 1; idx; idx = tree[idx].fws) {
if ( tree[idx].item)
new ItemTreeLocal( this, tree[idx].item, idx, NULL, flow_eDest_IntoLast);
new ItemTreeLocal( this, tree[idx].item, idx, NULL, flow_eDest_IntoLast);
else
new ItemTreeNode( this, tree[idx].sname, idx, NULL, flow_eDest_IntoLast);
new ItemTreeNode( this, tree[idx].sname, idx, NULL, flow_eDest_IntoLast);
}
}
brow_ResetNodraw( brow->ctx);
......@@ -527,7 +528,7 @@ int TblNav::init_brow_cb( FlowCtx *fctx, void *client_data)
}
int TblNav::get_select( sevcli_sHistItem **hi)
int TblNav::get_select( TblNav_sevhistobject **hi)
{
brow_tNode *node_list;
int node_count;
......@@ -574,7 +575,7 @@ void TblNav::unzoom()
brow_UnZoom( brow->ctx);
}
void TblNav::delete_item( sevcli_sHistItem *hi)
void TblNav::delete_item( TblNav_sevhistobject *hi)
{
brow_tNode *node_list;
int node_count;
......@@ -587,7 +588,7 @@ void TblNav::delete_item( sevcli_sHistItem *hi)
continue;
if ( tree[i].item &&
cdh_ObjidIsEqual( tree[i].item->oid, hi->oid) &&
strcmp( tree[i].item->attr[0].aname, hi->attr[0].aname) == 0) {
strcmp( tree[i].item->objectattrlist[0].aname, hi->objectattrlist[0].aname) == 0) {
tree[i].deleted = 1;
}
}
......@@ -603,7 +604,7 @@ void TblNav::delete_item( sevcli_sHistItem *hi)
case tblnav_eItemType_TreeLocal: {
ItemLocal *item = (ItemLocal *)baseitem;
if ( cdh_ObjidIsEqual( hi->oid, item->item.oid) &&
strcmp( hi->attr[0].aname, item->item.attr[0].aname) == 0) {
strcmp( hi->objectattrlist[0].aname, item->item.objectattrlist[0].aname) == 0) {
brow_DeleteNode( brow->ctx, item->node);
found = 1;
}
......@@ -616,7 +617,7 @@ void TblNav::delete_item( sevcli_sHistItem *hi)
}
}
ItemLocal::ItemLocal( TblNav *tblnav, sevcli_sHistItem *xitem,
ItemLocal::ItemLocal( TblNav *tblnav, TblNav_sevhistobject *xitem,
brow_tNode dest, flow_eDest dest_code) :
ItemBase( tblnav_eItemType_Local), item(*xitem)
{
......@@ -629,8 +630,11 @@ ItemLocal::ItemLocal( TblNav *tblnav, sevcli_sHistItem *xitem,
brow_SetAnnotPixmap( node, 0, tblnav->brow->pixmap_leaf);
strcpy( aname, item.oname);
strcat( aname, ".");
strcat( aname, item.attr[0].aname);
if( item.attrnum == 1 ) {
strcat( aname, ".");
strcat( aname, item.objectattrlist[0].aname);
}
printf("aname %s\n", aname);
brow_SetAnnotation( node, 0, aname, strlen(aname));
brow_SetAnnotation( node, 1, item.description, strlen(item.description));
}
......@@ -691,11 +695,11 @@ int ItemLocal::open_attributes( TblNav *tblnav, double x, double y)
sprintf( value, "%f", item.deadband);
new ItemLocalAttr( tblnav, "Deadband", value, node, flow_eDest_IntoLast);
for ( int i = 0; i < 1; i++) {
for ( int i = 0; i < (int)item.objectattrlist.size(); i++) {
sprintf( txt, "Attr[%d].Name", i);
new ItemLocalAttr( tblnav, txt, item.attr[0].aname, node, flow_eDest_IntoLast);
new ItemLocalAttr( tblnav, txt, item.objectattrlist[i].aname, node, flow_eDest_IntoLast);
switch ( item.attr[0].type) {
switch ( item.objectattrlist[i].type) {
case pwr_eType_Int64: strcpy( value, "Int64"); break;
case pwr_eType_Int32: strcpy( value, "Int32"); break;
case pwr_eType_Int16: strcpy( value, "Int16"); break;
......@@ -717,11 +721,11 @@ int ItemLocal::open_attributes( TblNav *tblnav, double x, double y)
new ItemLocalAttr( tblnav, txt, value, node, flow_eDest_IntoLast);
sprintf( txt, "Attr[%d].DataSize", i);
sprintf( value, "%d", item.attr[0].size);
sprintf( value, "%d", item.objectattrlist[i].size);
new ItemLocalAttr( tblnav, txt, value, node, flow_eDest_IntoLast);
sprintf( txt, "Attr[%d].Unit", i);
new ItemLocalAttr( tblnav, txt, item.attr[0].unit, node, flow_eDest_IntoLast);
new ItemLocalAttr( tblnav, txt, item.objectattrlist[i].unit, node, flow_eDest_IntoLast);
}
brow_SetOpen( node, tblnav_mOpen_Attributes);
brow_ResetNodraw( tblnav->brow->ctx);
......@@ -761,7 +765,7 @@ ItemLocalAttr::ItemLocalAttr( TblNav *tblnav, const char *name, char *value,
brow_SetAnnotation( node, 1, value, strlen(value));
}
ItemTreeLocal::ItemTreeLocal( TblNav *tblnav, sevcli_sHistItem *xitem, int index,
ItemTreeLocal::ItemTreeLocal( TblNav *tblnav, TblNav_sevhistobject *xitem, int index,
brow_tNode dest, flow_eDest dest_code) :
ItemLocal(tblnav, xitem, dest, dest_code), idx(index)
{
......@@ -774,8 +778,10 @@ ItemTreeLocal::ItemTreeLocal( TblNav *tblnav, sevcli_sHistItem *xitem, int index
strcpy( aname, s+1);
else
strcpy( aname, item.oname);
strcat( aname, ".");
strcat( aname, item.attr[0].aname);
if( item.attrnum == 1 ) {
strcat( aname, ".");
strcat( aname, item.objectattrlist[0].aname);
}
brow_SetAnnotation( node, 0, aname, strlen(aname));
}
......@@ -851,16 +857,16 @@ void TblNav::build_tree()
pwr_tAName aname;
int seg;
for ( int i = 0; i < item_cnt; i++) {
for ( int i = 0; i < (int)sevhistobjectlist.size(); i++) {
TblTreeNode n;
strcpy( aname, itemlist[i].oname);
strcpy( aname, sevhistobjectlist[i].oname);
strcat( aname, ".");
strcat( aname, itemlist[i].attr[0].aname);
strcat( aname, sevhistobjectlist[i].objectattrlist[0].aname);
seg = dcli_parse( aname, "-", "",
(char *) name_array, sizeof( name_array)/sizeof( name_array[0]),
sizeof( name_array[0]), 0);
(char *) name_array, sizeof( name_array)/sizeof( name_array[0]),
sizeof( name_array[0]), 0);
if ( tree.size() == 0) {
// First item
......@@ -869,77 +875,110 @@ void TblNav::build_tree()
tree.push_back(n0);
for ( int j = 0; j < seg; j++) {
TblTreeNode n;
n.fth = j;
tree[j].fch = j + 1;
strcpy( n.sname, name_array[j]);
if ( j == seg -1)
n.item = &itemlist[i];
tree.push_back(n);
TblTreeNode n;
n.fth = j;
tree[j].fch = j + 1;
strcpy( n.sname, name_array[j]);
if ( j == seg -1)
n.item = &sevhistobjectlist[i];
tree.push_back(n);
}
}
else {
int idx = 1;
int last = idx;
for ( int j = 0; j < seg; j++) {
int found = 0;
while ( idx) {
last = idx;
if ( strcmp( tree[idx].sname, name_array[j]) == 0) {
found = 1;
break;
}
idx = tree[idx].fws;
}
if ( !found) {
TblTreeNode n;
strcpy( n.sname, name_array[j]);
n.fth = tree[last].fth;
n.bws = last;
tree[last].fws = tree.size();
if ( j == seg - 1)
n.item = &itemlist[i];
tree.push_back(n);
for ( int k = j + 1; k < seg; k++) {
TblTreeNode n;
n.fth = tree.size() - 1;
if ( tree[n.fth].fch == 0)
tree[n.fth].fch = tree.size();
strcpy( n.sname, name_array[k]);
if ( k == seg - 1)
n.item = &itemlist[i];
tree.push_back(n);
}
break;
}
if ( tree[idx].fch == 0) {
TblTreeNode n;
strcpy( n.sname, name_array[j]);
n.fth = tree[last].fth;
n.bws = last;
tree[last].fws = tree.size();
if ( j == seg - 1)
n.item = &itemlist[i];
tree.push_back(n);
for ( int k = j + 1; k < seg; k++) {
TblTreeNode n;
n.fth = tree.size() - 1;
if ( tree[n.fth].fch == 0)
tree[n.fth].fch = tree.size();
strcpy( n.sname, name_array[k]);
if ( k == seg - 1)
n.item = &itemlist[i];
tree.push_back(n);
}
break;
}
idx = tree[idx].fch;
last = idx;
int found = 0;
while ( idx) {
last = idx;
if ( strcmp( tree[idx].sname, name_array[j]) == 0) {
found = 1;
break;
}
idx = tree[idx].fws;
}
if ( !found) {
TblTreeNode n;
strcpy( n.sname, name_array[j]);
n.fth = tree[last].fth;
n.bws = last;
tree[last].fws = tree.size();
if ( j == seg - 1)
n.item = &sevhistobjectlist[i];
tree.push_back(n);
for ( int k = j + 1; k < seg; k++) {
TblTreeNode n;
n.fth = tree.size() - 1;
if ( tree[n.fth].fch == 0)
tree[n.fth].fch = tree.size();
strcpy( n.sname, name_array[k]);
if ( k == seg - 1)
n.item = &sevhistobjectlist[i];
tree.push_back(n);
}
break;
}
if ( tree[idx].fch == 0) {
TblTreeNode n;
strcpy( n.sname, name_array[j]);
n.fth = tree[last].fth;
n.bws = last;
tree[last].fws = tree.size();
if ( j == seg - 1)
n.item = &sevhistobjectlist[i];
tree.push_back(n);
for ( int k = j + 1; k < seg; k++) {
TblTreeNode n;
n.fth = tree.size() - 1;
if ( tree[n.fth].fch == 0)
tree[n.fth].fch = tree.size();
strcpy( n.sname, name_array[k]);
if ( k == seg - 1)
n.item = &sevhistobjectlist[i];
tree.push_back(n);
}
break;
}
idx = tree[idx].fch;
last = idx;
}
}
}
}
void TblNav::create_objectlist( sevcli_sHistItem *xn_itemlist,
int xn_item_cnt,
pwr_tStatus *status)
{
sevcli_sHistItem *histItemPtr = xn_itemlist;
while ( (int)sevhistobjectlist.size() < xn_item_cnt ) {
//Item with multiple attributes
TblNav_sevhistobject object;
object.attrnum = histItemPtr->attrnum;
object.creatime = histItemPtr->creatime;
object.deadband = histItemPtr->deadband;
strncpy(object.description, histItemPtr->description, sizeof(object.description));
object.modtime = histItemPtr->modtime;
object.oid = histItemPtr->oid;
strncpy(object.oname, histItemPtr->oname, sizeof(histItemPtr->oname));
object.options = histItemPtr->options;
object.scantime = histItemPtr->scantime;
object.storagetime = histItemPtr->storagetime;
size_t j=0;
for ( j=0; j < object.attrnum; j++ ) {
TblNav_sevhistobjectattr oattr;
strncpy(oattr.aname, histItemPtr->attr[j].aname, sizeof(oattr.aname));
oattr.elem = histItemPtr->attr[j].elem;
oattr.size = histItemPtr->attr[j].size;
oattr.type = histItemPtr->attr[j].type;
strncpy(oattr.unit, histItemPtr->attr[j].unit, sizeof(oattr.unit));
object.objectattrlist.push_back(oattr);
}
sevhistobjectlist.push_back(object);
histItemPtr = (sevcli_sHistItem *)&histItemPtr->attr[j];
}
}
......@@ -63,6 +63,30 @@ typedef enum {
tblnav_mOpen_Attributes = 1 << 1
} tblnav_mOpen;
class TblNav_sevhistobjectattr {
public:
pwr_tAName aname;
pwr_eType type;
unsigned int size;
unsigned int elem;
pwr_tString16 unit;
};
class TblNav_sevhistobject {
public:
pwr_tOid oid;
pwr_tAName oname;
pwr_tDeltaTime storagetime;
pwr_tTime creatime;
pwr_tTime modtime;
pwr_tString80 description;
pwr_tFloat32 scantime;
pwr_tFloat32 deadband;
pwr_tMask options;
unsigned int attrnum;
vector<TblNav_sevhistobjectattr> objectattrlist;
};
class TblTreeNode {
public:
......@@ -73,7 +97,7 @@ public:
int fws;
int bws;
char sname[80];
sevcli_sHistItem *item;
TblNav_sevhistobject *item;
int deleted;
};
......@@ -100,6 +124,7 @@ class TblNavBrow {
};
//! The navigation area of the attribute editor.
class TblNav {
public:
......@@ -112,6 +137,7 @@ class TblNav {
void *parent_ctx;
TblNavBrow *brow;
sevcli_sHistItem *itemlist;
vector<TblNav_sevhistobject> sevhistobjectlist;
int item_cnt;
void (*message_cb)( void *, char, const char *);
int (*is_authorized_cb)( void *, unsigned int, int);
......@@ -122,14 +148,16 @@ class TblNav {
int is_authorized( unsigned int access = pwr_mAccess_AllSev, int msg = 1);
int create_items();
void build_tree();
int get_select( sevcli_sHistItem **hi);
int get_select( TblNav_sevhistobject **hi);
void get_zoom( double *zoom_factor);
void zoom( double zoom_factor);
void unzoom();
void show_tree();
void show_list();
void delete_item( sevcli_sHistItem *hi);
void delete_item( TblNav_sevhistobject *hi);
void create_objectlist( sevcli_sHistItem *xn_itemlist,
int xn_item_cnt,
pwr_tStatus *status);
virtual void message( char sev, const char *text);
virtual void set_inputfocus() {}
static int init_brow_cb( FlowCtx *fctx, void *client_data);
......@@ -146,10 +174,13 @@ class ItemBase {
//! Item for a normal attribute.
class ItemLocal : public ItemBase {
public:
ItemLocal( TblNav *tblnav, sevcli_sHistItem *item, brow_tNode dest, flow_eDest dest_code);
// ItemLocal( TblNav *tblnav, sevcli_sHistItem *item, brow_tNode dest, flow_eDest dest_code);
ItemLocal( TblNav *tblnav, TblNav_sevhistobject *item, brow_tNode dest, flow_eDest dest_code);
virtual ~ItemLocal() {}
sevcli_sHistItem item;
// sevcli_sHistItem item;
TblNav_sevhistobject item;
brow_tNode node;
int open_attributes( TblNav *tblnav, double x, double y);
......@@ -161,14 +192,15 @@ class ItemLocalAttr : public ItemBase {
ItemLocalAttr( TblNav *tblnav, const char *iname, char *ivalue, brow_tNode dest, flow_eDest dest_code);
virtual ~ItemLocalAttr() {}
sevcli_sHistItem item;
TblNav_sevhistobject item;
//sevcli_sHistItem item;
brow_tNode node;
};
//! Item for a normal attribute.
class ItemTreeLocal : public ItemLocal {
public:
ItemTreeLocal( TblNav *tblnav, sevcli_sHistItem *item, int index, brow_tNode dest, flow_eDest dest_code);
ItemTreeLocal( TblNav *tblnav, TblNav_sevhistobject *item, int index, brow_tNode dest, flow_eDest dest_code);
virtual ~ItemTreeLocal() {}
int idx;
......
......@@ -38,9 +38,9 @@ class sev_attr {
class sev_item {
public:
sev_item() : deadband_active(0), last_id(0), first_storage(1), status(0), logged_status(0),
deleted(0)
{ memset( old_value, 0, sizeof(old_value));}
sev_item() : deadband_active(0), last_id(0), value_size(0), old_value(0), first_storage(1), status(0), logged_status(0),
deleted(0)
{ /*memset( old_value, 0, sizeof(old_value));*/}
unsigned int id;
char tablename[256];
pwr_tOid oid;
......@@ -55,10 +55,12 @@ class sev_item {
pwr_tMask options;
int deadband_active;
unsigned int last_id;
char old_value[8];
//char old_value[8];
unsigned int value_size;
void *old_value;
int first_storage;
unsigned int attrnum;
sev_attr attr[1];
vector<sev_attr> attr;
pwr_tStatus status;
pwr_tStatus logged_status;
int deleted;
......@@ -92,5 +94,31 @@ class sev_db {
virtual int get_items( pwr_tStatus *sts) { return 0;}
virtual int delete_old_data( pwr_tStatus *sts, pwr_tOid oid, char *aname,
pwr_tMask options, pwr_tTime limit) { return 0;}
virtual char *oid_to_table( pwr_tOid oid, char *aname) { return 0;}
virtual int check_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx) { return 0;}
virtual int add_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx) { return 0;}
virtual int store_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime, char *description, pwr_tFloat32 scantime, pwr_tFloat32 deadband, pwr_tMask options) { return 0;}
virtual int add_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx) { return 0;}
virtual int get_item( pwr_tStatus *sts, sev_item *item, char *tablename) { return 0;}
virtual int get_objectitem( pwr_tStatus *sts, sev_item *item, char *tablename) { return 0;}
virtual int get_objectitems( pwr_tStatus *sts) { return 0;}
virtual int check_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx) { return 0;}
virtual int delete_old_objectdata( pwr_tStatus *sts, char *tablename,
pwr_tMask options, pwr_tTime limit) { return 0;}
virtual int get_objectvalues( pwr_tStatus *sts, sev_item *item,
unsigned int size, pwr_tTime *starttime, pwr_tTime *endtime,
int maxsize, pwr_tTime **tbuf, void **vbuf, unsigned int *bsize) { return 0;}
};
#endif
......@@ -25,6 +25,9 @@
#include <stdlib.h>
#include <errno.h>
#include <math.h>
#include <string>
#include <iostream>
#include <sstream>
#include "pwr.h"
#include "pwr_baseclasses.h"
......@@ -37,6 +40,7 @@
#include "rt_sev_msg.h"
#include "rt_errh.h"
using namespace std;
char sev_dbms_env::m_systemName[40];
sev_dbms_env::sev_dbms_env(const char *v_fileName) :
......@@ -262,9 +266,102 @@ MYSQL *sev_dbms_env::createDb(void)
rc = mysql_query( m_con, query);
if (rc) printf( "Create items table: %s\n", mysql_error(m_con));
updateDB_to_SevVersion2();
return con;
}
int sev_dbms_env::checkAndUpdateVersion(unsigned int version)
{
unsigned int old_version=1; //Proview 4.6.0.0 was first release with sev
int rc = mysql_query( m_con, "select * from sev_version");
if (rc) {
printf( "table sev_version do no exist\n");
}
else {
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_con);
if ( !result) {
printf( "selecting sev_version Error\n");
return 0;
}
row = mysql_fetch_row( result);
if (!row) {
printf( "selecting sev_version Error\n");
return 0;
}
old_version= strtoul( row[0], 0, 10);
mysql_free_result( result);
}
printf("old sev_version: %d, new sev_version: %d\n", old_version, version);
//add code for new versions here
if(old_version < 2 ) {
printf("Updating database tables to sev version 2\n");
updateDB_to_SevVersion2();
}
if(old_version != version) {
char query[100];
sprintf( query, "update sev_version set version = %d", version);
rc = mysql_query( m_con, query);
if (rc) printf( "Update sev_version: %s\n", mysql_error(m_con));
}
return 1;
}
int sev_dbms_env::updateDB_to_SevVersion2(void)
{
char query[400];
sprintf( query, "create table sev_version ("
"version int unsigned not null primary key);");
int rc = mysql_query( m_con, query);
if (rc) printf( "Create sev_version table: %s\n", mysql_error(m_con));
sprintf( query, "insert into sev_version (version) values(2)");
rc = mysql_query( m_con, query);
if (rc) printf( "Insert into table sev_version: %s\n", mysql_error(m_con));
sprintf( query, "create table objectitems ("
"id int unsigned not null primary key auto_increment,"
"tablename varchar(255),"
"vid int unsigned,"
"oix int unsigned,"
"oname varchar(255),"
"aname varchar(255),"
"uptime datetime,"
"cretime datetime,"
"storagetime int unsigned,"
"deadband float,"
"options int unsigned,"
"scantime float,"
"description varchar(80));");
rc = mysql_query( m_con, query);
if (rc) printf( "Create objectitems table: %s\n", mysql_error(m_con));
sprintf( query, "create table objectitemattributes ("
"tablename varchar(255) not null,"
"attributename varchar(255) not null,"
"attributeidx int unsigned not null,"
"attributetype int unsigned not null,"
"attributesize int unsigned not null,"
"PRIMARY KEY(tablename, attributename));");
rc = mysql_query( m_con, query);
if (rc) printf( "Create objectitemattributes table: %s\n", mysql_error(m_con));
return 1;
}
MYSQL *sev_dbms_env::openDb()
{
m_con = mysql_init(NULL);
......@@ -480,7 +577,7 @@ int sev_dbms::create_table( pwr_tStatus *sts, pwr_tOid oid, char *aname, pwr_eTy
strcpy( jumpstr, "");
sprintf( query, "create table %s ( %s"
"%s, value %s %s);",
"%s, value %s %s, index (time));",
oid_to_table(oid, aname), readoptstr, timeformatstr, pwrtype_to_type( type, size), jumpstr);
int rc = mysql_query( m_env->con(), query);
......@@ -579,11 +676,12 @@ int sev_dbms::get_items( pwr_tStatus *sts)
for ( int i = 0; i < rows; i++) {
sev_item item;
sev_attr attr;
item.attr.push_back(attr);
row = mysql_fetch_row( result);
if (!row) break;
printf( "%d %s %s\n", i, row[0], row[1]);
//printf( "%d %s %s\n", i, row[0], row[1]);
item.id = atoi( row[0]);
strncpy( item.tablename, row[1], sizeof(item.tablename));
......@@ -603,20 +701,31 @@ int sev_dbms::get_items( pwr_tStatus *sts)
item.deadband = atof(row[14]);
item.options = strtoul(row[15], 0, 10);
item.attrnum = 1;
m_items.push_back( item);
}
mysql_free_result( result);
for ( int i = 0; i < (int)m_items.size(); i++)
printf( "Item: %d %s\n", m_items[i].id, m_items[i].tablename);
//for ( int i = 0; i < (int)m_items.size(); i++)
// printf( "Item: %d %s\n", m_items[i].id, m_items[i].tablename);
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
pwr_tTime time, void *buf, unsigned int size)
pwr_tTime time, void *buf, unsigned int size)
{
if(size != m_items[item_idx].value_size) {
//Something is seriously wrong
printf("%s expected size:%d recevied size:%d ERROR!!\n", __FUNCTION__, m_items[item_idx].value_size, size);
*sts = SEV__DBERROR;
return 0;
}
if(m_items[item_idx].attrnum > 1) {
return store_objectvalue(sts, item_idx, attr_idx, time, buf, m_items[item_idx].old_value, size);
}
char query[200];
char bufstr[512];
char timstr[40];
......@@ -626,130 +735,132 @@ int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
if ( !m_items[item_idx].first_storage) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand) {
if ( m_items[item_idx].deadband_active) {
// Compare current value to old value
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_Float32:
if ( fabsf ( *(pwr_tFloat32 *)buf - *(pwr_tFloat32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tFloat32 *)m_items[item_idx].old_value = *(pwr_tFloat32 *)buf;
}
break;
case pwr_eType_Float64:
if ( fabsf ( *(pwr_tFloat64 *)buf - *(pwr_tFloat64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tFloat64 *)m_items[item_idx].old_value = *(pwr_tFloat64 *)buf;
}
break;
case pwr_eType_Int64:
if ( fabsf ( *(pwr_tInt64 *)buf - *(pwr_tInt64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt64 *)m_items[item_idx].old_value = *(pwr_tInt64 *)buf;
}
break;
case pwr_eType_Int32:
if ( fabsf ( *(pwr_tInt32 *)buf - *(pwr_tInt32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt32 *)m_items[item_idx].old_value = *(pwr_tInt32 *)buf;
}
break;
case pwr_eType_Int16:
if ( fabsf ( *(pwr_tInt16 *)buf - *(pwr_tInt16 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt16 *)m_items[item_idx].old_value = *(pwr_tInt16 *)buf;
}
break;
case pwr_eType_Int8:
case pwr_eType_Char:
if ( fabsf ( *(pwr_tInt8 *)buf - *(pwr_tInt8 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt8 *)m_items[item_idx].old_value = *(pwr_tInt8 *)buf;
}
break;
case pwr_eType_UInt64:
if ( fabsf ( *(pwr_tUInt64 *)buf - *(pwr_tUInt64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt64 *)m_items[item_idx].old_value = *(pwr_tUInt64 *)buf;
}
break;
case pwr_eType_UInt32:
case pwr_eType_Boolean:
if ( fabsf ( *(pwr_tUInt32 *)buf - *(pwr_tUInt32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt32 *)m_items[item_idx].old_value = *(pwr_tUInt32 *)buf;
}
break;
case pwr_eType_UInt16:
if ( fabsf ( *(pwr_tUInt16 *)buf - *(pwr_tUInt16 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt16 *)m_items[item_idx].old_value = *(pwr_tUInt16 *)buf;
}
break;
case pwr_eType_UInt8:
if ( fabsf ( *(pwr_tUInt8 *)buf - *(pwr_tUInt8 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt8 *)m_items[item_idx].old_value = *(pwr_tUInt8 *)buf;
}
break;
default: ;
}
// Compare current value to old value
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_Float32:
if ( fabsf ( *(pwr_tFloat32 *)buf - *(pwr_tFloat32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tFloat32 *)m_items[item_idx].old_value = *(pwr_tFloat32 *)buf;
}
break;
case pwr_eType_Float64:
if ( fabsf ( *(pwr_tFloat64 *)buf - *(pwr_tFloat64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tFloat64 *)m_items[item_idx].old_value = *(pwr_tFloat64 *)buf;
}
break;
case pwr_eType_Int64:
if ( fabsf ( *(pwr_tInt64 *)buf - *(pwr_tInt64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt64 *)m_items[item_idx].old_value = *(pwr_tInt64 *)buf;
}
break;
case pwr_eType_Int32:
if ( fabsf ( *(pwr_tInt32 *)buf - *(pwr_tInt32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt32 *)m_items[item_idx].old_value = *(pwr_tInt32 *)buf;
}
break;
case pwr_eType_Int16:
if ( fabsf ( *(pwr_tInt16 *)buf - *(pwr_tInt16 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt16 *)m_items[item_idx].old_value = *(pwr_tInt16 *)buf;
}
break;
case pwr_eType_Int8:
case pwr_eType_Char:
if ( fabsf ( *(pwr_tInt8 *)buf - *(pwr_tInt8 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tInt8 *)m_items[item_idx].old_value = *(pwr_tInt8 *)buf;
}
break;
case pwr_eType_UInt64:
if ( fabsf ( *(pwr_tUInt64 *)buf - *(pwr_tUInt64 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt64 *)m_items[item_idx].old_value = *(pwr_tUInt64 *)buf;
}
break;
case pwr_eType_UInt32:
case pwr_eType_Boolean:
if ( fabsf ( *(pwr_tUInt32 *)buf - *(pwr_tUInt32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt32 *)m_items[item_idx].old_value = *(pwr_tUInt32 *)buf;
}
break;
case pwr_eType_UInt16:
if ( fabsf ( *(pwr_tUInt16 *)buf - *(pwr_tUInt16 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt16 *)m_items[item_idx].old_value = *(pwr_tUInt16 *)buf;
}
break;
case pwr_eType_UInt8:
if ( fabsf ( *(pwr_tUInt8 *)buf - *(pwr_tUInt8 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
update_time_only = 1;
}
else {
m_items[item_idx].deadband_active = 0;
*(pwr_tUInt8 *)m_items[item_idx].old_value = *(pwr_tUInt8 *)buf;
}
break;
default: ;
}
}
else {
// Compare current value to old value
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_Float32:
if ( fabsf ( *(pwr_tFloat32 *)buf - *(pwr_tFloat32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
m_items[item_idx].deadband_active = 1;
set_jump = 1;
}
*(pwr_tFloat32 *)m_items[item_idx].old_value = *(pwr_tFloat32 *)buf;
break;
default: ;
}
// Compare current value to old value
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_Float32:
if ( fabsf ( *(pwr_tFloat32 *)buf - *(pwr_tFloat32 *)m_items[item_idx].old_value) < m_items[item_idx].deadband) {
m_items[item_idx].deadband_active = 1;
set_jump = 1;
}
*(pwr_tFloat32 *)m_items[item_idx].old_value = *(pwr_tFloat32 *)buf;
break;
default: ;
}
}
}
if ( set_jump && (m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)) {
sprintf( query, "update %s set jump = 1 where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
m_items[item_idx].last_id);
m_items[item_idx].tablename,
m_items[item_idx].last_id);
int rc = mysql_query( m_env->con(), query);
if (rc)
printf( "Update jump: %s\n", mysql_error(m_env->con()));
printf( "Update jump: %s\n", mysql_error(m_env->con()));
}
}
else
else {
m_items[item_idx].first_storage = 0;
memcpy(m_items[item_idx].old_value, buf, size);
}
*sts = time_AtoAscii( &time, time_eFormat_NumDateAndTime, timstr, sizeof(timstr));
if ( EVEN(*sts)) return 0;
......@@ -757,79 +868,81 @@ int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
*sts = cdh_AttrValueToString( m_items[item_idx].attr[attr_idx].type, buf, bufstr, sizeof(bufstr));
if ( EVEN(*sts)) return 0;
char colname[255];
strcpy(colname, "value");
if ( !update_time_only) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_PosixTime) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
switch( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, ntime, value) values (%ld,%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, ntime, value, jump) values (%ld,%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, ntime, value) values (%ld,%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr);
}
// Posix time, high resolution
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, ntime, %s) values (%ld,%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, ntime, %s, jump) values (%ld,%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, ntime, %s) values (%ld,%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
(long int)time.tv_sec, (long int)time.tv_nsec, bufstr);
}
}
else {
// Posix time, low resolution
switch( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, value) values (%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), (long int)time.tv_sec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, value, jump) values (%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), (long int)time.tv_sec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, value) values (%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), (long int)time.tv_sec, bufstr);
}
// Posix time, low resolution
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, %s) values (%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, (long int)time.tv_sec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, %s, jump) values (%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, (long int)time.tv_sec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, %s) values (%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, (long int)time.tv_sec, bufstr);
}
}
}
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
switch( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, ntime, value) values ('%s',%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
timstr, (long int)time.tv_nsec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, ntime, value, jump) values ('%s',%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
timstr, (long int)time.tv_nsec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, ntime, value) values ('%s',%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
timstr, (long int)time.tv_nsec, bufstr);
}
// Sql time, high resolution
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, ntime, %s) values ('%s',%ld,'%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
timstr, (long int)time.tv_nsec, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, ntime, %s, jump) values ('%s',%ld,%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
timstr, (long int)time.tv_nsec, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, ntime, %s) values ('%s',%ld,%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname,
timstr, (long int)time.tv_nsec, bufstr);
}
}
else {
// Sql time, low resolution
switch( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, value) values ('%s','%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), timstr, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, value, jump) values ('%s',%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), timstr, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, value) values ('%s',%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), timstr, bufstr);
}
// Sql time, low resolution
switch ( m_items[item_idx].attr[attr_idx].type) {
case pwr_eType_String:
sprintf( query, "insert into %s (time, %s) values ('%s','%s')",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, timstr, bufstr);
break;
default:
if ( m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand)
sprintf( query, "insert into %s (time, %s, jump) values ('%s',%s,%d)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, timstr, bufstr, set_jump);
else
sprintf( query, "insert into %s (time, %s) values ('%s',%s)",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), colname, timstr, bufstr);
}
}
}
int rc = mysql_query( m_env->con(), query);
......@@ -838,9 +951,9 @@ int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
*sts = SEV__DBERROR;
m_items[item_idx].status = *sts;
if ( m_items[item_idx].status != m_items[item_idx].logged_status) {
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database store error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database store error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
}
return 0;
}
......@@ -850,30 +963,30 @@ int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_PosixTime) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
sprintf( query, "update %s set time = %ld, ntime = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
(long int)time.tv_sec, (long int)time.tv_nsec, m_items[item_idx].last_id);
// Posix time, high resolution
sprintf( query, "update %s set time = %ld, ntime = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
(long int)time.tv_sec, (long int)time.tv_nsec, m_items[item_idx].last_id);
}
else {
// Posix time, low resolution
sprintf( query, "update %s set time = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), (long int)time.tv_sec,
m_items[item_idx].last_id);
// Posix time, low resolution
sprintf( query, "update %s set time = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), (long int)time.tv_sec,
m_items[item_idx].last_id);
}
}
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
sprintf( query, "update %s set time = '%s', ntime = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
timstr, (long int)time.tv_nsec, m_items[item_idx].last_id);
// Sql time, high resolution
sprintf( query, "update %s set time = '%s', ntime = %ld where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname),
timstr, (long int)time.tv_nsec, m_items[item_idx].last_id);
}
else {
// Sql time, low resolution
sprintf( query, "update %s set time = '%s' where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), timstr,
m_items[item_idx].last_id);
// Sql time, low resolution
sprintf( query, "update %s set time = '%s' where id = %d",
oid_to_table(m_items[item_idx].oid, m_items[item_idx].attr[attr_idx].aname), timstr,
m_items[item_idx].last_id);
}
}
......@@ -883,9 +996,9 @@ int sev_dbms::store_value( pwr_tStatus *sts, int item_idx, int attr_idx,
*sts = SEV__DBERROR;
m_items[item_idx].status = *sts;
if ( m_items[item_idx].status != m_items[item_idx].logged_status) {
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database update error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database update error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
}
return 0;
}
......@@ -934,7 +1047,7 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
......@@ -955,22 +1068,22 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
pwr_tTime update_time;
timestr_to_time( row[11], &create_time);
timestr_to_time( row[12], &update_time);
if ( time_Acomp( creatime, &stime) == 1)
stime = *creatime;
if ( time_Acomp( &etime, &update_time) == 1)
etime = update_time;
time_Adiff( &dt, &etime, &stime);
total_rows = int (time_DToFloat( 0, &dt) / scantime);
div = total_rows / maxsize + 1;
}
else if ( starttime) {
pwr_tTime update_time;
timestr_to_time( row[12], &update_time);
if ( time_Acomp( &update_time, starttime) != 1) {
mysql_free_result( result);
*sts = SEV__NODATATIME;
......@@ -982,7 +1095,7 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
else if ( endtime) {
pwr_tTime create_time;
timestr_to_time( row[11], &create_time);
if ( time_Acomp( endtime, &create_time) != 1) {
mysql_free_result( result);
*sts = SEV__NODATATIME;
......@@ -995,18 +1108,18 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
total_rows = atoi(row[4]);
}
mysql_free_result( result);
div = total_rows / maxsize + 1;
if ( starttime) {
*sts = time_AtoAscii( &stime, time_eFormat_NumDateAndTime, starttimstr,
sizeof(starttimstr));
sizeof(starttimstr));
if ( EVEN(*sts)) return 0;
starttimstr[19] = 0;
}
if ( endtime) {
*sts = time_AtoAscii( &etime, time_eFormat_NumDateAndTime, endtimstr,
sizeof(endtimstr));
sizeof(endtimstr));
if ( EVEN(*sts)) return 0;
endtimstr[19] = 0;
}
......@@ -1021,7 +1134,7 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
strcpy( jumpstr, "or jump = 1");
else
strcpy( jumpstr, "");
// 'order by' part
if ( options & pwr_mSevOptionsMask_ReadOptimized)
strcpy( orderby_part, "id");
......@@ -1036,81 +1149,81 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
if ( options & pwr_mSevOptionsMask_ReadOptimized) {
if ( starttime && endtime) {
if ( div == 1) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld and time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where time >= '%s' and time <= '%s'", starttimstr, endtimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld and time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where time >= '%s' and time <= '%s'", starttimstr, endtimstr);
}
else {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time >= %ld and time <= %ld",
div, jumpstr, (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time >= '%s' and time <= '%s'",
div, jumpstr, starttimstr, endtimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time >= %ld and time <= %ld",
div, jumpstr, (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time >= '%s' and time <= '%s'",
div, jumpstr, starttimstr, endtimstr);
}
}
else if ( starttime) {
if ( div == 1) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld", (long int)starttime->tv_sec);
else
sprintf( where_part, "where time >= '%s'", starttimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld", (long int)starttime->tv_sec);
else
sprintf( where_part, "where time >= '%s'", starttimstr);
}
else {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time >= %ld", div, jumpstr, (long int)starttime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time >= '%s'", div, jumpstr, starttimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time >= %ld", div, jumpstr, (long int)starttime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time >= '%s'", div, jumpstr, starttimstr);
}
}
else if ( endtime) {
if ( div == 1) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time <= %ld", (long int)endtime->tv_sec);
else
sprintf( where_part, "where time <= '%s'", endtimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time <= %ld", (long int)endtime->tv_sec);
else
sprintf( where_part, "where time <= '%s'", endtimstr);
}
else {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time <= %ld", div, jumpstr, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time <= '%s'", div, jumpstr, endtimstr);
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (id %% %d = 0 %s) and time <= %ld", div, jumpstr, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (id %% %d = 0 %s) and time <= '%s'", div, jumpstr, endtimstr);
}
}
else {
if ( div == 1)
strcpy( where_part, "");
else
sprintf( where_part, "where id %% %d = 0 %s", div, jumpstr);
sprintf( where_part, "where id %% %d = 0 %s", div, jumpstr);
}
}
else {
// Not read optimized
if ( starttime && endtime) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld and time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
sprintf( where_part, "where time >= %ld and time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where time >= '%s' and time <= '%s'", starttimstr, endtimstr);
sprintf( where_part, "where time >= '%s' and time <= '%s'", starttimstr, endtimstr);
}
else if ( starttime) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time >= %ld", (long int)starttime->tv_sec);
sprintf( where_part, "where time >= %ld", (long int)starttime->tv_sec);
else
sprintf( where_part, "where time >= '%s'", starttimstr);
sprintf( where_part, "where time >= '%s'", starttimstr);
}
else if ( endtime) {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where time <= %ld", (long int)endtime->tv_sec);
sprintf( where_part, "where time <= %ld", (long int)endtime->tv_sec);
else
sprintf( where_part, "where time <= '%s'", endtimstr);
sprintf( where_part, "where time <= '%s'", endtimstr);
}
else
strcpy( where_part, "");
}
sprintf( query, "select %s from %s %s order by %s",
column_part, oid_to_table(oid, aname), where_part, orderby_part);
column_part, oid_to_table(oid, aname), where_part, orderby_part);
rc = mysql_query( m_env->con(), query);
if (rc) {
......@@ -1118,7 +1231,7 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
*sts = SEV__DBERROR;
return 0;
}
result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Result Error\n");
......@@ -1127,51 +1240,51 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
}
int rows = mysql_num_rows( result);
int bufrows = rows;
if ( options & pwr_mSevOptionsMask_ReadOptimized) {
*tbuf = (pwr_tTime *) calloc( bufrows, sizeof(pwr_tTime));
*vbuf = calloc( bufrows, size);
int bcnt = 0;
for ( int i = 0; i < rows; i ++) {
int j = 0;
// if ( div > 1)
// mysql_data_seek( result, i);
row = mysql_fetch_row( result);
if (!row) break;
if ( options & pwr_mSevOptionsMask_PosixTime) {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
}
else {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
}
cdh_StringToAttrValue( type, row[j++], ((char *)*vbuf)+ bcnt * size);
bcnt++;
if ( options & pwr_mSevOptionsMask_HighTimeResolution)
printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
else
printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
//if ( options & pwr_mSevOptionsMask_HighTimeResolution)
// printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
//else
// printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
}
printf( "bcnt %d bufrows %d\n", bcnt, bufrows);
*bsize = bcnt;
......@@ -1181,45 +1294,45 @@ int sev_dbms::get_values( pwr_tStatus *sts, pwr_tOid oid, pwr_tMask options, flo
*tbuf = (pwr_tTime *) calloc( bufrows, sizeof(pwr_tTime));
*vbuf = calloc( bufrows, size);
int bcnt = 0;
for ( int i = 0; i < rows; i += div) {
int j = 0;
if ( div > 1)
mysql_data_seek( result, i);
mysql_data_seek( result, i);
row = mysql_fetch_row( result);
if (!row) break;
if ( options & pwr_mSevOptionsMask_PosixTime) {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
}
else {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
}
cdh_StringToAttrValue( type, row[j++], ((char *)*vbuf)+ bcnt * size);
bcnt++;
if ( options & pwr_mSevOptionsMask_HighTimeResolution)
printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
else
printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
//if ( options & pwr_mSevOptionsMask_HighTimeResolution)
// printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
//else
// printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
}
printf( "bcnt %d bufrows %d\n", bcnt, bufrows);
*bsize = bcnt;
......@@ -1256,9 +1369,9 @@ int sev_dbms::check_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *ana
if ( strcmp( oname, m_items[i].oname) != 0)
sprintf( &query[strlen(query)], "oname=\'%s\',", oname);
if ( type != m_items[i].attr[0].type)
sprintf( &query[strlen(query)], "type=%d,", type);
sprintf( &query[strlen(query)], "vtype=%d,", type);
if ( size != m_items[i].attr[0].size)
sprintf( &query[strlen(query)], "size=%d", size);
sprintf( &query[strlen(query)], "size=%d,", size);
sprintf( &query[strlen(query)], "uptime=\'%s\' ", timestr);
sprintf( &query[strlen(query)], "where id=%d;", m_items[i].id);
......@@ -1294,7 +1407,8 @@ int sev_dbms::add_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname
if ( EVEN(*sts)) return 0;
sev_item item;
sev_attr attr;
item.attr.push_back(attr);
item.id = 0;
strncpy( item.tablename, tablename, sizeof(item.tablename));
item.oid = oid;
......@@ -1310,6 +1424,7 @@ int sev_dbms::add_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname
item.scantime = scantime;
item.deadband = deadband;
item.options = options;
item.attrnum = 1;
m_items.push_back( item);
*idx = m_items.size() - 1;
......@@ -1353,13 +1468,25 @@ int sev_dbms::delete_old_data( pwr_tStatus *sts, pwr_tOid oid, char *aname,
if ( EVEN(*sts)) return 0;
timstr[19] = 0;
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( query, "delete from %s where time < %ld;",
oid_to_table(oid, aname), (long int)limit.tv_sec);
else
sprintf( query, "delete from %s where time < '%s';",
oid_to_table(oid, aname), timstr);
if(options & pwr_mSevOptionsMask_ReadOptimized) {
pwr_tUInt64 nbRowsToClean = 2000;
nbRowsToClean += get_minFromIntegerColumn(oid_to_table(oid, aname), (char *)"id");
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( query, "delete from %s where id < %llu and time < %ld;",
oid_to_table(oid, aname), nbRowsToClean, (long int)limit.tv_sec);
else
sprintf( query, "delete from %s where id < %llu and time < '%s';",
oid_to_table(oid, aname), nbRowsToClean, timstr);
}
else {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( query, "delete from %s where time < %ld;",
oid_to_table(oid, aname), (long int)limit.tv_sec);
else
sprintf( query, "delete from %s where time < '%s';",
oid_to_table(oid, aname), timstr);
}
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "Delete old data: %s\n", mysql_error(m_env->con()));
......@@ -1462,4 +1589,1358 @@ char *sev_dbms::pwrtype_to_type( pwr_eType type, unsigned int size)
return stype;
}
int sev_dbms::check_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx)
{
char timestr[40];
pwr_tTime uptime;
time_GetTime( &uptime);
time_AtoAscii( &uptime, time_eFormat_NumDateAndTime, timestr, sizeof(timestr));
timestr[19] = 0;
for ( unsigned int i = 0; i < m_items.size(); i++) {
if ( m_items[i].deleted)
continue;
if ( cdh_ObjidIsEqual( oid, m_items[i].oid) &&
cdh_NoCaseStrcmp( oname, m_items[i].oname) == 0) {
char query[400];
sprintf( query, "update objectitems set ");
sprintf( &query[strlen(query)], "storagetime=%ld,", (long int)storagetime.tv_sec);
sprintf( &query[strlen(query)], "description=\'%s\',", description);
sprintf( &query[strlen(query)], "scantime=%.3f,", scantime);
sprintf( &query[strlen(query)], "deadband=%.3f,", deadband);
//For now we can't change options. sprintf( &query[strlen(query)], "options=%d,", options);
sprintf( &query[strlen(query)], "uptime=\'%s\' ", timestr);
sprintf( &query[strlen(query)], "where vid=%d and oix=%d and tablename='%s';", oid.vid, oid.oix, tablename);
//printf("%s query:%s\n", __FUNCTION__, query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s : %s\n", __FUNCTION__, mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
m_items[i].storagetime = storagetime;
strncpy(m_items[i].description, description, sizeof(m_items[i].description));
m_items[i].scantime = scantime;
m_items[i].deadband = deadband;
//This won't work!! We have to alter the table to be able to change this
//m_items[i].options = options;
*idx = i;
*sts = SEV__SUCCESS;
return 1;
}
}
*sts = SEV__NOSUCHITEM;
return 0;
}
int sev_dbms::add_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx)
{
store_objectitem( sts, tablename, oid, oname, aname, storagetime, description,
scantime, deadband, options);
if ( EVEN(*sts)) return 0;
create_objecttable( sts, tablename, oid, aname, options, deadband);
if ( EVEN(*sts)) return 0;
*sts = SEV__SUCCESS;
sev_item item;
item.id = 0;
strncpy( item.tablename, tablename, sizeof(item.tablename));
item.oid = oid;
strncpy( item.oname, oname, sizeof(item.oname));
time_GetTime( &item.creatime);
item.modtime = item.creatime;
item.storagetime = storagetime;
strncpy( item.description, description, sizeof(item.description));
item.scantime = scantime;
item.deadband = deadband;
item.options = options;
item.attrnum = 0;
m_items.push_back( item);
*idx = m_items.size() - 1;
return 1;
}
int sev_dbms::store_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname,
char *aname, pwr_tDeltaTime storagetime, char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options)
{
char query[800];
char timestr[40];
pwr_tTime creatime;
time_GetTime( &creatime);
time_AtoAscii( &creatime, time_eFormat_NumDateAndTime, timestr, sizeof(timestr));
timestr[19] = 0;
sprintf( query, "insert into objectitems (id,tablename,vid,oix,oname,aname,uptime,cretime,storagetime,description,scantime,deadband,options) "
"values (0,'%s',%d,%d,'%s','%s','%s','%s',%ld,'%s',%f,%f,%d);",
tablename, oid.vid, oid.oix, oname, aname, timestr, timestr, (long int)storagetime.tv_sec, description, scantime, deadband, options);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "Store item: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::create_objecttable( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, pwr_tMask options, float deadband)
{
char query[2000];
char timeformatstr[80];
char jumpstr[80];
char idtypestr[20];
char readoptstr[80];
if ( options & pwr_mSevOptionsMask_PosixTime) {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
strcpy( timeformatstr, "sev__time int unsigned, sev__ntime int unsigned");
strcpy( idtypestr, "bigint");
}
else {
// Posix time, low resolution
strcpy( timeformatstr, "sev__time int unsigned");
strcpy( idtypestr, "int");
}
}
else {
if ( options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
strcpy( timeformatstr, "sev__time datetime not null, sev__ntime int unsigned");
strcpy( idtypestr, "bigint");
}
else {
// Sql time, low resolution
strcpy( timeformatstr, "sev__time datetime not null");
strcpy( idtypestr, "int");
}
}
if ( options & pwr_mSevOptionsMask_ReadOptimized)
sprintf( readoptstr, "sev__id %s unsigned not null primary key auto_increment,", idtypestr);
else
strcpy( readoptstr, "");
if ( options & pwr_mSevOptionsMask_UseDeadBand)
strcpy( jumpstr, ",sev__jump tinyint unsigned");
else
strcpy( jumpstr, "");
sprintf( query, "create table %s ( %s"
"%s %s, index (sev__time) );",
tablename, readoptstr, timeformatstr, jumpstr);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__ ,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::check_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx)
{
sev_item *item = &m_items[*idx];
for (size_t j = 0; j < item->attr.size(); j++) {
if (cdh_NoCaseStrcmp( aname, item->attr[j].aname) == 0) {
if (type != item->attr[j].type ||
size != item->attr[j].size) {
//Same name new type or size what to do?
//We try to alter the table if it is possible(float->double int->long or little_string->bigger_string probably works).
//If we can't alter the table we rename the column and create a new one
printf("Column:%s in %s has been changed from Type/size %d/%d to %d/%d\n",
aname, tablename, item->attr[j].type, item->attr[j].size, type, size );
errh_Warning("Column:%s in %s has been changed from Type/size %d/%d to %d/%d",
aname, tablename, item->attr[j].type, item->attr[j].size, type, size );
if (!alter_attrcolumn(sts, tablename, aname, type, size, item->attr[j].type, item->attr[j].size)) {
//We were not able to alter the column then we should rename the column and create a new one
if (!rename_attrcolumn(sts, tablename, aname, item->attr[j].type, item->attr[j].size)) {
//Very very bad this should not happen
errh_Error("Could not rename column that has been changed tablename:%s columnname:%s", tablename, aname);
//m_items[i].attr[j].status = -1; //TODO Skip this attribute during logging
*sts = SEV__DBERROR;
return 1;
}
errh_Warning("Column:%s in %s renamed to:%s_before_xxxx xx:xx:xx", aname, tablename, aname );
char query[2000];
sprintf( query, "alter table %s add `%s` %s;",
tablename, aname, pwrtype_to_type( type, size));
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 1;
}
}
item->attr[j].type = type;
item->attr[j].size = size;
update_objectitemattr(sts, tablename, aname, type, size);
}
*sts = SEV__SUCCESS;
return 1;
}
}
*sts = SEV__NOSUCHITEM;
return 0;
}
int sev_dbms::add_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx)
{
char query[2000];
sprintf( query, "alter table %s add `%s` %s;",
tablename, aname, pwrtype_to_type( type, size));
//printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
int aidx = get_nextattridx(sts, tablename);
sprintf( query, "insert into objectitemattributes (tablename, attributename, attributeidx, attributetype, attributesize) "
"values('%s', '%s', %d, %d, %d)", tablename, aname, aidx, type, size);
//printf( "%s: %s\n", __FUNCTION__ ,query);
rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
sev_attr newattr;
strncpy( newattr.aname, aname, sizeof(newattr.aname));
newattr.type = type;
newattr.size = size;
newattr.elem = 0;
m_items[*idx].attr.push_back(newattr);
m_items[*idx].attrnum = m_items[*idx].attr.size();
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::get_nextattridx( pwr_tStatus *sts, char *tablename )
{
char query[2000];
sprintf( query, "select max(attributeidx) from objectitemattributes where tablename='%s'", tablename);
//printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
if(rows > 1) {
printf( "Duplicate items Error\n");
*sts = SEV__DBERROR;
mysql_free_result( result);
return 0;
}
int attridx = -1;
for ( int i = 0; i < rows; i++) {
row = mysql_fetch_row( result);
if (!row) break;
if(row[0] != NULL) {
attridx = atoi( row[0]);
}
}
mysql_free_result( result);
*sts = SEV__SUCCESS;
return attridx+1;
}
pwr_tUInt64 sev_dbms::get_minFromIntegerColumn( char *tablename, char *colname )
{
char query[2000];
pwr_tUInt64 retVal = 0;
sprintf( query, "select min(`%s`) from %s", colname, tablename);
//printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
return 0;
}
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Result Error\n");
return retVal;
}
int rows = mysql_num_rows( result);
if(rows <= 0) {
mysql_free_result( result);
return retVal;
}
MYSQL_ROW row;
row = mysql_fetch_row( result);
if(row[0] != NULL) {
retVal = strtoull(row[0], 0, 10);
}
mysql_free_result( result);
return retVal;
}
int sev_dbms::store_objectvalue( pwr_tStatus *sts, int item_idx, int attr_idx,
pwr_tTime time, void *buf, void *oldbuf, unsigned int size)
{
void *data = buf;
void *olddata = oldbuf;
static const int constQueryLength = 3000;
string valuesStr;
string colsStr;
ostringstream queryOStr;
char query[constQueryLength];
char bufstr[512];
char bufInclEscCharstr[1025];
char timstr[40];
*sts = time_AtoAscii( &time, time_eFormat_NumDateAndTime, timstr, sizeof(timstr));
if ( EVEN(*sts)) return 0;
timstr[19] = 0;
bool updateOnlyTime = false;
bool setJump = false;
if ( !m_items[item_idx].first_storage &&
(m_items[item_idx].options & pwr_mSevOptionsMask_UseDeadBand) ) {
if ( m_items[item_idx].deadband_active) {
updateOnlyTime = true;
for (size_t i = 0; i < m_items[item_idx].attr.size(); i++) {
pwr_tFloat32 deadband = m_items[item_idx].deadband; //TODO should be on attribute
m_items[item_idx].deadband_active = check_deadband(m_items[item_idx].attr[i].type, m_items[item_idx].attr[i].size, deadband, buf, oldbuf);
if (!m_items[item_idx].deadband_active) {
updateOnlyTime = false;
break;
}
buf = (char*)buf + m_items[item_idx].attr[i].size;
oldbuf = (char*)oldbuf + m_items[item_idx].attr[i].size;
}
}
else {
setJump = true;
for (size_t i = 0; i < m_items[item_idx].attr.size(); i++) {
pwr_tFloat32 deadband = m_items[item_idx].deadband; //TODO should be on attribute
m_items[item_idx].deadband_active = check_deadband(m_items[item_idx].attr[i].type, m_items[item_idx].attr[i].size, deadband, buf, oldbuf);
if (!m_items[item_idx].deadband_active) {
setJump = false;
break;
}
buf = (char*)buf + m_items[item_idx].attr[i].size;
oldbuf = (char*)oldbuf + m_items[item_idx].attr[i].size;
}
}
}
buf = data;
oldbuf = olddata;
if(!updateOnlyTime) {
memcpy(oldbuf, buf, size);
for(size_t i = 0; i < m_items[item_idx].attr.size(); i++) {
if(m_items[item_idx].attr[i].type == pwr_eType_Time)
*sts = time_AtoAscii( (pwr_tTime*)buf, time_eFormat_NumDateAndTime, bufstr, sizeof(bufstr));
else
*sts = cdh_AttrValueToString( m_items[item_idx].attr[i].type, buf, bufstr, sizeof(bufstr));
if ( EVEN(*sts)) return 0;
if(m_items[item_idx].attr[i].type == pwr_eType_String ||
m_items[item_idx].attr[i].type == pwr_eType_Text) {
mysql_real_escape_string(m_env->con(), bufInclEscCharstr, bufstr, strlen(bufstr) );
valuesStr.append("'");
valuesStr.append(bufInclEscCharstr);
valuesStr.append("',");
}
else {
valuesStr.append("'");
valuesStr.append(bufstr);
valuesStr.append("',");
}
colsStr.append("`");
colsStr.append(m_items[item_idx].attr[i].aname);
colsStr.append("`,");
buf = (char*)buf + m_items[item_idx].attr[i].size;
}
//remove last ,
valuesStr.resize(valuesStr.length()-1);
colsStr.resize(colsStr.length()-1);
if ( m_items[item_idx].options & pwr_mSevOptionsMask_PosixTime) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
queryOStr << "insert into " << m_items[item_idx].tablename << " (sev__time, sev__ntime, " << colsStr << ") values (" << time.tv_sec <<
"," << time.tv_nsec << "," << valuesStr << ")";
snprintf(query, constQueryLength, "insert into %s (sev__time, sev__ntime, %s) values (%ld,%ld,%s)",
m_items[item_idx].tablename, colsStr.c_str(), (long int)time.tv_sec, (long int)time.tv_nsec, valuesStr.c_str());
}
else {
// Posix time, low resolution
queryOStr << "insert into " << m_items[item_idx].tablename << " (sev__time, " << colsStr << ") values (" << time.tv_sec <<
"," << valuesStr << ")";
snprintf(query, constQueryLength, "insert into %s (sev__time, %s) values (%ld,%s)",
m_items[item_idx].tablename, colsStr.c_str(), (long int)time.tv_sec, valuesStr.c_str());
}
}
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
queryOStr << "insert into " << m_items[item_idx].tablename << " (sev__time, sev__ntime, " << colsStr << ") values (" << "'" << timstr << "'" <<
"," << time.tv_nsec << "," << valuesStr << ")";
snprintf(query, constQueryLength, "insert into %s (sev__time, sev__ntime, %s) values ('%s',%ld,%s)",
m_items[item_idx].tablename, colsStr.c_str(), timstr, (long int)time.tv_nsec, valuesStr.c_str());
}
else {
// Sql time, low resolution
queryOStr << "insert into " << m_items[item_idx].tablename << " (sev__time, " << colsStr << ") values (" << "'" << timstr << "'" <<
"," << valuesStr << ")";
snprintf(query, constQueryLength, "insert into %s (sev__time, %s) values ('%s',%s)",
m_items[item_idx].tablename, colsStr.c_str(), timstr, valuesStr.c_str());
}
}
} //end insert new values
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_PosixTime) {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
queryOStr << "update " << m_items[item_idx].tablename << " set sev__time = " << time.tv_sec << ", sev__ntime = " << time.tv_nsec << " where sev__id = " << m_items[item_idx].last_id;
}
else {
// Posix time, low resolution
queryOStr << "update " << m_items[item_idx].tablename << " set sev__time = " << time.tv_sec << " where sev__id = " << m_items[item_idx].last_id;
}
}
else {
if ( m_items[item_idx].options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
queryOStr << "update " << m_items[item_idx].tablename << " set sev__time = '" << timstr << "', sev__ntime = " << time.tv_nsec << " where sev__id = " << m_items[item_idx].last_id;
}
else {
// Sql time, low resolution
queryOStr << "update " << m_items[item_idx].tablename << " set sev__time = '" << timstr << "' where sev__id = " << m_items[item_idx].last_id;
}
}
}
if ( setJump || updateOnlyTime) {
sprintf( query, "update %s set sev__jump = 1 where sev__id = %d",
m_items[item_idx].tablename,
m_items[item_idx].last_id);
int rc = mysql_query( m_env->con(), query);
if (rc)
printf( "Update jump: %s\n", mysql_error(m_env->con()));
}
//printf( "Store_objectvalue: %s\n", queryOStr.str().c_str());
int rc = mysql_query( m_env->con(), queryOStr.str().c_str());
if (rc) {
printf( "Update value: %s\n", mysql_error(m_env->con()));
printf( "Error in: %s\n", queryOStr.str().c_str());
*sts = SEV__DBERROR;
m_items[item_idx].status = *sts;
if ( m_items[item_idx].status != m_items[item_idx].logged_status) {
m_items[item_idx].logged_status = m_items[item_idx].status;
errh_Error( "Database update error: %s, table: %s object: %s",
mysql_error(m_env->con()), m_items[item_idx].tablename, m_items[item_idx].oname);
}
return 0;
}
if ( (m_items[item_idx].options & pwr_mSevOptionsMask_ReadOptimized) &&
!updateOnlyTime)
m_items[item_idx].last_id = mysql_insert_id( m_env->con());
m_items[item_idx].first_storage = 0;
*sts = SEV__SUCCESS;
m_items[item_idx].status = *sts;
m_items[item_idx].logged_status = 1;
return 1;
}
int sev_dbms::get_item( pwr_tStatus *sts, sev_item *item, char *tablename)
{
char query[300];
sprintf( query, "select id,tablename,vid,oix,oname,aname,uptime,cretime,storagetime,vtype,vsize,description,unit,scantime,deadband,options "
"from items where tablename='%s'", tablename);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__, mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
if(rows > 1) {
printf( "Duplicate items Error\n");
*sts = SEV__DBERROR;
mysql_free_result( result);
return 0;
}
if(rows == 0) {
printf( "No item Error\n");
*sts = SEV__DBERROR;
mysql_free_result( result);
return 0;
}
int col;
for ( int i = 0; i < rows; i++) {
row = mysql_fetch_row( result);
if (!row) break;
col=0;
sev_attr attr;
item->attr.push_back(attr);
item->id = atoi( row[col++]);
strncpy( item->tablename, row[col++], sizeof(item->tablename));
item->oid.vid = strtoul( row[col++], 0, 10);
item->oid.oix = strtoul( row[col++], 0, 10);
strncpy( item->oname, row[col++], sizeof(item->oname));
strncpy( item->attr[0].aname, row[col++], sizeof(item->attr[0].aname));
timestr_to_time( row[col++], &item->modtime);
timestr_to_time( row[col++], &item->creatime);
item->storagetime.tv_sec = strtoul( row[col++], 0, 10);
item->storagetime.tv_nsec = 0;
item->attr[0].type = (pwr_eType) strtoul( row[col++], 0, 10);
item->attr[0].size = strtoul( row[col++], 0, 10);
strncpy( item->description, row[col++], sizeof(item->description));
strncpy( item->attr[0].unit, row[col++], sizeof(item->attr[0].unit));
item->scantime = atof(row[col++]);
item->deadband = atof(row[col++]);
item->options = strtoul(row[col++], 0, 10);
item->attrnum = 1;
}
mysql_free_result( result);
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::get_objectitem( pwr_tStatus *sts, sev_item *item, char *tablename)
{
char query[300];
sprintf( query, "select id,tablename,vid,oix,oname,aname,uptime,cretime,storagetime,description,scantime,deadband,options "
"from objectitems where tablename='%s'", tablename);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__, mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "get_objectitem Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
if(!rows) {
mysql_free_result( result);
printf( "get_objectitem Row Error\n");
printf( "get_objectitem: %s\n", query);
*sts = SEV__DBERROR;
return 0;
}
row = mysql_fetch_row( result);
if (!row) {
mysql_free_result( result);
printf( "get_objectitem Row Error\n");
*sts = SEV__DBERROR;
return 0;
}
int col = 0;
item->id = atoi( row[col++]);
strncpy( item->tablename, row[col++], sizeof(item->tablename));
item->oid.vid = strtoul( row[col++], 0, 10);
item->oid.oix = strtoul( row[col++], 0, 10);
strncpy( item->oname, row[col++], sizeof(item->oname));
col++; //No aname in sev_item TODO add aname to sev_item??
timestr_to_time( row[col++], &item->modtime);
timestr_to_time( row[col++], &item->creatime);
item->storagetime.tv_sec = strtoul( row[col++], 0, 10);
item->storagetime.tv_nsec = 0;
strncpy( item->description, row[col++], sizeof(item->description));
item->scantime = atof(row[col++]);
item->deadband = atof(row[col++]);
item->options = strtoul(row[col++], 0, 10);
//Time to fetch all attributes for this item
get_objectitemattributes(sts, item, item->tablename);
item->attrnum = item->attr.size();
mysql_free_result( result);
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::get_objectitems( pwr_tStatus *sts)
{
char query[300];
sprintf( query, "select id,tablename,vid,oix,oname,aname,uptime,cretime,storagetime,description,scantime,deadband,options "
"from objectitems");
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "Get ObjectItems: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetObjectItems Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
int col;
for ( int i = 0; i < rows; i++) {
sev_item item;
row = mysql_fetch_row( result);
if (!row) break;
//printf( "%d %s %s\n", i, row[0], row[1]);
col=0;
item.id = atoi( row[col++]);
strncpy( item.tablename, row[col++], sizeof(item.tablename));
item.oid.vid = strtoul( row[col++], 0, 10);
item.oid.oix = strtoul( row[col++], 0, 10);
strncpy( item.oname, row[col++], sizeof(item.oname));
col++; //No aname in sev_item TODO add aname to sev_item??
timestr_to_time( row[col++], &item.modtime);
timestr_to_time( row[col++], &item.creatime);
item.storagetime.tv_sec = strtoul( row[col++], 0, 10);
item.storagetime.tv_nsec = 0;
strncpy( item.description, row[col++], sizeof(item.description));
item.scantime = atof(row[col++]);
item.deadband = atof(row[col++]);
item.options = strtoul(row[col++], 0, 10);
//Time to fetch all attributes for this item
get_objectitemattributes(sts, &item, item.tablename);
item.attrnum = item.attr.size();
m_items.push_back( item);
}
mysql_free_result( result);
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::get_objectitemattributes( pwr_tStatus *sts, sev_item *item, char *tablename)
{
char query[300];
sprintf( query, "select attributename, attributetype, attributesize from objectitemattributes where tablename='%s'order by attributeidx asc", tablename);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "Get ObjectItemAttr: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetObjectItemAttr Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
int col;
for ( int i = 0; i < rows; i++) {
sev_attr attr;
row = mysql_fetch_row( result);
if (!row) break;
col=0;
strncpy( attr.aname, row[col++], sizeof(attr.aname));
attr.type = (pwr_eType) strtoul( row[col++], 0, 10);
attr.size = strtoul( row[col++], 0, 10);
attr.unit[0] = '\0'; //No unit present TODO add??
item->value_size += attr.size;
item->attr.push_back( attr);
}
mysql_free_result( result);
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::delete_old_objectdata( pwr_tStatus *sts, char *tablename,
pwr_tMask options, pwr_tTime limit)
{
char query[300];
char timstr[40];
*sts = time_AtoAscii( &limit, time_eFormat_NumDateAndTime, timstr, sizeof(timstr));
if ( EVEN(*sts)) return 0;
timstr[19] = 0;
if(options & pwr_mSevOptionsMask_ReadOptimized) {
pwr_tUInt64 nbRowsToClean = 2000;
nbRowsToClean += get_minFromIntegerColumn(tablename, (char *)"sev__id");
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( query, "delete from %s where sev__id < %llu and sev__time < %ld;",
tablename, nbRowsToClean, (long int)limit.tv_sec);
else
sprintf( query, "delete from %s where sev__id < %llu and sev__time < '%s';",
tablename, nbRowsToClean, timstr);
}
else {
if ( options & pwr_mSevOptionsMask_PosixTime)
sprintf( query, "delete from %s where sev__time < %ld;",
tablename, (long int)limit.tv_sec);
else
sprintf( query, "delete from %s where sev__time < '%s';",
tablename, timstr);
}
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "Delete old object data: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
*sts = SEV__SUCCESS;
return 1;
}
int sev_dbms::alter_attrcolumn(pwr_tStatus *sts, char *tablename, char *aname,
pwr_eType newtype, unsigned int newsize,
pwr_eType oldtype, unsigned int oldsize)
{
//TODO
return 0;
}
int sev_dbms::rename_attrcolumn(pwr_tStatus *sts, char *tablename, char *aname, pwr_eType type, unsigned int size)
{
char query[2000];
char newname[500];
char timestr[40];
pwr_tTime uptime;
time_GetTime( &uptime);
time_AtoAscii( &uptime, time_eFormat_NumDateAndTime, timestr, sizeof(timestr));
timestr[19] = 0;
sprintf(newname, "%s_before_%s", aname, timestr);
sprintf(query, "alter table %s change `%s` `%s` %s", tablename, aname, newname, pwrtype_to_type(type, size));
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__, mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::remove_objectitemattr( pwr_tStatus *sts, char *tablename, char *aname)
{
char query[2000];
sprintf( query, "delete from objectitemattributes where tablename = '%s' and attributename = '%s'", tablename, aname);
//printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::update_objectitemattr( pwr_tStatus *sts, char *tablename, char *aname, pwr_eType type, unsigned int size)
{
char query[2000];
sprintf( query, "update objectitemattributes set attributetype=%d, attributesize=%d where tablename = '%s' and attributename = '%s'",
type, size, tablename, aname);
//printf( "%s: %s\n", __FUNCTION__ ,query);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "%s: %s\n", __FUNCTION__,mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
return 1;
}
int sev_dbms::check_deadband(pwr_eType type, unsigned int size, pwr_tFloat32 deadband, void *value, void *oldvalue)
{
int deadband_active = 0;
switch ( type) {
case pwr_eType_Float32:
if ( fabsf ( *(pwr_tFloat32 *)value - *(pwr_tFloat32 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_Float64:
if ( fabsf ( *(pwr_tFloat64 *)value - *(pwr_tFloat64 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_Int64:
if ( fabsf ( *(pwr_tInt64 *)value - *(pwr_tInt64 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_Int32:
if ( fabsf ( *(pwr_tInt32 *)value - *(pwr_tInt32 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_Int16:
if ( fabsf ( *(pwr_tInt16 *)value - *(pwr_tInt16 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_Int8:
case pwr_eType_Char:
if ( fabsf ( *(pwr_tInt8 *)value - *(pwr_tInt8 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_UInt64:
if ( fabsf ( *(pwr_tUInt64 *)value - *(pwr_tUInt64 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_UInt32:
case pwr_eType_Boolean:
if ( fabsf ( *(pwr_tUInt32 *)value - *(pwr_tUInt32 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_UInt16:
if ( fabsf ( *(pwr_tUInt16 *)value - *(pwr_tUInt16 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_UInt8:
if ( fabsf ( *(pwr_tUInt8 *)value - *(pwr_tUInt8 *)oldvalue) < deadband) {
deadband_active = 1;
}
break;
case pwr_eType_String:
case pwr_eType_Text:
if ( !memcmp(value, oldvalue, size) ) {
deadband_active = 1;
}
break;
default: ;
}
return deadband_active;
}
int sev_dbms::get_objectvalues( pwr_tStatus *sts, sev_item *item,
unsigned int size, pwr_tTime *starttime, pwr_tTime *endtime,
int maxsize, pwr_tTime **tbuf, void **vbuf, unsigned int *bsize)
{
char query[200];
string queryStr;
char starttimstr[40];
char endtimstr[40];
int total_rows;
int div;
pwr_tDeltaTime dt;
pwr_tTime stime, etime;
string colsStr;
char orderby_part[80];
char jumpstr[40];
char where_part[200];
if ( starttime && starttime->tv_sec == 0 && starttime->tv_nsec == 0)
starttime = 0;
else
stime = *starttime;
if ( endtime && endtime->tv_sec == 0 && endtime->tv_nsec == 0)
endtime = 0;
else
etime = *endtime;
// Get number of rows
sprintf( query, "show table status where name = '%s';", item->tablename);
int rc = mysql_query( m_env->con(), query);
if (rc) {
printf( "GetValues Query Error\n");
*sts = SEV__DBERROR;
return 0;
}
MYSQL_ROW row;
MYSQL_RES *result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Status Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
row = mysql_fetch_row( result);
if (!row) {
printf( "GetValues Status Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
if ( starttime && endtime) {
pwr_tTime create_time;
pwr_tTime update_time;
timestr_to_time( row[11], &create_time);
timestr_to_time( row[12], &update_time);
if ( time_Acomp( &item->creatime, &stime) == 1)
stime = item->creatime;
if ( time_Acomp( &etime, &update_time) == 1)
etime = update_time;
time_Adiff( &dt, &etime, &stime);
total_rows = int (time_DToFloat( 0, &dt) / item->scantime);
div = total_rows / maxsize + 1;
}
else if ( starttime) {
pwr_tTime update_time;
timestr_to_time( row[12], &update_time);
if ( time_Acomp( &update_time, starttime) != 1) {
mysql_free_result( result);
*sts = SEV__NODATATIME;
return 0;
}
time_Adiff( &dt, &update_time, starttime);
total_rows = int (time_DToFloat( 0, &dt) / item->scantime);
}
else if ( endtime) {
pwr_tTime create_time;
timestr_to_time( row[11], &create_time);
if ( time_Acomp( endtime, &create_time) != 1) {
mysql_free_result( result);
*sts = SEV__NODATATIME;
return 0;
}
time_Adiff( &dt, endtime, &create_time);
total_rows = int (time_DToFloat( 0, &dt) / item->scantime);
}
else {
total_rows = atoi(row[4]);
}
mysql_free_result( result);
div = total_rows / maxsize + 1;
if ( starttime) {
*sts = time_AtoAscii( &stime, time_eFormat_NumDateAndTime, starttimstr,
sizeof(starttimstr));
if ( EVEN(*sts)) return 0;
starttimstr[19] = 0;
}
if ( endtime) {
*sts = time_AtoAscii( &etime, time_eFormat_NumDateAndTime, endtimstr,
sizeof(endtimstr));
if ( EVEN(*sts)) return 0;
endtimstr[19] = 0;
}
// Column part
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution) {
colsStr.append("sev__time, sev__ntime, ");
}
else {
colsStr.append("sev__time, ");
}
for(size_t i = 0; i < item->attr.size(); i++) {
colsStr.append("`");
colsStr.append(item->attr[i].aname);
colsStr.append("`,");
}
//remove last ,
colsStr.resize(colsStr.length()-1);
if ( item->options & pwr_mSevOptionsMask_UseDeadBand)
strcpy( jumpstr, "or sev__jump = 1");
else
strcpy( jumpstr, "");
// 'order by' part
if ( item->options & pwr_mSevOptionsMask_ReadOptimized)
strcpy( orderby_part, "sev__id");
else {
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution)
strcpy( orderby_part, "sev__time,sev__ntime");
else
strcpy( orderby_part, "sev__time");
}
// 'where' part
if ( item->options & pwr_mSevOptionsMask_ReadOptimized) {
if ( starttime && endtime) {
if ( div == 1) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time >= %ld and sev__time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where sev__time >= '%s' and sev__time <= '%s'", starttimstr, endtimstr);
}
else {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time >= %ld and sev__time <= %ld",
div, jumpstr, (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time >= '%s' and sev__time <= '%s'",
div, jumpstr, starttimstr, endtimstr);
}
}
else if ( starttime) {
if ( div == 1) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time >= %ld", (long int)starttime->tv_sec);
else
sprintf( where_part, "where sev__time >= '%s'", starttimstr);
}
else {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time >= %ld", div, jumpstr, (long int)starttime->tv_sec);
else
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time >= '%s'", div, jumpstr, starttimstr);
}
}
else if ( endtime) {
if ( div == 1) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time <= %ld", (long int)endtime->tv_sec);
else
sprintf( where_part, "where sev__time <= '%s'", endtimstr);
}
else {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time <= %ld", div, jumpstr, (long int)endtime->tv_sec);
else
sprintf( where_part, "where (sev__id %% %d = 0 %s) and sev__time <= '%s'", div, jumpstr, endtimstr);
}
}
else {
if ( div == 1)
strcpy( where_part, "");
else
sprintf( where_part, "where sev__id %% %d = 0 %s", div, jumpstr);
}
}
else {
// Not read optimized
if ( starttime && endtime) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time >= %ld and sev__time <= %ld", (long int)starttime->tv_sec, (long int)endtime->tv_sec);
else
sprintf( where_part, "where sev__time >= '%s' and sev__time <= '%s'", starttimstr, endtimstr);
}
else if ( starttime) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time >= %ld", (long int)starttime->tv_sec);
else
sprintf( where_part, "where sev__time >= '%s'", starttimstr);
}
else if ( endtime) {
if ( item->options & pwr_mSevOptionsMask_PosixTime)
sprintf( where_part, "where sev__time <= %ld", (long int)endtime->tv_sec);
else
sprintf( where_part, "where sev__time <= '%s'", endtimstr);
}
else
strcpy( where_part, "");
}
queryStr.append("select ");
queryStr.append(colsStr);
queryStr.append(" from ");
queryStr.append(item->tablename);
queryStr.append(" ");
queryStr.append(where_part);
queryStr.append(" order by ");
queryStr.append(orderby_part);
printf("%s: %s\n", __FUNCTION__, queryStr.c_str());
rc = mysql_query( m_env->con(), queryStr.c_str());
if (rc) {
printf( "Get Values: %s\n", mysql_error(m_env->con()));
*sts = SEV__DBERROR;
return 0;
}
result = mysql_store_result( m_env->con());
if ( !result) {
printf( "GetValues Result Error\n");
*sts = SEV__DBERROR;
return 0;
}
int rows = mysql_num_rows( result);
int bufrows = rows;
if ( item->options & pwr_mSevOptionsMask_ReadOptimized) {
*tbuf = (pwr_tTime *) calloc( bufrows, sizeof(pwr_tTime));
*vbuf = calloc( bufrows, item->value_size);
int bcnt = 0;
for ( int i = 0; i < rows; i ++) {
int j = 0;
// if ( div > 1)
// mysql_data_seek( result, i);
row = mysql_fetch_row( result);
if (!row) break;
if ( item->options & pwr_mSevOptionsMask_PosixTime) {
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
}
else {
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
}
int read_size = 0;
for(size_t k = 0; k < item->attr.size(); k++) {
if(row[j] == 0) {
//Null value
switch(item->attr[k].type) {
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_Int8:
case pwr_eType_Int16:
case pwr_eType_Int32:
case pwr_eType_Int64:
case pwr_eType_UInt8:
case pwr_eType_UInt16:
case pwr_eType_UInt32:
case pwr_eType_UInt64:
case pwr_eType_Mask:
case pwr_eType_Enum:
cdh_StringToAttrValue( item->attr[k].type, "0", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
case pwr_eType_Time:
case pwr_eType_DeltaTime:
//TODO deltatime??
cdh_StringToAttrValue( item->attr[k].type, "1970-01-01 00:00:00", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
default:
cdh_StringToAttrValue( item->attr[k].type, " ", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
}
j++;
}
else {
cdh_StringToAttrValue( item->attr[k].type, row[j++], ((char *)*vbuf)+ bcnt * item->value_size + read_size);
}
read_size += item->attr[k].size;
}
bcnt++;
//if ( item->options & pwr_mSevOptionsMask_HighTimeResolution)
// printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
//else
// printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
}
printf( "bcnt %d bufrows %d\n", bcnt, bufrows);
*bsize = bcnt;
mysql_free_result( result);
}
else {
*tbuf = (pwr_tTime *) calloc( bufrows, sizeof(pwr_tTime));
*vbuf = calloc( bufrows, size);
int bcnt = 0;
for ( int i = 0; i < rows; i += div) {
int j = 0;
if ( div > 1)
mysql_data_seek( result, i);
row = mysql_fetch_row( result);
if (!row) break;
if ( item->options & pwr_mSevOptionsMask_PosixTime) {
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution) {
// Posix time, high resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Posix time, low resolution
(*tbuf)[bcnt].tv_sec = strtoul( row[j++], 0, 10);
}
else {
if ( item->options & pwr_mSevOptionsMask_HighTimeResolution) {
// Sql time, high resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
(*tbuf)[bcnt].tv_nsec = strtoul( row[j++], 0, 10);
}
else
// Sql time, low resolution
timestr_to_time( row[j++], &(*tbuf)[bcnt]);
}
int read_size = 0;
for(size_t k = 0; k < item->attr.size(); k++) {
if(row[j] == 0) {
//Null value
switch(item->attr[k].type) {
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_Int8:
case pwr_eType_Int16:
case pwr_eType_Int32:
case pwr_eType_Int64:
case pwr_eType_UInt8:
case pwr_eType_UInt16:
case pwr_eType_UInt32:
case pwr_eType_UInt64:
case pwr_eType_Mask:
case pwr_eType_Enum:
cdh_StringToAttrValue( item->attr[k].type, "0", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
case pwr_eType_Time:
case pwr_eType_DeltaTime:
//TODO deltatime??
cdh_StringToAttrValue( item->attr[k].type, "1970-01-01 00:00:00", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
default:
cdh_StringToAttrValue( item->attr[k].type, " ", ((char *)*vbuf)+ bcnt * item->value_size + read_size);
break;
}
j++;
}
else {
cdh_StringToAttrValue( item->attr[k].type, row[j++], ((char *)*vbuf)+ bcnt * item->value_size + read_size);
}
read_size += item->attr[k].size;
}
bcnt++;
//if ( item->options & pwr_mSevOptionsMask_HighTimeResolution)
// printf( "%5d %5d %s.%9s %s\n", i, bcnt, row[0], row[1], row[2]);
//else
// printf( "%5d %5d %s %s\n", i, bcnt, row[0], row[1]);
}
printf( "bcnt %d bufrows %d\n", bcnt, bufrows);
*bsize = bcnt;
mysql_free_result( result);
}
*sts = SEV__SUCCESS;
return 1;
}
sev_dbms::~sev_dbms()
{
printf("Freeing memory\n");
for(size_t idx = 0; idx < m_items.size(); idx++) {
if( m_items[idx].old_value != 0 ) {
free(m_items[idx].old_value);
m_items[idx].old_value = 0;
}
}
}
#endif
......@@ -67,6 +67,8 @@ class sev_dbms_env
int open(const char *host, const char *user, const char *passwd,
const char *dbName, unsigned int port, const char *socket);
int checkAndUpdateVersion(unsigned int version);
int updateDB_to_SevVersion2(void);
MYSQL *createDb(void);
MYSQL *openDb(void);
bool exists() { return m_exists;}
......@@ -104,7 +106,7 @@ class sev_dbms : public sev_db {
sev_dbms_env *m_env;
sev_dbms( sev_dbms_env *env) : m_env(env) {}
~sev_dbms() {}
~sev_dbms();
int check_item( pwr_tStatus *sts, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime, pwr_eType type, unsigned int size,
......@@ -136,7 +138,40 @@ class sev_dbms : public sev_db {
char *oid_to_table( pwr_tOid oid, char *aname);
char *pwrtype_to_type( pwr_eType type, unsigned int size);
static int timestr_to_time( char *tstr, pwr_tTime *ts);
int check_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx);
int add_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime,
char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options, unsigned int *idx);
int store_objectitem( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *oname, char *aname,
pwr_tDeltaTime storagetime, char *description, pwr_tFloat32 scantime,
pwr_tFloat32 deadband, pwr_tMask options);
int create_objecttable( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname,
pwr_tMask options, float deadband);
int add_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx);
int store_objectvalue( pwr_tStatus *sts, int item_idx, int attr_idx,
pwr_tTime time, void *buf, void *oldbuf, unsigned int size);
int get_item( pwr_tStatus *sts, sev_item *item, char *tablename);
int get_objectitem( pwr_tStatus *sts, sev_item *item, char *tablename);
int get_objectitems( pwr_tStatus *sts);
int get_objectitemattributes( pwr_tStatus *sts, sev_item *item, char *tablename);
int check_objectitemattr( pwr_tStatus *sts, char *tablename, pwr_tOid oid, char *aname, char *oname,
pwr_eType type, unsigned int size, unsigned int *idx);
int get_nextattridx( pwr_tStatus *sts, char *tablename );
int delete_old_objectdata( pwr_tStatus *sts, char *tablename,
pwr_tMask options, pwr_tTime limit);
int alter_attrcolumn(pwr_tStatus *sts, char *tablename, char *aname, pwr_eType newtype, unsigned int newsize, pwr_eType oldtype, unsigned int oldsize);
int rename_attrcolumn(pwr_tStatus *sts, char *tablename, char *aname, pwr_eType type, unsigned int size);
int remove_objectitemattr( pwr_tStatus *sts, char *tablename, char *aname);
int update_objectitemattr( pwr_tStatus *sts, char *tablename, char *aname, pwr_eType type, unsigned int size);
int check_deadband(pwr_eType type, unsigned int size, pwr_tFloat32 deadband, void *value, void *oldvalue);
int get_objectvalues( pwr_tStatus *sts, sev_item *item, unsigned int size, pwr_tTime *starttime, pwr_tTime *endtime,
int maxsize, pwr_tTime **tbuf, void **vbuf, unsigned int *bsize);
pwr_tUInt64 get_minFromIntegerColumn( char *tablename, char *colname );
};
#endif
#endif
......@@ -33,19 +33,20 @@
#include "rt_sevhistmon.h"
#include "rt_sev_msg.h"
#include "rt_pwr_msg.h"
#include <iostream>
#define sevclient_cQix 121
using namespace std;
int rt_sevhistmon::init()
{
pwr_tStatus sts;
qcom_sQid qid;
qcom_sQid qini;
qcom_sNode node;
pwr_tNid nid;
pwr_tOid conf_oid;
qcom_sQid qini;
qcom_sNode node;
pwr_tNid nid;
pwr_tOid conf_oid;
pwr_tOName oname;
errh_Init("pwr_sevhistmon", errh_eNAnix);
// errh_SetStatus( PWR__SRVSTARTUP);
......@@ -81,11 +82,11 @@ int rt_sevhistmon::init()
if (!qcom_CreateQ(&sts, &qid, &attr, "SevClient")) {
if ( sts == QCOM__QALLREXIST) {
if ( !qcom_AttachQ(&sts, &qid)) {
if ( !qcom_DeleteQ(&sts, &qid))
throw co_error(sts);
if ( !qcom_CreateQ(&sts, &qid, &attr, "SevClient"))
throw co_error(sts);
}
if ( !qcom_DeleteQ(&sts, &qid))
throw co_error(sts);
if ( !qcom_CreateQ(&sts, &qid, &attr, "SevClient"))
throw co_error(sts);
}
}
else
throw co_error( sts);
......@@ -112,7 +113,7 @@ int rt_sevhistmon::init()
m_nodes.push_back( n);
}
while(EVEN(gdh_NethandlerRunning()))
while (EVEN(gdh_NethandlerRunning()))
sleep(1);
return init_objects();
......@@ -132,10 +133,10 @@ int rt_sevhistmon::init_objects()
// Get all SevHist and SevHistThread objects
int thread_cnt = 0;
for ( sts = gdh_GetClassList( pwr_cClass_SevHistThread, &hs_oid);
ODD(sts);
sts = gdh_GetNextObject( hs_oid, &hs_oid)) {
ODD(sts);
sts = gdh_GetNextObject( hs_oid, &hs_oid)) {
sev_sevhistthread hs;
m_sts = gdh_ObjidToName( hs_oid, oname, sizeof(oname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
......@@ -150,9 +151,9 @@ int rt_sevhistmon::init_objects()
bool found = false;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
if ( cdh_NoCaseStrcmp( hs.nodename, m_nodes[i].name) == 0) {
hs.nid = m_nodes[i].nid;
found = true;
break;
hs.nid = m_nodes[i].nid;
found = true;
break;
}
}
m_confp->ThreadObjects[thread_cnt++] = hs_oid;
......@@ -175,12 +176,12 @@ int rt_sevhistmon::init_objects()
m_confp->ThreadObjects[i] = pwr_cNOid;
for ( sts = gdh_GetClassListAttrRef( pwr_cClass_SevHist, &h_aref);
ODD(sts);
sts = gdh_GetNextAttrRef( pwr_cClass_SevHist, &h_aref, &h_aref)) {
ODD(sts);
sts = gdh_GetNextAttrRef( pwr_cClass_SevHist, &h_aref, &h_aref)) {
sev_sevhist h;
pwr_sClass_SevHist *h_p;
int hs_idx;
m_sts = gdh_AttrRefToPointer( &h_aref, (void **)&h_p);
if ( EVEN(m_sts)) throw co_error(m_sts);
......@@ -192,15 +193,15 @@ int rt_sevhistmon::init_objects()
hs_idx = -1;
for ( int i = 0; i < (int) m_hs.size(); i++) {
if ( cdh_ObjidIsEqual( h_p->ThreadObject, m_hs[i].oid)) {
hs_idx = i;
break;
hs_idx = i;
break;
}
}
if ( hs_idx == -1) {
errh_Error( "Invalid HistServerObject %s", hname);
continue;
}
m_sts = gdh_GetAttributeCharAttrref( &h_p->Attribute, &a_tid, &a_size, &a_offset, &a_dim);
if ( EVEN(m_sts)) {
errh_Error( "Invalid SevHist Attribute %s", hname);
......@@ -219,7 +220,7 @@ int rt_sevhistmon::init_objects()
if ( ODD(sts)) {
sts = gdh_GetObjectInfoAttrref( &uaref, &h.unit, sizeof(h.unit));
if ( EVEN(sts))
strcpy( h.unit, "");
strcpy( h.unit, "");
}
else
strcpy( h.unit, "");
......@@ -228,25 +229,11 @@ int rt_sevhistmon::init_objects()
h.size = a_size;
h.scantime = m_hs[hs_idx].scantime;
switch ( h.type) {
case pwr_eType_Boolean:
case pwr_eType_Int64:
case pwr_eType_Int32:
case pwr_eType_Int16:
case pwr_eType_Int8:
case pwr_eType_UInt64:
case pwr_eType_UInt32:
case pwr_eType_UInt16:
case pwr_eType_UInt8:
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_String:
case pwr_eType_Time:
break;
default:
if( !correct_histtype(h.type) ) {
errh_Error( "Invalid SevHist Attribute type %s", hname);
continue;
}
m_sts = gdh_AttrrefToName( &h_p->Attribute, h.aname, sizeof(h.aname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
......@@ -260,11 +247,317 @@ int rt_sevhistmon::init_objects()
m_hs[hs_idx].threadp->NoOfItems++;
}
init_sevhistobjects();
set_status();
return 1;
}
int rt_sevhistmon::init_sevhistobjects()
{
pwr_tStatus sts;
pwr_tAttrRef h_aref;
pwr_tTid a_tid;
unsigned int a_size, a_offset, a_dim;
pwr_tAName hname;
for ( sts = gdh_GetClassListAttrRef( pwr_cClass_SevHistObject, &h_aref);
ODD(sts);
sts = gdh_GetNextAttrRef( pwr_cClass_SevHistObject, &h_aref, &h_aref)) {
sev_sevhistobject h;
pwr_sClass_SevHistObject *h_p;
int hs_idx;
m_sts = gdh_AttrRefToPointer( &h_aref, (void **)&h_p);
if ( EVEN(m_sts)) throw co_error(m_sts);
h.aref = h_p->Object;
m_sts = gdh_AttrrefToName( &h_aref, hname, sizeof(hname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
hs_idx = -1;
for ( int i = 0; i < (int) m_hs.size(); i++) {
if ( cdh_ObjidIsEqual( h_p->ThreadObject, m_hs[i].oid)) {
hs_idx = i;
break;
}
}
if ( hs_idx == -1) {
errh_Error( "Invalid HistServerObject %s", hname);
continue;
}
m_sts = gdh_GetAttributeCharAttrref( &h_p->Object, &a_tid, &a_size, &a_offset, &a_dim);
if ( EVEN(m_sts)) {
errh_Error( "Invalid SevHistObject Attribute %s", hname);
continue;
}
h.storagetime = h_p->StorageTime;
h.deadband = h_p->DeadBand;
h.options = h_p->Options;
strncpy( h.description, h_p->Description, sizeof(h.description));
h.scantime = m_hs[hs_idx].scantime;
h.sevid.nid = m_nodes[0].nid;
h.sevid.rix = m_next_rix++;
//Time to fetch all attributes for the object and put them into a list
m_sts = gdh_AttrrefToName( &h_p->Object, hname, sizeof(hname), cdh_mName_volumeStrict);
if ( EVEN(m_sts)) throw co_error(m_sts);
strcpy(h.aname, hname);
get_sevhistobjectattributes(hname, &h.sevhistobjectattrlist, hs_idx, true);
h.datasize = 0;
for( size_t k = 0; k < h.sevhistobjectattrlist.size(); k++ )
h.datasize += h.sevhistobjectattrlist[k].size;
//Check if this object have a chance to be stored in one table
if( h.datasize >= 65536 ) {
errh_Warning( "SevHistObject Attribute %s is to big(maxsize 65536), ignored", hname);
continue;
}
if( h.sevhistobjectattrlist.size() > 200 ) {
errh_Warning( "SevHistObject Attribute %s has to many attributes(max 200), ignored", hname);
continue;
}
m_hs[hs_idx].size += h.datasize;
m_hs[hs_idx].threadp->NoOfItems += h.sevhistobjectattrlist.size();
m_hs[hs_idx].sevhistobjectlist.push_back(h);
//for( size_t k = 0; k < m_hs[hs_idx].sevhistobjectlist.size(); k++ ) {
// std::cout << m_hs[hs_idx].sevhistobjectlist[k].aname << endl;
// for( size_t l = 0; l < m_hs[hs_idx].sevhistobjectlist[k].sevhistobjectattrlist.size(); l++ ) {
// std::cout << m_hs[hs_idx].sevhistobjectlist[k].sevhistobjectattrlist[l].aname << endl;
// }
//}
}
return 1;
}
void rt_sevhistmon::insert_sevhistobjectattr(pwr_sAttrRef *aref,
pwr_tAName objectname, // Name of object,
int hs_idx,
vector<sev_sevhistobjectattr> *listP)
{
pwr_tTid a_tid;
unsigned int a_size, a_offset, a_dim;
sev_sevhistobjectattr oattr;
m_sts = gdh_GetAttributeCharAttrref( aref, &a_tid, &a_size, &a_offset, &a_dim);
if ( EVEN(m_sts)) {
errh_Error( "Invalid SevHist Attribute %s", objectname);
return;
}
oattr.type = (pwr_eType) a_tid;
oattr.size = a_size;
oattr.unit[0] = '\0';
if( !correct_histtype(oattr.type) ) {
errh_Error( "Invalid SevHist Attribute type %s, ignored\n", objectname);
return;
}
//We ignore description fields
string str = objectname;
if( str.find(".Description") != string::npos ) {
errh_Info( "Ignoring SevHist Attribute %s\n", objectname);
return;
}
strncpy(oattr.aname, objectname, sizeof(pwr_tAName));
m_sts = gdh_RefObjectInfo( oattr.aname, &oattr.datap, &oattr.refid, oattr.size);
if ( EVEN(m_sts)) {
errh_Error( "Unable to link to Attribute %s", oattr.aname);
return;
}
listP->push_back(oattr);
}
int rt_sevhistmon::get_sevhistobjectattributes (
pwr_tAName objectname, // Name of object
vector<sev_sevhistobjectattr> *listP, // Pointer to list
int hs_idx,
pwr_tBoolean first
)
{
pwr_tAName attrname;
pwr_sAttrRef attrref;
pwr_tStatus sts;
pwr_tTid tid;
unsigned int i;
int rows, j, elements;
char idx[20];
pwr_tUInt32 size, offs, elem;
pwr_tBoolean tgtdynamic = 0;
pwr_tObjid volobject;
pwr_tClassId volclass;
sts = gdh_NameToAttrref(pwr_cNObjid, objectname, &attrref);
if ( EVEN(sts)) return sts;
if (first) {
volobject.vid = attrref.Objid.vid;
volobject.oix = pwr_cNObjectIx;
if (ODD(gdh_GetObjectClass(volobject, &volclass)))
tgtdynamic = volclass == pwr_eClass_DynamicVolume;
if (tgtdynamic) {
if (attrref.Flags.b.Indirect)
return 2;
attrref.Offset = 0;
attrref.Flags.b.Indirect = 0;
attrref.Flags.b.Object = 1;
sts = gdh_GetObjectSize(attrref.Objid, (pwr_tUInt32 *)&attrref.Size);
if ( EVEN(sts)) return sts;
// Insert list element
insert_sevhistobjectattr(&attrref, objectname, hs_idx, listP);
return sts;
}
}
sts = gdh_GetAttrRefTid (&attrref, &tid);
if ( EVEN(sts)) return sts;
if (cdh_tidIsCid(tid)) {
sts = gdh_GetAttributeCharacteristics( objectname, NULL, &size, &offs, &elem);
if ( EVEN(sts)) return sts;
if (elem > 1) {
for (i = 0; i < elem; i++) {
strcpy(attrname, objectname);
sprintf(idx, "[%d]", i);
strcat(attrname, idx);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
}
else {
gdh_sAttrDef *bd;
sts = gdh_GetObjectBodyDef( tid, &bd, &rows, attrref.Objid);
if ( EVEN(sts)) return sts;
for ( int i = 0; (int)i < rows; i++) {
if ( bd[i].attr->Param.Info.Flags & PWR_MASK_RTVIRTUAL ||
bd[i].attr->Param.Info.Flags & PWR_MASK_PRIVATE)
continue;
if ( bd[i].attr->Param.Info.Flags & PWR_MASK_ARRAY)
elements = bd[i].attr->Param.Info.Elements;
else
elements = 1;
if ( bd[i].attr->Param.Info.Flags & PWR_MASK_CLASS) {
if ( elements == 1) {
strcpy(attrname, objectname);
strcat(attrname, ".");
strcat(attrname, bd[i].attrName);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
else {
for ( j = 0; j < elements; j++) {
strcpy(attrname, objectname);
strcat(attrname, ".");
strcat(attrname, bd[i].attrName);
sprintf( idx, "[%d]", j);
strcat(attrname, idx);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
}
}
else {
if (elements > 1) {
for ( j = 0; j < elements; j++) {
strcpy(attrname, objectname);
strcat(attrname, ".");
strcat(attrname, bd[i].attrName);
sprintf( idx, "[%d]", j);
strcat(attrname, idx);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
}
else {
strcpy(attrname, objectname);
strcat(attrname, ".");
strcat(attrname, bd[i].attrName);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
}
}
free( (char *)bd);
}
}
else {
sts = gdh_GetAttributeCharacteristics( objectname, &tid, &size, &offs, &elem);
if ( EVEN(sts)) return sts;
if (elem > 1) {
for (i = 0; i < elem; i++) {
strcpy(attrname, objectname);
sprintf(idx, "[%d]", i);
strcat(attrname, idx);
// call again ...
sts = get_sevhistobjectattributes (attrname, listP, hs_idx, 0);
}
}
else {
// Insert list element
insert_sevhistobjectattr(&attrref, objectname, hs_idx, listP);
}
}
return sts;
}
bool rt_sevhistmon::correct_histtype(const pwr_eType type)
{
switch ( type) {
case pwr_eType_Boolean:
case pwr_eType_Int64:
case pwr_eType_Int32:
case pwr_eType_Int16:
case pwr_eType_Int8:
case pwr_eType_UInt64:
case pwr_eType_UInt32:
case pwr_eType_UInt16:
case pwr_eType_UInt8:
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_String:
case pwr_eType_Time:
return true;
break;
default:
return false;
}
}
int rt_sevhistmon::close_objects()
{
for ( unsigned int i = 0; i < m_hs.size(); i++) {
......@@ -288,14 +581,14 @@ int rt_sevhistmon::close()
int rt_sevhistmon::send_data()
{
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
int msize;
sev_sMsgHistDataStore *msg;
sev_sHistData *dp;
int stime;
pwr_tTime current_time;
int stime;
pwr_tTime current_time;
pwr_tStatus conf_sts = SEV__SUCCESS;
for ( unsigned int i = 0; i < m_hs.size(); i++) {
......@@ -305,12 +598,15 @@ int rt_sevhistmon::send_data()
stime = int(m_hs[i].scantime / m_scantime + 0.5);
if ( !stime || m_loopcnt % stime != 0)
continue;
m_hs[i].threadp->ScanCount++;
msize = m_hs[i].sevhistlist.size() * (sizeof(*dp) - sizeof(dp->data)) + m_hs[i].size;
msize += sizeof(*msg) - sizeof(msg->Data);
unsigned int histobjectsize = (m_hs[i].sevhistobjectlist.size() * (sizeof(*dp) - sizeof(dp->data)));
msize += histobjectsize;
msg = (sev_sMsgHistDataStore *) qcom_Alloc(&lsts, msize);
put.size = msize;
......@@ -329,9 +625,26 @@ int rt_sevhistmon::send_data()
dp = (sev_sHistData *)((char *)dp + sizeof( *dp) - sizeof(dp->data) + dp->size);
}
void *dpp;
for ( unsigned int j = 0; j < m_hs[i].sevhistobjectlist.size(); j++) {
dp->sevid = m_hs[i].sevhistobjectlist[j].sevid;
dp->size = m_hs[i].sevhistobjectlist[j].datasize;
dpp = &(dp->data);
for ( unsigned int k = 0; k < m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist.size(); k++) {
//dp->type = m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].type;
//printf("sevhistobj[%d].attrlist[%d].aname: %s size:%d\n", j, k, m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].aname, m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].size);
//if( m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].type == pwr_eType_String ) {
// printf("text:%s\n", (char*)m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].datap);
//}
memcpy( dpp, m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].datap, m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].size);
dpp = (sev_sHistData *)((char *)dpp + m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[k].size);
}
dp = (sev_sHistData *)((char *)dp + sizeof( *dp) - sizeof(dp->data) + dp->size);
}
tgt.nid = m_hs[i].nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
......@@ -344,7 +657,7 @@ int rt_sevhistmon::send_data()
conf_sts = sts;
qcom_Free( &sts, put.data);
continue;
}
}
m_hs[i].threadp->SendCount++;
m_hs[i].threadp->Status = sts;
}
......@@ -359,13 +672,13 @@ void rt_sevhistmon::set_status()
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
if ( m_nodes[i].connected && m_nodes[i].status != 0 &&
errh_Severity( m_nodes[i].status) > errh_Severity( sts))
errh_Severity( m_nodes[i].status) > errh_Severity( sts))
sts = m_nodes[i].status;
}
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( EVEN( m_hs[i].threadp->Status) &&
errh_Severity( m_hs [i].threadp->Status) > errh_Severity( sts)) {
errh_Severity( m_hs [i].threadp->Status) > errh_Severity( sts)) {
sts = m_hs[i].threadp->Status;
}
}
......@@ -374,16 +687,16 @@ void rt_sevhistmon::set_status()
int rt_sevhistmon::retry_connect()
{
pwr_tStatus sts;
pwr_tStatus sts;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
if ( m_nodes[i].is_server && !m_nodes[i].connected) {
m_nodes[i].ctime += m_scantime;
if ( m_nodes[i].ctime > 60) {
m_nodes[i].ctime = 0;
m_nodes[i].ctime = 0;
send_connect( m_nodes[i].nid, &sts);
send_connect( m_nodes[i].nid, &sts);
}
}
}
......@@ -392,19 +705,19 @@ int rt_sevhistmon::retry_connect()
int rt_sevhistmon::connect()
{
pwr_tStatus sts;
pwr_tStatus sts;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
// Check if this node should be connected
bool found = false;
for ( unsigned int j = 0; j < m_hs.size(); j++) {
if ( m_hs[i].configerror)
continue;
if ( m_hs[j].configerror)
continue;
if ( cdh_NoCaseStrcmp( m_nodes[i].name, m_hs[j].nodename) == 0) {
found = true;
break;
}
found = true;
break;
}
}
if ( !found)
continue;
......@@ -418,14 +731,14 @@ int rt_sevhistmon::connect()
bool rt_sevhistmon::send_connect( pwr_tNid nid, pwr_tStatus *sts)
{
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus lsts;
tgt.nid = nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
......@@ -439,17 +752,17 @@ bool rt_sevhistmon::send_connect( pwr_tNid nid, pwr_tStatus *sts)
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
}
}
return ODD(*sts);
}
bool rt_sevhistmon::send_server_status_request( pwr_tStatus *sts)
{
int stime;
float scantime = 30;
pwr_tStatus send_sts;
int stime;
float scantime = 30;
pwr_tStatus send_sts;
*sts = SEV__SUCCESS;
stime = int(scantime / m_scantime + 0.5);
......@@ -460,7 +773,7 @@ bool rt_sevhistmon::send_server_status_request( pwr_tStatus *sts)
if ( m_nodes[i].connected) {
send_server_status_request( m_nodes[i].nid, &send_sts);
if ( EVEN(send_sts))
*sts = send_sts;
*sts = send_sts;
}
}
return true;
......@@ -468,14 +781,14 @@ bool rt_sevhistmon::send_server_status_request( pwr_tStatus *sts)
bool rt_sevhistmon::send_server_status_request( pwr_tNid nid, pwr_tStatus *sts)
{
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus lsts;
tgt.nid = nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
......@@ -489,7 +802,7 @@ bool rt_sevhistmon::send_server_status_request( pwr_tNid nid, pwr_tStatus *sts)
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
}
}
return ODD(*sts);
}
......@@ -507,12 +820,14 @@ void rt_sevhistmon::receive_server_status( sev_sMsgServerStatus *msg, pwr_tNid n
int rt_sevhistmon::send_itemlist( pwr_tNid nid)
{
int item_cnt = 0;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
int size;
pwr_tAName aname;
char *s;
int attr_cnt = 0;
int objectitem_cnt = 0;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus sts, lsts;
int size = 0;
pwr_tAName aname;
char *s;
// Identify node
bool found = false;
......@@ -524,54 +839,113 @@ int rt_sevhistmon::send_itemlist( pwr_tNid nid)
}
}
int histobjectsize = 0;
// Count items for this node
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( m_hs[i].configerror)
continue;
if ( nid == m_hs[i].nid)
item_cnt += m_hs[i].sevhistlist.size();
{
item_cnt += m_hs[i].sevhistlist.size();
attr_cnt += m_hs[i].sevhistlist.size();
objectitem_cnt += m_hs[i].sevhistobjectlist.size();
for( size_t j = 0; j < m_hs[i].sevhistobjectlist.size(); j++ ) {
attr_cnt += m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist.size();
histobjectsize += (m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist.size() * sizeof(sev_sHistAttr));
}
}
}
if ( item_cnt == 0)
if ( item_cnt == 0 && objectitem_cnt == 0 )
return 1;
size = sizeof(sev_sMsgHistItems) + (item_cnt - 1) * sizeof(sev_sHistItem);
if( item_cnt != 0 ) {
size = sizeof(sev_sMsgHistItems) + (item_cnt - 1) * sizeof(sev_sHistItem);
size += objectitem_cnt * (sizeof(sev_sHistItem) - sizeof(sev_sHistAttr)) + histobjectsize;
}
else {
size += (objectitem_cnt - 1) * (sizeof(sev_sHistItem) - sizeof(sev_sHistAttr)) + histobjectsize;
}
put.size = size;
put.data = qcom_Alloc(&lsts, put.size);
((sev_sMsgHistItems *)put.data)->Type = sev_eMsgType_HistItems;
((sev_sMsgHistItems *)put.data)->Status = SEV__SUCCESS;
((sev_sMsgHistItems *)put.data)->NumItems = item_cnt + objectitem_cnt;
((sev_sMsgHistItems *)put.data)->NumAttributes = attr_cnt;
int k = 0;
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( m_hs[i].configerror)
continue;
if ( nid == m_hs[i].nid) {
for ( unsigned int j = 0; j < m_hs[i].sevhistlist.size(); j++) {
((sev_sMsgHistItems *)put.data)->Items[k].oid = m_hs[i].sevhistlist[j].aref.Objid;
strcpy( aname, m_hs[i].sevhistlist[j].aname);
s = strchr( aname, '.');
if ( !s)
continue;
*s = 0;
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].oname, aname);
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].attr[0].aname, s + 1);
((sev_sMsgHistItems *)put.data)->Items[k].storagetime =
net_DeltaTimeToNetTime( &m_hs[i].sevhistlist[j].storagetime);
((sev_sMsgHistItems *)put.data)->Items[k].deadband = m_hs[i].sevhistlist[j].deadband;
((sev_sMsgHistItems *)put.data)->Items[k].options = m_hs[i].sevhistlist[j].options;
((sev_sMsgHistItems *)put.data)->Items[k].attr[0].type = m_hs[i].sevhistlist[j].type;
((sev_sMsgHistItems *)put.data)->Items[k].attr[0].size = m_hs[i].sevhistlist[j].size;
((sev_sMsgHistItems *)put.data)->Items[k].sevid = m_hs[i].sevhistlist[j].sevid;
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].description,
m_hs[i].sevhistlist[j].description,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].description));
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].attr[0].unit,
m_hs[i].sevhistlist[j].unit,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].attr[0].unit));
((sev_sMsgHistItems *)put.data)->Items[k].scantime = m_hs[i].sevhistlist[j].scantime;
k++;
((sev_sMsgHistItems *)put.data)->Items[k].attrnum = 1;
((sev_sMsgHistItems *)put.data)->Items[k].oid = m_hs[i].sevhistlist[j].aref.Objid;
strcpy( aname, m_hs[i].sevhistlist[j].aname);
s = strchr( aname, '.');
if ( !s)
continue;
*s = 0;
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].oname, aname);
strcpy( ((sev_sMsgHistItems *)put.data)->Items[k].attr[0].aname, s + 1);
((sev_sMsgHistItems *)put.data)->Items[k].storagetime =
net_DeltaTimeToNetTime( &m_hs[i].sevhistlist[j].storagetime);
((sev_sMsgHistItems *)put.data)->Items[k].deadband = m_hs[i].sevhistlist[j].deadband;
((sev_sMsgHistItems *)put.data)->Items[k].options = m_hs[i].sevhistlist[j].options;
((sev_sMsgHistItems *)put.data)->Items[k].attr[0].type = m_hs[i].sevhistlist[j].type;
((sev_sMsgHistItems *)put.data)->Items[k].attr[0].size = m_hs[i].sevhistlist[j].size;
((sev_sMsgHistItems *)put.data)->Items[k].sevid = m_hs[i].sevhistlist[j].sevid;
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].description,
m_hs[i].sevhistlist[j].description,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].description));
strncpy( ((sev_sMsgHistItems *)put.data)->Items[k].attr[0].unit,
m_hs[i].sevhistlist[j].unit,
sizeof(((sev_sMsgHistItems *)put.data)->Items[0].attr[0].unit));
((sev_sMsgHistItems *)put.data)->Items[k].scantime = m_hs[i].sevhistlist[j].scantime;
k++;
}
}
}
//Add the objectitems at the end of the message
sev_sHistItem *buffP = &((sev_sMsgHistItems *)put.data)->Items[k];
for ( unsigned int i = 0; i < m_hs.size(); i++) {
if ( m_hs[i].configerror)
continue;
if ( nid == m_hs[i].nid) {
int numberOfAttributes;
for ( unsigned int j = 0; j < m_hs[i].sevhistobjectlist.size(); j++) {
buffP->oid = m_hs[i].sevhistobjectlist[j].aref.Objid;
strcpy( aname, m_hs[i].sevhistobjectlist[j].aname);
strcpy( buffP->oname, aname);
buffP->storagetime = net_DeltaTimeToNetTime( &m_hs[i].sevhistobjectlist[j].storagetime);
buffP->deadband = m_hs[i].sevhistobjectlist[j].deadband;
buffP->options = m_hs[i].sevhistobjectlist[j].options;
buffP->sevid = m_hs[i].sevhistobjectlist[j].sevid;
strncpy( buffP->description, m_hs[i].sevhistobjectlist[j].description, sizeof(pwr_tString80) );
buffP->scantime = m_hs[i].sevhistobjectlist[j].scantime;
buffP->attrnum = m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist.size();
for( size_t jj = 0; jj < m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist.size(); jj++ ) {
strcpy( aname, m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[jj].aname);
//Point out attribute name
s = strchr( aname, '.');
if ( !s)
continue;
*s = 0;
strcpy( buffP->attr[jj].aname, s+1);
buffP->attr[jj].type = m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[jj].type;
buffP->attr[jj].size = m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[jj].size;
strncpy( buffP->attr[jj].unit,
m_hs[i].sevhistobjectlist[j].sevhistobjectattrlist[jj].unit, sizeof(pwr_tString16));
}
numberOfAttributes = buffP->attrnum;
//buffP points after the last attribute written
buffP = (sev_sHistItem *)&buffP->attr[numberOfAttributes];
}
}
}
......@@ -579,7 +953,7 @@ int rt_sevhistmon::send_itemlist( pwr_tNid nid)
tgt.nid = nid;
tgt.qix = sev_eProcSevServer;
put.reply.nid = m_nodes[0].nid;
put.reply.qix = sev_eProcSevClient;
put.type.b = (qcom_eBtype) sev_cMsgClass;
......@@ -589,15 +963,15 @@ int rt_sevhistmon::send_itemlist( pwr_tNid nid)
if ( !qcom_Put( &sts, &tgt, &put)) {
qcom_Free( &sts, put.data);
return 0;
}
}
// If all nodes are connected, set running status
if ( !m_allconnected) {
bool all_conn = true;
for ( unsigned int i = 0; i < m_nodes.size(); i++) {
if ( m_nodes[i].is_server && !m_nodes[i].connected) {
all_conn = false;
break;
all_conn = false;
break;
}
}
if ( all_conn) {
......@@ -631,50 +1005,50 @@ int rt_sevhistmon::mainloop()
}
switch (get.type.b) {
case sev_cMsgClass:
switch ( get.type.s) {
case sev_eMsgType_NodeUp:
case sev_eMsgType_HistItemsRequest:
send_itemlist( get.sender.nid);
break;
case sev_eMsgType_ServerStatus:
receive_server_status( (sev_sMsgServerStatus *) mp, get.sender.nid);
break;
case sev_cMsgClass:
switch ( get.type.s) {
case sev_eMsgType_NodeUp:
case sev_eMsgType_HistItemsRequest:
send_itemlist( get.sender.nid);
break;
case sev_eMsgType_ServerStatus:
receive_server_status( (sev_sMsgServerStatus *) mp, get.sender.nid);
break;
default: ;
}
break;
case qcom_eBtype_event: {
ini_mEvent new_event;
qcom_sEvent *ep = (qcom_sEvent*) get.data;
new_event.m = ep->mask;
if (new_event.b.oldPlcStop && !m_swap) {
m_swap = 1;
// errh_SetStatus( PWR__SRVRESTART);
m_confp->Status = PWR__SRVRESTART;
close();
}
else if (new_event.b.swapDone && m_swap) {
m_swap = 0;
try {
init_objects();
connect();
}
catch ( co_error e) {
errh_Error( "SevHistMonitor terminating, %m", e.sts());
exit(0);
}
// errh_SetStatus( PWR__SRUN);
m_confp->Status = PWR__SRUN;
errh_Info("Warm restart completed");
}
else if (new_event.b.terminate) {
m_confp->Status = PWR__SRVTERM;
exit(0);
}
break;
}
default: ;
}
break;
case qcom_eBtype_event: {
ini_mEvent new_event;
qcom_sEvent *ep = (qcom_sEvent*) get.data;
new_event.m = ep->mask;
if (new_event.b.oldPlcStop && !m_swap) {
m_swap = 1;
// errh_SetStatus( PWR__SRVRESTART);
m_confp->Status = PWR__SRVRESTART;
close();
}
else if (new_event.b.swapDone && m_swap) {
m_swap = 0;
try {
init_objects();
connect();
}
catch ( co_error e) {
errh_Error( "SevHistMonitor terminating, %m", e.sts());
exit(0);
}
// errh_SetStatus( PWR__SRUN);
m_confp->Status = PWR__SRUN;
errh_Info("Warm restart completed");
}
else if (new_event.b.terminate) {
m_confp->Status = PWR__SRVTERM;
exit(0);
}
break;
}
default: ;
}
qcom_Free( &sts, mp);
......
......@@ -42,6 +42,32 @@ class sev_sevhist {
pwr_tFloat32 scantime;
};
class sev_sevhistobjectattr {
public:
pwr_tAttrRef aref;
pwr_tString80 description;
pwr_tString16 unit;
pwr_tAName aname;
pwr_tRefId refid;
void *datap;
pwr_eType type;
unsigned int size;
};
class sev_sevhistobject {
public:
pwr_tAttrRef aref;
pwr_tAName aname;
pwr_tDeltaTime storagetime;
pwr_tFloat32 deadband;
pwr_tMask options;
pwr_tRefId sevid;
pwr_tString80 description;
pwr_tFloat32 scantime;
unsigned int datasize;
vector<sev_sevhistobjectattr> sevhistobjectattrlist;
};
class sev_sevhistthread {
public:
sev_sevhistthread() : configerror(0) {}
......@@ -54,6 +80,7 @@ class sev_sevhistthread {
pwr_tRefId refid;
int configerror;
vector<sev_sevhist> sevhistlist;
vector<sev_sevhistobject> sevhistobjectlist;
};
class sev_node {
......@@ -88,6 +115,16 @@ class rt_sevhistmon {
int init();
int init_objects();
int init_sevhistobjects();
void insert_sevhistobjectattr(pwr_sAttrRef *aref,
pwr_tAName objectname,
int hs_idx,
vector<sev_sevhistobjectattr> *listP);
int get_sevhistobjectattributes (pwr_tAName objectname,
vector<sev_sevhistobjectattr> *listP,
int hs_idx,
pwr_tBoolean first);
bool correct_histtype(const pwr_eType type);
int close();
int close_objects();
int mainloop();
......
......@@ -42,7 +42,9 @@ typedef enum {
sev_eMsgType_HistItemDelete,
sev_eMsgType_HistItemStatus,
sev_eMsgType_ServerStatusRequest,
sev_eMsgType_ServerStatus
sev_eMsgType_ServerStatus,
sev_eMsgType_HistObjectDataGetRequest,
sev_eMsgType_HistObjectDataGet
} sev_eMsgType;
typedef struct {
......@@ -83,7 +85,9 @@ typedef struct {
typedef struct {
sev_eMsgType Type;
pwr_tStatus Status;
pwr_tStatus Status;
unsigned int NumItems;
unsigned int NumAttributes;
sev_sHistItem Items[1];
} sev_sMsgHistItems;
......@@ -113,6 +117,18 @@ typedef struct {
int Data[1];
} sev_sMsgHistDataGet;
typedef struct {
sev_eMsgType Type;
pwr_tOid Oid;
pwr_tOName AName;
pwr_tStatus Status;
int NumPoints;
int NumAttributes;
unsigned int TotalDataSize;
sev_sHistAttr Attr[1];
int Data[1];
} sev_sMsgHistObjectDataGet;
typedef struct {
sev_eMsgType Type;
pwr_tOid Oid;
......
......@@ -115,6 +115,104 @@ int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem **l
tgt.qix = sev_eProcSevServer;
put.reply = ctx->qid;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistItemsRequest;
put.msg_id = ctx->msg_id++;
put.size = sizeof(*msg);
msg = (sev_sMsgAny *) qcom_Alloc( sts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_HistItemsRequest;
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
return 0;
}
sev_sMsgHistItems *rmsg;
memset( &get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistItems *) qcom_Get( sts, &ctx->qid, &get, tmo);
if ( *sts == QCOM__TMO || !rmsg) {
return 0;
}
if ( get.type.b == sev_cMsgClass &&
get.type.s == (qcom_eStype) sev_eMsgType_HistItems)
break;
qcom_Free( sts, rmsg);
}
*sts = rmsg->Status;
if ( EVEN(*sts))
return 0;
//int item_cnt = (get.size - sizeof(sev_sMsgHistItems)) / sizeof(sev_sHistItem) + 1;
int item_cnt = rmsg->NumItems;
int attr_cnt = rmsg->NumAttributes;
unsigned int data_size = (item_cnt * sizeof(sevcli_sHistItem)) + ((attr_cnt - item_cnt) * sizeof(sevcli_sHistAttr));
printf("Get size: %d, data size: %d\n", get.size, data_size);
lp = (sevcli_sHistItem *) malloc( data_size );
sevcli_sHistItem *lp2 = lp;
sev_sHistItem *itemPtr = ((sev_sMsgHistItems *)rmsg)->Items;
for ( i = 0; i < item_cnt; i++) {
printf("i : %d\n", i);
lp->oid = itemPtr->oid;
strncpy( lp->oname, itemPtr->oname, sizeof(lp->oname));
lp->storagetime = net_NetTimeToDeltaTime( &itemPtr->storagetime);
lp->deadband = itemPtr->deadband;
lp->options = itemPtr->options;
lp->creatime = net_NetTimeToTime( &itemPtr->creatime);
lp->modtime = net_NetTimeToTime( &itemPtr->modtime);
strncpy( lp->description, itemPtr->description, sizeof(lp->description));
lp->scantime = itemPtr->scantime;
lp->attrnum = itemPtr->attrnum;
size_t j=0;
for( j=0; j < lp->attrnum; j++ ) {
lp->attr[j].type = itemPtr->attr[j].type;
lp->attr[j].size = itemPtr->attr[j].size;
strncpy( lp->attr[j].aname, itemPtr->attr[j].aname, sizeof(lp->attr[0].aname));
strncpy( lp->attr[j].unit, itemPtr->attr[j].unit, sizeof(lp->attr[0].unit));
}
itemPtr = (sev_sHistItem *)&itemPtr->attr[j];
lp = (sevcli_sHistItem *)&lp->attr[j];
}
qcom_Free( sts, rmsg);
*cnt = item_cnt;
*list = lp2;
*sts = SEV__SUCCESS;
return 1;
}
/*
int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem **list,
unsigned int *cnt)
{
sev_sMsgAny *msg;
qcom_sQid tgt;
qcom_sPut put;
pwr_tStatus lsts;
int tmo = 1000;
qcom_sGet get;
sevcli_sHistItem *lp;
int i;
if ( ctx->server)
tgt.nid = ctx->server;
else
tgt.nid = ctx->qid.nid;
tgt.qix = sev_eProcSevServer;
put.reply = ctx->qid;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistItemsRequest;
......@@ -180,6 +278,7 @@ int sevcli_get_itemlist( pwr_tStatus *sts, sevcli_tCtx ctx, sevcli_sHistItem **l
*sts = SEV__SUCCESS;
return 1;
}
*/
int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
char *aname, pwr_tTime starttime, pwr_tTime endtime, int numpoints,
......@@ -220,6 +319,7 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
// Empty queue
sev_sMsgHistDataGet *rmsg;
memset( &get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistDataGet *) qcom_Get(sts, &ctx->qid, &get, 0);
if ( !rmsg)
......@@ -268,6 +368,116 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
return 1;
}
int sevcli_get_objectitemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname,
pwr_tTime starttime, pwr_tTime endtime, int numpoints,
pwr_tTime **tbuf, void **vbuf, int *rows,
sevcli_sHistAttr **histattr, int *numattributes)
{
sev_sMsgHistDataGetRequest *msg;
qcom_sQid tgt;
qcom_sPut put;
int tmo = 30000;
qcom_sGet get;
pwr_tStatus lsts;
if ( ctx->server)
tgt.nid = ctx->server;
else
tgt.nid = ctx->qid.nid;
tgt.qix = sev_eProcSevServer;
put.reply = ctx->qid;
put.type.b = (qcom_eBtype) sev_cMsgClass;
put.type.s = (qcom_eStype) sev_eMsgType_HistObjectDataGetRequest;
put.msg_id = ctx->msg_id++;
put.size = sizeof(*msg);
msg = (sev_sMsgHistDataGetRequest *) qcom_Alloc( sts, put.size);
put.data = msg;
msg->Type = sev_eMsgType_HistObjectDataGetRequest;
msg->Oid = oid;
strncpy( msg->AName, aname, sizeof(msg->AName));
msg->StartTime = net_TimeToNetTime( &starttime);
msg->EndTime = net_TimeToNetTime( &endtime);
msg->NumPoints = numpoints;
// Empty queue
sev_sMsgHistObjectDataGet *rmsg;
memset(&get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistObjectDataGet *) qcom_Get(sts, &ctx->qid, &get, 0);
if ( !rmsg)
break;
}
if ( !qcom_Put( sts, &tgt, &put)) {
qcom_Free( &lsts, put.data);
*sts = 0;
return 0;
}
memset( &get, 0, sizeof(get));
for (;;) {
rmsg = (sev_sMsgHistObjectDataGet *) qcom_Get(sts, &ctx->qid, &get, tmo);
if ( *sts == QCOM__TMO || !rmsg) {
*sts = 0;
return 0;
}
if ( get.type.b == sev_cMsgClass &&
get.type.s == (qcom_eStype) sev_eMsgType_HistObjectDataGet &&
cdh_ObjidIsEqual( oid, rmsg->Oid) &&
cdh_NoCaseStrcmp( aname, rmsg->AName) == 0)
break;
qcom_Free( sts, rmsg);
}
*sts = rmsg->Status;
if ( EVEN(*sts))
return 0;
if( rmsg->NumPoints == 0 ) {
*sts = 0;
return 0;
}
*numattributes = rmsg->NumAttributes;
int item_cnt = rmsg->NumPoints;
unsigned int timebufsize = item_cnt * sizeof(pwr_tTime);
unsigned int databufsize = rmsg->TotalDataSize - timebufsize;
*tbuf = malloc( timebufsize);
*vbuf = malloc( databufsize );
sevcli_sHistAttr *attrptr;
attrptr = calloc( rmsg->NumAttributes, sizeof(sevcli_sHistAttr) );
int attrCount = rmsg->NumAttributes;
void *ptr = &rmsg->Attr[attrCount];
memcpy( *tbuf, ptr, item_cnt * sizeof(pwr_tTime));
memcpy( *vbuf, (char *)ptr + item_cnt * sizeof(pwr_tTime), databufsize );
*rows = item_cnt;
int i = 0;
for( i = 0; i < rmsg->NumAttributes; i++ ) {
strncpy(attrptr[i].aname, rmsg->Attr[i].aname, sizeof(attrptr[0].aname));
attrptr[i].type = rmsg->Attr[i].type;
attrptr[i].size = rmsg->Attr[i].size;
}
*histattr = attrptr;
qcom_Free( sts, rmsg);
*sts = SEV__SUCCESS;
return 1;
}
int sevcli_delete_item( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname)
{
sev_sMsgHistItemDelete *msg;
......
......@@ -76,7 +76,10 @@ int sevcli_get_itemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid,
pwr_tTime **tbuf, void **vbuf, int *rows,
pwr_eType *vtype, unsigned int *vsize);
int sevcli_delete_item( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname);
int sevcli_get_objectitemdata( pwr_tStatus *sts, sevcli_tCtx ctx, pwr_tOid oid, char *aname,
pwr_tTime starttime, pwr_tTime endtime, int numpoints,
pwr_tTime **tbuf, void **vbuf, int *rows,
sevcli_sHistAttr **histattr, int *numattributes);
#ifdef __cplusplus
}
......
......@@ -42,6 +42,7 @@ SObject pwrb:Class
! below the current signal object.
!
! @b See also
! @classlink SevHistObject pwrb_sevhistobject.html
! @classlink SevHistThread pwrb_sevhistthread.html
! @classlink SevHistMonitor pwrb_sevhistmonitor.html
! @classlink SevHistServer pwrb_sevhistserver.html
......
......@@ -33,6 +33,7 @@ SObject pwrb:Class
! @b See also
! @classlink SevHistThread pwrb_sevhistthread.html
! @classlink SevHist pwrb_sevhist.html
! @classlink SevHistObject pwrb_sevhistobject.html
! @classlink SevHistServer pwrb_sevhistserver.html
!*/
Object SevHistMonitor $ClassDef 534
......
!
! Proview $Id: pwrb_c_sevhistobject.wb_load,v 1.2 2009-11-24 16:06:00 claes Exp $
! Copyright (C) 2005 SSAB Oxelsund AB.
!
! This program is free software; you can redistribute it and/or
! modify it under the terms of the GNU General Public License as
! published by the Free Software Foundation, either version 2 of
! the License, or (at your option) any later version.
!
! This program is distributed in the hope that it will be useful
! but WITHOUT ANY WARRANTY; without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! GNU General Public License for more details.
!
! You should have received a copy of the GNU General Public License
! along with the program, if not, write to the Free Software
! Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
!
! pwrb_c_sevhistobject.wb_load -- Defines the class SevHistObject.
!
SObject pwrb:Class
!/**
! @Version 2.0
! @Group PlantConfiguration,SevHist
! @Summary Configures historical data storage for an objects all attribute values.
! Configures historical data storage for x scalar
! quantitites or elements in x number of one-dimensional vectors. (Datastorage
! History).
!
! In a relational database, data resides in
! two-dimensional tables known as relations. A relation
! consist of rows and columns.
!
! The SevHistObject object specifies which quantity is to be
! stored and in which relation. Up to three different
! relations can be specified.
!
! @b See also
! @classlink SevHist pwrb_sevhist.html
! @classlink SevHistThread pwrb_sevhistthread.html
! @classlink SevHistMonitor pwrb_sevhistmonitor.html
! @classlink SevHistServer pwrb_sevhistserver.html
!*/
Object SevHistObject $ClassDef 539
Body SysBody
Attr Editor = pwr_eEditor_AttrEd
Attr Method = pwr_eMethod_Standard
EndBody
Object RtBody $ObjBodyDef 1
Body SysBody
Attr StructName = "SevHistObject"
EndBody
!/**
! Optional desription.
!*/
Object Description $Attribute 1
Body SysBody
Attr TypeRef = "pwrs:Type-$String80"
EndBody
EndObject
!/**
! Specifies the complete name of the object whose
! attribute values is to be stored.
!*/
Object Object $Attribute 2
Body SysBody
Attr TypeRef = "pwrs:Type-$AttrRef"
EndBody
EndObject
!/**
! SevHistThread object that specifies the storage scantime
! and in which server the data is stored.
!*/
Object ThreadObject $Attribute 3
Body SysBody
Attr TypeRef = "pwrs:Type-$Objid"
EndBody
EndObject
!/**
! Time the data will be stored in the database.
! Data that is older than this time will be removed from
! the database by a garbage collector.
!*/
Object StorageTime $Attribute 4
Body SysBody
Attr TypeRef = "pwrs:Type-$DeltaTime"
EndBody
EndObject
!/**
! The deadband is a range around the last stored value, where no new values
! will be stored, i.e a value has to differ more than the deadband / 2 from
! the last stored value to be stored.
!
! Deadband contains the size of deadband. Note that the DeadBand bit in options also
! has to be set to activte the deadband function.
!*/
Object DeadBand $Attribute 5
Body SysBody
Attr TypeRef = "pwrs:Type-$Float32"
EndBody
EndObject
!/**
! Storage options.
!*/
Object Options $Attribute 6
Body SysBody
Attr TypeRef = "pwrb:Type-SevHistOptionsMask"
EndBody
EndObject
EndObject
Object Template SevHistObject
Body RtBody
Attr DeadBand = 0.0
Attr Options = 4
EndBody
EndObject
Object PostCreate $DbCallBack
Body SysBody
Attr MethodName = "SevHist-PostCreate"
EndBody
EndObject
Object PostMove $DbCallBack
Body SysBody
Attr MethodName = "SevHist-PostMove"
EndBody
EndObject
Object ConfiguratorPoson $Menu
Object Pointed $Menu
Object ConnectThread $MenuButton
Body SysBody
Attr ButtonName = "Connect SevHistThread"
Attr MethodName = "$Objid-Connect"
Attr MethodArguments[0] = "ThreadObject"
Attr MethodArguments[1] = "SevHistThread"
Attr FilterName = "$Objid-IsOkConnect"
Attr FilterArguments[0] = "ThreadObject"
Attr FilterArguments[1] = "SevHistThread"
EndBody
EndObject
EndObject
EndObject
EndObject
EndSObject
......@@ -37,6 +37,7 @@ SObject pwrb:Class
! @classlink SevHistThread pwrb_sevhistthread.html
! @classlink SevHistMonitor pwrb_sevhistmonitor.html
! @classlink SevHist pwrb_sevhist.html
! @classlink SevHistObject pwrb_sevhistobject.html
!*/
Object SevServer $ClassDef 535
Body SysBody
......
......@@ -706,10 +706,18 @@ wb_orep *wb_vrepmem::createObject(pwr_tStatus *sts, wb_cdef cdef, wb_destination
if ( d.oid().oix == 0) {
dest = root_object;
if ( code == ldh_eDest_IntoLast)
code = ldh_eDest_After;
if ( code == ldh_eDest_IntoFirst)
code = ldh_eDest_Before;
if ( !root_object) {
if ( code == ldh_eDest_After)
code = ldh_eDest_IntoLast;
if ( code == ldh_eDest_Before)
code = ldh_eDest_IntoFirst;
}
else {
if ( code == ldh_eDest_IntoLast)
code = ldh_eDest_After;
if ( code == ldh_eDest_IntoFirst)
code = ldh_eDest_Before;
}
}
else {
dest = findObject( d.oid().oix);
......
......@@ -51,11 +51,12 @@ XttSevHistGtk::XttSevHistGtk( void *parent_ctx,
pwr_tOid *xn_oid,
pwr_tOName *xn_aname,
sevcli_tCtx xn_scctx,
int *sts) :
XttSevHist( parent_ctx, name, xn_oid, xn_aname, xn_scctx, sts), parent_widget(parent_wid)
int *sts, bool sevhistobject) :
XttSevHist( parent_ctx, name, xn_oid, xn_aname, xn_scctx, sts, sevhistobject), parent_widget(parent_wid)
{
char title[250];
strncpy(title, name, sizeof(title));
if ( EVEN(*sts))
// Error from XttSevHist
return;
......
......@@ -37,7 +37,8 @@ class XttSevHistGtk : public XttSevHist {
pwr_tOid *xn_oid,
pwr_tOName *xn_aname,
sevcli_tCtx xn_scctx,
int *sts);
int *sts,
bool sevhistobject);
~XttSevHistGtk();
};
......
......@@ -221,11 +221,11 @@ XttTrend *XNavGtk::xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *
}
XttSevHist *XNavGtk::xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname,
sevcli_tCtx scctx, pwr_tStatus *sts)
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject)
{
GtkWidget *w;
return new XttSevHistGtk( this, parent_wid, name, &w, oid, aname, scctx, sts);
return new XttSevHistGtk( this, parent_wid, name, &w, oid, aname, scctx, sts, sevhistobject);
}
XttFast *XNavGtk::xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts)
......
......@@ -59,7 +59,7 @@ class XNavGtk : public XNav {
XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup,
pwr_tStatus *sts);
XttSevHist *xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname,
sevcli_tCtx scctx, pwr_tStatus *sts);
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject=false);
XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts);
XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv,
pwr_tStatus *sts);
......
......@@ -422,7 +422,7 @@ static pwr_tStatus OpenHistory( xmenu_sMenuCall *ip)
sts = gdh_GetAttrRefTid( objar, &classid);
if ( EVEN(sts)) return sts;
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_PlotGroup) {
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject || classid == pwr_cClass_PlotGroup) {
sts = gdh_AttrrefToName( &ip->Pointed, name, sizeof(name),
cdh_mName_volumeStrict);
if ( EVEN(sts)) return sts;
......@@ -444,7 +444,7 @@ static pwr_tStatus OpenHistory( xmenu_sMenuCall *ip)
// Default XttGraph found
sts = gdh_GetAttrRefTid( &defhist, &classid);
if ( ODD(sts) &&
(classid == pwr_cClass_SevHist || classid == pwr_cClass_PlotGroup)) {
(classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject || classid == pwr_cClass_PlotGroup)) {
sts = gdh_AttrrefToName( &defhist, name, sizeof(name),
cdh_mName_volumeStrict);
......@@ -467,7 +467,7 @@ static pwr_tStatus OpenHistory( xmenu_sMenuCall *ip)
sts = gdh_GetObjectClass( oid, &classid);
if ( EVEN(sts)) return sts;
if ( classid == pwr_cClass_SevHist) {
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject) {
found++;
if ( found == 1)
child = oid;
......@@ -516,7 +516,7 @@ static pwr_tStatus OpenHistoryFilter( xmenu_sMenuCall *ip)
sts = gdh_GetAttrRefTid( objar, &classid);
if ( EVEN(sts)) return sts;
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_PlotGroup) {
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject || classid == pwr_cClass_PlotGroup) {
return XNAV__SUCCESS;
}
......@@ -531,7 +531,7 @@ static pwr_tStatus OpenHistoryFilter( xmenu_sMenuCall *ip)
// Default XttGraph found
sts = gdh_GetAttrRefTid( &defhist, &classid);
if ( ODD(sts) &&
(classid == pwr_cClass_SevHist || classid == pwr_cClass_PlotGroup))
(classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject || classid == pwr_cClass_PlotGroup))
return XNAV__SUCCESS;
}
......@@ -544,7 +544,7 @@ static pwr_tStatus OpenHistoryFilter( xmenu_sMenuCall *ip)
sts = gdh_GetObjectClass( child, &classid);
if ( EVEN(sts)) return sts;
if ( classid == pwr_cClass_SevHist)
if ( classid == pwr_cClass_SevHist || classid == pwr_cClass_SevHistObject)
return XNAV__SUCCESS;
sts = gdh_GetNextSibling( child, &child);
......
......@@ -50,12 +50,13 @@ XttSevHist::XttSevHist( void *parent_ctx,
pwr_tOid *xn_oid,
pwr_tOName *xn_aname,
sevcli_tCtx xn_scctx,
int *sts) :
int *sts,
bool sevhistobject) :
xnav(parent_ctx), gcd(0), curve(0), rows(0), vsize(0), timerid(0), close_cb(0), help_cb(0),
first_scan(1), scctx(xn_scctx), oid(xn_oid[0]), time_low_old(0), time_high_old(0)
first_scan(1), scctx(xn_scctx), oid(xn_oid[0]), time_low_old(0), time_high_old(0), sevhistobject(sevhistobject)
{
strncpy( aname, xn_aname[0], sizeof(aname));
get_data( sts, pwr_cNTime, pwr_cNTime);
if ( EVEN(*sts)) return;
......@@ -70,6 +71,9 @@ XttSevHist::~XttSevHist()
int XttSevHist::get_data( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to)
{
if( sevhistobject ) {
return get_objectdata(sts, from, to);
}
pwr_tTime *tbuf;
void *vbuf;
pwr_tDeltaTime trange;
......@@ -167,6 +171,151 @@ int XttSevHist::get_data( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to)
return 1;
}
int XttSevHist::get_objectdata( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to)
{
pwr_tTime *tbuf;
void *vbuf;
sevcli_sHistAttr *histattrbuf;
int numAttributes;
pwr_tDeltaTime trange;
sevcli_get_objectitemdata( sts, scctx, oid, aname, from, to, 1000, &tbuf, &vbuf,
&rows, &histattrbuf, &numAttributes);
if ( EVEN(*sts))
return 0;
// Create data for time axis
gcd = new GeCurveData( curve_eDataType_DsTrend);
gcd->data[0] = (double *) calloc( 1, 8 * rows);
for ( int i = 0; i < rows; i++)
gcd->data[0][i] = (double)tbuf[i].tv_sec + (double)1e-9 * tbuf[i].tv_nsec;
strcpy( gcd->name[0], "Time");
gcd->axis_type[0] = curve_eAxis_x;
strcpy( gcd->format[0], "%10t");
//todo linesize br vi kunna f frn sevcli_get_objectitemdata
int linesize = 0;
for( int i = 0; i < numAttributes; i++) {
linesize += histattrbuf[i].size;
}
void *dataptr = vbuf;
int tmp = 0;
gcd->cols = 1;
for( int i = 0; i < numAttributes; i++) {
switch ( histattrbuf[i].type ) {
case pwr_eType_Int64:
case pwr_eType_Int32:
case pwr_eType_Int16:
case pwr_eType_Int8:
case pwr_eType_UInt64:
case pwr_eType_UInt32:
case pwr_eType_UInt16:
case pwr_eType_UInt8:
case pwr_eType_Float32:
case pwr_eType_Float64:
case pwr_eType_Boolean:
break;
default:
tmp += histattrbuf[i].size;
continue;
}
if( gcd->cols >= CURVE_MAX_COLS ) {
printf("To many columns for curve class max:%d\n", CURVE_MAX_COLS);
break;
}
gcd->cols++;
strcpy( gcd->name[gcd->cols-1], histattrbuf[i].aname);
gcd->data[gcd->cols-1] = (double *) calloc( 1, 8 * rows);
gcd->axis_type[gcd->cols-1] = curve_eAxis_y;
dataptr = (char *)vbuf + tmp;
//tmp += histattrbuf[i].size;
for ( int j = 0; j < rows; j++) {
//dataptr = (char *)dataptr + linesize*j;
dataptr = ((char *)vbuf)+ j * linesize + tmp;
switch ( histattrbuf[i].type ) {
case pwr_eType_Int64:
gcd->data[gcd->cols-1][j] = *(pwr_tInt64 *)dataptr;
break;
case pwr_eType_Int32:
gcd->data[gcd->cols-1][j] = *(pwr_tInt32 *)dataptr;
break;
case pwr_eType_Int16:
gcd->data[gcd->cols-1][j] = *(pwr_tInt16 *)dataptr;
break;
case pwr_eType_Int8:
gcd->data[gcd->cols-1][j] = *(pwr_tInt8 *)dataptr;
break;
case pwr_eType_UInt64:
gcd->data[gcd->cols-1][j] = *(pwr_tUInt64 *)dataptr;
break;
case pwr_eType_UInt32:
gcd->data[gcd->cols-1][j] = *(pwr_tUInt32 *)dataptr;
break;
case pwr_eType_UInt16:
gcd->data[gcd->cols-1][j] = *(pwr_tUInt16 *)dataptr;
break;
case pwr_eType_UInt8:
gcd->data[gcd->cols-1][j] = *(pwr_tUInt8 *)dataptr;
break;
case pwr_eType_Float32:
gcd->data[gcd->cols-1][j] = *(pwr_tFloat32 *)dataptr;
break;
case pwr_eType_Float64:
gcd->data[gcd->cols-1][j] = *(pwr_tFloat64 *)dataptr;
break;
case pwr_eType_Boolean:
gcd->data[gcd->cols-1][j] = *(pwr_tBoolean *)dataptr;
break;
default:
*sts = SEV__CURVETYPE;
return 0;
}
}
tmp += histattrbuf[i].size;
}
free( tbuf);
free( vbuf);
free( histattrbuf);
gcd->rows = rows;
gcd->get_borders();
gcd->get_default_axis();
if ( to.tv_sec != 0 && from.tv_sec != 0) {
time_Adiff( &trange, &to, &from);
if ( time_DToFloat( 0, &trange) < 600)
strcpy( gcd->format[0], "%10t");
else
strcpy( gcd->format[0], "%11t");
}
else
strcpy( gcd->format[0], "%11t");
gcd->select_color( 0);
if ( curve) {
curve->set_curvedata( gcd); // This will free the old gcd
curve->configure_curves();
curve->configure_axes();
curve->redraw();
}
*sts = SEV__SUCCESS;
return 1;
}
void XttSevHist::pop()
{
curve->pop();
......
......@@ -73,6 +73,7 @@ class XttSevHist {
CoWow *wow;
long int time_low_old;
long int time_high_old;
bool sevhistobject; //!< Indicates that it is a SevHistObject
//! Constructor
XttSevHist( void *xn_parent_ctx,
......@@ -80,7 +81,7 @@ class XttSevHist {
pwr_tOid* xn_oid,
pwr_tOName *xn_aname,
sevcli_tCtx xn_scctx,
int *sts);
int *sts, bool sevhistobject);
//! Destructor
virtual ~XttSevHist();
......@@ -88,6 +89,7 @@ class XttSevHist {
//! Pop sevhist window.
void pop();
int get_data( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to);
int get_objectdata( pwr_tStatus *sts, pwr_tTime from, pwr_tTime to);
static void sevhist_close_cb( void *ctx);
static void sevhist_higher_res_cb( void *ctx);
......
......@@ -337,7 +337,7 @@ class XNav {
virtual XttTrend *xtttrend_new( char *name, pwr_tAttrRef *objar, pwr_tAttrRef *plotgroup,
pwr_tStatus *sts) {return 0;}
virtual XttSevHist *xttsevhist_new( char *name, pwr_tOid *oid, pwr_tOName *aname,
sevcli_tCtx scctx, pwr_tStatus *sts) {return 0;}
sevcli_tCtx scctx, pwr_tStatus *sts, bool sevhistobject=false) {return 0;}
virtual XttFast *xttfast_new( char *name, pwr_tAttrRef *objar, pwr_tStatus *sts) {return 0;}
virtual XAttOne *xattone_new( pwr_tAttrRef *objar, char *title, unsigned int priv,
pwr_tStatus *sts) {return 0;}
......
......@@ -3120,6 +3120,7 @@ static int xnav_open_func( void *client_data,
pwr_tAttrRef aref;
pwr_tAName aname;
char *s;
bool sevHistObjectFound = false;
// Command is "OPEN HISTORY"
......@@ -3175,11 +3176,14 @@ static int xnav_open_func( void *client_data,
if (EVEN(sts)) return sts;
switch ( classid) {
case pwr_cClass_SevHist:
break;
case pwr_cClass_SevHist:
break;
case pwr_cClass_SevHistObject:
sevHistObjectFound = true;
break;
case pwr_cClass_PlotGroup:
xnav->message('E', "Not yet implemented");
return XNAV__HOLDCOMMAND;
xnav->message('E', "Not yet implemented");
return XNAV__HOLDCOMMAND;
default:
xnav->message('E', "Error in object class");
return XNAV__HOLDCOMMAND;
......@@ -3187,25 +3191,49 @@ static int xnav_open_func( void *client_data,
if ( plotgroup_found)
break;
sts = gdh_ArefANameToAref( &sevhist_aref, "Attribute", &attr_aref);
if ( EVEN(sts)) return sts;
if( sevHistObjectFound ) {
sts = gdh_ArefANameToAref( &sevhist_aref, "Object", &attr_aref);
if ( EVEN(sts)) return sts;
sts = gdh_GetObjectInfoAttrref( &attr_aref, &aref, sizeof(aref));
if ( EVEN(sts)) return sts;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mNName);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
sts = gdh_GetObjectInfoAttrref( &attr_aref, &aref, sizeof(aref));
if ( EVEN(sts)) return sts;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mNName);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
s = strchr( aname, '.');
if ( !s) {
//It is a complete object
anamev[i][0] = '\0';
}
else {
strcpy( anamev[i], s+1);
}
oidv[i] = aref.Objid;
}
s = strchr( aname, '.');
if ( !s) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
else {
sts = gdh_ArefANameToAref( &sevhist_aref, "Attribute", &attr_aref);
if ( EVEN(sts)) return sts;
sts = gdh_GetObjectInfoAttrref( &attr_aref, &aref, sizeof(aref));
if ( EVEN(sts)) return sts;
sts = gdh_AttrrefToName( &aref, aname, sizeof(aname), cdh_mNName);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
s = strchr( aname, '.');
if ( !s) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
strcpy( anamev[i], s+1);
oidv[i] = aref.Objid;
}
strcpy( anamev[i], s+1);
oidv[i] = aref.Objid;
// Get server and connect to server
sts = gdh_ArefANameToAref( &sevhist_aref, "ThreadObject", &attr_aref);
......@@ -3217,19 +3245,19 @@ static int xnav_open_func( void *client_data,
histthread_aref = cdh_ObjidToAref( histthread_oid);
sts = gdh_ArefANameToAref( &histthread_aref, "ServerNode", &attr_aref);
if ( EVEN(sts)) {
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
xnav->message('E', "Error in SevHist configuration");
return XNAV__HOLDCOMMAND;
}
sts = gdh_GetObjectInfoAttrref( &attr_aref, server_node, sizeof(server_node));
if ( EVEN(sts)) return sts;
if ( !xnav->scctx) {
sevcli_init( &sts, &xnav->scctx);
if ( EVEN(sts)) return sts;
sevcli_init( &sts, &xnav->scctx);
if ( EVEN(sts)) return sts;
}
sevcli_set_servernode( &sts, xnav->scctx, server_node);
if ( EVEN(sts)) return sts;
if ( EVEN(sts)) return sts;
}
oidv[i] = pwr_cNOid;
......@@ -3251,10 +3279,16 @@ static int xnav_open_func( void *client_data,
xnav->message('E', "Not yet implemented");
return XNAV__HOLDCOMMAND;
}
else if( sevHistObjectFound ) {
hist = xnav->xttsevhist_new( title_str, oidv, anamev, xnav->scctx, &sts, true);
if ( ODD(sts)) {
hist->help_cb = xnav_sevhist_help_cb;
}
}
else {
hist = xnav->xttsevhist_new( title_str, oidv, anamev, xnav->scctx, &sts);
if ( ODD(sts)) {
hist->help_cb = xnav_sevhist_help_cb;
hist->help_cb = xnav_sevhist_help_cb;
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment