#pragma once ///////////////////////////////////////////////////////////////////// // NoSqlDb.h - key/value pair in-memory database // // ver 1.2 // // Jim Fawcett, CSE687 - Object Oriented Design, Spring 2017 // ///////////////////////////////////////////////////////////////////// /* * Package Operations: * ------------------- * This package defines two classes that support key/value storage: * - Element defines a single value stored in the database. * It provides metadata properties: * - nam * - manual information * - maintenance information * - query mechanism * - persistance mechanism * - TestExecutive that demonstrates the requirements you meet * * Required Files: * --------------- * NoSqlDb.h, NoSqlDb.cpp, CppProperties.h, CppProperties.cpp * * Maintenance History: *--------------------- * ver 1.2 : 06 Feb 2017 * - added children * - modified Element::show() * - added these comments * ver 1.1 : 28 Jan 2017 * - fixed bug in NoSqlDb::count() by replacing * unordered_map::count() with * unordered_map::size(); * Ver 1.0 : 25 Jan 2017 * - first release */ #include #include #include #include #include #include #include "../CppProperties/CppProperties.h" #include "../DateTime/DateTime.h" namespace NoSQLDB { using Key = std::string; using Keys = std::vector; using Name = std::string; using Category = std::string; using Children = std::vector; ///////////////////////////////////////////////////////////////////// // Element class represents a data record in our NoSql database // - in our NoSql database that is just the value in a key/value pair // - it needs to store child data, something for you to implement // template class Element { public: Element() {} Element(Name aName, Category aCat) : name(aName), category(aCat) {}; Property name; // metadata Property category; // metadata Property dateTime; // metadata Property children; // metadata Property data; // data void saveChild(Key); std::string show(); }; template void Element::saveChild(Key key) { children.getValue().push_back(key); } template std::string Element::show() { std::ostringstream out; out.setf(std::ios::adjustfield, std::ios::left); out << "\n " << std::setw(8) << "name" << " : " << name; out << "\n " << std::setw(8) << "category" << " : " << category; out << "\n " << std::setw(8) << "dateTime" << " : " << DateTime(dateTime).time(); Children children_ = static_cast(children); if (children_.size() > 0) { out << "\n " << std::setw(8) << "children" << " : "; for (size_t i = 0; i < children_.size(); ++i) { out << children_[i]; if (i < children_.size()) out << ", "; } } out << "\n " << std::setw(8) << "data" << " : " << data; out << "\n"; return out.str(); } ///////////////////////////////////////////////////////////////////// // NoSqlDb class is a key/value pair in-memory database // - stores and retrieves elements // - you will need to add query capability // That should probably be another class that uses NoSqlDb // template class NoSqlDb { public: using Key = std::string; using Keys = std::vector; Keys keys(); bool hasKey(Key key); bool saveRecord(Key key, Element elem); bool saveValue(Key key, Element elem); bool removeRecord(Key key); Element value(Key key); size_t count(); private: using Item = std::pair>; std::unordered_map> store; }; template typename NoSqlDb::Keys NoSqlDb::keys() { Keys keys; for (Item item : store) { keys.push_back(item.first); } return keys; } template bool NoSqlDb::hasKey(Key key) { if (store.find(key) == store.end()) return false; return true; } template bool NoSqlDb::saveRecord(Key key, Element elem) { if (store.find(key) != store.end()) return false; store[key] = elem; return true; } template bool NoSqlDb::removeRecord(Key key) { if (store.find(key) == store.end()) return false; size_t numErased = store.erase(key); if (numErased == 1) { // remove key from all other element's children collections for (Key k : keys()) { Keys& children = store[k].children.getValue(); // note Keys& - we don't want copy of children Keys::iterator iter; for (iter = children.begin(); iter != children.end(); ++iter) { if ((*iter) == key) { children.erase(iter); break; } } } return true; } return false; } template bool NoSqlDb::saveValue(Key key, Element elem) { if (store.find(key) == store.end()) return false; store[key] = elem; return true; } template Element NoSqlDb::value(Key key) { if (store.find(key) != store.end()) return store[key]; return Element(); } template size_t NoSqlDb::count() { return store.size(); } }