예제 #1
0
// runExecute is the code that implements the execute command.
func runExecute(cmd *cobra.Command, args []string) error {
	cmd.Printf("Executing View : Name[%s]\n", execute.viewName)

	// Validate the input parameters.
	if execute.viewName == "" || execute.itemKey == "" {
		return fmt.Errorf("view name and item key must be specified")
	}

	// Ready the view parameters.
	viewParams := wire.ViewParams{
		ViewName:          execute.viewName,
		ItemKey:           execute.itemKey,
		ResultsCollection: execute.resultsCollection,
		BufferLimit:       execute.bufferLimit,
	}

	// Execute the view.
	results, err := wire.Execute("", mgoDB, graphDB, &viewParams)
	if err != nil {
		return err
	}

	// Prepare the results for printing.
	data, err := json.MarshalIndent(results, "", "    ")
	if err != nil {
		return err
	}

	cmd.Printf("\n%s\n\n", string(data))
	cmd.Println("\n", "Executing View : Executed")
	return nil
}
예제 #2
0
// materializeView executes a view, creates a temporary collection for the view, and
// modifies the query to query the temporary collection.
func materializeView(context interface{}, db *db.DB, q *query.Query, vars map[string]string) (string, error) {

	// Make sure we have a valid connection to the graph.
	graph, err := db.GraphHandle(context)
	if err != nil {
		return "", err
	}

	// Make sure we have the information we need to execute the view.
	viewName, ok := vars["view"]
	if !ok {
		return "", fmt.Errorf("Vars does not include \"view\".")
	}

	itemKey, ok := vars["item"]
	if !ok {
		return "", fmt.Errorf("Vars does not include \"item\".")
	}

	// Generate a unique name for the collection.
	viewCol := uuid.New()

	// Prepare the parameters for executing the view.
	viewParams := wire.ViewParams{
		ViewName:          viewName,
		ItemKey:           itemKey,
		ResultsCollection: viewCol,
	}

	// Execute the view.
	if _, err := wire.Execute(context, db, graph, &viewParams); err != nil {
		return viewCol, err
	}

	// Provide the query with the temporary collection name.
	q.Collection = viewCol

	return viewCol, nil
}
예제 #3
0
// TestExecuteViews tests the execution of different views.
func TestExecuteViews(t *testing.T) {
	db, store := setup(t)
	defer teardown(t, db, store)

	// Build our table of the different test sets.
	execViews := []struct {
		typ   string
		views []execView
	}{
		{typ: "Positive", views: getPosViews()},
		{typ: "Negative", views: getNegViews()},
	}

	// Iterate over all the different test view.
	for _, ev := range execViews {

		t.Logf("Given the need to execute %s view tests.", ev.typ)
		{
			for _, vw := range ev.views {

				// Setup a sub-test for each test view.
				tf := func(t *testing.T) {
					t.Logf("\tWhen using the view named %s", vw.viewName)
					{
						// Form the view parameters.
						viewParams := wire.ViewParams{
							ViewName:          wirePrefix + vw.viewName,
							ItemKey:           wirePrefix + vw.itemKey,
							ResultsCollection: vw.collection,
							BufferLimit:       vw.bufferLimit,
						}

						// Generate the view.
						result, err := wire.Execute(tests.Context, db, store, &viewParams)
						if err != nil && !vw.fail {
							t.Fatalf("\t%s\tShould be able to execute the view", tests.Failed)
						}
						t.Logf("\t%s\tShould be able to execute the view.", tests.Success)
						if err != nil && vw.fail {
							errDoc, ok := result.Results.(bson.M)
							if !ok || len(errDoc["error"].(string)) == 0 {
								t.Fatalf("\t%s\tShould return a single error document : %s", tests.Failed, err)
							}
							t.Logf("\t%s\tShould return a single error document.", tests.Success)
							return
						}

						// Process the results in mongo if the view is persisted.
						var viewItems []bson.M
						if len(vw.collection) > 0 {

							// Check the result message.
							msg, ok := result.Results.(bson.M)
							if !ok || msg["number_of_results"] != vw.number {
								t.Fatalf("\t%s\tShould be able to get %d items in the view", tests.Failed, vw.number)
							}
							t.Logf("\t%s\tShould be able to get %d items in the view.", tests.Success, vw.number)

							// Query the output collection.
							f := func(c *mgo.Collection) error {
								return c.Find(nil).All(&viewItems)
							}

							if err := db.ExecuteMGO(tests.Context, "testcollection", f); err != nil {
								t.Fatalf("\t%s\tShould be able to query the output collection : %s", tests.Failed, err)
							}
							t.Logf("\t%s\tShould be able to query the output collection.", tests.Success)

							// Verify that we get the same number of items back.
							if len(viewItems) != vw.number {
								t.Fatalf("\t%s\tShould be able to get %d items from the output collection", tests.Failed, vw.number)
							}
							t.Logf("\t%s\tShould be able to get %d items from the output collection.", tests.Success, vw.number)

							// Delete the persisted collection to clean up.
							f = func(c *mgo.Collection) error {
								return c.DropCollection()
							}

							if err := db.ExecuteMGO(tests.Context, vw.collection, f); err != nil {
								t.Fatalf("\t%s\tShould be able to drop the output collection : %s", tests.Failed, err)
							}
							t.Logf("\t%s\tShould be able to drop the output collection.", tests.Success)

						}

						// Otherwise, get the items directly from the result.
						var ok bool
						if vw.collection == "" {
							viewItems, ok = result.Results.([]bson.M)
							if !ok || len(viewItems) != vw.number {
								t.Fatalf("\t%s\tShould be able to get %d items in the view", tests.Failed, vw.number)
							}
							t.Logf("\t%s\tShould be able to get %d items in the view.", tests.Success, vw.number)
						}

						// Check the content of the items returned.
						commonData := wire.Result{
							Results: viewItems,
						}
						data, err := json.Marshal(commonData)
						if err != nil {
							t.Errorf("\t%s\tShould be able to marshal the result : %s", tests.Failed, err)
							return
						}
						t.Logf("\t%s\tShould be able to marshal the result.", tests.Success)

						for _, rslt := range vw.results {

							// We just need to find the string inside the result.
							if !strings.Contains(string(data), rslt) {
								t.Log("\t\tRsl:", string(data))
								for _, rslt := range vw.results {
									t.Log("\t\tExp:", rslt)
								}
								t.Errorf("\t%s\tShould have the correct result.", tests.Failed)
								return
							}
						}
						t.Logf("\t%s\tShould have the correct result", tests.Success)
						return
					}
				}

				t.Run(vw.viewName, tf)
			}
		}
	}
}