summaryrefslogtreecommitdiff
path: root/tools/export.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tools/export.cpp')
-rw-r--r--tools/export.cpp69
1 files changed, 44 insertions, 25 deletions
diff --git a/tools/export.cpp b/tools/export.cpp
index 5603823..0262c4b 100644
--- a/tools/export.cpp
+++ b/tools/export.cpp
@@ -33,34 +33,34 @@ namespace po = boost::program_options;
class Export : public Tool {
public:
- Export() : Tool( "export" ){
+ Export() : Tool( "export" ) {
addFieldOptions();
add_options()
- ("query,q" , po::value<string>() , "query filter, as a JSON string" )
- ("csv","export to csv instead of json")
- ("out,o", po::value<string>(), "output file; if not specified, stdout is used")
- ("jsonArray", "output to a json array rather than one object per line")
- ;
+ ("query,q" , po::value<string>() , "query filter, as a JSON string" )
+ ("csv","export to csv instead of json")
+ ("out,o", po::value<string>(), "output file; if not specified, stdout is used")
+ ("jsonArray", "output to a json array rather than one object per line")
+ ;
_usesstdout = false;
}
-
- int run(){
+
+ int run() {
string ns;
const bool csv = hasParam( "csv" );
const bool jsonArray = hasParam( "jsonArray" );
ostream *outPtr = &cout;
string outfile = getParam( "out" );
auto_ptr<ofstream> fileStream;
- if ( hasParam( "out" ) ){
+ if ( hasParam( "out" ) ) {
size_t idx = outfile.rfind( "/" );
- if ( idx != string::npos ){
+ if ( idx != string::npos ) {
string dir = outfile.substr( 0 , idx + 1 );
create_directories( dir );
}
ofstream * s = new ofstream( outfile.c_str() , ios_base::out );
fileStream.reset( s );
outPtr = s;
- if ( ! s->good() ){
+ if ( ! s->good() ) {
cerr << "couldn't open [" << outfile << "]" << endl;
return -1;
}
@@ -72,36 +72,55 @@ public:
try {
ns = getNS();
- } catch (...) {
+ }
+ catch (...) {
printHelp(cerr);
return 1;
}
auth();
- if ( hasParam( "fields" ) || csv ){
+ if ( hasParam( "fields" ) || csv ) {
needFields();
- fieldsToReturn = &_fieldsObj;
+
+ // we can't use just _fieldsObj since we support everything getFieldDotted does
+
+ set<string> seen;
+ BSONObjBuilder b;
+
+ BSONObjIterator i( _fieldsObj );
+ while ( i.more() ){
+ BSONElement e = i.next();
+ string f = str::before( e.fieldName() , '.' );
+ if ( seen.insert( f ).second )
+ b.append( f , 1 );
+ }
+
+ realFieldsToReturn = b.obj();
+ fieldsToReturn = &realFieldsToReturn;
}
-
-
- if ( csv && _fields.size() == 0 ){
+
+
+ if ( csv && _fields.size() == 0 ) {
cerr << "csv mode requires a field list" << endl;
return -1;
}
+ Query q( getParam( "query" , "" ) );
+ if ( q.getFilter().isEmpty() && !hasParam("dbpath"))
+ q.snapshot();
- auto_ptr<DBClientCursor> cursor = conn().query( ns.c_str() , ((Query)(getParam( "query" , "" ))).snapshot() , 0 , 0 , fieldsToReturn , QueryOption_SlaveOk | QueryOption_NoCursorTimeout );
+ auto_ptr<DBClientCursor> cursor = conn().query( ns.c_str() , q , 0 , 0 , fieldsToReturn , QueryOption_SlaveOk | QueryOption_NoCursorTimeout );
- if ( csv ){
- for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ){
+ if ( csv ) {
+ for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ) {
if ( i != _fields.begin() )
out << ",";
out << *i;
}
out << endl;
}
-
+
if (jsonArray)
out << '[';
@@ -109,12 +128,12 @@ public:
while ( cursor->more() ) {
num++;
BSONObj obj = cursor->next();
- if ( csv ){
- for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ){
+ if ( csv ) {
+ for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ) {
if ( i != _fields.begin() )
out << ",";
const BSONElement & e = obj.getFieldDotted(i->c_str());
- if ( ! e.eoo() ){
+ if ( ! e.eoo() ) {
out << e.jsonString( Strict , false );
}
}
@@ -133,7 +152,7 @@ public:
if (jsonArray)
out << ']' << endl;
-
+
cerr << "exported " << num << " records" << endl;
return 0;