Files
mongo/db/query.cpp

193 lines
4.3 KiB
C++
Raw Normal View History

2007-10-19 19:35:48 -04:00
// query.cpp
#include "stdafx.h"
#include "query.h"
#include "pdfile.h"
#include "jsobj.h"
#include "../util/builder.h"
2007-11-04 16:17:44 -05:00
#include <time.h>
2007-10-19 19:35:48 -04:00
int nextCursorId = 1;
2007-10-30 05:50:14 -04:00
void deleteObjects(const char *ns, JSObj pattern, bool justOne) {
cout << "delete ns:" << ns << " queryobjsize:" <<
pattern.objsize() << endl;
2007-11-02 21:30:40 -04:00
if( strncmp(ns, "system.", 7) == 0 ) {
cout << "ERROR: attempt to delete in system namespace " << ns << endl;
return;
}
2007-10-30 05:50:14 -04:00
JSMatcher matcher(pattern);
2007-11-01 22:34:44 -04:00
auto_ptr<Cursor> c = theDataFileMgr.findAll(ns);
while( c->ok() ) {
Record *r = c->_current();
DiskLoc rloc = c->currLoc();
c->advance(); // must advance before deleting as the next ptr will die
2007-10-30 05:50:14 -04:00
JSObj js(r);
if( matcher.matches(js) ) {
cout << " found match to delete" << endl;
theDataFileMgr.deleteRecord(ns, r, rloc);
if( justOne )
return;
}
}
}
void updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert) {
cout << "update ns:" << ns << " objsize:" << updateobj.objsize() << " queryobjsize:" <<
pattern.objsize() << endl;
2007-11-02 21:30:40 -04:00
if( strncmp(ns, "system.", 7) == 0 ) {
cout << "ERROR: attempt to update in system namespace " << ns << endl;
return;
}
2007-10-30 05:50:14 -04:00
JSMatcher matcher(pattern);
2007-11-01 22:34:44 -04:00
auto_ptr<Cursor> c = theDataFileMgr.findAll(ns);
while( c->ok() ) {
Record *r = c->_current();
2007-10-30 05:50:14 -04:00
JSObj js(r);
if( matcher.matches(js) ) {
cout << " found match to update" << endl;
2007-11-01 22:34:44 -04:00
theDataFileMgr.update(ns, r, c->currLoc(), updateobj.objdata(), updateobj.objsize());
2007-10-30 05:50:14 -04:00
return;
}
2007-11-01 22:34:44 -04:00
c->advance();
2007-10-30 05:50:14 -04:00
}
cout << " no match found. ";
if( upsert )
cout << "doing upsert.";
cout << endl;
if( upsert )
theDataFileMgr.insert(ns, (void*) updateobj.objdata(), updateobj.objsize());
}
2007-11-04 16:17:44 -05:00
typedef map<long long, ClientCursor*> CCMap;
CCMap clientCursors;
long long allocCursorId() {
long long x;
while( 1 ) {
x = (((long long)rand()) << 32);
x = x | time(0);
if( clientCursors.count(x) == 0 )
break;
}
return x;
}
2007-10-28 16:38:06 -04:00
QueryResult* runQuery(const char *ns, int ntoreturn, JSObj jsobj) {
cout << "runQuery ns:" << ns << " ntoreturn:" << ntoreturn << " queryobjsize:" <<
jsobj.objsize() << endl;
2007-10-19 19:35:48 -04:00
BufBuilder b;
2007-11-04 16:17:44 -05:00
auto_ptr<JSMatcher> matcher(new JSMatcher(jsobj));
2007-10-19 19:35:48 -04:00
QueryResult *qr = 0;
2007-10-28 16:38:06 -04:00
b.skip(sizeof(QueryResult));
2007-10-19 19:35:48 -04:00
int n = 0;
2007-11-01 22:34:44 -04:00
auto_ptr<Cursor> c =
2007-11-04 16:17:44 -05:00
// strcmp(ns, "system.namespaces") == 0 ?
// makeNamespaceCursor() :
2007-11-01 22:34:44 -04:00
theDataFileMgr.findAll(ns);
2007-11-04 16:17:44 -05:00
long long cursorid = 0;
2007-11-01 22:34:44 -04:00
while( c->ok() ) {
JSObj js = c->current();
2007-11-04 16:17:44 -05:00
if( matcher->matches(js) ) {
2007-11-01 22:34:44 -04:00
b.append((void*) js.objdata(), js.objsize());
2007-10-28 22:20:57 -04:00
n++;
2007-11-04 16:17:44 -05:00
if( n >= ntoreturn && ntoreturn != 0 ) {
// more...so save a cursor
ClientCursor *cc = new ClientCursor();
cc->c = c;
cursorid = allocCursorId();
cc->cursorid = cursorid;
cc->matcher = matcher;
cc->ns = ns;
cc->pos = n;
clientCursors[cursorid] = cc;
2007-10-28 22:20:57 -04:00
break;
2007-11-04 16:17:44 -05:00
}
2007-10-28 22:20:57 -04:00
}
2007-11-01 22:34:44 -04:00
c->advance();
2007-10-19 19:35:48 -04:00
}
qr = (QueryResult *) b.buf();
qr->len = b.len();
qr->reserved = 0;
qr->operation = opReply;
2007-11-04 16:17:44 -05:00
qr->cursorId = cursorid;
2007-10-28 14:42:59 -04:00
qr->startingFrom = 0;
2007-10-19 19:35:48 -04:00
qr->nReturned = n;
b.decouple();
return qr;
}
2007-11-04 16:17:44 -05:00
QueryResult* getMore(const char *ns, int ntoreturn, long long cursorid) {
cout << "getMore ns:" << ns << " ntoreturn:" << ntoreturn << " cursorid:" <<
cursorid << endl;
BufBuilder b;
ClientCursor *cc = 0;
CCMap::iterator it = clientCursors.find(cursorid);
if( it == clientCursors.end() ) {
cout << "Cursor not found in map. cursorid: " << cursorid << endl;
}
else {
cc = it->second;
}
b.skip(sizeof(QueryResult));
int start = 0;
int n = 0;
if( cc ) {
start = cc->pos;
Cursor *c = cc->c.get();
while( 1 ) {
if( !c->ok() ) {
// done! kill cursor.
cursorid = 0;
clientCursors.erase(it);
delete cc;
cc = 0;
break;
}
JSObj js = c->current();
if( cc->matcher->matches(js) ) {
b.append((void*) js.objdata(), js.objsize());
n++;
if( n >= ntoreturn && ntoreturn != 0 ) {
cc->pos += n;
break;
}
}
}
c->advance();
}
QueryResult *qr = (QueryResult *) b.buf();
qr->cursorId = cursorid;
qr->startingFrom = start;
qr->len = b.len();
qr->reserved = 0;
qr->operation = opReply;
qr->nReturned = n;
b.decouple();
return qr;
}