/* **************************************************************************** * * attributeType - * */ static std::string attributeType ( const std::string& tenant, const std::vector<std::string>& servicePathV, const std::string entityType, const std::string attrName ) { std::string idType = std::string("_id.") + ENT_ENTITY_TYPE; std::string idServicePath = std::string("_id.") + ENT_SERVICE_PATH; std::string attributeName = std::string(ENT_ATTRS) + "." + attrName; BSONObj query = BSON(idType << entityType << idServicePath << fillQueryServicePath(servicePathV) << attributeName << BSON("$exists" << true)); std::auto_ptr<DBClientCursor> cursor; std::string err; if (!collectionQuery(getEntitiesCollectionName(tenant), query, &cursor, &err)) { return ""; } while (cursor->more()) { BSONObj r; try { r = cursor->nextSafe(); } catch (const AssertionException &e) { // $err raised LM_E(("Runtime Error (assertion exception in nextSafe(): %s", e.what())); continue; } LM_T(LmtMongo, ("retrieved document: '%s'", r.toString().c_str())); /* It could happen that different entities within the same entity type may have attributes with the same name * but different types. In that case, one type (at random) is returned. A list could be returned but the * NGSIv2 operations only allow to set one type */ BSONObj attrs = getField(r, ENT_ATTRS).embeddedObject(); BSONObj attr = getField(attrs, attrName).embeddedObject(); return getStringField(attr, ENT_ATTRS_TYPE); } return ""; }
/* **************************************************************************** * * countEntities - * */ static long long countEntities(const std::string& tenant, const std::vector<std::string>& servicePathV,std::string entityType) { DBClientBase* connection = NULL; std::string idType = std::string("_id.") + ENT_ENTITY_TYPE; std::string idServicePath = std::string("_id.") + ENT_SERVICE_PATH; BSONObj query = BSON(idType << entityType << idServicePath << fillQueryServicePath(servicePathV)); LM_T(LmtMongo, ("count() in '%s' collection: '%s'", getEntitiesCollectionName(tenant).c_str(), query.toString().c_str())); try { connection = getMongoConnection(); long long c = connection->count(getEntitiesCollectionName(tenant).c_str(), query); releaseMongoConnection(connection); LM_I(("Database Operation Successful (%s)", query.toString().c_str())); return c; } catch (const DBException& e) { releaseMongoConnection(connection); LM_E(("Database Error ('%s', '%s')", query.toString().c_str(), e.what())); } catch (...) { releaseMongoConnection(connection); LM_E(("Database Error ('%s', '%s')", query.toString().c_str(), "generic exception")); } return -1; }
/* **************************************************************************** * * countEntities - * */ static long long countEntities(const std::string& tenant, const std::vector<std::string>& servicePathV,std::string entityType) { std::string idType = std::string("_id.") + ENT_ENTITY_TYPE; std::string idServicePath = std::string("_id.") + ENT_SERVICE_PATH; BSONObj query = BSON(idType << entityType << idServicePath << fillQueryServicePath(servicePathV)); std::string err; unsigned long long c; if (!collectionCount(getEntitiesCollectionName(tenant), query, &c, &err)) { return -1; } return c; }
/* **************************************************************************** * * attributeType - * */ static std::string attributeType ( const std::string& tenant, const std::vector<std::string>& servicePathV, const std::string entityType, const std::string attrName ) { std::string idType = std::string("_id.") + ENT_ENTITY_TYPE; std::string idServicePath = std::string("_id.") + ENT_SERVICE_PATH; std::string attributeName = std::string(ENT_ATTRS) + "." + attrName; BSONObj query = BSON(idType << entityType << idServicePath << fillQueryServicePath(servicePathV) << attributeName << BSON("$exists" << true)); std::auto_ptr<DBClientCursor> cursor; DBClientBase* connection = NULL; LM_T(LmtMongo, ("query() in '%s' collection: '%s'", getEntitiesCollectionName(tenant).c_str(), query.toString().c_str())); try { connection = getMongoConnection(); cursor = connection->query(getEntitiesCollectionName(tenant).c_str(), query); /* * We have observed that in some cases of DB errors (e.g. the database daemon is down) instead of * raising an exception, the query() method sets the cursor to NULL. In this case, we raise the * exception ourselves */ if (cursor.get() == NULL) { throw DBException("Null cursor from mongo (details on this is found in the source code)", 0); } releaseMongoConnection(connection); LM_I(("Database Operation Successful (%s)", query.toString().c_str())); } catch (const DBException &e) { releaseMongoConnection(connection); LM_E(("Database Error ('%s', '%s')", query.toString().c_str(), e.what())); return ""; } catch (...) { releaseMongoConnection(connection); LM_E(("Database Error ('%s', '%s')", query.toString().c_str(), "generic exception")); return ""; } while (cursor->more()) { BSONObj r = cursor->next(); LM_T(LmtMongo, ("retrieved document: '%s'", r.toString().c_str())); /* It could happen that different entities within the same entity type may have attributes with the same name * but different types. In that case, one type (at random) is returned. A list could be returned but the * NGSIv2 operations only allow to set one type */ return r.getField(ENT_ATTRS).embeddedObject().getField(attrName).embeddedObject().getStringField(ENT_ATTRS_TYPE); } return ""; }