Exemplo n.º 1
0
//  finds the names of the document with the most fields in a collection 
std::set<string> getCollFields(DBClientConnection& c, string db, string collection){
   
    int longest;
    
    // mongo fieldnames = sql column names
    set<string> fieldnames;
    
    // get the list of ODBC supported fields (columns) from collection.meta collection
    // collection.meta should only contain one document
    std::auto_ptr<mongo::DBClientCursor> cursor = c.query(db+"."+collection+".meta");
    
    BSONObj d = cursor->next();
    
    if (d.nFields() != 0){
        longest = d.nFields();
        d.getFieldNames(fieldnames);
    }
    
    // if no meta collection find collection with most fields
    if (longest == 0) {
    
        cursor = c.query(db+"."+collection);
    
        while( cursor->more() ) {
            //  get next doc/row/tuple
            BSONObj doc = cursor->next();
            if(longest < doc.nFields()){
                longest = doc.nFields();
                doc.getFieldNames(fieldnames);
            }
        }
    }
    return fieldnames;
}
Exemplo n.º 2
0
    int run(){

        path root( getParam( "out" , "dump" ) );
        string db = _db;
        
        if ( db == "*" ){
            cout << "all dbs" << endl;

            BSONObj res = _conn.findOne( "admin.$cmd" , BSON( "listDatabases" << 1 ) );
            BSONObj dbs = res.getField( "databases" ).embeddedObjectUserCheck();
            set<string> keys;
            dbs.getFieldNames( keys );
            for ( set<string>::iterator i = keys.begin() ; i != keys.end() ; i++ ) {
                string key = *i;
                
                BSONObj dbobj = dbs.getField( key ).embeddedObjectUserCheck();
                
                const char * dbName = dbobj.getField( "name" ).valuestr();
                if ( (string)dbName == "local" )
                    continue;

                go ( dbName , root / dbName );
            }
        }
        else {
            go( db , root / db );
        }
        return 0;
    }
 virtual void parseObjectRecursive(const BSONObj& object, string& key, int elementIndex=0, int elementCount=1, int arrayIndex = -1, int arrayCount = 0) {
     stack.push(object, key, elementIndex, elementCount, arrayIndex, arrayCount);
     visitor.onObjectStart(stack);
     set<string> keys;
     object.getFieldNames(keys); // Get the key names of the BSON object.
     int ei = 0;
     int ec = keys.size();
     for (string key : keys) {
         BSONElement e = object.getField(key);
         parseElementRecursive(e, key, ei++, ec, arrayIndex);
     }
     visitor.onObjectEnd(stack);
     stack.drop();
 }
Exemplo n.º 4
0
int gridfs_listxattr(const char* path, char* list, size_t size)
{
  path = fuse_to_mongo_path(path);

  if(open_files.find(path) != open_files.end()) {
    return 0;
  }

  ScopedDbConnection sdc(*gridfs_options.conn_string);
  bool digest = true;
  string err = "";
  sdc.conn().DBClientWithCommands::auth(gridfs_options.db, gridfs_options.username, gridfs_options.password, err, digest);
  fprintf(stderr, "DEBUG: %s\n", err.c_str());
  GridFS gf(sdc.conn(), gridfs_options.db);
  GridFile file = gf.findFile(path);
  sdc.done();

  if(!file.exists()) {
    return -ENOENT;
  }

  int len = 0;
  BSONObj metadata = file.getMetadata();
  set<string> field_set;
  metadata.getFieldNames(field_set);
  for(set<string>::const_iterator s = field_set.begin(); s != field_set.end(); s++) {
    string attr_name = namespace_xattr(*s);
    int field_len = attr_name.size() + 1;
    len += field_len;
    if(size >= len) {
      memcpy(list, attr_name.c_str(), field_len);
      list += field_len;
    }
  }

  if(size == 0) {
    return len;
  } else if(size < len) {
    return -ERANGE;
  }

  return len;
}
Exemplo n.º 5
0
int gridfs_listxattr(const char* path, char* list, size_t size)
{
  path = fuse_to_mongo_path(path);

  if(open_files.find(path) != open_files.end()) {
    return 0;
  }

  ScopedDbConnection sdc(*gridfs_options.conn_string);
  ScopedDbConnection_init(sdc);
  GridFS gf(sdc.conn(), gridfs_options.db, gridfs_options.prefix);
  GridFile file = gf.findFile(path);
  sdc.done();

  if(!file.exists()) {
    return -ENOENT;
  }

  int len = 0;
  BSONObj metadata = file.getMetadata();
  set<string> field_set;
  metadata.getFieldNames(field_set);
  for(set<string>::const_iterator s = field_set.begin(); s != field_set.end(); s++) {
    string attr_name = namespace_xattr(*s);
    int field_len = attr_name.size() + 1;
    len += field_len;
    if(size >= len) {
      memcpy(list, attr_name.c_str(), field_len);
      list += field_len;
    }
  }

  if(size == 0) {
    return len;
  } else if(size < len) {
    return -ERANGE;
  }

  return len;
}
Exemplo n.º 6
0
void simCount(DBClientConnection& c, string dbcoll, BSONObj bobject){
        
    cout<<"\n simCount \n"<< endl;
    
    // BSONObj cx = BSONObjBuilder().append(fromjson("{age:12}")).obj();
    
    mongo::BSONObj cx = fromjson("{age: {$gt : 12, $lt : 40}}");
    mongo::BSONObj dx = fromjson("{age: {$gt : 12}, age:{$lt : 40}}");
    
    
    mongo::Query query = QUERY("age"<< NE << 12);
    auto_ptr<mongo::DBClientCursor> cursor = c.query(dbcoll,dx);
    
    set<string> fieldnames;
    
    while( cursor->more() ) {
        BSONObj p = cursor->next();
        cout<< p.nFields() <<endl;
        cout << p.getField("name").toString() << endl;
        cout << p.getFieldNames(fieldnames) << endl;
        cout << fieldnames.size() << endl;
    }
}
Exemplo n.º 7
0
Arquivo: dump.cpp Projeto: ANTco/mongo
    int run() {
        bool usingMongos = isMongos();
        int serverAuthzVersion = 0;
        BSONObj dumpQuery;

        if (mongoDumpGlobalParams.repair){
            return repair();
        }

        {
            if (mongoDumpGlobalParams.query.size()) {
                dumpQuery = fromjson(mongoDumpGlobalParams.query);
            }
        }

        if (mongoDumpGlobalParams.dumpUsersAndRoles) {
            uassertStatusOK(auth::getRemoteStoredAuthorizationVersion(&conn(true),
                                                                      &serverAuthzVersion));
            uassert(17369,
                    mongoutils::str::stream() << "Backing up users and roles is only supported for "
                            "clusters with auth schema versions 1, 3 or 4; found " <<
                            serverAuthzVersion,
                    serverAuthzVersion == AuthorizationManager::schemaVersion24 ||
                    serverAuthzVersion == AuthorizationManager::schemaVersion26Final ||
                    serverAuthzVersion == AuthorizationManager::schemaVersion28SCRAM);
        }

        string opLogName = "";
        unsigned long long opLogStart = 0;
        if (mongoDumpGlobalParams.useOplog) {

            BSONObj isMaster;
            conn("true").simpleCommand("admin", &isMaster, "isMaster");

            if (isMaster.hasField("hosts")) { // if connected to replica set member
                opLogName = "local.oplog.rs";
            }
            else {
                opLogName = "local.oplog.$main";
                if ( ! isMaster["ismaster"].trueValue() ) {
                    toolError() << "oplog mode is only supported on master or replica set member"
                              << std::endl;
                    return -1;
                }
            }

            BSONObj op = conn(true).findOne(opLogName, Query().sort("$natural", -1), 0, QueryOption_SlaveOk);
            if (op.isEmpty()) {
                toolError() << "No operations in oplog. Please ensure you are connecting to a "
                            << "master." << std::endl;
                return -1;
            }

            verify(op["ts"].type() == Timestamp);
            opLogStart = op["ts"]._numberLong();
        }

        // check if we're outputting to stdout
        if (mongoDumpGlobalParams.outputDirectory == "-") {
            if (toolGlobalParams.db != "" && toolGlobalParams.coll != "") {
                writeCollectionStdout(toolGlobalParams.db + "." + toolGlobalParams.coll, dumpQuery,
                                      usingMongos);
                return 0;
            }
            else {
                toolError() << "You must specify database and collection to print to stdout"
                          << std::endl;
                return -1;
            }
        }

        boost::filesystem::path root(mongoDumpGlobalParams.outputDirectory);

        if (toolGlobalParams.db == "") {
            if (toolGlobalParams.coll != "") {
                toolError() << "--db must be specified with --collection" << std::endl;
                return -1;
            }

            toolInfoLog() << "all dbs" << std::endl;

            BSONObj res = conn( true ).findOne( "admin.$cmd" , BSON( "listDatabases" << 1 ) );
            if ( ! res["databases"].isABSONObj() ) {
                toolError() << "output of listDatabases isn't what we expected, no 'databases' "
                          << "field:\n" << res << std::endl;
                return -2;
            }
            BSONObj dbs = res["databases"].embeddedObjectUserCheck();
            set<string> keys;
            dbs.getFieldNames( keys );
            for ( set<string>::iterator i = keys.begin() ; i != keys.end() ; i++ ) {
                string key = *i;
                
                if ( ! dbs[key].isABSONObj() ) {
                    toolError() << "database field not an document key: " << key << " value: "
                              << dbs[key] << std::endl;
                    return -3;
                }

                BSONObj dbobj = dbs[key].embeddedObjectUserCheck();

                const char * dbName = dbobj.getField( "name" ).valuestr();
                if ( (string)dbName == "local" )
                    continue;

                boost::filesystem::path outdir = root / dbName;
                toolInfoLog() << "DATABASE: " << dbName << "\t to \t" << outdir.string()
                        << std::endl;
                go ( dbName , "", dumpQuery, outdir, "", usingMongos );
            }
        }
        else {
            boost::filesystem::path outdir = root / toolGlobalParams.db;
            toolInfoLog() << "DATABASE: " << toolGlobalParams.db << "\t to \t" << outdir.string()
                    << std::endl;
            go(toolGlobalParams.db, toolGlobalParams.coll, dumpQuery, outdir, "", usingMongos);
            if (mongoDumpGlobalParams.dumpUsersAndRoles &&
                    serverAuthzVersion >= AuthorizationManager::schemaVersion26Final &&
                    toolGlobalParams.db != "admin") {
                toolInfoLog() << "Backing up user and role data for the " << toolGlobalParams.db <<
                        " database";
                Query query = Query(BSON("db" << toolGlobalParams.db));
                go("admin", "system.users", query, outdir, "$admin.system.users", usingMongos);
                go("admin", "system.roles", query, outdir, "$admin.system.roles", usingMongos);
            }
        }

        if (!opLogName.empty()) {
            BSONObjBuilder b;
            b.appendTimestamp("$gt", opLogStart);

            dumpQuery = BSON("ts" << b.obj());

            writeCollectionFile( opLogName , dumpQuery, root / "oplog.bson", usingMongos );
        }

        return 0;
    }
Exemplo n.º 8
0
    int run() {
        
        if ( hasParam( "repair" ) ){
            warning() << "repair is a work in progress" << endl;
            return repair();
        }

        {
            string q = getParam("query");
            if ( q.size() )
                _query = fromjson( q );
        }

        string opLogName = "";
        unsigned long long opLogStart = 0;
        if (hasParam("oplog")) {
            if (hasParam("query") || hasParam("db") || hasParam("collection")) {
                cout << "oplog mode is only supported on full dumps" << endl;
                return -1;
            }


            BSONObj isMaster;
            conn("true").simpleCommand("admin", &isMaster, "isMaster");

            if (isMaster.hasField("hosts")) { // if connected to replica set member
                opLogName = "local.oplog.rs";
            }
            else {
                opLogName = "local.oplog.$main";
                if ( ! isMaster["ismaster"].trueValue() ) {
                    cout << "oplog mode is only supported on master or replica set member" << endl;
                    return -1;
                }
            }

            auth("local");

            BSONObj op = conn(true).findOne(opLogName, Query().sort("$natural", -1), 0, QueryOption_SlaveOk);
            if (op.isEmpty()) {
                cout << "No operations in oplog. Please ensure you are connecting to a master." << endl;
                return -1;
            }

            assert(op["ts"].type() == Timestamp);
            opLogStart = op["ts"]._numberLong();
        }

        // check if we're outputting to stdout
        string out = getParam("out");
        if ( out == "-" ) {
            if ( _db != "*" && _coll != "*" ) {
                writeCollectionStdout( _db+"."+_coll );
                return 0;
            }
            else {
                cout << "You must specify database and collection to print to stdout" << endl;
                return -1;
            }
        }

        _usingMongos = isMongos();

        path root( out );
        string db = _db;

        if ( db == "*" ) {
            cout << "all dbs" << endl;
            auth( "admin" );

            BSONObj res = conn( true ).findOne( "admin.$cmd" , BSON( "listDatabases" << 1 ) );
            if ( ! res["databases"].isABSONObj() ) {
                error() << "output of listDatabases isn't what we expected, no 'databases' field:\n" << res << endl;
                return -2;
            }
            BSONObj dbs = res["databases"].embeddedObjectUserCheck();
            set<string> keys;
            dbs.getFieldNames( keys );
            for ( set<string>::iterator i = keys.begin() ; i != keys.end() ; i++ ) {
                string key = *i;
                
                if ( ! dbs[key].isABSONObj() ) {
                    error() << "database field not an object key: " << key << " value: " << dbs[key] << endl;
                    return -3;
                }

                BSONObj dbobj = dbs[key].embeddedObjectUserCheck();

                const char * dbName = dbobj.getField( "name" ).valuestr();
                if ( (string)dbName == "local" )
                    continue;

                go ( dbName , root / dbName );
            }
        }
        else {
            auth( db );
            go( db , root / db );
        }

        if (!opLogName.empty()) {
            BSONObjBuilder b;
            b.appendTimestamp("$gt", opLogStart);

            _query = BSON("ts" << b.obj());

            writeCollectionFile( opLogName , root / "oplog.bson" );
        }

        return 0;
    }
/* ****************************************************************************
*
* ContextElementResponse::ContextElementResponse -
*
* This constructor builds the CER object based in a BSON object taken from the
* entities collection at DB.
*
* Note that statusCode is not touched by this constructor.
*/
ContextElementResponse::ContextElementResponse(const mongo::BSONObj& entityDoc, const AttributeList& attrL, bool includeEmpty)
{
  prune = false;

  // Entity
  BSONObj id = getField(entityDoc, "_id").embeddedObject();
  contextElement.entityId.fill(getStringField(id, ENT_ENTITY_ID), getStringField(id, ENT_ENTITY_TYPE), "false");
  contextElement.entityId.servicePath = id.hasField(ENT_SERVICE_PATH) ? getStringField(id, ENT_SERVICE_PATH) : "";

  /* Get the location attribute (if it exists) */
  std::string locAttr;
  if (entityDoc.hasElement(ENT_LOCATION))
  {
    locAttr = getStringField(getObjectField(entityDoc, ENT_LOCATION), ENT_LOCATION_ATTRNAME);
  }


  //
  // Attribute vector
  // FIXME P5: constructor for BSONObj could be added to ContextAttributeVector/ContextAttribute classes, to make building more modular
  //
  BSONObj                attrs = getField(entityDoc, ENT_ATTRS).embeddedObject();
  std::set<std::string>  attrNames;

  attrs.getFieldNames(attrNames);
  for (std::set<std::string>::iterator i = attrNames.begin(); i != attrNames.end(); ++i)
  {
    std::string        attrName = *i;
    BSONObj            attr     = getField(attrs, attrName).embeddedObject();
    ContextAttribute*  caP      = NULL;
    ContextAttribute   ca;

    // Name and type
    ca.name           = dbDotDecode(basePart(attrName));
    std::string mdId  = idPart(attrName);
    ca.type           = getStringField(attr, ENT_ATTRS_TYPE);

    // Skip attribute if the attribute is in the list (or attrL is empty)
    if (!includedAttribute(ca, attrL))
    {
      continue;
    }

    /* It could happen (although very rarely) that the value field is missing in the
     * DB for the attribute. The following is a safety check measure to protect against that */
    if (!attr.hasField(ENT_ATTRS_VALUE))
    {
      caP = new ContextAttribute(ca.name, ca.type, "");
    }
    else
    {
      switch(getField(attr, ENT_ATTRS_VALUE).type())
      {
      case String:
        ca.stringValue = getStringField(attr, ENT_ATTRS_VALUE);
        if (!includeEmpty && ca.stringValue.length() == 0)
        {
          continue;
        }
        caP = new ContextAttribute(ca.name, ca.type, ca.stringValue);
        break;

      case NumberDouble:
        ca.numberValue = getField(attr, ENT_ATTRS_VALUE).Number();
        caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
        break;

      case NumberInt:
        ca.numberValue = (double) getIntField(attr, ENT_ATTRS_VALUE);
        caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
        break;

      case Bool:
        ca.boolValue = getBoolField(attr, ENT_ATTRS_VALUE);
        caP = new ContextAttribute(ca.name, ca.type, ca.boolValue);
        break;

      case jstNULL:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->valueType = orion::ValueTypeNone;
        break;

      case Object:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeObject);
        compoundObjectResponse(caP->compoundValueP, getField(attr, ENT_ATTRS_VALUE));
        break;

      case Array:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeVector);
        compoundVectorResponse(caP->compoundValueP, getField(attr, ENT_ATTRS_VALUE));
        break;

      default:
        LM_E(("Runtime Error (unknown attribute value type in DB: %d)", getField(attr, ENT_ATTRS_VALUE).type()));
      }
    }

    /* Setting ID (if found) */
    if (mdId != "")
    {
      Metadata* md = new Metadata(NGSI_MD_ID, "string", mdId);
      caP->metadataVector.push_back(md);
    }

    /* Setting location metatda (if found) */
    if (locAttr == ca.name)
    {
      Metadata* md = new Metadata(NGSI_MD_LOCATION, "string", LOCATION_WGS84);
      caP->metadataVector.push_back(md);
    }

    /* Setting custom metadata (if any) */
    if (attr.hasField(ENT_ATTRS_MD))
    {
      std::vector<BSONElement> metadataV = getField(attr, ENT_ATTRS_MD).Array();

      for (unsigned int ix = 0; ix < metadataV.size(); ++ix)
      {
        Metadata* md = new Metadata(metadataV[ix].embeddedObject());
        caP->metadataVector.push_back(md);
      }
    }

    contextElement.contextAttributeVector.push_back(caP);
  }
}
Exemplo n.º 10
0
/* ****************************************************************************
*
* ContextElementResponse::ContextElementResponse -
*
* This constructor builds the CER object based in a BSON object taken from the
* entities collection at DB.
*
* Note that statusCode is not touched by this constructor.
*/
ContextElementResponse::ContextElementResponse
(
  const mongo::BSONObj&  entityDoc,
  const AttributeList&   attrL,
  bool                   includeEmpty,
  const std::string&     apiVersion
)
{
  prune = false;

  // Entity
  BSONObj id = getFieldF(entityDoc, "_id").embeddedObject();

  std::string entityId   = getStringFieldF(id, ENT_ENTITY_ID);
  std::string entityType = id.hasField(ENT_ENTITY_TYPE) ? getStringFieldF(id, ENT_ENTITY_TYPE) : "";

  contextElement.entityId.fill(entityId, entityType, "false");
  contextElement.entityId.servicePath = id.hasField(ENT_SERVICE_PATH) ? getStringFieldF(id, ENT_SERVICE_PATH) : "";

  /* Get the location attribute (if it exists) */
  std::string locAttr;
  if (entityDoc.hasElement(ENT_LOCATION))
  {
    locAttr = getStringFieldF(getObjectFieldF(entityDoc, ENT_LOCATION), ENT_LOCATION_ATTRNAME);
  }


  //
  // Attribute vector
  // FIXME P5: constructor for BSONObj could be added to ContextAttributeVector/ContextAttribute classes, to make building more modular
  //
  BSONObj                attrs = getObjectFieldF(entityDoc, ENT_ATTRS);
  std::set<std::string>  attrNames;

  attrs.getFieldNames(attrNames);
  for (std::set<std::string>::iterator i = attrNames.begin(); i != attrNames.end(); ++i)
  {
    std::string        attrName = *i;
    BSONObj            attr     = getObjectFieldF(attrs, attrName);
    ContextAttribute*  caP      = NULL;
    ContextAttribute   ca;

    // Name and type
    ca.name           = dbDotDecode(basePart(attrName));
    std::string mdId  = idPart(attrName);
    ca.type           = getStringFieldF(attr, ENT_ATTRS_TYPE);

    // Skip attribute if the attribute is in the list (or attrL is empty or includes "*")
    if (!includedAttribute(ca, attrL))
    {
      continue;
    }

    /* It could happen (although very rarely) that the value field is missing in the
     * DB for the attribute. The following is a safety check measure to protect against that */
    if (!attr.hasField(ENT_ATTRS_VALUE))
    {
      caP = new ContextAttribute(ca.name, ca.type, "");
    }
    else
    {
      switch(getFieldF(attr, ENT_ATTRS_VALUE).type())
      {
      case String:
        ca.stringValue = getStringFieldF(attr, ENT_ATTRS_VALUE);
        if (!includeEmpty && ca.stringValue.length() == 0)
        {
          continue;
        }
        caP = new ContextAttribute(ca.name, ca.type, ca.stringValue);
        break;

      case NumberDouble:
        ca.numberValue = getNumberFieldF(attr, ENT_ATTRS_VALUE);
        caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
        break;

      case NumberInt:
        ca.numberValue = (double) getIntFieldF(attr, ENT_ATTRS_VALUE);
        caP = new ContextAttribute(ca.name, ca.type, ca.numberValue);
        break;

      case Bool:
        ca.boolValue = getBoolFieldF(attr, ENT_ATTRS_VALUE);
        caP = new ContextAttribute(ca.name, ca.type, ca.boolValue);
        break;

      case jstNULL:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->valueType = orion::ValueTypeNone;
        break;

      case Object:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeObject);
        caP->valueType = orion::ValueTypeObject;
        compoundObjectResponse(caP->compoundValueP, getFieldF(attr, ENT_ATTRS_VALUE));
        break;

      case Array:
        caP = new ContextAttribute(ca.name, ca.type, "");
        caP->compoundValueP = new orion::CompoundValueNode(orion::ValueTypeVector);
        // FIXME P7: next line is counterintuitive. If the object is a vector, why
        // we need to use ValueTypeObject here? Because otherwise Metadata::toJson()
        // method doesn't work. A littely crazy... it should be fixed.
        caP->valueType = orion::ValueTypeObject;
        compoundVectorResponse(caP->compoundValueP, getFieldF(attr, ENT_ATTRS_VALUE));
        break;

      default:
        LM_E(("Runtime Error (unknown attribute value type in DB: %d)", getFieldF(attr, ENT_ATTRS_VALUE).type()));
      }
    }

    /* Setting ID (if found) */
    if (mdId != "")
    {
      Metadata* md = new Metadata(NGSI_MD_ID, "string", mdId);
      caP->metadataVector.push_back(md);
    }

    if (apiVersion == "v1")
    {
      /* Setting location metadata (if found) */
      if ((locAttr == ca.name) && (ca.type != GEO_POINT))
      {
        /* Note that if attribute type is geo:point then the user is using the "new way"
         * of locating entities in NGSIv1, thus location metadata is not rendered */
        Metadata* md = new Metadata(NGSI_MD_LOCATION, "string", LOCATION_WGS84);
        caP->metadataVector.push_back(md);
      }
    }

    /* Setting custom metadata (if any) */
    if (attr.hasField(ENT_ATTRS_MD))
    {
      BSONObj                mds = getObjectFieldF(attr, ENT_ATTRS_MD);
      std::set<std::string>  mdsSet;

      mds.getFieldNames(mdsSet);
      for (std::set<std::string>::iterator i = mdsSet.begin(); i != mdsSet.end(); ++i)
      {
        std::string currentMd = *i;
        Metadata*   md = new Metadata(dbDotDecode(currentMd), getObjectFieldF(mds, currentMd));
        caP->metadataVector.push_back(md);
      }
    }

    /* Set creDate and modDate at attribute level */
    if (attr.hasField(ENT_ATTRS_CREATION_DATE))
    {
      caP->creDate = (double) getIntOrLongFieldAsLongF(attr, ENT_ATTRS_CREATION_DATE);
    }

    if (attr.hasField(ENT_ATTRS_MODIFICATION_DATE))
    {
      caP->modDate = (double) getIntOrLongFieldAsLongF(attr, ENT_ATTRS_MODIFICATION_DATE);
    }

    contextElement.contextAttributeVector.push_back(caP);
  }

  /* Set creDate and modDate at entity level */
  if (entityDoc.hasField(ENT_CREATION_DATE))
  {
    contextElement.entityId.creDate = (double) getIntOrLongFieldAsLongF(entityDoc, ENT_CREATION_DATE);
  }

  if (entityDoc.hasField(ENT_MODIFICATION_DATE))
  {
    contextElement.entityId.modDate = (double) getIntOrLongFieldAsLongF(entityDoc, ENT_MODIFICATION_DATE);
  }
}
Exemplo n.º 11
0
    QueryPlan::QueryPlan( const FieldBoundSet &fbs, const BSONObj &order, const IndexDetails *index ) :
    fbs_( fbs ),
    order_( order ),
    index_( index ),
    optimal_( false ),
    scanAndOrderRequired_( true ),
    keyMatch_( false ),
    exactKeyMatch_( false ),
    direction_( 0 ),
    unhelpful_( false ) {
        // full table scan case
        if ( !index_ ) {
            if ( order_.isEmpty() || !strcmp( order_.firstElement().fieldName(), "$natural" ) )
                scanAndOrderRequired_ = false;
            return;
        }

        BSONObj idxKey = index->keyPattern();
        BSONObjIterator o( order );
        BSONObjIterator k( idxKey );
        if ( !o.more() )
            scanAndOrderRequired_ = false;
        while( o.more() ) {
            BSONElement oe = o.next();
            if ( oe.eoo() ) {
                scanAndOrderRequired_ = false;
                break;
            }
            if ( !k.more() )
                break;
            BSONElement ke;
            while( 1 ) {
                ke = k.next();
                if ( ke.eoo() )
                    goto doneCheckOrder;
                if ( strcmp( oe.fieldName(), ke.fieldName() ) == 0 )
                    break;
                if ( !fbs.bound( ke.fieldName() ).equality() )
                    goto doneCheckOrder;
            }
            int d = oe.number() == ke.number() ? 1 : -1;
            if ( direction_ == 0 )
                direction_ = d;
            else if ( direction_ != d )
                break;
        }
    doneCheckOrder:
        if ( scanAndOrderRequired_ )
            direction_ = 0;
        BSONObjIterator i( idxKey );
        int indexedQueryCount = 0;
        int exactIndexedQueryCount = 0;
        int optimalIndexedQueryCount = 0;
        bool stillOptimalIndexedQueryCount = true;
        set< string > orderFieldsUnindexed;
        order.getFieldNames( orderFieldsUnindexed );
        BSONObjBuilder startKeyBuilder;
        BSONObjBuilder endKeyBuilder;
        while( i.more() ) {
            BSONElement e = i.next();
            if ( e.eoo() )
                break;
            const FieldBound &fb = fbs.bound( e.fieldName() );
            int number = (int) e.number(); // returns 0.0 if not numeric
            bool forward = ( ( number >= 0 ? 1 : -1 ) * ( direction_ >= 0 ? 1 : -1 ) > 0 );
            startKeyBuilder.appendAs( forward ? fb.lower() : fb.upper(), "" );
            endKeyBuilder.appendAs( forward ? fb.upper() : fb.lower(), "" );
            if ( fb.nontrivial() )
                ++indexedQueryCount;
            if ( stillOptimalIndexedQueryCount ) {
                if ( fb.nontrivial() )
                    ++optimalIndexedQueryCount;
                if ( !fb.equality() )
                    stillOptimalIndexedQueryCount = false;
            } else {
                if ( fb.nontrivial() )
                    optimalIndexedQueryCount = -1;
            }
            if ( fb.equality() ) {
                BSONElement e = fb.upper();
                if ( !e.isNumber() && !e.mayEncapsulate() && e.type() != RegEx )
                    ++exactIndexedQueryCount;
            }
            orderFieldsUnindexed.erase( e.fieldName() );
        }
        if ( !scanAndOrderRequired_ &&
             ( optimalIndexedQueryCount == fbs.nNontrivialBounds() ) )
            optimal_ = true;
        if ( indexedQueryCount == fbs.nNontrivialBounds() &&
            orderFieldsUnindexed.size() == 0 ) {
            keyMatch_ = true;
            if ( exactIndexedQueryCount == fbs.nNontrivialBounds() )
                exactKeyMatch_ = true;
        }
        startKey_ = startKeyBuilder.obj();
        endKey_ = endKeyBuilder.obj();
        if ( !keyMatch_ &&
            ( scanAndOrderRequired_ || order_.isEmpty() ) &&
            !fbs.bound( idxKey.firstElement().fieldName() ).nontrivial() )
            unhelpful_ = true;
    }