ExpressionResult* evalEqual(const BSONObj& bson, BaseExpression* left, BaseExpression* right) { ExpressionResult* valLeft = left->eval(bson); ExpressionResult* valRight= right->eval(bson); bool result = false; if (valLeft->type() != valRight->type()) { result = false; } else if (((valLeft->type() != ExpressionResult::RT_NULL) && (valRight->type() == ExpressionResult::RT_NULL)) || ((valLeft->type() == ExpressionResult::RT_NULL) && (valRight->type() != ExpressionResult::RT_NULL))) { result = false; } else { // the types are ensured to be equal switch (valLeft->type()) { case ExpressionResult::RT_INT: result = ((__int32)*valLeft == (__int32)*valRight); break; case ExpressionResult::RT_LONG: case ExpressionResult::RT_LONG64: result = ((__int64)*valLeft == (__int64)*valRight); break; case ExpressionResult::RT_DOUBLE: result = ((double)*valLeft == (double)*valRight); break; case ExpressionResult::RT_BOOLEAN: result = ((bool)*valLeft == (bool)*valRight); break; case ExpressionResult::RT_PTRCHAR: { result = ((djondb::string)*valLeft == (djondb::string)*valRight); break; } break; case ExpressionResult::RT_STRINGDB: { std::string leftS = *valLeft; std::string rightS = *valRight; result = (leftS.compare(rightS) == 0); } break; case ExpressionResult::RT_BSON: { BSONObj* bleft = (BSONObj*)*valLeft; BSONObj* bright = (BSONObj*)*valRight; result = (*bleft == *bright); break; } } } delete valLeft; delete valRight; return new ExpressionResult(result); }
ExpressionResult* evalComparison(const BSONObj& bson, const FILTER_OPERATORS& oper, BaseExpression* left, BaseExpression* right) { ExpressionResult* valLeft = left->eval(bson); ExpressionResult* valRight= right->eval(bson); if (valLeft->type() != valRight->type()) { // ERROR types does not match delete valLeft; delete valRight; return new ExpressionResult(false); } bool resultGreather = false; // this will compare only greather than, and at the end will invert // based on the sign if ((valLeft->type() != ExpressionResult::RT_NULL) && (valRight->type() == ExpressionResult::RT_NULL)) { resultGreather = true; } else if (((valLeft->type() == ExpressionResult::RT_NULL) && (valRight->type() != ExpressionResult::RT_NULL))) { resultGreather = false; } else { switch (valLeft->type()) { case ExpressionResult::RT_INT: resultGreather = ((__int32)*valLeft > (__int32)*valRight); break; case ExpressionResult::RT_LONG: case ExpressionResult::RT_LONG64: resultGreather = ((__int64)*valLeft > (__int64)*valRight); break; case ExpressionResult::RT_DOUBLE: resultGreather = ((double)*valLeft > (double)*valRight); break; } } ExpressionResult* result = NULL; if ((!resultGreather && (oper == FO_GREATEREQUALTHAN)) || (resultGreather && (oper == FO_LESSEQUALTHAN))) { result = evalEqual(bson, left, right); } else { bool bres; if ((oper == FO_LESSTHAN) || (oper == FO_LESSEQUALTHAN)) { bres = !resultGreather; }else { bres = resultGreather; } result = new ExpressionResult(bres); } delete valLeft; delete valRight; return result; }
std::list<Index*> IndexPage::find(BufferManager* manager, FilterParser* parser) { if (!isLoaded()) { loadPage(manager); } std::list<Index*> result; for (int x = 0; x < size; x++) { BSONObj* key = elements[x]->key; if (key->getString("_id").compare("c597-43e1-ae9b-6f5451b28295") == 0) { cout << "Hey!" << endl; } bool match = false; ExpressionResult* expresult = parser->eval(*key); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { result.push_back(elements[x]); } } for (int x = 0; x <= size; x++) { IndexPage* innerPage = pointers[x]; if (innerPage != NULL) { std::list<Index*> inner = innerPage->find(manager, parser); result.insert(result.begin(), inner.begin(), inner.end()); } } return result; }
BSONObj* DBController::findFirst(const char* db, const char* ns, const char* select, const char* filter, const BSONObj* options) throw(ParseException) { if (_logger->isDebug()) _logger->debug(2, "DBController::findFirst db: %s, ns: %s, select: %s, filter: %s", db, ns, select, filter); std::string filedir = _dataDir + db; filedir = filedir + FILESEPARATOR; std::stringstream ss; ss << filedir << ns << ".dat"; std::string filename = ss.str(); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); MMapInputStream* mmis = new MMapInputStream(filename.c_str(), 0); DBFileInputStream* dbStream = new DBFileInputStream(mmis); BSONArrayObj result; BSONInputStream* bis = new BSONInputStream(mmis); FilterParser* parser = FilterParser::parse(filter); BSONBufferedObj* obj = NULL; BSONObj* bsonResult = NULL; mmis->seek(29); while (!mmis->eof()) { if (obj == NULL) { obj = new BSONBufferedObj(mmis->pointer(), mmis->length() - mmis->currentPos()); } else { obj->reset(mmis->pointer(), mmis->length() - mmis->currentPos()); } mmis->seek(mmis->currentPos() + obj->bufferLength()); // Only "active" Records if (obj->getInt("_status") == 1) { ExpressionResult* result = parser->eval(*obj); if (result->type() == ExpressionResult::RT_BOOLEAN) { bool bres = *result; if (bres) { bsonResult = obj->select(select); break; } } delete result; } if (bsonResult) { break; } } if (obj != NULL) delete obj; dbStream->close(); delete dbStream; mmis->close(); delete mmis; delete parser; delete bis; return bsonResult; }
ExpressionResult* not_expression(BaseExpression* expression, const BSONObj& bson) { ExpressionResult* tmpresult = expression->eval(bson); ExpressionResult* result = NULL; if (tmpresult->type() == ExpressionResult::RT_BOOLEAN) { bool bres = *tmpresult; result = new ExpressionResult(!bres); } else { throw ParseException(D_ERROR_PARSEERROR, "Exists signature is wrong. Use Exists($'field')."); } delete tmpresult; return result; }
std::list<Index*> IndexPage::find(FilterParser* parser) const { std::list<Index*> result; for (int x = 0; x < size; x++) { BSONObj* key = elements[x]->key; bool match = false; ExpressionResult* expresult = parser->eval(*key); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { result.push_back(elements[x]); } } for (int x = 0; x <= size; x++) { IndexPage* innerPage = pointers[x]; if (innerPage != NULL) { std::list<Index*> inner = innerPage->find(parser); result.insert(result.begin(), inner.begin(), inner.end()); } } return result; }
BSONArrayObj* DBController::findFullScan(const char* db, const char* ns, const char* select, FilterParser* parser, const BSONObj* options) throw(ParseException) { if (_logger->isDebug()) _logger->debug(2, "DBController::findFullScan with parser db: %s, ns: %s", db, ns); std::string filedir = _dataDir + db; filedir = filedir + FILESEPARATOR; std::stringstream ss; ss << filedir << ns << ".dat"; std::string filename = ss.str(); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, INDEX_FTYPE); // Execute open on streammanager, just to check that the file was alrady opened StreamManager::getStreamManager()->open(db, ns, DATA_FTYPE); //FileInputStream* fis = new FileInputStream(filename.c_str(), "rb"); MMapInputStream* mmis = new MMapInputStream(filename.c_str(), 0); DBFileInputStream* dbStream = new DBFileInputStream(mmis); BSONArrayObj* result = new BSONArrayObj(); BSONInputStream* bis = new BSONInputStream(dbStream); std::set<std::string> tokens = parser->xpathTokens(); std::string filterSelect; if ((strcmp(select, "*") != 0) && (tokens.size() > 0)) { // this will reserve enough space to concat the filter tokens filterSelect.reserve(tokens.size() * 100); filterSelect.append("$'_status'"); for (std::set<std::string>::iterator i = tokens.begin(); i != tokens.end(); i++) { std::string token = *i; filterSelect.append(", "); filterSelect.append("$'"); filterSelect.append(token); filterSelect.append("'"); } } else { filterSelect = "*"; } mmis->seek(29); BSONBufferedObj* obj = NULL; __int64 maxResults = 3000; if ((options != NULL) && options->has("limit")) { BSONContent* content = options->getContent("limit"); if (content->type() == INT_TYPE) { maxResults = options->getInt("limit"); } else if (content->type() == LONG_TYPE) { maxResults = options->getLong("limit"); } } else { std::string smax = getSetting("max_results"); if (smax.length() > 0) { #ifdef WINDOWS maxResults = _atoi64(smax.c_str()); #else maxResults = atoll(smax.c_str()); #endif } } __int64 count = 0; while (!mmis->eof() && (count < maxResults)) { if (obj == NULL) { obj = new BSONBufferedObj(mmis->pointer(), mmis->length() - mmis->currentPos()); } else { obj->reset(mmis->pointer(), mmis->length() - mmis->currentPos()); } mmis->seek(mmis->currentPos() + obj->bufferLength()); // Only "active" Records if (obj->getInt("_status") == 1) { bool match = false; ExpressionResult* expresult = parser->eval(*obj); if (expresult->type() == ExpressionResult::RT_BOOLEAN) { match = *expresult; } delete expresult; if (match) { BSONObj* objSubselect = obj->select(select); result->add(*objSubselect); delete objSubselect; count++; } } } if (obj != NULL) delete obj; delete bis; dbStream->close(); delete dbStream; return result; }