/* * query.cpp * * Created on: Feb 19, 2015 * Author: Axel Auweter */ #include #include #include #include #include #include #include #include #include "dcdbendian.h" #include "query.h" void DCDBQuery::setLocalTimeEnabled(bool enable) { useLocalTime = enable; } bool DCDBQuery::getLocalTimeEnabled() { return useLocalTime; } void DCDBQuery::setRawOutputEnabled(bool enable) { useRawOutput = enable; } bool DCDBQuery::getRawOutputEnabled() { return useRawOutput; } void DCDBQuery::setFloatOutputEnabled(bool enable) { useFloatOutput = enable; } bool DCDBQuery::getFloatOutputEnabled() { return useFloatOutput; } void DCDBQuery::doQuery(const char* hostname, std::list sensors, DCDBTimeStamp start, DCDBTimeStamp end) { /* Create a new connection to the database */ DCDBConnection* connection; connection = new DCDBConnection(); connection->setHostname(hostname); if (!connection->connect()) { std::cout << "Cannot connect to database." << std::endl; } /* Initialize the SensorConfig interface */ SensorConfig sensorConfig(connection); SensorDataStore sensorDataStore(connection); /* Print the CSV header */ std::cout << "Sensor,Time,Value" << std::endl; /* Iterate over list of sensors requested by the user */ for (std::list::iterator it = sensors.begin(); it != sensors.end(); it++) { bool unitConvert = false; bool scale = false; double scalingFactor = 1; std::string modifierStr; DCDBUnit baseUnit = DCDBUnit_None, targetUnit = DCDBUnit_None; /* Check if the sensor was requested in a different unit or with scaling factor */ if (it->find('/') != std::string::npos) { modifierStr = it->substr(it->find('/')+1, it->length()); /* Remove the modifier from the string */ *it = it->substr(0, it->find('/')); /* Check what type of modificatino is requested */ boost::regex e("\\.?[0-9]*", boost::regex::extended); if (boost::regex_match(modifierStr, e)) { scale = true; sscanf(modifierStr.c_str(), "%lf", &scalingFactor); } else { unitConvert = true; targetUnit = UnitConv::fromString(modifierStr); DCDBPublicSensor sen; sensorConfig.getPublicSensorByName(sen, it->c_str()); baseUnit = UnitConv::fromString(sen.unit); } } /* Lookup the sensor in the published sensors table */ std::string pattern; switch (sensorConfig.getSensorPattern(pattern, *it)) { case SC_OK: break; case SC_INVALIDSESSION: std::cout << "Invalid session." << std::endl; return; case SC_UNKNOWNSENSOR: std::cout << "Unknown sensor: " << *it << std::endl; return; default: std::cout << "Unknown error." << std::endl; return; } /* Expand the pattern into a list of existing sensors in the time range */ std::list sensorIds; switch (sensorConfig.getSensorListForPattern(sensorIds, pattern, start, end)) { case SC_OK: break; case SC_INVALIDPATTERN: std::cout << "Invalid pattern." << std::endl; return; default: std::cout << "Unknown error." << std::endl; return; } /* Iterate over the expanded list of sensorIds and output the results in CSV format */ for (std::list::iterator sit = sensorIds.begin(); sit != sensorIds.end(); sit++) { std::list readings; sensorDataStore.query(readings, *sit, start, end); /* Iterate over the readings */ for (std::list::iterator rit = readings.begin(); rit != readings.end(); rit++) { double fvalue; int64_t ivalue; SensorDataStoreReading reading = *rit; /* Assign the reading to local variable */ if (useFloatOutput) { fvalue = reading.value; } else { ivalue = reading.value; } /* Convert the unit if requested */ if (unitConvert) { if (useFloatOutput) { if (!UnitConv::convert(fvalue, baseUnit, targetUnit)) { std::cerr << "Warning, cannot convert units (" << UnitConv::toString(baseUnit) << " -> " << UnitConv::toString(targetUnit) << ")" << std::endl; unitConvert = false; } } else { if (!UnitConv::convert(ivalue, baseUnit, targetUnit)) { std::cerr << "Warning, cannot convert units (" << UnitConv::toString(baseUnit) << " -> " << UnitConv::toString(targetUnit) << ")" << std::endl; unitConvert = false; } } } /* Scale the value if requested */ if (scale) { if (useFloatOutput) { fvalue *= scalingFactor; } else { ivalue *= scalingFactor; } } /* Print the sensor's public name */ std::cout << *it << ","; /* Print the time stamp */ if (useLocalTime) { reading.timeStamp.convertToLocal(); } if (useRawOutput) { std::cout << reading.timeStamp.getRaw() << ","; } else { std::cout << reading.timeStamp.getString() << ","; } /* Print the sensor value */ if (useFloatOutput) { std::cout << fvalue << std::endl; } else { std::cout << ivalue << std::endl; } } } } /* * Clean up */ connection->disconnect(); delete connection; } DCDBQuery::DCDBQuery() { connection = nullptr; useLocalTime = false; useRawOutput = false; useFloatOutput = false; }