0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-11-30 17:10:48 +01:00

Merge branch 'master' of git@github.com:mongodb/mongo

This commit is contained in:
Eliot Horowitz 2009-05-20 14:51:25 -04:00
commit afafd6aee9
19 changed files with 196 additions and 71 deletions

View File

@ -663,7 +663,7 @@ mongod = env.Program( "mongod" , commonFiles + coreDbFiles + serverOnlyFiles + [
Default( mongod )
# tools
allToolFiles = allClientFiles + [ "tools/Tool.cpp" ]
allToolFiles = commonFiles + coreDbFiles + serverOnlyFiles + [ "client/gridfs.cpp", "tools/Tool.cpp" ]
env.Program( "mongodump" , allToolFiles + [ "tools/dump.cpp" ] )
env.Program( "mongorestore" , allToolFiles + [ "tools/restore.cpp" ] )
@ -828,6 +828,7 @@ if not onlyServer and not noshell:
addSmoketest( "smokeSharding", [ "mongo", "mongod", "mongos" ], [ jsDirTestSpec( "sharding" ) ] )
addSmoketest( "smokeJsPerf", [ "mongo" ], [ mongo[0].abspath + " " + jsSpec( [ "perf", "*.js" ] ) ] )
addSmoketest( "smokeQuota", [ "mongo" ], runShellTest )
addSmoketest( "smokeTool", [ "mongo" ], [ jsDirTestSpec( "tool" ) ] )
mongodForTests = None
mongodForTestsPort = "27017"
@ -881,7 +882,7 @@ def addMongodReqTargets( env, target, source ):
testEnv.Alias( "addMongodReqTargets", [], [addMongodReqTargets] )
testEnv.AlwaysBuild( "addMongodReqTargets" )
testEnv.Alias( "smokeAll", [ "smoke", "mongosTest", "smokeClone", "smokeRepl", "addMongodReqTargets", "smokeDisk", "smokeSharding" ] )
testEnv.Alias( "smokeAll", [ "smoke", "mongosTest", "smokeClone", "smokeRepl", "addMongodReqTargets", "smokeDisk", "smokeSharding", "smokeTool" ] )
testEnv.AlwaysBuild( "smokeAll" )
def addMongodReqNoJsTargets( env, target, source ):

View File

@ -328,15 +328,6 @@ namespace mongo {
Timer startupSrandTimer;
void acquirePathLock() {
#if !defined(_WIN32) && !defined(__sunos__)
string name = ( boost::filesystem::path( dbpath ) / "mongod.lock" ).native_file_string();
lockFile = open( name.c_str(), O_RDONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
massert( "Unable to create / open lock file for dbpath: " + name, lockFile > 0 );
massert( "Unable to acquire lock for dbpath: " + name, flock( lockFile, LOCK_EX | LOCK_NB ) == 0 );
#endif
}
void _initAndListen(int listenPort, const char *appserverLoc = null) {
#if !defined(_WIN32)

View File

@ -698,4 +698,13 @@ namespace mongo {
::exit(rc);
}
void acquirePathLock() {
#if !defined(_WIN32) && !defined(__sunos__)
string name = ( boost::filesystem::path( dbpath ) / "mongod.lock" ).native_file_string();
lockFile = open( name.c_str(), O_RDONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
massert( "Unable to create / open lock file for dbpath: " + name, lockFile > 0 );
massert( "Unable to acquire lock for dbpath: " + name, flock( lockFile, LOCK_EX | LOCK_NB ) == 0 );
#endif
}
} // namespace mongo

View File

@ -144,5 +144,8 @@ namespace mongo {
string oldName_;
};
};
extern int lockFile;
void acquirePathLock();
} // namespace mongo

View File

@ -386,6 +386,7 @@ namespace mongo {
compareOp - Equality, LT, GT, etc.
deep - out param. set to true/false if we scanned an array
isArr -
nextArr - true if an array has already been found
Special forms:
@ -424,7 +425,7 @@ namespace mongo {
BSONElement z = ai.next();
if ( z.type() == Object ) {
BSONObj eo = z.embeddedObject();
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep, false, nextArr);
int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep, false, true);
if ( cmp > 0 ) {
if ( deep ) *deep = true;
return 1;
@ -446,7 +447,7 @@ namespace mongo {
return -1;
BSONObj eo = se.embeddedObject();
return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array, true);
return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array, nextArr);
} else {
e = obj.getField(fieldName);
}

View File

@ -89,12 +89,7 @@ int main( int argc, char** argv ) {
dbpathSpec += "/";
dbpath = dbpathSpec.c_str();
#if !defined(_WIN32) && !defined(__sunos__)
string name = ( boost::filesystem::path( dbpath ) / "mongod.lock" ).native_file_string();
int lockFile = open( name.c_str(), O_RDONLY | O_CREAT, S_IRWXU | S_IRWXG | S_IRWXO );
massert( "Unable to create / open lock file for dbpath: " + name, lockFile > 0 );
massert( "Unable to acquire lock for dbpath: " + name, flock( lockFile, LOCK_EX | LOCK_NB ) == 0 );
#endif
acquirePathLock();
srand( seed );
printGitVersion();

View File

@ -623,6 +623,22 @@ namespace QueryTests {
ASSERT_EQUALS( 1U, client().count( ns, fromjson( "{i:{$in:['a']}}" ) ) );
}
};
class EmbeddedArray : public ClientBase {
public:
~EmbeddedArray() {
client().dropCollection( "unittests.querytests.EmbeddedArray" );
}
void run() {
const char *ns = "unittests.querytests.EmbeddedArray";
client().insert( ns, fromjson( "{foo:{bar:['spam']}}" ) );
client().insert( ns, fromjson( "{foo:{bar:['spam','eggs']}}" ) );
client().insert( ns, fromjson( "{bar:['spam']}" ) );
client().insert( ns, fromjson( "{bar:['spam','eggs']}" ) );
ASSERT_EQUALS( 2U, client().count( ns, BSON( "bar" << "spam" ) ) );
ASSERT_EQUALS( 2U, client().count( ns, BSON( "foo.bar" << "spam" ) ) );
}
};
class All : public Suite {
public:
@ -657,6 +673,7 @@ namespace QueryTests {
add< MinMax >();
add< DirectLocking >();
add< FastCountIn >();
add< EmbeddedArray >();
}
};

View File

@ -4,10 +4,8 @@ var baseName = "jstests_repl6test";
soonCount = function( m, count ) {
assert.soon( function() {
// print( "check count" );
// print( "count: " + s.getDB( baseName ).z.find().count() );
return m.getDB( baseName ).a.find().count() == count;
} );
}, "expected count: " + count + " from : " + m );
}
doTest = function( signal ) {

53
jstests/tool/tool1.js Normal file
View File

@ -0,0 +1,53 @@
// mongo tool tests, very basic to start with
baseName = "jstests_tool_tool1";
dbPath = "/data/db/" + baseName + "/";
externalPath = "/data/db/" + baseName + "_external/"
externalFile = externalPath + "export.json"
port = allocatePorts( 1 )[ 0 ];
resetDbpath( externalPath );
m = startMongod( "--port", port, "--dbpath", dbPath, "--nohttpinterface" );
c = m.getDB( baseName ).getCollection( baseName );
c.save( { a: 1 } );
startMongoProgramNoConnect( "mongodump", "--host", "127.0.0.1:" + port, "--out", externalPath );
sleep( 3000 );
c.drop();
startMongoProgramNoConnect( "mongorestore", "--host", "127.0.0.1:" + port, "--dir", externalPath );
assert.soon( function() { return c.findOne() && 1 == c.findOne().a; } );
resetDbpath( externalPath );
startMongoProgramNoConnect( "mongoexport", "--host", "127.0.0.1:" + port, "-d", baseName, "-c", baseName, "--out", externalFile );
sleep( 3000 );
c.drop();
startMongoProgramNoConnect( "mongoimportjson", "--host", "127.0.0.1:" + port, "-d", baseName, "-c", baseName, "--file", externalFile );
assert.soon( function() { return c.findOne() && 1 == c.findOne().a; } );
stopMongod( port );
resetDbpath( externalPath );
startMongoProgramNoConnect( "mongodump", "--dbpath", dbPath, "--out", externalPath );
sleep( 3000 );
resetDbpath( dbPath );
startMongoProgramNoConnect( "mongorestore", "--dbpath", dbPath, "--dir", externalPath );
sleep( 5000 );
m = startMongoProgram( "mongod", "--port", port, "--dbpath", dbPath, "--nohttpinterface" );
c = m.getDB( baseName ).getCollection( baseName );
assert( c.findOne(), "object missing" );
assert( 1 == c.findOne().a, "object wrong" );
stopMongod( port );
resetDbpath( externalPath );
startMongoProgramNoConnect( "mongoexport", "--dbpath", dbPath, "-d", baseName, "-c", baseName, "--out", externalFile );
sleep( 3000 );
resetDbpath( dbPath );
startMongoProgramNoConnect( "mongoimportjson", "--dbpath", dbPath, "-d", baseName, "-c", baseName, "--file", externalFile );
sleep( 5000 );
m = startMongoProgram( "mongod", "--port", port, "--dbpath", dbPath, "--nohttpinterface" );
c = m.getDB( baseName ).getCollection( baseName );
assert( c.findOne(), "object missing" );
assert( 1 == c.findOne().a, "object wrong" );

View File

@ -54,6 +54,7 @@
933E22110F4327B2000209E3 /* perftest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = perftest.cpp; sourceTree = "<group>"; };
933E22120F4327B2000209E3 /* perftest.o */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.objfile"; path = perftest.o; sourceTree = "<group>"; };
933EF9C70FC3434000C4B294 /* quota1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = quota1.js; sourceTree = "<group>"; };
9340BBEA0FC4521C00656DE0 /* tool1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = tool1.js; sourceTree = "<group>"; };
9342232B0EF16D4F00608550 /* connpool.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = connpool.cpp; sourceTree = "<group>"; };
9342232C0EF16D4F00608550 /* connpool.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = connpool.h; sourceTree = "<group>"; };
9342232D0EF16D4F00608550 /* dbclient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dbclient.cpp; sourceTree = "<group>"; };
@ -378,6 +379,14 @@
path = quota;
sourceTree = "<group>";
};
9340BBE90FC4521C00656DE0 /* tool */ = {
isa = PBXGroup;
children = (
9340BBEA0FC4521C00656DE0 /* tool1.js */,
);
path = tool;
sourceTree = "<group>";
};
9342232A0EF16D4F00608550 /* client */ = {
isa = PBXGroup;
children = (
@ -588,6 +597,7 @@
93A8D1D10F37544800C92B85 /* jstests */ = {
isa = PBXGroup;
children = (
9340BBE90FC4521C00656DE0 /* tool */,
933EF9C60FC3434000C4B294 /* quota */,
93DB95170FC1D3D50047F950 /* capped4.js */,
93DB94A40FC1BFA30047F950 /* capped3.js */,

View File

@ -124,7 +124,7 @@ namespace mongo {
memset(address.sin_zero, 0, sizeof(address.sin_zero));
address.sin_family = AF_INET;
address.sin_port = 0;
address.sin_addr.s_addr = 0;
address.sin_addr.s_addr = inet_addr( "127.0.0.1" );
assert( 0 == ::bind( s, (sockaddr*)&address, sizeof( address ) ) );
sockaddr_in newAddress;
@ -136,7 +136,7 @@ namespace mongo {
}
sort( ports.begin(), ports.end() );
for( int i = 1; i < ports.size(); ++i )
for( unsigned i = 1; i < ports.size(); ++i )
massert( "duplicate ports allocated", ports[ i - 1 ] != ports[ i ] );
BSONObjBuilder b;
b.append( "", ports );
@ -217,7 +217,7 @@ namespace mongo {
}
argv_[ args.nFields() ] = 0;
if ( program == "mongo" )
if ( program != "mongod" && program != "mongos" && program != "mongobridge" )
port_ = 0;
else
assert( port_ > 0 );

View File

@ -6,13 +6,7 @@
#include <boost/filesystem/operations.hpp>
namespace mongo {
DBClientBase *createDirectClient() {
cout << "no direct client available" << endl;
assert( false );
return 0;
}
} // namespace mongo
#include "util/file_allocator.h"
using namespace std;
using namespace mongo;
@ -20,7 +14,7 @@ using namespace mongo;
namespace po = boost::program_options;
mongo::Tool::Tool( string name , string defaultDB , string defaultCollection ) :
_name( name ) , _db( defaultDB ) , _coll( defaultCollection ){
_name( name ) , _db( defaultDB ) , _coll( defaultCollection ), _useDirect() {
_options = new po::options_description( name + " options" );
_options->add_options()
@ -28,6 +22,7 @@ mongo::Tool::Tool( string name , string defaultDB , string defaultCollection ) :
("host,h",po::value<string>(), "mongo host to connect to" )
("db,d",po::value<string>(), "database to use" )
("collection,c",po::value<string>(), "collection to use (some commands)" )
("dbpath",po::value<string>(), "directly access mongod data files in this path, instead of connecting to a mongod instance" )
;
}
@ -53,19 +48,29 @@ int mongo::Tool::main( int argc , char ** argv ){
printExtraHelp( cerr );
return 0;
}
const char * host = "127.0.0.1";
if ( _params.count( "host" ) )
host = _params["host"].as<string>().c_str();
string errmsg;
if ( ! _conn.connect( host , errmsg ) ){
cerr << "couldn't connect to [" << host << "] " << errmsg << endl;
return -1;
if ( !hasParam( "dbpath" ) ) {
const char * host = "127.0.0.1";
if ( _params.count( "host" ) )
host = _params["host"].as<string>().c_str();
string errmsg;
if ( ! _conn.connect( host , errmsg ) ){
cerr << "couldn't connect to [" << host << "] " << errmsg << endl;
return -1;
}
cerr << "connected to: " << host << endl;
} else {
_useDirect = true;
static string myDbpath = getParam( "dbpath" );
mongo::dbpath = myDbpath.c_str();
mongo::acquirePathLock();
#if !defined(_WIN32)
theFileAllocator().start();
#endif
}
cerr << "connected to: " << host << endl;
if ( _params.count( "db" ) )
_db = _params["db"].as<string>();

View File

@ -11,6 +11,7 @@
#endif
#include "client/dbclient.h"
#include "db/instance.h"
using std::string;
@ -48,17 +49,21 @@ namespace mongo {
}
virtual int run() = 0;
virtual void printExtraHelp( ostream & out );
protected:
string _name;
mongo::DBClientConnection _conn;
string _db;
string _coll;
mongo::DBClientBase &conn() { return _useDirect ? (mongo::DBClientBase&)_direct : (mongo::DBClientBase&)_conn; };
private:
mongo::DBClientConnection _conn;
mongo::DBDirectClient _direct;
bool _useDirect;
boost::program_options::options_description * _options;
boost::program_options::positional_options_description _positonalOptions;

View File

@ -58,15 +58,42 @@ private:
MessagingPort &mp_;
};
set<MessagingPort*> ports;
class MyListener : public Listener {
public:
MyListener( int port ) : Listener( "", port ) {}
virtual void accepted(MessagingPort *mp) {
ports.insert( mp );
Forwarder f( *mp );
boost::thread t( f );
}
};
auto_ptr< MyListener > listener;
#if !defined(_WIN32)
#include <execinfo.h>
void cleanup( int sig ) {
close( listener->socket() );
for ( set<MessagingPort*>::iterator i = ports.begin(); i != ports.end(); i++ )
(*i)->shutdown();
::exit( 0 );
}
void setupSignals() {
signal( SIGINT , cleanup );
signal( SIGTERM , cleanup );
signal( SIGPIPE , cleanup );
signal( SIGABRT , cleanup );
signal( SIGSEGV , cleanup );
signal( SIGBUS , cleanup );
signal( SIGFPE , cleanup );
}
#else
inline void setupSignals() {}
#endif
void helpExit() {
cout << "usage mongobridge --port <port> --dest <destUri>" << endl;
cout << " port: port to listen for mongo messages" << endl;
@ -80,7 +107,8 @@ void check( bool b ) {
}
int main( int argc, char **argv ) {
setupSignals();
check( argc == 5 );
for( int i = 1; i < 5; ++i ) {
@ -95,9 +123,9 @@ int main( int argc, char **argv ) {
}
check( port != 0 && !destUri.empty() );
MyListener l( port );
l.init();
l.listen();
listener.reset( new MyListener( port ) );
listener->init();
listener->listen();
return 0;
}

View File

@ -40,7 +40,7 @@ public:
int out = open( outputFile.string().c_str() , O_WRONLY | O_CREAT | O_TRUNC , 0666 );
assert( out );
auto_ptr<DBClientCursor> cursor = _conn.query( coll.c_str() , BSONObj() , 0 , 0 , 0 , Option_SlaveOk );
auto_ptr<DBClientCursor> cursor = conn().query( coll.c_str() , BSONObj() , 0 , 0 , 0 , Option_SlaveOk );
int num = 0;
while ( cursor->more() ) {
@ -61,7 +61,7 @@ public:
string sns = db + ".system.namespaces";
auto_ptr<DBClientCursor> cursor = _conn.query( sns.c_str() , BSONObj() , 0 , 0 , 0 , Option_SlaveOk );
auto_ptr<DBClientCursor> cursor = conn().query( sns.c_str() , BSONObj() , 0 , 0 , 0 , Option_SlaveOk );
while ( cursor->more() ) {
BSONObj obj = cursor->next();
if ( obj.toString().find( ".$" ) != string::npos )
@ -84,7 +84,7 @@ public:
if ( db == "*" ){
cout << "all dbs" << endl;
BSONObj res = _conn.findOne( "admin.$cmd" , BSON( "listDatabases" << 1 ) );
BSONObj res = conn().findOne( "admin.$cmd" , BSON( "listDatabases" << 1 ) );
BSONObj dbs = res.getField( "databases" ).embeddedObjectUserCheck();
set<string> keys;
dbs.getFieldNames( keys );
@ -105,6 +105,7 @@ public:
}
return 0;
}
};
int main( int argc , char ** argv ) {

View File

@ -36,15 +36,21 @@ class Export : public Tool {
public:
Export() : Tool( "export" ){
add_options()
("query,q" , po::value<string>() , " query filter" )
("fields,f" , po::value<string>() , " comma seperated list of field names e.g. -f=name,age " )
("query,q" , po::value<string>() , "query filter" )
("fields,f" , po::value<string>() , "comma seperated list of field names e.g. -f=name,age " )
("csv","export to csv instead of json")
("out,o", po::value<string>(), "output file; if not specified, stdout is used")
;
}
int run(){
const string ns = getNS();
const bool csv = hasParam( "csv" );
ostream *outPtr = &cout;
string outfile = getParam( "out" );
if ( hasParam( "out" ) )
outPtr = new ofstream( outfile.c_str() );
ostream &out = *outPtr;
BSONObj * fieldsToReturn = 0;
BSONObj realFieldsToReturn;
@ -74,15 +80,15 @@ public:
}
auto_ptr<DBClientCursor> cursor = _conn.query( ns.c_str() , getParam( "query" , "" ) , 0 , 0 , fieldsToReturn , Option_SlaveOk );
auto_ptr<DBClientCursor> cursor = conn().query( ns.c_str() , getParam( "query" , "" ) , 0 , 0 , fieldsToReturn , Option_SlaveOk );
if ( csv ){
for ( vector<string>::iterator i=fields.begin(); i != fields.end(); i++ ){
if ( i != fields.begin() )
cout << ",";
cout << *i;
out << ",";
out << *i;
}
cout << endl;
out << endl;
}
while ( cursor->more() ) {
@ -90,15 +96,15 @@ public:
if ( csv ){
for ( vector<string>::iterator i=fields.begin(); i != fields.end(); i++ ){
if ( i != fields.begin() )
cout << ",";
out << ",";
const BSONElement & e = obj[i->c_str()];
if ( ! e.eoo() )
cout << e.jsonString( TenGen , false );
out << e.jsonString( TenGen , false );
}
cout << endl;
out << endl;
}
else {
cout << obj.jsonString() << endl;
out << obj.jsonString() << endl;
}
}

View File

@ -65,7 +65,7 @@ public:
return -1;
}
GridFS g( _conn , _db );
GridFS g( conn() , _db );
string filename = getParam( "file" );
if ( cmd == "list" ){

View File

@ -63,11 +63,11 @@ public:
if ( hasParam( "drop" ) ){
cout << "dropping: " << ns << endl;
_conn.dropCollection( ns.c_str() );
conn().dropCollection( ns.c_str() );
}
if ( hasParam( "idbefore" ) ){
_conn.ensureIndex( ns.c_str() , BSON( "_id" << 1 ) );
conn().ensureIndex( ns.c_str() , BSON( "_id" << 1 ) );
}
int num = 0;
@ -87,7 +87,7 @@ public:
try {
BSONObj o = fromjson( line );
_conn.insert( ns.c_str() , o );
conn().insert( ns.c_str() , o );
}
catch ( MsgAssertionException& ma ){
cout << "exception:" << ma.toString() << endl;
@ -101,7 +101,7 @@ public:
}
if ( hasParam( "id" ) ){
_conn.ensureIndex( ns.c_str() , BSON( "_id" << 1 ) );
conn().ensureIndex( ns.c_str() , BSON( "_id" << 1 ) );
}
return 0;

View File

@ -79,8 +79,10 @@ public:
ns += "." + l;
}
if ( boost::filesystem::file_size( root ) == 0 )
return;
if ( boost::filesystem::file_size( root ) == 0 ) {
out() << "file " + root.native_file_string() + " empty, aborting" << endl;
return;
}
out() << "\t going into namespace [" << ns << "]" << endl;
@ -95,7 +97,7 @@ public:
while ( read < mmf.length() ) {
BSONObj o( data );
_conn.insert( ns.c_str() , o );
conn().insert( ns.c_str() , o );
read += o.objsize();
data += o.objsize();