// getObjectFromByteArg takes an object in extended JSON, and converts it to an object that // can be passed straight to db.collection.find(...) as a query or sort critera. // Returns an error if the string is not valid JSON, or extended JSON. func getObjectFromByteArg(queryRaw []byte) (map[string]interface{}, error) { parsedJSON := map[string]interface{}{} err := json.Unmarshal(queryRaw, &parsedJSON) if err != nil { return nil, fmt.Errorf("query '%v' is not valid JSON: %v", queryRaw, err) } err = bsonutil.ConvertJSONDocumentToBSON(parsedJSON) if err != nil { return nil, err } return parsedJSON, nil }
// MetadataFromJSON takes a slice of JSON bytes and unmarshals them into usable // collection options and indexes for restoring collections. func (restore *MongoRestore) MetadataFromJSON(jsonBytes []byte) (bson.D, []IndexDocument, error) { if len(jsonBytes) == 0 { // skip metadata parsing if the file is empty return nil, nil, nil } meta := &Metadata{} err := json.Unmarshal(jsonBytes, meta) if err != nil { return nil, nil, err } // first get the ordered key information for each index, // then merge it with a set of options stored as a map metaAsMap := metaDataMapIndex{} err = json.Unmarshal(jsonBytes, &metaAsMap) if err != nil { return nil, nil, fmt.Errorf("error unmarshalling metadata as map: %v", err) } for i := range meta.Indexes { // remove "key" from the map so we can decode it properly later delete(metaAsMap.Indexes[i], "key") // parse extra index fields meta.Indexes[i].Options = metaAsMap.Indexes[i] if err := bsonutil.ConvertJSONDocumentToBSON(meta.Indexes[i].Options); err != nil { return nil, nil, fmt.Errorf("extended json error: %v", err) } // parse the values of the index keys, so we can support extended json for pos, field := range meta.Indexes[i].Key { meta.Indexes[i].Key[pos].Value, err = bsonutil.ParseJSONValue(field.Value) if err != nil { return nil, nil, fmt.Errorf("extended json in '%v' field: %v", field.Name, err) } } } // parse the values of options fields, to support extended json meta.Options, err = bsonutil.GetExtendedBsonD(meta.Options) if err != nil { return nil, nil, fmt.Errorf("extended json in 'options': %v", err) } return meta.Options, meta.Indexes, nil }
// ImportDocument converts the given JSON object to a BSON object func (jsonImporter *JSONImportInput) ImportDocument() (bson.M, error) { var document bson.M if jsonImporter.IsArray { if err := jsonImporter.readJSONArraySeparator(); err != nil { return nil, err } } if err := jsonImporter.Decoder.Decode(&document); err != nil { return nil, err } // reinitialize the reader with data left in the decoder's buffer and the // handle to the underlying reader jsonImporter.Reader = io.MultiReader(jsonImporter.Decoder.Buffered(), jsonImporter.readerPtr) // convert any data produced by mongoexport to the appropriate underlying // extended BSON type. NOTE: this assumes specially formated JSON values // in the input JSON - values such as: // // { $oid: 53cefc71b14ed89d84856287 } // // should be interpreted as: // // ObjectId("53cefc71b14ed89d84856287") // // This applies for all the other extended JSON types MongoDB supports if err := bsonutil.ConvertJSONDocumentToBSON(document); err != nil { return nil, err } jsonImporter.NumImported++ // reinitialize the decoder with its existing buffer and the underlying // reader jsonImporter.Decoder = json.NewDecoder(jsonImporter.Reader) return document, nil }
// Convert mongo extended json types from their strict JSON representation // to appropriate bson types // http://docs.mongodb.org/manual/reference/mongodb-extended-json/ func normalizeObj(rawObj Document) error { return bsonutil.ConvertJSONDocumentToBSON(rawObj) }