From 66f3aeb21c56580257f4ceb0d828ddb4fb4ccf6f Mon Sep 17 00:00:00 2001 From: travisturner Date: Fri, 10 Jan 2014 17:51:19 -0600 Subject: [PATCH] add support for macros, with Otto javascript to insert filters into macro --- executor/executor.go | 33 ++++++----------------------- executor/utils.go | 50 ++++++++++++++++++++++++++++++++++++++++++++ query/query.go | 31 ++++++++++++++++++--------- 3 files changed, 77 insertions(+), 37 deletions(-) create mode 100644 executor/utils.go diff --git a/executor/executor.go b/executor/executor.go index 8b10a755f..33ca5baab 100644 --- a/executor/executor.go +++ b/executor/executor.go @@ -2,14 +2,12 @@ package executor import ( "fmt" - "io/ioutil" "log" "pilosa/config" "pilosa/core" "pilosa/db" "pilosa/query" "pilosa/util" - "tux21b.org/v1/gocql/uuid" "github.com/davecgh/go-spew/spew" ) @@ -62,12 +60,6 @@ func (self *Executor) RunQueryTest(database_name string, pql string) string { return pql } -type queryListItem struct { - id *uuid.UUID - label string - pql string -} - func (self *Executor) runQuery(database *db.Database, qry *query.Query) { process, err := self.service.GetProcess() if err != nil { @@ -113,37 +105,24 @@ func (self *Executor) RunPQL(database_name string, pql string) interface{} { } else { macros_dir := config.Get("macros").(string) macros_file := macros_dir + "/" + outer_token + ".js" - file_data, err := ioutil.ReadFile(macros_file) - if err != nil { - spew.Dump(err) - } - spew.Dump(file_data) - - // CUSTOM QUERY LIST /////////////// - var query_list []queryListItem - query_list = append(query_list, queryListItem{label: "set1", pql: "set(20, 1)"}) - query_list = append(query_list, queryListItem{label: "set2", pql: "set(20, 1)"}) - query_list = append(query_list, queryListItem{label: "set3", pql: "set(20, 2)"}) - query_list = append(query_list, queryListItem{label: "set4", pql: "set(20, 3)"}) - query_list = append(query_list, queryListItem{label: "set5", pql: "set(20, 4)"}) - query_list = append(query_list, queryListItem{label: "count", pql: "count(get(20))"}) - //////////////////////////////////// + filter := query.TokensToString(tokens) + query_list := GetMacro(macros_file, filter).(query.QueryList) for i, _ := range query_list { - qry := query.QueryForPQL(query_list[i].pql) + qry := query.QueryForPQL(query_list[i].PQL) go self.runQuery(database, qry) - query_list[i].id = qry.Id + query_list[i].Id = qry.Id } // technically, this is blocking on the hold for each query, but it may be ok, since we need them all for the final anyway. final_result := make(map[string]interface{}) for i, _ := range query_list { - final, err := self.service.Hold.Get(query_list[i].id, 10) + final, err := self.service.Hold.Get(query_list[i].Id, 10) if err != nil { spew.Dump(err) } spew.Dump(final) - final_result[query_list[i].label] = final + final_result[query_list[i].Label] = final } return final_result diff --git a/executor/utils.go b/executor/utils.go new file mode 100644 index 000000000..b4ee7cb6e --- /dev/null +++ b/executor/utils.go @@ -0,0 +1,50 @@ +package executor + +import ( + "io/ioutil" + "pilosa/query" + + "github.com/davecgh/go-spew/spew" + "github.com/robertkrimen/otto" +) + +func GetMacro(file_name string, filter string) interface{} { + + file_data, err := ioutil.ReadFile(file_name) + if err != nil { + spew.Dump(err) + } + s := string(file_data[:]) + + js := "query_list = (function (filter){" + s + "})('" + filter + "');" + + Otto := otto.New() + Otto.Run(js) + query_objects, err := Otto.Get("query_list") + + query_list_interface, err := query_objects.Export() + if err != nil { + spew.Dump(err) + } + + var query_list query.QueryList + + // ql is []interface{} + switch ql := query_list_interface.(type) { + case []interface{}: + spew.Dump("INTERFACE", ql) + // q is map[string]interface{} + for i, _ := range ql { + q := ql[i].(map[string]interface{}) + spew.Dump(ql[i]) + spew.Dump(q) + spew.Dump(q["label"].(string)) + spew.Dump(q["pql"].(string)) + query_list = append(query_list, query.QueryListItem{Label: q["label"].(string), PQL: q["pql"].(string)}) + } + default: + spew.Dump("DEFAULT") + } + + return query_list +} diff --git a/query/query.go b/query/query.go index a82711ffb..cba9e5a69 100644 --- a/query/query.go +++ b/query/query.go @@ -2,6 +2,8 @@ package query import ( "pilosa/db" + "strings" + "github.com/davecgh/go-spew/spew" "tux21b.org/v1/gocql/uuid" ) @@ -12,6 +14,14 @@ type QueryResults struct { Data interface{} } +type QueryList []QueryListItem + +type QueryListItem struct { + Id *uuid.UUID + Label string + PQL string +} + type Query struct { Id *uuid.UUID Operation string @@ -43,21 +53,22 @@ func QueryForTokens(tokens []Token) *Query { func QueryPlanForTokens(database *db.Database, tokens []Token, destination *db.Location) *QueryPlan { query := QueryForTokens(tokens) return QueryPlanForQuery(database, query, destination) - /* - //spew.Dump(query) - query_planner := QueryPlanner{Database: database} - id := uuid.RandomUUID() - query_plan := query_planner.Plan(query, &id, destination) - //spew.Dump(query_plan) - return query_plan - */ } func QueryPlanForQuery(database *db.Database, query *Query, destination *db.Location) *QueryPlan { - //spew.Dump(query) query_planner := QueryPlanner{Database: database} id := uuid.RandomUUID() query_plan := query_planner.Plan(query, &id, destination) - //spew.Dump(query_plan) return query_plan } + +func TokensToString(tokens []Token) string { + var str []string + for i, _ := range tokens { + spew.Dump(tokens[i].Text) + str = append(str, tokens[i].Text) + } + // for now, we're just using this function to pull the filter out of the outer function "outerfunc(filter)" + str = str[2 : len(str)-1] + return strings.Join(str, "") +}