#include "db.h" #include #include #include #include #include extern "C" { #include } static std::unordered_map dbs; static std::mutex getDBmutex; static bool sensor_name_is_sane(std::string& name) { for (auto it = name.begin(); it != name.end(); ++it) { if (not ((*it >= '0' and *it <= '9') or (*it >= 'A' and *it <= 'Z') or (*it >= 'a' and *it <= 'z') or (*it == '.') or (*it == '_'))) { return false; } } return true; } std::string db_make_key(const uint64_t timestamp) { std::stringstream key; key << "ts-"; key << std::setfill('0') << std::setw(20) << timestamp; return key.str(); } leveldb::DB *db_get(std::string& name) { getDBmutex.lock(); if (dbs.find(name) == dbs.end()) { if (not sensor_name_is_sane(name)) { getDBmutex.unlock(); return nullptr; } leveldb::DB *db; leveldb::Options options; options.create_if_missing = true; leveldb::Status status = leveldb::DB::Open(options, "data/"+name, &db); if (not status.ok()) { std::cout << status.ToString() << std::endl; getDBmutex.unlock(); return nullptr; } dbs[name] = db; getDBmutex.unlock(); return db; } else { getDBmutex.unlock(); return dbs.at(name); } } bool db_insert(std::string& name, const uint64_t timestamp, std::string& value) { leveldb::DB *db = db_get(name); if (db == nullptr) return false; auto status = db->Put(leveldb::WriteOptions(), db_make_key(timestamp), value); return status.ok(); } void db_close() { auto it = dbs.begin(); while (it != dbs.end()) { std::cout << "Close Database: " << (*it).first << std::endl; delete (*it).second; dbs.erase(it++); //post increment! } std::cout << std::endl; } std::list * db_list() { std::list * list = new std::list(); struct dirent * dp; DIR* dirp = opendir("data"); if (dirp != NULL) { while ((dp = readdir(dirp)) != NULL) { if (dp->d_name[0] != '.') list->push_back(std::string(dp->d_name)); } (void)closedir(dirp); } return list; }