diff --git a/go.mod b/go.mod index c28a6db..60c611d 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/google/orderedcode v0.0.1 github.com/klauspost/compress v1.17.0 // indirect github.com/kr/pretty v0.3.1 // indirect + github.com/pkg/errors v0.9.1 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/stretchr/testify v1.8.4 github.com/vmihailenco/msgpack/v5 v5.3.5 diff --git a/json.go b/json.go index a5095bc..73be35f 100644 --- a/json.go +++ b/json.go @@ -3,6 +3,7 @@ package clover import ( "bufio" "encoding/json" + "fmt" "os" d "github.com/ostafen/clover/v2/document" @@ -10,7 +11,7 @@ import ( ) // ExportCollection exports an existing collection to a JSON file. -func (db *DB) ExportCollection(collectionName string, exportPath string) error { +func (db *DB) ExportCollection(collectionName string, exportPath string) (err error) { exists, err := db.HasCollection(collectionName) if err != nil { return err @@ -18,23 +19,40 @@ func (db *DB) ExportCollection(collectionName string, exportPath string) error { if !exists { return ErrCollectionNotExist } - - result, err := db.FindAll(query.NewQuery(collectionName)) + q := query.NewQuery(collectionName) + f, err := os.Create(exportPath) if err != nil { return err } + defer f.Close() - docs := make([]map[string]interface{}, 0) - for _, doc := range result { - docs = append(docs, doc.AsMap()) - } - - jsonString, err := json.Marshal(docs) - if err != nil { - return err + defer func() { + if p := recover(); p != nil { + err = fmt.Errorf("internal error: %v", p) + } + }() + isFirst := true + err = db.ForEach(q, func(doc *d.Document) bool { + jsonByte, err := json.Marshal(doc.AsMap()) + if err != nil { + panic(err) + } + jsonString := string(jsonByte) + if isFirst { + isFirst = false + jsonString = "[" + jsonString + } else { + jsonString = "," + jsonString + } + if _, err := f.WriteString(jsonString); err != nil { + panic(err) + } + return true + }) + if err == nil { + _, err = f.WriteString("]") } - - return os.WriteFile(exportPath, jsonString, os.ModePerm) + return } // ImportCollection imports a collection from a JSON file.