diff options
Diffstat (limited to 'src/mongo/tools/export.cpp')
| -rw-r--r-- | src/mongo/tools/export.cpp | 143 |
1 files changed, 66 insertions, 77 deletions
diff --git a/src/mongo/tools/export.cpp b/src/mongo/tools/export.cpp index ad2195846f0..75460f76a15 100644 --- a/src/mongo/tools/export.cpp +++ b/src/mongo/tools/export.cpp @@ -1,5 +1,3 @@ -// export.cpp - /** * Copyright (C) 2008 10gen Inc. * @@ -14,55 +12,42 @@ * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* As a special exception, the copyright holders give permission to link the +* code of portions of this program with the OpenSSL library under certain +* conditions as described in each individual source file and distribute +* linked combinations including the program with the OpenSSL library. You +* must comply with the GNU Affero General Public License in all respects +* for all of the code used other than as permitted herein. If you modify +* file(s) with this exception, you may extend this exception to your +* version of the file(s), but you are not obligated to do so. If you do not +* wish to do so, delete this exception statement from your version. If you +* delete this exception statement from all source files in the program, +* then also delete it in the license file. */ -#include "pch.h" -#include "db/json.h" -#include "mongo/base/initializer.h" -#include "mongo/client/dbclientcursor.h" - -#include "tool.h" +#include "mongo/pch.h" +#include <boost/filesystem/convenience.hpp> +#include <boost/filesystem/operations.hpp> #include <fstream> #include <iostream> -#include <boost/filesystem/convenience.hpp> -#include <boost/filesystem/operations.hpp> -#include <boost/program_options.hpp> +#include "mongo/client/dbclientcursor.h" +#include "mongo/db/json.h" +#include "mongo/tools/mongoexport_options.h" +#include "mongo/tools/tool.h" +#include "mongo/tools/tool_logger.h" +#include "mongo/util/options_parser/option_section.h" using namespace mongo; -namespace po = boost::program_options; - class Export : public Tool { public: - 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") - ("slaveOk,k", po::value<bool>()->default_value(true) , "use secondaries for export if available, default true") - ("forceTableScan", "force a table scan (do not use $snapshot)" ) - ; - _usesstdout = false; - } - - virtual void preSetup() { - if ( hasParam("out") ) { - string out = getParam("out"); - if ( out != "-" ) { - // we write output to standard error by default to avoid - // mangling output, but we don't need to do this if an output - // file was specified - useStandardOutput(true); - } - } - } + Export() : Tool() { } - virtual void printExtraHelp( ostream & out ) { - out << "Export MongoDB data to CSV, TSV or JSON files.\n" << endl; + virtual void printHelp( ostream & out ) { + printMongoExportHelp(&out); } // Turn every double quote character into two double quote characters @@ -107,7 +92,10 @@ public: case jstOID: return "ObjectID(" + object.OID().toString() + ")"; // OIDs are always 24 bytes case Date: - return timeToISOString(object.Date() / 1000); + // We need to check if we can actually format this date. See SERVER-13760. + return object.Date().isFormatable() ? + dateToISOStringUTC(object.Date()) : + csvEscape(object.jsonString(Strict, false)); case Timestamp: return csvEscape(object.jsonString(Strict, false)); case RegEx: @@ -134,22 +122,19 @@ public: 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" ) && outfile != "-" ) { - size_t idx = outfile.rfind( "/" ); + if (mongoExportGlobalParams.outputFileSpecified && mongoExportGlobalParams.outputFile != "-") { + size_t idx = mongoExportGlobalParams.outputFile.rfind("/"); if ( idx != string::npos ) { - string dir = outfile.substr( 0 , idx + 1 ); + string dir = mongoExportGlobalParams.outputFile.substr( 0 , idx + 1 ); boost::filesystem::create_directories( dir ); } - ofstream * s = new ofstream( outfile.c_str() , ios_base::out ); + ofstream * s = new ofstream(mongoExportGlobalParams.outputFile.c_str(), ios_base::out); fileStream.reset( s ); outPtr = s; if ( ! s->good() ) { - cerr << "couldn't open [" << outfile << "]" << endl; + cerr << "couldn't open [" << mongoExportGlobalParams.outputFile << "]" << endl; return -1; } } @@ -166,18 +151,17 @@ public: return 1; } - if ( hasParam( "fields" ) || csv ) { - needFields(); + if (toolGlobalParams.fieldsSpecified || mongoExportGlobalParams.csv) { - // we can't use just _fieldsObj since we support everything getFieldDotted does + // we can't use just toolGlobalParams.fields 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() , '.' ); + for (std::vector<std::string>::iterator i = toolGlobalParams.fields.begin(); + i != toolGlobalParams.fields.end(); i++) { + std::string f = str::before(*i, '.'); if ( seen.insert( f ).second ) b.append( f , 1 ); } @@ -187,38 +171,47 @@ public: } - if ( csv && _fields.size() == 0 ) { + if (mongoExportGlobalParams.csv && !toolGlobalParams.fieldsSpecified) { cerr << "csv mode requires a field list" << endl; return -1; } - Query q( getParam( "query" , "" ) ); - if ( q.getFilter().isEmpty() && !hasParam("dbpath") && !hasParam("forceTableScan") ) - q.snapshot(); + Query q(mongoExportGlobalParams.query); + if (mongoExportGlobalParams.sort != "") { + BSONObj sortSpec = mongo::fromjson(mongoExportGlobalParams.sort); + q.sort(sortSpec); + } - bool slaveOk = _params["slaveOk"].as<bool>(); + if (mongoExportGlobalParams.snapShotQuery) { + q.snapshot(); + } - auto_ptr<DBClientCursor> cursor = conn().query( ns.c_str() , q , 0 , 0 , fieldsToReturn , ( slaveOk ? QueryOption_SlaveOk : 0 ) | QueryOption_NoCursorTimeout ); + auto_ptr<DBClientCursor> cursor = conn().query(ns.c_str(), q, + mongoExportGlobalParams.limit, mongoExportGlobalParams.skip, fieldsToReturn, + (mongoExportGlobalParams.slaveOk ? QueryOption_SlaveOk : 0) | + QueryOption_NoCursorTimeout); - if ( csv ) { - for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ) { - if ( i != _fields.begin() ) + if (mongoExportGlobalParams.csv) { + for (std::vector<std::string>::iterator i = toolGlobalParams.fields.begin(); + i != toolGlobalParams.fields.end(); i++) { + if (i != toolGlobalParams.fields.begin()) out << ","; out << *i; } out << endl; } - if (jsonArray) + if (mongoExportGlobalParams.jsonArray) out << '['; long long num = 0; while ( cursor->more() ) { num++; BSONObj obj = cursor->next(); - if ( csv ) { - for ( vector<string>::iterator i=_fields.begin(); i != _fields.end(); i++ ) { - if ( i != _fields.begin() ) + if (mongoExportGlobalParams.csv) { + for (std::vector<std::string>::iterator i = toolGlobalParams.fields.begin(); + i != toolGlobalParams.fields.end(); i++) { + if (i != toolGlobalParams.fields.begin()) out << ","; const BSONElement & e = obj.getFieldDotted(i->c_str()); if ( ! e.eoo() ) { @@ -228,27 +221,23 @@ public: out << endl; } else { - if (jsonArray && num != 1) + if (mongoExportGlobalParams.jsonArray && num != 1) out << ','; out << obj.jsonString(); - if (!jsonArray) + if (!mongoExportGlobalParams.jsonArray) out << endl; } } - if (jsonArray) + if (mongoExportGlobalParams.jsonArray) out << ']' << endl; - cerr << "exported " << num << " records" << endl; + toolInfoOutput() << "exported " << num << " records" << endl; return 0; } }; -int main( int argc , char ** argv, char** envp ) { - mongo::runGlobalInitializersOrDie(argc, argv, envp); - Export e; - return e.main( argc , argv ); -} +REGISTER_MONGO_TOOL(Export); |
