func main() { spec.RegisterDatabaseFlags() cpuCount := runtime.NumCPU() runtime.GOMAXPROCS(cpuCount) flag.Usage = func() { fmt.Fprintln(os.Stderr, "Usage: csv-export [options] dataset > filename") flag.PrintDefaults() } flag.Parse() if flag.NArg() != 1 { util.CheckError(errors.New("expected dataset arg")) } ds, err := spec.GetDataset(flag.Arg(0)) util.CheckError(err) defer ds.Database().Close() comma, err := csv.StringToRune(*delimiter) util.CheckError(err) err = d.Try(func() { defer profile.MaybeStartProfile().Stop() nomsList, structDesc := csv.ValueToListAndElemDesc(ds.HeadValue(), ds.Database()) csv.Write(nomsList, structDesc, comma, os.Stdout) }) if err != nil { fmt.Println("Failed to export dataset as CSV:") fmt.Println(err) } }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: %s [options] <dataset>\n", os.Args[0]) flag.PrintDefaults() } spec.RegisterDatabaseFlags(flag.CommandLine) flag.Parse(true) if flag.NArg() != 1 { fmt.Fprintln(os.Stderr, "Missing required dataset argument") return } ds, err := spec.GetDataset(flag.Arg(0)) if err != nil { fmt.Fprintf(os.Stderr, "Could not create dataset: %s\n", err) return } defer ds.Database().Close() newVal := uint64(1) if lastVal, ok := ds.MaybeHeadValue(); ok { newVal = uint64(lastVal.(types.Number)) + 1 } _, err = ds.CommitValue(types.Number(newVal)) if err != nil { fmt.Fprintf(os.Stderr, "Error committing: %s\n", err) return } fmt.Println(newVal) }
func start(dataset string, mount mount) { ds, err := spec.GetDataset(dataset) if err != nil { fmt.Fprintf(os.Stderr, "Could not create dataset: %s\n", err) return } hv, ok := ds.MaybeHeadValue() if ok { if !types.IsSubtype(fsType, hv.Type()) { fmt.Fprintf(os.Stderr, "Invalid dataset head: expected type '%s' but found type '%s'\n", fsType.Desc.(types.StructDesc).Name, hv.Type().Desc.(types.StructDesc).Name) return } } else { rootAttr := makeAttr(0777) // create the root directory with maximally permissive permissions rootDir := types.NewStructWithType(directoryType, types.ValueSlice{types.NewMap()}) rootInode := types.NewStructWithType(inodeType, types.ValueSlice{rootAttr, rootDir}) hv = types.NewStructWithType(fsType, types.ValueSlice{rootInode}) } mount(&nomsFS{ FileSystem: pathfs.NewDefaultFileSystem(), ds: ds, head: hv.(types.Struct), mdLock: &sync.Mutex{}, nodes: make(map[hash.Hash]*nNode), }) }
func (s *nomsDiffTestSuite) TestNomsDiffSummarize() { datasetName := "diffSummarizeTest" str := spec.CreateValueSpecString("ldb", s.LdbDir, datasetName) ds, err := spec.GetDataset(str) s.NoError(err) defer ds.Database().Close() ds, err = addCommit(ds, "first commit") s.NoError(err) r1 := spec.CreateHashSpecString("ldb", s.LdbDir, ds.HeadRef().TargetHash()) ds, err = addCommit(ds, "second commit") s.NoError(err) r2 := spec.CreateHashSpecString("ldb", s.LdbDir, ds.HeadRef().TargetHash()) out, _ := s.Run(main, []string{"diff", "--summarize", r1, r2}) s.Contains(out, "Comparing commit values") s.Contains(out, "1 insertion (100.00%), 1 deletion (100.00%), 0 changes (0.00%), (1 value vs 1 value)") out, _ = s.Run(main, []string{"diff", "--summarize", r1 + ".value", r2 + ".value"}) s.NotContains(out, "Comparing commit values") ds, err = ds.CommitValue(types.NewList(types.Number(1), types.Number(2), types.Number(3), types.Number(4))) s.NoError(err) r3 := spec.CreateHashSpecString("ldb", s.LdbDir, ds.HeadRef().TargetHash()) + ".value" ds, err = ds.CommitValue(types.NewList(types.Number(1), types.Number(222), types.Number(4))) s.NoError(err) r4 := spec.CreateHashSpecString("ldb", s.LdbDir, ds.HeadRef().TargetHash()) + ".value" out, _ = s.Run(main, []string{"diff", "--summarize", r3, r4}) s.Contains(out, "1 insertion (25.00%), 2 deletions (50.00%), 0 changes (0.00%), (4 values vs 3 values)") }
func runDs(args []string) int { if toDelete != "" { set, err := spec.GetDataset(toDelete) d.CheckError(err) oldCommitRef, errBool := set.MaybeHeadRef() if !errBool { d.CheckError(fmt.Errorf("Dataset %v not found", set.ID())) } store, err := set.Database().Delete(set.ID()) d.CheckError(err) defer store.Close() fmt.Printf("Deleted dataset %v (was %v)\n\n", set.ID(), oldCommitRef.TargetHash().String()) } else { if len(args) != 1 { d.CheckError(fmt.Errorf("Database arg missing")) } store, err := spec.GetDatabase(args[0]) d.CheckError(err) defer store.Close() store.Datasets().IterAll(func(k, v types.Value) { fmt.Println(k) }) } return 0 }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: %s [options] <dataset>\n", os.Args[0]) flag.PrintDefaults() } spec.RegisterDatabaseFlags() flag.Parse() if flag.NArg() != 1 { util.CheckError(errors.New("expected dataset arg")) } ds, err := spec.GetDataset(flag.Arg(0)) util.CheckError(err) defer ds.Database().Close() newVal := uint64(1) if lastVal, ok := ds.MaybeHeadValue(); ok { newVal = uint64(lastVal.(types.Number)) + 1 } _, err = ds.Commit(types.Number(newVal)) d.Exp.NoError(err) fmt.Println(newVal) }
func testCommitInResults(s *nomsLogTestSuite, str string, i int) { ds, err := spec.GetDataset(str) s.NoError(err) ds, err = ds.CommitValue(types.Number(i)) s.NoError(err) commit := ds.Head() ds.Database().Close() res, _ := s.Run(main, []string{"log", str}) s.Contains(res, commit.Hash().String()) }
func (s *nomsLogTestSuite) TestNomsLog() { datasetName := "dsTest" str := spec.CreateValueSpecString("ldb", s.LdbDir, datasetName) ds, err := spec.GetDataset(str) s.NoError(err) ds.Database().Close() s.Panics(func() { s.Run(main, []string{"log", str}) }) testCommitInResults(s, str, 1) testCommitInResults(s, str, 2) }
func writeTestData(str string, value types.Value) types.Ref { ds, err := spec.GetDataset(str) d.Chk.NoError(err) r1 := ds.Database().WriteValue(value) ds, err = ds.CommitValue(r1) d.Chk.NoError(err) err = ds.Database().Close() d.Chk.NoError(err) return r1 }
func (s *nomsDiffTestSuite) TestNomsDiffOutputNotTruncated() { datasetName := "diffTest" str := spec.CreateValueSpecString("ldb", s.LdbDir, datasetName) ds, err := spec.GetDataset(str) s.NoError(err) ds, err = addCommit(ds, "first commit") s.NoError(err) r1 := spec.CreateValueSpecString("ldb", s.LdbDir, "#"+ds.HeadRef().TargetHash().String()) ds, err = addCommit(ds, "second commit") s.NoError(err) r2 := spec.CreateValueSpecString("ldb", s.LdbDir, "#"+ds.HeadRef().TargetHash().String()) ds.Database().Close() out, _ := s.Run(main, []string{"diff", r1, r2}) s.True(strings.HasSuffix(out, "\"second commit\"\n }\n"), out) }
func main() { toDelete := flag.String("d", "", "dataset to delete") flag.Usage = func() { fmt.Fprintln(os.Stderr, "Noms dataset management\n") fmt.Fprintln(os.Stderr, "Usage: noms ds [<database> | -d <dataset>]") flag.PrintDefaults() fmt.Fprintf(os.Stderr, "\nFor detailed information on spelling datastores and datasets, see: at https://github.com/attic-labs/noms/blob/master/doc/spelling.md.\n\n") } flag.Parse() if *toDelete != "" { set, err := spec.GetDataset(*toDelete) util.CheckError(err) oldCommitRef, errBool := set.MaybeHeadRef() if !errBool { util.CheckError(fmt.Errorf("Dataset %v not found", set.ID())) } store, err := set.Database().Delete(set.ID()) util.CheckError(err) defer store.Close() fmt.Printf("Deleted dataset %v (was %v)\n\n", set.ID(), oldCommitRef.TargetHash().String()) } else { if flag.NArg() != 1 { flag.Usage() return } store, err := spec.GetDatabase(flag.Arg(0)) util.CheckError(err) defer store.Close() store.Datasets().IterAll(func(k, v types.Value) { fmt.Println(k) }) } }
func main() { var dsStr = flag.String("ds", "", "noms dataset to read/write from") flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: %s [flags] [command] [command-args]\n\n", os.Args[0]) fmt.Fprintln(os.Stderr, "Flags:") flag.PrintDefaults() fmt.Fprintln(os.Stderr, "\nCommands:") fmt.Fprintln(os.Stderr, "\tadd-person <id> <name> <title>") fmt.Fprintln(os.Stderr, "\tlist-persons") } flag.Parse() if flag.NArg() == 0 { fmt.Fprintln(os.Stderr, "Not enough arguments") return } if *dsStr == "" { fmt.Fprintln(os.Stderr, "Required flag '-ds' not set") return } ds, err := spec.GetDataset(*dsStr) defer ds.Database().Close() if err != nil { fmt.Fprintf(os.Stderr, "Could not create dataset: %s\n", err) return } switch flag.Arg(0) { case "add-person": addPerson(ds) case "list-persons": listPersons(ds) default: fmt.Fprintf(os.Stderr, "Unknown command: %s\n", flag.Arg(0)) } }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "usage: %s <url> <dataset>\n", os.Args[0]) flag.PrintDefaults() } spec.RegisterDatabaseFlags(flag.CommandLine) flag.Parse(true) if len(flag.Args()) != 2 { d.CheckError(errors.New("expected url and dataset flags")) } ds, err := spec.GetDataset(flag.Arg(1)) d.CheckError(err) url := flag.Arg(0) if url == "" { flag.Usage() } res, err := http.Get(url) if err != nil { log.Fatalf("Error fetching %s: %+v\n", url, err) } else if res.StatusCode != 200 { log.Fatalf("Error fetching %s: %s\n", url, res.Status) } defer res.Body.Close() var jsonObject interface{} err = json.NewDecoder(res.Body).Decode(&jsonObject) if err != nil { log.Fatalln("Error decoding JSON: ", err) } _, err = ds.CommitValue(jsontonoms.NomsValueFromDecodedJSON(jsonObject, true)) d.PanicIfError(err) ds.Database().Close() }
func main() { cpuCount := runtime.NumCPU() runtime.GOMAXPROCS(cpuCount) flag.Usage = func() { fmt.Fprintf(os.Stderr, "Moves datasets between or within databases\n\n") fmt.Fprintf(os.Stderr, "noms sync [options] <source-object> <dest-dataset>\n\n") flag.PrintDefaults() fmt.Fprintf(os.Stderr, "\nFor detailed information on spelling objects and datasets, see: at https://github.com/attic-labs/noms/blob/master/doc/spelling.md.\n\n") } spec.RegisterDatabaseFlags() flag.Parse() if flag.NArg() != 2 { util.CheckError(errors.New("expected a source object and destination dataset")) } sourceStore, sourceObj, err := spec.GetPath(flag.Arg(0)) util.CheckError(err) defer sourceStore.Close() sinkDataset, err := spec.GetDataset(flag.Arg(1)) util.CheckError(err) defer sinkDataset.Database().Close() err = d.Try(func() { defer profile.MaybeStartProfile().Stop() var err error sinkDataset, err = sinkDataset.Pull(sourceStore, types.NewRef(sourceObj), int(*p)) d.Exp.NoError(err) }) if err != nil { log.Fatal(err) } }
func main() { // Actually the delimiter uses runes, which can be multiple characters long. // https://blog.golang.org/strings delimiter := flag.String("delimiter", ",", "field delimiter for csv file, must be exactly one character long.") spec.RegisterDatabaseFlags(flag.CommandLine) profile.RegisterProfileFlags(flag.CommandLine) flag.Usage = func() { fmt.Fprintln(os.Stderr, "Usage: csv-export [options] dataset > filename") flag.PrintDefaults() } flag.Parse(true) if flag.NArg() != 1 { d.CheckError(errors.New("expected dataset arg")) } ds, err := spec.GetDataset(flag.Arg(0)) d.CheckError(err) defer ds.Database().Close() comma, err := csv.StringToRune(*delimiter) d.CheckError(err) err = d.Try(func() { defer profile.MaybeStartProfile().Stop() nomsList, structDesc := csv.ValueToListAndElemDesc(ds.HeadValue(), ds.Database()) csv.Write(nomsList, structDesc, comma, os.Stdout) }) if err != nil { fmt.Println("Failed to export dataset as CSV:") fmt.Println(err) } }
func main() { comment := flag.String("comment", "", "comment to add to commit's meta data") stdin := flag.Bool("stdin", false, "read blob from stdin") spec.RegisterDatabaseFlags(flag.CommandLine) flag.Usage = func() { fmt.Fprintf(os.Stderr, "Fetches a URL, file, or stdin into a noms blob\n\nUsage: %s [--stdin?] [url-or-local-path?] [dataset]\n", os.Args[0]) flag.PrintDefaults() } flag.Parse(true) if !(*stdin && flag.NArg() == 1) && flag.NArg() != 2 { flag.Usage() os.Exit(-1) } start = time.Now() ds, err := spec.GetDataset(flag.Arg(flag.NArg() - 1)) d.CheckErrorNoUsage(err) defer ds.Database().Close() var r io.Reader var contentLength int64 var sourceType, sourceVal string if *stdin { r = os.Stdin contentLength = -1 } else if url := flag.Arg(0); strings.HasPrefix(url, "http") { resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %s\n", url, err) return } switch resp.StatusCode / 100 { case 4, 5: fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %d (%s)\n", url, resp.StatusCode, resp.Status) return } r = resp.Body contentLength = resp.ContentLength sourceType, sourceVal = "url", url } else { // assume it's a file f, err := os.Open(url) if err != nil { fmt.Fprintf(os.Stderr, "Invalid URL %s - does not start with 'http' and isn't local file either. fopen error: %s", url, err) return } s, err := f.Stat() if err != nil { fmt.Fprintf(os.Stderr, "Could not stat file %s: %s", url, err) return } r = f contentLength = s.Size() sourceType, sourceVal = "file", url } pr := progressreader.New(r, getStatusPrinter(contentLength)) b := types.NewStreamingBlob(pr, ds.Database()) mi := metaInfoForCommit(sourceType, sourceVal, *comment) ds, err = ds.Commit(b, dataset.CommitOptions{Meta: mi}) if err != nil { d.Chk.Equal(datas.ErrMergeNeeded, err) fmt.Fprintf(os.Stderr, "Could not commit, optimistic concurrency failed.") return } status.Done() fmt.Println("Done") }
func main() { err := d.Try(func() { spec.RegisterDatabaseFlags(flag.CommandLine) profile.RegisterProfileFlags(flag.CommandLine) flag.Usage = customUsage flag.Parse(true) if flag.NArg() != 2 { d.CheckError(errors.New("Expected directory path followed by dataset")) } dir := flag.Arg(0) ds, err := spec.GetDataset(flag.Arg(1)) d.CheckError(err) defer profile.MaybeStartProfile().Stop() cpuCount := runtime.NumCPU() filesChan := make(chan fileIndex, 1024) refsChan := make(chan refIndex, 1024) getFilePaths := func() { index := 0 err := filepath.Walk(dir, func(path string, info os.FileInfo, err error) error { d.PanicIfTrue(err != nil, "Cannot traverse directories") if !info.IsDir() && filepath.Ext(path) == ".xml" { filesChan <- fileIndex{path, index} index++ } return nil }) d.PanicIfError(err) close(filesChan) } wg := sync.WaitGroup{} importXML := func() { expectedType := types.NewMap() for f := range filesChan { file, err := os.Open(f.path) d.PanicIfTrue(err != nil, "Error getting XML") xmlObject, err := mxj.NewMapXmlReader(file) d.PanicIfTrue(err != nil, "Error decoding XML") object := xmlObject.Old() file.Close() nomsObj := jsontonoms.NomsValueFromDecodedJSON(object, false) d.Chk.IsType(expectedType, nomsObj) var r types.Ref if !*noIO { r = ds.Database().WriteValue(nomsObj) } refsChan <- refIndex{r, f.index} } wg.Done() } go getFilePaths() for i := 0; i < cpuCount*8; i++ { wg.Add(1) go importXML() } go func() { wg.Wait() close(refsChan) // done converting xml to noms }() refList := refIndexList{} for r := range refsChan { refList = append(refList, r) } sort.Sort(refList) refs := make([]types.Value, len(refList)) for idx, r := range refList { refs[idx] = r.ref } rl := types.NewList(refs...) if !*noIO { _, err := ds.CommitValue(rl) d.PanicIfError(err) } }) if err != nil { log.Fatal(err) } }
func main() { // Actually the delimiter uses runes, which can be multiple characters long. // https://blog.golang.org/strings delimiter := flag.String("delimiter", ",", "field delimiter for csv file, must be exactly one character long.") comment := flag.String("comment", "", "comment to add to commit's meta data") header := flag.String("header", "", "header row. If empty, we'll use the first row of the file") name := flag.String("name", "Row", "struct name. The user-visible name to give to the struct type that will hold each row of data.") columnTypes := flag.String("column-types", "", "a comma-separated list of types representing the desired type of each column. if absent all types default to be String") pathDescription := "noms path to blob to import" path := flag.String("path", "", pathDescription) flag.StringVar(path, "p", "", pathDescription) dateFlag := flag.String("date", "", fmt.Sprintf(`date of commit in ISO 8601 format ("%s"). By default, the current date is used.`, dateFormat)) noProgress := flag.Bool("no-progress", false, "prevents progress from being output if true") destType := flag.String("dest-type", "list", "the destination type to import to. can be 'list' or 'map:<pk>', where <pk> is the index position (0-based) of the column that is a the unique identifier for the column") skipRecords := flag.Uint("skip-records", 0, "number of records to skip at beginning of file") destTypePattern := regexp.MustCompile("^(list|map):(\\d+)$") spec.RegisterDatabaseFlags(flag.CommandLine) profile.RegisterProfileFlags(flag.CommandLine) flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: csv-import [options] <csvfile> <dataset>\n\n") flag.PrintDefaults() } flag.Parse(true) var err error switch { case flag.NArg() == 0: err = errors.New("Maybe you put options after the dataset?") case flag.NArg() == 1 && *path == "": err = errors.New("If <csvfile> isn't specified, you must specify a noms path with -p") case flag.NArg() == 2 && *path != "": err = errors.New("Cannot specify both <csvfile> and a noms path with -p") case flag.NArg() > 2: err = errors.New("Too many arguments") } d.CheckError(err) var date = *dateFlag if date == "" { date = time.Now().UTC().Format(dateFormat) } else { _, err := time.Parse(dateFormat, date) d.CheckErrorNoUsage(err) } defer profile.MaybeStartProfile().Stop() var r io.Reader var size uint64 var filePath string var dataSetArgN int if *path != "" { db, val, err := spec.GetPath(*path) d.CheckError(err) if val == nil { d.CheckError(fmt.Errorf("Path %s not found\n", *path)) } blob, ok := val.(types.Blob) if !ok { d.CheckError(fmt.Errorf("Path %s not a Blob: %s\n", *path, types.EncodedValue(val.Type()))) } defer db.Close() r = blob.Reader() size = blob.Len() dataSetArgN = 0 } else { filePath = flag.Arg(0) res, err := os.Open(filePath) d.CheckError(err) defer res.Close() fi, err := res.Stat() d.CheckError(err) r = res size = uint64(fi.Size()) dataSetArgN = 1 } if !*noProgress { r = progressreader.New(r, getStatusPrinter(size)) } comma, err := csv.StringToRune(*delimiter) d.CheckErrorNoUsage(err) var dest int var pk int if *destType == "list" { dest = destList } else if match := destTypePattern.FindStringSubmatch(*destType); match != nil { dest = destMap pk, err = strconv.Atoi(match[2]) d.CheckErrorNoUsage(err) } else { fmt.Println("Invalid dest-type: ", *destType) return } cr := csv.NewCSVReader(r, comma) for i := uint(0); i < *skipRecords; i++ { cr.Read() } var headers []string if *header == "" { headers, err = cr.Read() d.PanicIfError(err) } else { headers = strings.Split(*header, string(comma)) } ds, err := spec.GetDataset(flag.Arg(dataSetArgN)) d.CheckError(err) defer ds.Database().Close() kinds := []types.NomsKind{} if *columnTypes != "" { kinds = csv.StringsToKinds(strings.Split(*columnTypes, ",")) } var value types.Value if dest == destList { value, _ = csv.ReadToList(cr, *name, headers, kinds, ds.Database()) } else { value = csv.ReadToMap(cr, headers, pk, kinds, ds.Database()) } mi := metaInfoForCommit(date, filePath, *path, *comment) _, err = ds.Commit(value, dataset.CommitOptions{Meta: mi}) if !*noProgress { status.Clear() } d.PanicIfError(err) }
func main() { flag.Usage = func() { fmt.Fprintf(os.Stderr, "Fetches a URL into a noms blob\n\nUsage: %s <dataset> <url>:\n", os.Args[0]) flag.PrintDefaults() } spec.RegisterDatabaseFlags() flag.Parse() if flag.NArg() != 2 { util.CheckError(errors.New("expected dataset and url arguments")) } ds, err := spec.GetDataset(flag.Arg(0)) util.CheckError(err) defer ds.Database().Close() url := flag.Arg(1) start = time.Now() var pr io.Reader if strings.HasPrefix(url, "http") { resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %s\n", url, err) return } switch resp.StatusCode / 100 { case 4, 5: fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %d (%s)\n", url, resp.StatusCode, resp.Status) return } pr = progressreader.New(resp.Body, getStatusPrinter(resp.ContentLength)) } else { // assume it's a file f, err := os.Open(url) if err != nil { fmt.Fprintf(os.Stderr, "Invalid URL %s - does not start with 'http' and isn't local file either. fopen error: %s", url, err) return } s, err := f.Stat() if err != nil { fmt.Fprintf(os.Stderr, "Could not stat file %s: %s", url, err) return } pr = progressreader.New(f, getStatusPrinter(s.Size())) } b := types.NewBlob(pr) ds, err = ds.Commit(b) if err != nil { d.Chk.True(datas.ErrMergeNeeded == err) fmt.Fprintf(os.Stderr, "Could not commit, optimistic concurrency failed.") return } status.Done() fmt.Println("Done") }
func main() { var ( // Actually the delimiter uses runes, which can be multiple characters long. // https://blog.golang.org/strings delimiter = flag.String("delimiter", ",", "field delimiter for csv file, must be exactly one character long.") header = flag.String("header", "", "header row. If empty, we'll use the first row of the file") name = flag.String("name", "Row", "struct name. The user-visible name to give to the struct type that will hold each row of data.") columnTypes = flag.String("column-types", "", "a comma-separated list of types representing the desired type of each column. if absent all types default to be String") noProgress = flag.Bool("no-progress", false, "prevents progress from being output if true") destType = flag.String("dest-type", "list", "the destination type to import to. can be 'list' or 'map:<pk>', where <pk> is the index position (0-based) of the column that is a the unique identifier for the column") destTypePattern = regexp.MustCompile("^(list|map):(\\d+)$") ) spec.RegisterDatabaseFlags() cpuCount := runtime.NumCPU() runtime.GOMAXPROCS(cpuCount) flag.Usage = func() { fmt.Fprintf(os.Stderr, "Usage: csv-import [options] <dataset> <csvfile>\n\n") flag.PrintDefaults() } flag.Parse() if flag.NArg() != 2 { err := fmt.Errorf("Expected exactly two parameters (dataset and path) after flags, but you have %d. Maybe you put a flag after the path?", flag.NArg()) util.CheckError(err) } path := flag.Arg(1) defer profile.MaybeStartProfile().Stop() res, err := os.Open(path) d.Exp.NoError(err) defer res.Close() comma, err := csv.StringToRune(*delimiter) if err != nil { util.CheckError(err) return } var dest int var pk int if *destType == "list" { dest = destList } else if match := destTypePattern.FindStringSubmatch(*destType); match != nil { dest = destMap pk, err = strconv.Atoi(match[2]) d.Chk.NoError(err) } else { fmt.Println("Invalid dest-type: ", *destType) return } fi, err := res.Stat() d.Chk.NoError(err) var r io.Reader = res if !*noProgress { r = progressreader.New(r, getStatusPrinter(uint64(fi.Size()))) } cr := csv.NewCSVReader(r, comma) var headers []string if *header == "" { headers, err = cr.Read() d.Exp.NoError(err) } else { headers = strings.Split(*header, string(comma)) } ds, err := spec.GetDataset(flag.Arg(0)) util.CheckError(err) defer ds.Database().Close() kinds := []types.NomsKind{} if *columnTypes != "" { kinds = csv.StringsToKinds(strings.Split(*columnTypes, ",")) } var value types.Value if dest == destList { value, _ = csv.ReadToList(cr, *name, headers, kinds, ds.Database()) } else { value = csv.ReadToMap(cr, headers, pk, kinds, ds.Database()) } _, err = ds.Commit(value) if !*noProgress { status.Clear() } d.Exp.NoError(err) }
func main() { comment := flag.String("comment", "", "comment to add to commit's meta data") spec.RegisterDatabaseFlags(flag.CommandLine) flag.Usage = func() { fmt.Fprintf(os.Stderr, "Fetches a URL (or file) into a noms blob\n\nUsage: %s <url-or-local-path> <dataset>:\n", os.Args[0]) flag.PrintDefaults() } flag.Parse(true) if flag.NArg() != 2 { d.CheckErrorNoUsage(errors.New("expected dataset and url arguments")) } ds, err := spec.GetDataset(flag.Arg(1)) d.CheckErrorNoUsage(err) defer ds.Database().Close() url := flag.Arg(0) fileOrUrl := "file" start = time.Now() var pr io.Reader if strings.HasPrefix(url, "http") { resp, err := http.Get(url) if err != nil { fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %s\n", url, err) return } switch resp.StatusCode / 100 { case 4, 5: fmt.Fprintf(os.Stderr, "Could not fetch url %s, error: %d (%s)\n", url, resp.StatusCode, resp.Status) return } pr = progressreader.New(resp.Body, getStatusPrinter(resp.ContentLength)) fileOrUrl = "url" } else { // assume it's a file f, err := os.Open(url) if err != nil { fmt.Fprintf(os.Stderr, "Invalid URL %s - does not start with 'http' and isn't local file either. fopen error: %s", url, err) return } s, err := f.Stat() if err != nil { fmt.Fprintf(os.Stderr, "Could not stat file %s: %s", url, err) return } pr = progressreader.New(f, getStatusPrinter(s.Size())) fileOrUrl = "file" } b := types.NewStreamingBlob(pr, ds.Database()) mi := metaInfoForCommit(fileOrUrl, url, *comment) ds, err = ds.Commit(b, dataset.CommitOptions{Meta: mi}) if err != nil { d.Chk.Equal(datas.ErrMergeNeeded, err) fmt.Fprintf(os.Stderr, "Could not commit, optimistic concurrency failed.") return } status.Done() fmt.Println("Done") }