summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2008-09-09 10:19:31 -0400
committerDwight <dmerriman@gmail.com>2008-09-09 10:19:31 -0400
commit98d4a02dcbb943961c0c30e3b556bd4150f62c4c (patch)
tree5ec54d56da27cacffcc89d985e9eac3c1b5d2d37
parent8dd8937576635dbe8da2ea4cce90854ab79aeb19 (diff)
downloadmongo-98d4a02dcbb943961c0c30e3b556bd4150f62c4c.tar.gz
dbgrid start
-rw-r--r--db/db.sln6
-rw-r--r--db/db.vcproj16
-rw-r--r--db/jsobj.cpp458
-rw-r--r--db/makefile8
-rw-r--r--db/query.cpp10
-rw-r--r--stdafx.cpp5
6 files changed, 30 insertions, 473 deletions
diff --git a/db/db.sln b/db/db.sln
index 9ebc444204b..43585735798 100644
--- a/db/db.sln
+++ b/db/db.sln
@@ -3,6 +3,8 @@ Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db", "db.vcproj", "{215B2D68-0A70-4D10-8E75-B31010C62A91}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dbgrid", "..\dbgrid\dbgrid.vcproj", "{E03717ED-69B4-4D21-BC55-DF6690B585C6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -13,6 +15,10 @@ Global
{215B2D68-0A70-4D10-8E75-B31010C62A91}.Debug|Win32.Build.0 = Debug|Win32
{215B2D68-0A70-4D10-8E75-B31010C62A91}.Release|Win32.ActiveCfg = Release|Win32
{215B2D68-0A70-4D10-8E75-B31010C62A91}.Release|Win32.Build.0 = Release|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Debug|Win32.ActiveCfg = Debug|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Debug|Win32.Build.0 = Debug|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Release|Win32.ActiveCfg = Release|Win32
+ {E03717ED-69B4-4D21-BC55-DF6690B585C6}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/db/db.vcproj b/db/db.vcproj
index 6ab824bf3c7..ece0d5c6bf4 100644
--- a/db/db.vcproj
+++ b/db/db.vcproj
@@ -215,6 +215,10 @@
>
</File>
<File
+ RelativePath=".\matcher.cpp"
+ >
+ </File>
+ <File
RelativePath="..\grid\message.cpp"
>
</File>
@@ -403,10 +407,6 @@
Name="misc"
>
<File
- RelativePath=".\how_to_build.txt"
- >
- </File>
- <File
RelativePath=".\makefile"
>
</File>
@@ -426,14 +426,6 @@
RelativePath="..\pcre-7.4\pcrecpp.h"
>
</File>
- <File
- RelativePath=".\testdb.js"
- >
- </File>
- <File
- RelativePath=".\todo.txt"
- >
- </File>
</Filter>
<Filter
Name="libs_etc"
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index 51c8df5f1a3..8687321f3e4 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -19,101 +19,6 @@
#include "stdafx.h"
#include "jsobj.h"
#include "../util/goodies.h"
-#include "javajs.h"
-
-#if defined(_WIN32)
-
-#include <hash_map>
-using namespace stdext;
-
-typedef const char * MyStr;
-struct less_str {
- bool operator()(const MyStr & x, const MyStr & y) const {
- if ( strcmp(x, y) > 0)
- return true;
-
- return false;
- }
-};
-
-typedef hash_map<const char*, int, hash_compare<const char *, less_str> > strhashmap;
-
-#else
-
-#include <ext/hash_map>
-using namespace __gnu_cxx;
-
-typedef const char * MyStr;
-struct eq_str {
- bool operator()(const MyStr & x, const MyStr & y) const {
- if ( strcmp(x, y) == 0)
- return true;
-
- return false;
- }
-};
-
-typedef hash_map<const char*, int, hash<const char *>, eq_str > strhashmap;
-
-#endif
-
-#include "minilex.h"
-
-MiniLex minilex;
-
-class Where {
-public:
- Where() { codeCopy = 0; }
- ~Where() {
- JavaJS->scopeFree(scope);
- delete codeCopy;
- scope = 0; func = 0; codeCopy = 0;
- }
- jlong scope, func;
- strhashmap fields;
-// map<string,int> fields;
- bool fullObject;
- int nFields;
- char *codeCopy;
-
- void setFunc(const char *code) {
- codeCopy = new char[strlen(code)+1];
- strcpy(codeCopy,code);
- func = JavaJS->functionCreate( code );
- minilex.grabVariables(codeCopy, fields);
- // if user references db, eg db.foo.save(obj),
- // we make sure we have the whole thing.
- fullObject = fields.count("fullObject") +
- fields.count("db") > 0;
- nFields = fields.size();
- }
-
- void buildSubset(JSObj& src, JSObjBuilder& dst) {
- JSElemIter it(src);
- int n = 0;
- if( !it.more() ) return;
- while( 1 ) {
- Element e = it.next();
- if( e.eoo() )
- break;
- if( //n == 0 &&
- fields.find(e.fieldName()) != fields.end()
- //fields.count(e.fieldName())
- ) {
- dst.append(e);
- if( ++n >= nFields )
- break;
- }
- }
- }
-};
-
-JSMatcher::~JSMatcher() {
- for( int i = 0; i < nBuilders; i++ )
- delete builders[i];
- delete in;
- delete where;
-}
Element nullElement;
@@ -334,304 +239,6 @@ int getGtLtOp(Element& e) {
return op;
}
-#include "pdfile.h"
-
-JSMatcher::JSMatcher(JSObj &_jsobj) :
- in(0), where(0), jsobj(_jsobj), nRegex(0)
-{
- nBuilders = 0;
-
- JSElemIter i(jsobj);
- n = 0;
- while( i.more() ) {
- Element e = i.next();
- if( e.eoo() )
- break;
-
- if( e.type() == Code && strcmp(e.fieldName(), "$where")==0 ) {
- // $where: function()...
- assert( where == 0 );
- where = new Where();
- const char *code = e.valuestr();
- massert( "$where query, but jni is disabled", JavaJS );
- where->scope = JavaJS->scopeCreate();
- JavaJS->scopeSetString(where->scope, "$client", client->name.c_str());
- where->setFunc(code);
- continue;
- }
-
- if( e.type() == RegEx ) {
- if( nRegex >= 4 ) {
- cout << "ERROR: too many regexes in query" << endl;
- }
- else {
- pcrecpp::RE_Options options;
- options.set_utf8(true);
- const char *flags = e.regexFlags();
- while( flags && *flags ) {
- if( *flags == 'i' )
- options.set_caseless(true);
- else if( *flags == 'm' )
- options.set_multiline(true);
- else if( *flags == 'x' )
- options.set_extended(true);
- flags++;
- }
- regexs[nRegex].re = new pcrecpp::RE(e.regex(), options);
- regexs[nRegex].fieldName = e.fieldName();
- nRegex++;
- }
- continue;
- }
-
- // greater than / less than...
- // e.g., e == { a : { $gt : 3 } }
- // or
- // { a : { $in : [1,2,3] } }
- if( e.type() == Object ) {
- // e.g., fe == { $gt : 3 }
- JSElemIter j(e.embeddedObject());
- bool ok = false;
- while( j.more() ) {
- Element fe = j.next();
- if( fe.eoo() )
- break;
- // Element fe = e.embeddedObject().firstElement();
- const char *fn = fe.fieldName();
- if( fn[0] == '$' && fn[1] ) {
- if( fn[2] == 't' ) {
- int op = Equality;
- if( fn[1] == 'g' ) {
- if( fn[3] == 0 ) op = GT;
- else if( fn[3] == 'e' && fn[4] == 0 ) op = GTE;
- }
- else if( fn[1] == 'l' ) {
- if( fn[3] == 0 ) op = LT;
- else if( fn[3] == 'e' && fn[4] == 0 ) op = LTE;
- }
- if( op && nBuilders < 8) {
- JSObjBuilder *b = new JSObjBuilder();
- builders[nBuilders++] = b;
- b->appendAs(fe, e.fieldName());
- toMatch.push_back( b->done().firstElement() );
- compareOp.push_back(op);
- n++;
- ok = true;
- }
- }
- else if( fn[1] == 'i' && fn[2] == 'n' && fn[3] == 0 && fe.type() == Array ) {
- // $in
- assert( in == 0 ); // only one per query supported so far. finish...
- in = new set<Element,element_lt>();
- JSElemIter i(fe.embeddedObject());
- if( i.more() ) {
- while( 1 ) {
- Element ie = i.next();
- if( ie.eoo() )
- break;
- in->insert(ie);
- }
- }
- toMatch.push_back(e); // not actually used at the moment
- compareOp.push_back(opIN);
- n++;
- ok = true;
- }
- }
- else {
- ok = false;
- break;
- }
- }
- if( ok )
- continue;
- }
-
- {
- // normal, simple case e.g. { a : "foo" }
- toMatch.push_back(e);
- compareOp.push_back(Equality);
- n++;
- }
- }
-}
-
-inline int JSMatcher::valuesMatch(Element& l, Element& r, int op) {
- if( op == 0 )
- return l.valuesEqual(r);
-
- if( op == opIN ) {
- // { $in : [1,2,3] }
- int c = in->count(l);
- return c;
- }
-
- /* check LT, GTE, ... */
- if( l.type() != r.type() )
- return false;
- int c = compareElementValues(l, r);
- int z = 1 << (c+1);
- return (op & z);
-}
-
-/* Check if a particular field matches.
-
- fieldName - field to match "a.b" if we are reaching into an embedded object.
- toMatch - element we want to match.
- obj - database object to check against
- compareOp - Equality, LT, GT, etc.
- deep - out param. set to true/false if we scanned an array
- isArr -
-
- Special forms:
-
- { "a.b" : 3 } means obj.a.b == 3
- { a : { $lt : 3 } } means obj.a < 3
- { a : { $in : [1,2] } } means [1,2].contains(obj.a)
-
- return value
- -1 mismatch
- 0 missing element
- 1 match
-*/
-int JSMatcher::matchesDotted(const char *fieldName, Element& toMatch, JSObj& obj, int compareOp, bool *deep, bool isArr) {
- {
- const char *p = strchr(fieldName, '.');
- if( p ) {
- string left(fieldName, p-fieldName);
-
- Element e = obj.getField(left.c_str());
- if( e.eoo() )
- return 0;
- if( e.type() != Object && e.type() != Array )
- return -1;
-
- JSObj eo = e.embeddedObject();
- return matchesDotted(p+1, toMatch, eo, compareOp, deep, e.type() == Array);
- }
- }
-
- Element e = obj.getField(fieldName);
-
- if( valuesMatch(e, toMatch, compareOp) ) {
- return 1;
- }
- else if( e.type() == Array ) {
- JSElemIter ai(e.embeddedObject());
- while( ai.more() ) {
- Element z = ai.next();
- if( valuesMatch( z, toMatch, compareOp) ) {
- if( deep )
- *deep = true;
- return 1;
- }
- }
- }
- else if( isArr ) {
- JSElemIter ai(obj);
- while( ai.more() ) {
- Element z = ai.next();
- if( z.type() == Object ) {
- JSObj eo = z.embeddedObject();
- int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep);
- if( cmp > 0 ) {
- if( deep ) *deep = true;
- return 1;
- }
- }
- }
- }
- else if( e.eoo() ) {
- return 0;
- }
- return -1;
-}
-
-extern int dump;
-
-inline bool _regexMatches(RegexMatcher& rm, Element& e) {
- char buf[64];
- const char *p = buf;
- if( e.type() == String || e.type() == Symbol )
- p = e.valuestr();
- else if( e.type() == Number ) {
- sprintf(buf, "%f", e.number());
- }
- else if( e.type() == Date ) {
- unsigned long long d = e.date();
- time_t t = (d/1000);
- time_t_to_String(t, buf);
- }
- else
- return false;
- return rm.re->PartialMatch(p);
-}
-/* todo: internal dotted notation scans -- not done yet here. */
-inline bool regexMatches(RegexMatcher& rm, Element& e, bool *deep) {
- if( e.type() != Array )
- return _regexMatches(rm, e);
-
- JSElemIter ai(e.embeddedObject());
- while( ai.more() ) {
- Element z = ai.next();
- if( _regexMatches(rm, z) ) {
- if( deep )
- *deep = true;
- return true;
- }
- }
- return false;
-}
-
-/* See if an object matches the query.
- deep - return true when meanswe looked into arrays for a match
-*/
-bool JSMatcher::matches(JSObj& jsobj, bool *deep) {
- if( deep )
- *deep = false;
-
- /* assuming there is usually only one thing to match. if more this
- could be slow sometimes. */
-
- // check normal non-regex cases:
- for( int i = 0; i < n; i++ ) {
- Element& m = toMatch[i];
- int cmp = matchesDotted(toMatch[i].fieldName(), toMatch[i], jsobj, compareOp[i], deep);
-
- /* missing is ok iff we were looking for null */
- if( cmp < 0 )
- return false;
- if( cmp == 0 && (m.type() != jstNULL && m.type() != Undefined ) )
- return false;
- }
-
- for( int r = 0; r < nRegex; r++ ) {
- RegexMatcher& rm = regexs[r];
- Element e = jsobj.getFieldDotted(rm.fieldName);
- if( e.eoo() )
- return false;
- if( !regexMatches(rm, e, deep) )
- return false;
- }
-
- if( where ) {
- if( where->func == 0 )
- return false; // didn't compile
- if( jsobj.objsize() < 200 || where->fullObject ) {
- JavaJS->scopeSetObject(where->scope, "obj", &jsobj);
- } else {
- JSObjBuilder b;
- where->buildSubset(jsobj, b);
- JSObj temp = b.done();
- JavaJS->scopeSetObject(where->scope, "obj", &temp);
- }
- if( JavaJS->invoke(where->scope, where->func) )
- return false;
- return JavaJS->scopeGetBoolean(where->scope, "return") != 0;
- }
-
- return true;
-}
/* JSObj ------------------------------------------------------------*/
@@ -829,7 +436,6 @@ int JSObj::addFields(JSObj& from, set<string>& fields) {
/*-- test things ----------------------------------------------------*/
#pragma pack(push,1)
-
struct MaxKeyData {
MaxKeyData() { totsize=7; maxkey=MaxKey; name=0; eoo=EOO; }
int totsize;
@@ -844,6 +450,7 @@ struct JSObj0 {
int totsize;
char eoo;
} js0;
+#pragma pack(pop)
Element::Element() {
data = &js0.eoo;
@@ -851,60 +458,13 @@ Element::Element() {
totalSize = -1;
}
-struct JSObj1 js1;
-
-struct JSObj2 {
- JSObj2() {
- totsize=sizeof(JSObj2);
- s = String; strcpy_s(sname, 7, "abcdef"); slen = 10;
- strcpy_s(sval, 10, "123456789"); eoo = EOO;
- }
- unsigned totsize;
- char s;
- char sname[7];
- unsigned slen;
- char sval[10];
- char eoo;
-} js2;
-
-struct JSUnitTest {
- JSUnitTest() {
- JSObj j1((const char *) &js1);
- JSObj j2((const char *) &js2);
- JSMatcher m(j2);
- assert( m.matches(j1) );
- js2.sval[0] = 'z';
- assert( !m.matches(j1) );
- JSMatcher n(j1);
- assert( n.matches(j1) );
- assert( !n.matches(j2) );
-
- JSObj j0((const char *) &js0);
- JSMatcher p(j0);
- assert( p.matches(j1) );
- assert( p.matches(j2) );
- }
-} jsunittest;
-
+#pragma pack(push,1)
+struct EmptyObject {
+ EmptyObject() { len = 5; jstype = EOO; }
+ int len;
+ char jstype;
+} emptyObject;
#pragma pack(pop)
-struct RXTest {
- RXTest() {
- /*
- static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
- static const boost::regex b(".....");
- cout << "regex result: " << regex_match("hello", e) << endl;
- cout << "regex result: " << regex_match("abcoo", b) << endl;
- */
- pcrecpp::RE re1(")({a}h.*o");
- pcrecpp::RE re("h.llo");
- assert( re.FullMatch("hello") );
- assert( !re1.FullMatch("hello") );
-
-
- pcrecpp::RE_Options options;
- options.set_utf8(true);
- pcrecpp::RE part("dwi", options);
- assert( part.PartialMatch("dwight") );
- }
-} rxtest;
+JSObj emptyObj((char *) &emptyObject);
+
diff --git a/db/makefile b/db/makefile
index a199765173d..abbf77161be 100644
--- a/db/makefile
+++ b/db/makefile
@@ -5,12 +5,15 @@ FLAGS= ${CFLAGS} -fPIC -ggdb -pthread -O3 -I .. -Isrc/p -I/src/p/db -L/usr/loca
LIB_DEPS = -lpcrecpp -lpcre
LIB_BOOST = -lboost_thread -lboost_filesystem
-LIBS= $(LIB_DEPS) $(LIB_BOOST) -lstdc++
+LIBS= $(LIB_DEPS) $(LIB_BOOST) -lstdc++
+DBGRID_LIBS = $(LIB_BOOST) -lstdc++
JVM_LIBS = -L/opt/java/lib/
OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o dbclient.o btreecursor.o cloner.o namespace.o
+DBGRID_OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/util.o dbclient.o ../dbgrid/dbgrid.o
+
# ../grid/protorecv.o ../grid/protosend.o
GPP = g++
@@ -41,6 +44,9 @@ _REQ_GPP_VER = 4.2
db: $(OBJS) db.o
$(GPP) $(FLAGS) -o $@ $(OBJS) db.o $(LIBS) $(JVM_LIBS)
# -./db quicktest
+
+dbgrid: $(DBGRID_OBJS) ../dbgrid/dbgrid.o
+ $(GPP) $(FLAGS) -o $@ $(DBGRID_OBJS) $(DBGRID_LIBS)
javatest: javatest.o $(OBJS)
$(GPP) $(FLAGS) -o $@ javatest.o $(OBJS) $(LIBS) $(JVM_LIBS)
diff --git a/db/query.cpp b/db/query.cpp
index 47522d8818c..3e29977f461 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -41,16 +41,6 @@ LRUishMap<JSObj,DiskLoc,5> lrutest(123);
int nextCursorId = 1;
extern bool useCursors;
-#pragma pack(push,1)
-struct EmptyObject {
- EmptyObject() { len = 5; jstype = EOO; }
- int len;
- char jstype;
-} emptyObject;
-#pragma pack(pop)
-
-JSObj emptyObj((char *) &emptyObject);
-
int getGtLtOp(Element& e);
void appendElementHandlingGtLt(JSObjBuilder& b, Element& e);
int runCount(const char *ns, JSObj& cmd, string& err);
diff --git a/stdafx.cpp b/stdafx.cpp
index 56ea439d52e..b050390966f 100644
--- a/stdafx.cpp
+++ b/stdafx.cpp
@@ -23,18 +23,20 @@
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file
+/*
struct MyAsserts {
MyAsserts() {
}
} myassertsstdafx;
+*/
#undef assert
#undef yassert
#include "assert.h"
-void sayDbContext(const char *p = 0);
+void sayDbContext(const char *errmsg = 0);
void wasserted(const char *msg, const char *file, unsigned line) {
problem() << "Assertion failure " << msg << ' ' << file << ' ' << line << endl;
@@ -55,3 +57,4 @@ void msgasserted(const char *msg) {
cout << "Assertion: " << msg << '\n';
throw AssertionException();
}
+