diff --git a/README.md b/README.md index 9650860..173a178 100644 --- a/README.md +++ b/README.md @@ -17,11 +17,9 @@ You may modify the following fields in the POST - name - description - notes -You must use the query command parameters to modify other properties -- addContact=UUID -- delContact=UUID -- addLocation=UUID -- delLocation=UUID + +### Delete +- Children must be empty ## Inventory Tags ### Creation rules diff --git a/build b/build index d2e1cef..abc4eff 100644 --- a/build +++ b/build @@ -1 +1 @@ -44 \ No newline at end of file +46 \ No newline at end of file diff --git a/src/RESTAPI_handler.cpp b/src/RESTAPI_handler.cpp index 64f6a01..ede260d 100644 --- a/src/RESTAPI_handler.cpp +++ b/src/RESTAPI_handler.cpp @@ -111,6 +111,26 @@ namespace OpenWifi { return Default; } + bool RESTAPIHandler::HasParameter(const std::string &Name, std::string &Value) { + for (const auto &i : Parameters_) { + if (i.first == Name) { + Value = i.second; + return true; + } + } + return false; + } + + bool RESTAPIHandler::HasParameter(const std::string &Name, uint64_t & Value) { + for (const auto &i : Parameters_) { + if (i.first == Name) { + Value = std::stoi(i.second); + return true; + } + } + return false; + } + const std::string &RESTAPIHandler::GetBinding(const std::string &Name, const std::string &Default) { auto E = Bindings_.find(Poco::toLower(Name)); if (E == Bindings_.end()) diff --git a/src/RESTAPI_handler.h b/src/RESTAPI_handler.h index 9c03ebb..56a0e45 100644 --- a/src/RESTAPI_handler.h +++ b/src/RESTAPI_handler.h @@ -146,6 +146,8 @@ namespace OpenWifi { [[nodiscard]] static std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default=""); [[nodiscard]] static bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false); [[nodiscard]] static uint64_t GetWhen(const Poco::JSON::Object::Ptr &Obj); + bool HasParameter(const std::string &QueryParameter, std::string &Value); + bool HasParameter(const std::string &QueryParameter, uint64_t & Value); protected: BindingMap Bindings_; diff --git a/src/RESTAPI_inventory_list_handler.cpp b/src/RESTAPI_inventory_list_handler.cpp index c75329b..8aa84e1 100644 --- a/src/RESTAPI_inventory_list_handler.cpp +++ b/src/RESTAPI_inventory_list_handler.cpp @@ -31,6 +31,7 @@ namespace OpenWifi{ Poco::Net::HTTPServerResponse &Response) { try { + std::string UUID; if(!QB_.Select.empty()) { auto DevUIIDS = Utils::Split(QB_.Select); Poco::JSON::Array Arr; @@ -49,6 +50,39 @@ namespace OpenWifi{ Answer.set("inventoryTags",Arr); ReturnObject(Request, Answer, Response); return; + } else if(HasParameter("entity",UUID)) { + std::string Arg; + if(HasParameter("countOnly",Arg) && Arg=="true") { + Poco::JSON::Object Answer; + auto C = Storage()->InventoryDB().Count(Storage()->InventoryDB().MakeWhere("entiry",ORM::EQUAL,UUID)); + Answer.set("count", C); + ReturnObject(Request, Answer, Response); + return; + } + bool SerialOnly=false; + if(HasParameter("serialOnly",Arg) && Arg=="true") + SerialOnly=true; + InventoryTagVec Tags; + Storage()->InventoryDB().GetRecords(QB_.Offset, QB_.Limit, Tags, Storage()->InventoryDB().MakeWhere("entity",ORM::EQUAL,UUID)); + Poco::JSON::Array Array; + for(const auto &i:Tags) { + if(SerialOnly) { + Array.add(i.serialNumber); + } else { + Poco::JSON::Object O; + i.to_json(O); + Array.add(O); + } + } + Poco::JSON::Object Answer; + if(SerialOnly) + Answer.set("serialNumbers", Array); + else + Answer.set("tags", Array); + ReturnObject(Request, Answer, Response); + return; + } else if(HasParameter("venue",UUID)) { + } else { std::vector Tags; Storage()->InventoryDB().GetRecords(QB_.Offset,QB_.Limit,Tags); diff --git a/src/orm.h b/src/orm.h index 2712fb7..f6d36d8 100644 --- a/src/orm.h +++ b/src/orm.h @@ -109,7 +109,7 @@ namespace ORM { } enum CompareOperations { - EQUAL, + EQUAL = 0 , LESS, LESS_OR_EQUAL, GREATER, @@ -117,6 +117,7 @@ namespace ORM { NOT_EQUAL }; + static std::vector OpsToString{ " = " , " < " , " <= " , " > " , " >= " , " != "}; inline std::string to_string(ORM::CompareOperations O) { switch(O) { case EQUAL: return "="; @@ -259,6 +260,26 @@ namespace ORM { return R; } + std::string MakeWhere( const std::string &S, CompareOperations Op, const std::string &V) { + std::string R; + + assert( FieldNames_.find(S) != FieldNames_.end() ); + + R = S + OpsToString[Op] + "\"" + Escape(V) + "\"" ; + + return R; + } + + std::string MakeWhere( const std::string &S, CompareOperations & Op, uint64_t &V) { + std::string R; + + assert( FieldNames_.find(S) != FieldNames_.end() ); + + R = S + OpsToString[Op] + std::to_string(V) ; + + return R; + } + inline bool Create() { std::string S; @@ -333,6 +354,9 @@ namespace ORM { template bool GetRecord( const char * FieldName, T Value, RecordType & R) { try { + + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + Poco::Data::Session Session = Pool_.get(); Poco::Data::Statement Select(Session); RecordTuple RT; @@ -356,8 +380,11 @@ namespace ORM { typedef std::vector StringVec; template < typename T, - typename T0, typename T1> bool GR(const StringVec &FieldName, T & R,T0 &V0, T1 &V1) { + typename T0, typename T1> bool GR(const char *FieldName, T & R,T0 &V0, T1 &V1) { try { + + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + Poco::Data::Session Session = Pool_.get(); Poco::Data::Statement Select(Session); RecordTuple RT; @@ -411,6 +438,8 @@ namespace ORM { template bool UpdateRecord( const char *FieldName, T & Value, RecordType & R) { try { + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + Poco::Data::Session Session = Pool_.get(); Poco::Data::Statement Update(Session); @@ -432,6 +461,8 @@ namespace ORM { template bool DeleteRecord( const char *FieldName, T Value) { try { + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + Poco::Data::Session Session = Pool_.get(); Poco::Data::Statement Delete(Session); @@ -464,6 +495,8 @@ namespace ORM { bool Exists(const char *FieldName, std::string & Value) { try { + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + RecordType R; if(GetRecord(FieldName,Value,R)) return true; @@ -474,8 +507,31 @@ namespace ORM { return false; } + uint64_t Count( const std::string & Where="" ) { + try { + uint64_t Cnt=0; + + Poco::Data::Session Session = Pool_.get(); + Poco::Data::Statement Select(Session); + + std::string st{"SELECT COUNT(*) FROM " + DBName + " " + (Where.empty() ? "" : (" where " + Where)) }; + + Select << st , + Poco::Data::Keywords::into(Cnt); + Select.execute(); + + return Cnt; + + } catch (const Poco::Exception &E) { + Logger_.log(E); + } + return 0; + } + template bool ManipulateVectorMember( X T, const char *FieldName, std::string & ParentUUID, std::string & ChildUUID, bool Add) { try { + assert( FieldNames_.find(FieldName) != FieldNames_.end() ); + RecordType R; if(GetRecord(FieldName, ParentUUID, R)) { auto it = std::lower_bound((R.*T).begin(),(R.*T).end(),ChildUUID); diff --git a/src/storage_inventory.h b/src/storage_inventory.h index a53ca78..cd4e144 100644 --- a/src/storage_inventory.h +++ b/src/storage_inventory.h @@ -32,6 +32,8 @@ namespace OpenWifi { std::string > InventoryDBRecordType; + typedef std::vector InventoryTagVec; + class InventoryDB : public ORM::DB { public: InventoryDB( ORM::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);