예제 #1
0
BSONObj* DjondbConnection::findByKey(const char* db, const char* ns, const char* select, const char* id) {
	if (_logger->isDebug()) _logger->debug("executing findByKey db: %s, ns: %s, select: %s, id: %s", db, ns, select, id);

	if (!isOpen()) {
		throw DjondbException(D_ERROR_CONNECTION, "Not connected to any server");
	}
	std::string filter = format("$'_id' == '%s'", id);

	BSONArrayObj* result = find(const_cast<char*>(db), const_cast<char*>(ns), const_cast<char*>(select), const_cast<char*>(filter.c_str()));

	BSONObj* res = NULL;
	if (result->length() == 1) {
		if (_logger->isDebug()) _logger->debug(2, "findByKey found 1 result");
		res = *result->begin();
	} else {
		if (result->length() > 1) {
			throw DjondbException(D_ERROR_TOO_MANY_RESULTS, "The result contains more than 1 result");
		}
	}
   BSONObj* bsonresult = NULL;
	if (res != NULL) {
		// creates a copy of the result before deleting the temporal objects
		bsonresult = new BSONObj(*res);
	}

	delete result;
	return bsonresult;
}
예제 #2
0
파일: main.cpp 프로젝트: chiehwen/djondb
		void testParserArray()
		{
			cout << "testParserArray" << endl;

			BSONArrayObj* array = BSONParser::parseArray("[{age: 1, name: 'John', salary: 3500.25, rel1: {innertext: 'inner text'}}, {age: 2, name: 'John2', salary: 23500.25, rel1: {innertext: 'inner text2'}}]");
			TEST_ASSERT(array != NULL);
			TEST_ASSERT(array->length() == 2);

			BSONObj* obj = array->get(0);
			TEST_ASSERT(obj != NULL);
			TEST_ASSERT(obj->has("age"));
			TEST_ASSERT(obj->getInt("age") == 1);
			TEST_ASSERT(obj->has("name"));
			TEST_ASSERT(strcmp(obj->getString("name"), "John") == 0);

			TEST_ASSERT(obj->has("salary"));
			TEST_ASSERT(obj->getDouble("salary") == 3500.25);

			TEST_ASSERT(obj->getBSON("rel1") != NULL);
			TEST_ASSERT(strcmp(obj->getBSON("rel1")->getString("innertext"), "inner text") == 0);

			BSONArrayObj::iterator i = array->begin();
			TEST_ASSERT(i != array->end());
			delete array;
		}
예제 #3
0
		void testFind(int port, int top = 10000000) {
			DjondbConnection* conn = DjondbConnectionManager::getConnection("localhost", port);

			if (!conn->open()) {
				cout << "Not connected" << endl;
				exit(0);
			}

			Logger* log = getLogger(NULL);

			log->startTimeRecord();
			log->info("Testing find performance over: %d finds.", top);
			for (int x = 0; x < top; x++) {
				BSONArrayObj* arr = conn->executeQuery("select top 1 * from db:testperformance");
				if (arr->length() == 0) {
					log->info("Error an id was not found");
					exit(1);
				}
				delete arr;
			}
			log->stopTimeRecord();

			DTime time = log->recordedTime();

			cout << "Total find secs: " << time.totalSecs() << endl;
			if (time.totalSecs() > 0) {
				log->info("Found %d: throughtput: %d.", top, (top / time.totalSecs()));
			} else {
				log->info("Found :%d, throughtput too high to be measured", top);
			}
			if ((time.totalSecs() > 0) && ((top / time.totalSecs()) < 16000))  {
				log->info("Performance is not good enough");
			}
		}
예제 #4
0
파일: shell.cpp 프로젝트: chiehwen/djondb
v8::Handle<v8::Value> find(const v8::Arguments& args) {
	if (args.Length() < 2) {
		return v8::ThrowException(v8::String::New("usage: db.find(db, namespace)\ndb.find(db, namespace, filter)\ndb.find(db, namespace, select, filter)"));
	}

	if (__djonConnection == NULL) {
		return v8::ThrowException(v8::String::New("You're not connected to any db, please use: connect(server, [port])"));
	}
	v8::HandleScope handle_scope;
	v8::String::Utf8Value strDB(args[0]);
	std::string db = ToCString(strDB);
	v8::String::Utf8Value str(args[1]);
	std::string ns = ToCString(str);
	std::string select = "*";
	std::string filter = "";
	if (args.Length() == 3) {
		v8::String::Utf8Value strFilter(args[2]);
		filter = ToCString(strFilter);
	}
	if (args.Length() == 4) {
		v8::String::Utf8Value strSelect(args[2]);
		select = ToCString(strSelect);
		v8::String::Utf8Value strFilter(args[3]);
		filter = ToCString(strFilter);
	}
	/* 
		std::string json;
		if (args[2]->IsObject()) {
		json = toJson(args[2]->ToObject());
		} else {
		json = ToCString(v8::String::Utf8Value(args[2]));
		}
		*/

	try {
		BSONArrayObj* result = __djonConnection->find(db, ns, select, filter);

		char* str = result->toChar();

		v8::Handle<v8::Value> jsonValue = parseJSON(v8::String::New(str));
		free(str);
		delete result;
		return jsonValue;
	} catch (ParseException e) {
		return v8::ThrowException(v8::String::New("the filter expression contains an error\n"));
	}
	/* 
		v8::Handle<v8::Context> context = v8::Context::GetCurrent();
		v8::Handle<v8::Object> global = context->Global();

		v8::Handle<v8::Object> objresult = global->Get(v8::String::New(sresult.c_str()))->ToObject();


		return objresult;
	//return v8::String::New(sresult.c_str());
	*/
}
예제 #5
0
BSONArrayObj* DBController::find(const char* db, const char* ns, const char* select, const char* filter, const BSONObj* options) throw(ParseException) {
	if (_logger->isDebug()) _logger->debug(2, "DBController::find db: %s, ns: %s, select: %s, filter: %s", db, ns, select, filter);

	BSONArrayObj* result;

	FilterParser* parser = FilterParser::parse(filter);

	std::set<std::string> tokens = parser->tokens();

	if (IndexFactory::indexFactory.containsIndex(db, ns, tokens)) {
		IndexAlgorithm* impl = IndexFactory::indexFactory.index(db, ns, tokens);

		std::list<Index*> elements = impl->find(parser);

		std::string filedir = _dataDir + db;
		filedir = filedir + FILESEPARATOR;

		std::stringstream ss;
		ss << filedir << ns << ".dat";

		std::string filename = ss.str();
		result = new BSONArrayObj();
		FileInputStream* fis = new FileInputStream(filename.c_str(), "rb");
		DBFileInputStream* dbStream = new DBFileInputStream(fis);

		BSONInputStream* bis = new BSONInputStream(dbStream);
		for (std::list<Index*>::iterator it = elements.begin(); it != elements.end(); it++) {
			Index* index = *it;

			long posData = index->posData;
			dbStream->seek(posData);

			BSONObj* obj = bis->readBSON(select);

			result->add(*obj);

			delete obj;
		}
		delete bis;
		delete dbStream;

	} else {
		result = findFullScan(db, ns, select, parser, options);
	}

	delete parser;
	return result;
}
예제 #6
0
파일: main.cpp 프로젝트: chiehwen/djondb
		void testXPath() {
			cout << "testXPath" << endl;

			BSONObj* obj1 = BSONParser::parse("{ name: 'John', age: 35, one: { data: 1 }, children: [ { name: 'Joshua', age: 15}, { name: 'Mary', age: 30}] }");

			__int32 age = *obj1->getXpath("age");

			TEST_ASSERT(age == 35);

			BSONArrayObj* children = *obj1->getXpath("children");
			TEST_ASSERT(children->length() == 2);

			__int32 data = *obj1->getXpath("one.data");
			TEST_ASSERT(data == 1);

			delete obj1;
		}
예제 #7
0
void testTransactionMergedData()
{
	printf("%s\n", "testTransactionMergedData");
	BaseTransaction* tx = new BaseTransaction(_controller);
	tx->dropNamespace("db", "testcommit");

	BSONObj ooutTX;
	std::string* idOut = uuid();
	ooutTX.add("_id", const_cast<char*>(idOut->c_str()));
	ooutTX.add("name", "JohnOut");
	tx->insert("db", "testcommit", &ooutTX);

	// Insert out of the transaction
	std::string* tuid = uuid();
	StdTransaction* stx = new StdTransaction(tx, *tuid);

	BSONObj o;
	std::string* id = uuid();
	o.add("_id", const_cast<char*>(id->c_str()));
	o.add("name", "John");
	stx->insert("db", "testcommit", &o);

	BSONArrayObj* res = stx->find("db", "testcommit", "*", "");
	TEST_ASSERT(res->length() == 2);

	BSONArrayObj* resOut = tx->find("db", "testcommit", "*", "");
	TEST_ASSERT(resOut->length() == 1);

	stx->commit();
	delete stx;

	BSONArrayObj* resOut2 = tx->find("db", "testcommit", "*", "");
	TEST_ASSERT(resOut2->length() == 2);

	delete tx;
	delete res;
	delete resOut;
	delete resOut2;
	delete tuid;
	printf("%s\n", "~testTransactionMergedData");
}
예제 #8
0
파일: main.cpp 프로젝트: chiehwen/djondb
		void testCopyBSON()
		{
			cout << "testCopyBSON" << endl;

			BSONObj* objOrig = new BSONObj();
			// Add in
			objOrig->add("int", 1);
			objOrig->add("string", (char*)"test");
			objOrig->add("long", (__int64)1L);
			objOrig->add("double", 1.1);

			BSONObj rel;
			rel.add("innertext", (char*)"inner text");
			objOrig->add("rel1", rel);

			BSONArrayObj array;
			BSONObj b1;
			b1.add("b1", "test");
			array.add(b1);
			BSONObj b2;
			b2.add("b1", "test2");
			array.add(b2);
			objOrig->add("array", array);

			BSONObj* obj = new BSONObj(*objOrig);
			delete objOrig;
			objOrig = NULL;

			TEST_ASSERT(obj->has("int"));
			TEST_ASSERT(obj->getInt("int") == 1);

			TEST_ASSERT(strcmp(obj->getString("string"), "test") == 0);

			TEST_ASSERT(obj->has("long"));
			TEST_ASSERT(obj->getLong("long") == 1L);

			TEST_ASSERT(obj->has("double"));
			TEST_ASSERT(obj->getDouble("double") == 1.1);

			BSONObj* temp = obj->getBSON("rel1");
			TEST_ASSERT(temp != NULL);
			TEST_ASSERT(strcmp(obj->getBSON("rel1")->getString("innertext"), "inner text") == 0);

			TEST_ASSERT(obj->getBSONArray("array") != NULL);
			BSONArrayObj* arrayR = obj->getBSONArray("array");
			TEST_ASSERT(arrayR != NULL);
			TEST_ASSERT(arrayR->length() == 2);

			BSONObj* el1 = arrayR->get(0);
			TEST_ASSERT(el1 != NULL);

			BSONObj* el2 = arrayR->get(1);
			TEST_ASSERT(el2 != NULL);
			delete obj;
		}
예제 #9
0
BSONArrayObj* BSONParser::parseArray(const char* chrs, __int32& pos) {
    BSONArrayObj* result = NULL;
    while (chrs[pos] == ' ') {
        pos++;
    }
    if (chrs[pos] != '[') {
        // error
    } else {
        result = new BSONArrayObj();
    }

    while ((pos < strlen(chrs)) && (chrs[pos] != ']')) {
        while ((pos < strlen(chrs)) && (chrs[pos] != ']') && (chrs[pos] != '{'))
            pos++;
        if (chrs[pos] == '{') {
            BSONObj* bson = parseBSON(chrs, pos);
            result->add(*bson);
            delete bson;
        }
    }
    return result;
}
예제 #10
0
void testTransaction()
{
	printf("%s\n", "testTransaction");
	DummyController* controller = new DummyController();

	BaseTransaction* tx = new BaseTransaction(controller);

	tx->dropNamespace("db", "txns");

	BSONObj o;
	std::string* id = uuid();
	o.add("_id", const_cast<char*>(id->c_str()));
	o.add("name", "John");
	tx->insert("db", "txns", &o);

	BSONArrayObj* res = tx->find("db", "txns", "*", "");

	TEST_ASSERT(res->length() == 1);
	BSONObj* test1 = *res->begin();
	TEST_ASSERT(test1->getString("name").compare("John") == 0);
	test1->add("name", "Peter");
	tx->update("db", "txns", test1);

	delete res;

	res = tx->find("db", "txns", "*", "");

	TEST_ASSERT(res->length() == 1);
	BSONObj* test2 = *res->begin();
	TEST_ASSERT(test2->getString("name").compare("Peter") == 0);

	delete res;
	printf("%s\n", "Deleting tx");
	delete tx;
	delete controller;
	delete id;
	printf("%s\n", "~testTransaction");
}
예제 #11
0
BSONObj* BSONObj::select(const char* sel) const {
	std::set<std::string> columns = bson_splitSelect(sel);
	bool include_all = (strcmp(sel, "*") == 0);

	BSONObj* result = new BSONObj();

	for (std::map<std::string, BSONContent* >::const_iterator i = this->_elements.begin(); i != this->_elements.end(); i++) {
		std::string key = i->first;
		if (include_all || (columns.find(key) != columns.end())) {
			BSONContent* origContent = i->second;

			switch (origContent->type()) {
				case BSON_TYPE:  
					{
						BSONContentBSON* bbson = (BSONContentBSON*)origContent;
						BSONObj* inner = (BSONObj*)*bbson;

						if (!include_all) {
							char* subselect = bson_subselect(sel, key.c_str());
							BSONObj* innerSubSelect = inner->select(subselect);
							result->add(key, *innerSubSelect);
							delete innerSubSelect;
						} else {
							result->add(key, *inner);
						}
						break;
					}
				case BSONARRAY_TYPE: 
					{
						BSONContentBSONArray* bbsonarray = (BSONContentBSONArray*)origContent;
						BSONArrayObj* innerArray = (BSONArrayObj*)*bbsonarray;
						if (!include_all) {
							char* subselect = bson_subselect(sel, key.c_str());
							BSONArrayObj* innerSubArray = innerArray->select(subselect);
							result->add(key, *innerSubArray);
							delete innerSubArray;
						} else {
							result->add(key, *innerArray);
						}
						break;
					}
				case BOOL_TYPE: 
					{
						BSONContentBoolean* bb = (BSONContentBoolean*)origContent;
						bool val = *bb;
						result->add(key, val);
						break;
					}
				case INT_TYPE: 
					{
						BSONContentInt* bint = (BSONContentInt*)origContent;
						__int32 val = *bint;
						result->add(key, val);
						break;
					}
				case LONG_TYPE:
					{
						BSONContentLong* blong = (BSONContentLong*)origContent;
						__int64 val = *blong;
						result->add(key, val);
						break;
					}
				case DOUBLE_TYPE:
					{
						BSONContentDouble* bdouble = (BSONContentDouble*)origContent;
						double val = *bdouble;
						result->add(key, val);
						break;
					}
				case PTRCHAR_TYPE:
				case STRING_TYPE:
					{
						BSONContentString* bstring = (BSONContentString*)origContent;
						djondb::string str = *bstring;
						const char* val = str.c_str();
						__int32 len = str.length();
						result->add(key, const_cast<char*>(val), len);
						break;
					}
			}
		}
	}
	return result;
}
예제 #12
0
char* BSONObj::toChar() {
	// if the toChar was already calculated before use it
	if (_cBSON != NULL) {
		return strcpy(_cBSON);
	}

	Logger* log = getLogger(NULL);
	
	char* result = (char*)malloc(MAX_BSONOBJ_BUFFER);
	memset(result, 0, MAX_BSONOBJ_BUFFER);

	__int32 pos = 0;
	result[0] = '{';
	pos += 1;

	bool first = true;
	
	for (std::map<std::string, BSONContent* >::const_iterator i = _elements.begin(); i != _elements.end(); i++) {
		if (!first) {
			result[pos] = ',';
			pos++;
		}
		first = false;
		BSONContent* content = i->second;
		std::string key = i->first;
		sprintf(result + pos, " \"%s\" : ", key.c_str());
		pos += key.length() + 6;
		//ss << "\"" << key << "\" :";
		char* chr;
		const char* cstr;
		switch (content->type())  {
			case BSON_TYPE: {
									 BSONContentBSON* bbson = (BSONContentBSON*)content;
									 BSONObj* bson = (BSONObj*)*bbson;
									 char* chrbson = bson->toChar();
									 sprintf(result + pos, "%s", chrbson);
									 free(chrbson);
									 break;
								 }
			case BSONARRAY_TYPE: {
											BSONContentBSONArray* bbsonarray = (BSONContentBSONArray*)content;
											BSONArrayObj* bsonarray = (BSONArrayObj*)*bbsonarray;
											char* chrbsonarray = bsonarray->toChar();
											sprintf(result + pos, "%s", chrbsonarray);
											free(chrbsonarray);
											break;
										}
			case BOOL_TYPE:  {
									 BSONContentBoolean* bb = (BSONContentBoolean*)content;
									 sprintf(result + pos, "%s", ((bool)*bb?"true": "false"));
									 break;
								 }
			case INT_TYPE:  {
									 BSONContentInt* bint = (BSONContentInt*)content;
									 sprintf(result + pos, "%d", (__int32)*bint);
									 break;
								 }
			case LONG_TYPE: {
									 BSONContentLong* blong = (BSONContentLong*)content;
									 sprintf(result + pos, "%ld", (__int64)*blong);
									 break;
								 }
			case DOUBLE_TYPE: {
									 BSONContentDouble* bdouble = (BSONContentDouble*)content;
									 sprintf(result + pos, "%f", (double)*bdouble);
									 break;
								 }
			case STRING_TYPE:
			case PTRCHAR_TYPE: { 
										 BSONContentString* bstring = (BSONContentString*)content;

										 djondb::string s = *bstring;
										 sprintf(result + pos, "\"%.*s\"", s.length(), s.c_str());
										 break;
									 }
		}
		pos = strlen(result);
		assert(pos < MAX_BSONOBJ_BUFFER);
	}
	result[pos] = '}';
	result[pos+1] = 0;
	pos++;

	__int32 len = strlen(result);

	// Saves the value to cache the calculated value
	_cBSON = result;

	char* cresult = strcpy(result);

	if (log->isDebug()) log->debug("toChar result: %s", cresult);

	return cresult;
}
예제 #13
0
BSONObj* BSONBufferedObj::select(const char* sel) const {
	std::set<std::string> columns = bson_splitSelect(sel);
	bool include_all = (strcmp(sel, "*") == 0);

	BSONObj* result = new BSONObj();

	for (int x = 0; x < _elements; x++) {
		std::string key(_keys[x], *_keySize[x]);
		if (include_all || (columns.find(key) != columns.end())) {
			BSONTYPE type = getType(const_cast<char*>(key.c_str()));

			switch (type) {
				case BSON_TYPE:  
					{
						BSONBufferedObj* inner = getBSON(key);

						char* subselect = "*";
						if (!include_all) {
							subselect = bson_subselect(sel, key.c_str());
						}
						BSONObj* innerSubSelect = inner->select(subselect);
						result->add(key, *innerSubSelect);
						delete innerSubSelect;
						break;
					}
				case BSONARRAY_TYPE: 
					{
						BSONArrayObj* innerArray = getBSONArray(key);
						char* subselect = "*";
						if (!include_all) {
							subselect = bson_subselect(sel, key.c_str());
						}
						BSONArrayObj* innerSubArray = innerArray->select(subselect);
						result->add(key, *innerSubArray);
						delete innerSubArray;
						break;
					}
				case BOOL_TYPE: 
					{
						bool val = getBoolean(key);
						result->add(key, val);
						break;
					}
				case INT_TYPE: 
					{
						__int32 val = getInt(key);
						result->add(key, val);
						break;
					}
				case LONG_TYPE:
					{
						__int64 val = getLong(key);
						result->add(key, val);
						break;
					}
				case LONG64_TYPE:
					{
						__LONG64 val = getLong(key);
						result->add(key, val);
						break;
					}
				case DOUBLE_TYPE:
					{
						double val = getDouble(key);
						result->add(key, val);
						break;
					}
				case STRING_TYPE:
				case PTRCHAR_TYPE:
					{
						djondb::string val = getDJString(key);
						result->add(key, const_cast<char*>(val.c_str()), val.length());
						break;
					}
			}
		}
	}
	return result;
}
예제 #14
0
파일: main.cpp 프로젝트: chiehwen/djondb
		void testBSON()
		{
			cout << "testBSON" << endl;
			BSONObj* obj = new BSONObj();
			// Add in
			obj->add("int", 1);
			obj->add("string", (const char*)"test");
			obj->add("long", (__int64) 10000000000L);
			obj->add("double", 1.1);

			BSONObj rel;
			rel.add("innertext", (char*)"inner text");
			obj->add("rel1", rel);

			BSONArrayObj array;
			BSONObj b1;
			b1.add("b1", "test");
			array.add(b1);
			BSONObj b2;
			b2.add("b1", "test2");
			array.add(b2);
			obj->add("array", array);

			TEST_ASSERT(obj->has("int"));
			TEST_ASSERT(obj->getInt("int") == 1);

			TEST_ASSERT(strcmp(obj->getString("string"), "test") == 0);

			TEST_ASSERT(obj->has("long"));
			cout << "long: " << obj->getLong("long") << endl;
			TEST_ASSERT(obj->getLong("long") == 10000000000L);

			TEST_ASSERT(obj->has("double"));
			TEST_ASSERT(obj->getDouble("double") == 1.1);

			TEST_ASSERT(obj->has("rel1"));
			TEST_ASSERT(strcmp(obj->getBSON("rel1")->getString("innertext"), "inner text") == 0);
			
			TEST_ASSERT(obj->has("array"));
			BSONArrayObj* arrayR = obj->getBSONArray("array");
			TEST_ASSERT(arrayR != NULL);
			TEST_ASSERT(arrayR->length() == 2);

			BSONObj* el1 = arrayR->get(0);
			TEST_ASSERT(el1 != NULL);
			
			BSONObj* el2 = arrayR->get(1);
			TEST_ASSERT(el2 != NULL);

			// test a non existant attribute
			try {
				obj->getLong("xx");
				TEST_FAIL("The getLong should throw an exception");
			} catch (BSONException e) {
			}

			try {
				obj->getString("xxx");
				TEST_FAIL("The getString should throw an exception");
			} catch (BSONException e) {
			}
			delete obj;
		}
예제 #15
0
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;
}