コード例 #1
0
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);
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: bplusindexp.cpp プロジェクト: FikiHafana/djondb
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;
}
コード例 #4
0
ファイル: dbcontroller.cpp プロジェクト: FikiHafana/djondb
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;
}
コード例 #5
0
ファイル: unaryexpression.cpp プロジェクト: FikiHafana/djondb
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;
}
コード例 #6
0
ファイル: bplusindex.cpp プロジェクト: FikiHafana/djondb
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;
}
コード例 #7
0
ファイル: dbcontroller.cpp プロジェクト: FikiHafana/djondb
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;
}