// ValidateSettings returns an error if any settings specified on the command line // were invalid, or nil if they are valid. func (exp *MongoExport) ValidateSettings() error { // Namespace must have a valid database if none is specified, // use 'test' if exp.ToolOptions.Namespace.DB == "" { exp.ToolOptions.Namespace.DB = "test" } if exp.ToolOptions.Namespace.Collection == "" { return fmt.Errorf("must specify a collection") } if err := util.ValidateCollectionName(exp.ToolOptions.Namespace.Collection); err != nil { return err } exp.OutputOpts.Type = strings.ToLower(exp.OutputOpts.Type) if exp.ToolOptions.HiddenOptions.CSVOutputType { log.Log(log.Always, "csv flag is deprecated; please use --type=csv instead") exp.OutputOpts.Type = CSV } if exp.OutputOpts.Type == "" { // special error for an empty type value return fmt.Errorf("--type cannot be empty") } if exp.OutputOpts.Type != CSV && exp.OutputOpts.Type != JSON { return fmt.Errorf("invalid output type '%v', choose 'json' or 'csv'", exp.OutputOpts.Type) } if exp.InputOpts.Query != "" && exp.InputOpts.ForceTableScan { return fmt.Errorf("cannot use --forceTableScan when specifying --query") } if exp.InputOpts.Query != "" && exp.InputOpts.QueryFile != "" { return fmt.Errorf("either --query or --queryFile can be specified as a query option") } if exp.InputOpts != nil && exp.InputOpts.HasQuery() { content, err := exp.InputOpts.GetQuery() if err != nil { return err } _, err2 := getObjectFromByteArg(content) if err2 != nil { return err2 } } if exp.InputOpts != nil && exp.InputOpts.Sort != "" { _, err := getSortFromArg(exp.InputOpts.Sort) if err != nil { return err } } return nil }
// ValidateSettings ensures that the tool specific options supplied for // MongoImport are valid. func (imp *MongoImport) ValidateSettings(args []string) error { // namespace must have a valid database; if none is specified, use 'test' if imp.ToolOptions.DB == "" { imp.ToolOptions.DB = "test" } err := util.ValidateDBName(imp.ToolOptions.DB) if err != nil { return fmt.Errorf("invalid database name: %v", err) } imp.InputOptions.Type = strings.ToLower(imp.InputOptions.Type) // use JSON as default input type if imp.InputOptions.Type == "" { imp.InputOptions.Type = JSON } else { if !(imp.InputOptions.Type == TSV || imp.InputOptions.Type == JSON || imp.InputOptions.Type == CSV) { return fmt.Errorf("unknown type %v", imp.InputOptions.Type) } } // ensure headers are supplied for CSV/TSV if imp.InputOptions.Type == CSV || imp.InputOptions.Type == TSV { if !imp.InputOptions.HeaderLine { if imp.InputOptions.Fields == nil && imp.InputOptions.FieldFile == nil { return fmt.Errorf("must specify --fields, --fieldFile or --headerline to import this file type") } if imp.InputOptions.FieldFile != nil && *imp.InputOptions.FieldFile == "" { return fmt.Errorf("--fieldFile can not be empty string") } if imp.InputOptions.Fields != nil && imp.InputOptions.FieldFile != nil { return fmt.Errorf("incompatible options: --fields and --fieldFile") } } else { if imp.InputOptions.Fields != nil { return fmt.Errorf("incompatible options: --fields and --headerline") } if imp.InputOptions.FieldFile != nil { return fmt.Errorf("incompatible options: --fieldFile and --headerline") } } if _, err := ValidatePG(imp.InputOptions.ParseGrace); err != nil { return err } } else { // input type is JSON if imp.InputOptions.HeaderLine { return fmt.Errorf("can not use --headerline when input type is JSON") } if imp.InputOptions.Fields != nil { return fmt.Errorf("can not use --fields when input type is JSON") } if imp.InputOptions.FieldFile != nil { return fmt.Errorf("can not use --fieldFile when input type is JSON") } if imp.IngestOptions.IgnoreBlanks { return fmt.Errorf("can not use --ignoreBlanks when input type is JSON") } if imp.InputOptions.ColumnsHaveTypes { return fmt.Errorf("can not use --columnsHaveTypes when input type is JSON") } } // deprecated if imp.IngestOptions.Upsert == true { imp.IngestOptions.Mode = modeUpsert } // parse UpsertFields, may set default mode to modeUpsert if imp.IngestOptions.UpsertFields != "" { if imp.IngestOptions.Mode == "" { imp.IngestOptions.Mode = modeUpsert } else if imp.IngestOptions.Mode == modeInsert { return fmt.Errorf("can not use --upsertFields with --mode=insert") } imp.upsertFields = strings.Split(imp.IngestOptions.UpsertFields, ",") if err := validateFields(imp.upsertFields); err != nil { return fmt.Errorf("invalid --upsertFields argument: %v", err) } } else if imp.IngestOptions.Mode != modeInsert { imp.upsertFields = []string{"_id"} } // set default mode, must be after parsing UpsertFields if imp.IngestOptions.Mode == "" { imp.IngestOptions.Mode = modeInsert } // double-check mode choices if !(imp.IngestOptions.Mode == modeInsert || imp.IngestOptions.Mode == modeUpsert || imp.IngestOptions.Mode == modeMerge) { return fmt.Errorf("invalid --mode argument: %v", imp.IngestOptions.Mode) } if imp.IngestOptions.Mode != modeInsert { imp.IngestOptions.MaintainInsertionOrder = true log.Logvf(log.Info, "using upsert fields: %v", imp.upsertFields) } // set the number of decoding workers to use for imports if imp.IngestOptions.NumDecodingWorkers <= 0 { imp.IngestOptions.NumDecodingWorkers = imp.ToolOptions.MaxProcs } log.Logvf(log.DebugLow, "using %v decoding workers", imp.IngestOptions.NumDecodingWorkers) // set the number of insertion workers to use for imports if imp.IngestOptions.NumInsertionWorkers <= 0 { imp.IngestOptions.NumInsertionWorkers = 1 } log.Logvf(log.DebugLow, "using %v insert workers", imp.IngestOptions.NumInsertionWorkers) // if --maintainInsertionOrder is set, we can only allow 1 insertion worker if imp.IngestOptions.MaintainInsertionOrder { imp.IngestOptions.NumInsertionWorkers = 1 } // get the number of documents per batch if imp.IngestOptions.BulkBufferSize <= 0 || imp.IngestOptions.BulkBufferSize > 1000 { imp.IngestOptions.BulkBufferSize = 1000 } // ensure no more than one positional argument is supplied if len(args) > 1 { return fmt.Errorf("only one positional argument is allowed") } // ensure either a positional argument is supplied or an argument is passed // to the --file flag - and not both if imp.InputOptions.File != "" && len(args) != 0 { return fmt.Errorf("incompatible options: --file and positional argument(s)") } if imp.InputOptions.File == "" { if len(args) != 0 { // if --file is not supplied, use the positional argument supplied imp.InputOptions.File = args[0] } } // ensure we have a valid string to use for the collection if imp.ToolOptions.Collection == "" { log.Logvf(log.Always, "no collection specified") fileBaseName := filepath.Base(imp.InputOptions.File) lastDotIndex := strings.LastIndex(fileBaseName, ".") if lastDotIndex != -1 { fileBaseName = fileBaseName[0:lastDotIndex] } log.Logvf(log.Always, "using filename '%v' as collection", fileBaseName) imp.ToolOptions.Collection = fileBaseName } err = util.ValidateCollectionName(imp.ToolOptions.Collection) if err != nil { return fmt.Errorf("invalid collection name: %v", err) } return nil }