// TestInferId tests the inference of an item_id from type and source id. func TestInferId(t *testing.T) { tests.ResetLog() defer tests.DisplayLog() // Test the inference of item_id where source_id is present. d, err := itemfix.GetData("data.json") if err != nil { t.Fatalf("\t%s\tShould be able to load item data.json fixture: %v", tests.Failed, err) } // Create an item out of the data. it := item.Item{ Type: "test_type", Version: 1, Data: d, } // Infer the id from the data. if err := it.InferIDFromData(); err != nil { t.Fatalf("\t%s\tShould be able to InferID from data containing field id: %v", tests.Failed, err) } // Check to ensure the id is as expected. if it.ID != fmt.Sprintf("%s_%v", it.Type, d["id"]) { t.Fatalf("\t%s\tShould infer item_id of form type + \"_\" + source_id: %v", tests.Failed, err) } // Test the inference of item_id where source_id is not present. d, err = itemfix.GetData("data_without_id.json") if err != nil { t.Fatalf("\t%s\tShould be able to load item data_without_id.json fixture: %v", tests.Failed, err) } // Create an item out of the data. it = item.Item{ Type: "test_type", Version: 1, Data: d, } // Ensure that the id fails without the source_id in data. if err := it.InferIDFromData(); err == nil { t.Fatalf("\t%s\tShould not be able to InferID from data not containing field id: %v", tests.Failed, err) } }
// Import receives POSTed data, itemizes it then imports it via the item API. // 204 SuccessNoContent, 400 Bad Request, 404 Not Found, 500 Internal. func (dataHandle) Import(c *web.Context) error { // Unmarshall the data packet from the Request Body. var dat map[string]interface{} if err := json.NewDecoder(c.Request.Body).Decode(&dat); err != nil { return err } // Create a new item with known Type, Version and Data. itm := item.Item{ Type: c.Params["type"], Version: defaultVersion, Data: dat, } // Item.ID must be inferred from the source_id in the data. if err := itm.InferIDFromData(); err != nil { return err } db := c.Ctx["DB"].(*db.DB) graphHandle, err := db.GraphHandle(c.SessionID) if err != nil { return err } // Upsert the item into the items collection and add/remove necessary // quads to/from the graph. if err := sponge.Import(c.SessionID, db, graphHandle, &itm); err != nil { return err } // Respond with no content success. c.Respond(itm, http.StatusOK) return nil }
// viewSave retrieve items for a view and saves those items to a new collection. func viewSave(context interface{}, mgoDB *db.DB, v *view.View, viewParams *ViewParams, ids []string, embeds embeddedRels) error { // Determine the buffer limit that will be used for saving this view. if viewParams.BufferLimit != 0 { bufferLimit = viewParams.BufferLimit } // Form the query. q := bson.M{"item_id": bson.M{"$in": ids}} results, err := mgoDB.BatchedQueryMGO(context, v.Collection, q) if err != nil { return err } // Set up a Bulk upsert. tx, err := mgoDB.BulkOperationMGO(context, viewParams.ResultsCollection) if err != nil { return err } // Group the embedded relationships by item and predicate/tag. embedByItem, err := groupEmbeds(embeds) if err != nil { return err } // Iterate over the view items. var queuedDocs int var result item.Item for results.Next(&result) { // Get the related IDs to embed. itemEmbeds, ok := embedByItem[result.ID] if ok { // Put the related IDs in the item. relMap := make(map[string]interface{}) for k, v := range itemEmbeds { relMap[k] = v } result.Related = relMap } // Queue the upsert of the result. tx.Upsert(bson.M{"item_id": result.ID}, result) queuedDocs++ // If the queued documents for upsert have reached the buffer limit, // run the bulk upsert and re-initialize the bulk operation. if queuedDocs >= bufferLimit { if _, err := tx.Run(); err != nil { return err } tx, err = mgoDB.BulkOperationMGO(context, viewParams.ResultsCollection) if err != nil { return err } queuedDocs = 0 } } if err := results.Close(); err != nil { return err } // Run the bulk operation for any remaining queued documents. if _, err := tx.Run(); err != nil { return err } return nil }