mirror of
https://github.com/featurebasedb/featurebase.git
synced 2026-09-07 00:55:55 +00:00
Beginning of better error handling.
This commit is contained in:
parent
fcb287103b
commit
483f4d22ca
6 changed files with 60 additions and 30 deletions
14
core/http.go
14
core/http.go
|
|
@ -161,12 +161,15 @@ func (self *WebService) HandleQuery(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
results := self.service.Executor.RunPQL(database_name, pql)
|
||||
results, err := self.service.Executor.RunPQL(database_name, pql)
|
||||
if err != nil {
|
||||
http.Error(w, "Error running query: "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
encoder := json.NewEncoder(w)
|
||||
err = encoder.Encode(results)
|
||||
if err != nil {
|
||||
log.Fatal("Error encoding stats")
|
||||
http.Error(w, "Error encoding: "+err.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -230,7 +233,12 @@ func (self *WebService) HandleSetBit(w http.ResponseWriter, r *http.Request) {
|
|||
filter := int(t)
|
||||
for bitmap_id := range bitmaps(frame, obj) {
|
||||
pql := fmt.Sprintf("set(%d, %s, %d, %d)", bitmap_id, frame, filter, profile_id)
|
||||
results = append(results, self.service.Executor.RunPQL(db, pql))
|
||||
result, err := self.service.Executor.RunPQL(db, pql)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
results = append(results, result)
|
||||
// results = append(results, db+" "+pql)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,16 +62,19 @@ func (self *Executor) RunQueryTest(database_name string, pql string) string {
|
|||
return pql
|
||||
}
|
||||
|
||||
func (self *Executor) runQuery(database *db.Database, qry *query.Query) {
|
||||
func (self *Executor) runQuery(database *db.Database, qry *query.Query) error {
|
||||
process, err := self.service.GetProcess()
|
||||
if err != nil {
|
||||
spew.Dump(err)
|
||||
return err
|
||||
}
|
||||
process_id := process.Id()
|
||||
fragment_id := util.SUUID(0)
|
||||
destination := db.Location{&process_id, fragment_id}
|
||||
|
||||
query_plan := query.QueryPlanForQuery(database, qry, &destination)
|
||||
query_plan, err := query.QueryPlanForQuery(database, qry, &destination)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// loop over the query steps and send to Transport
|
||||
for _, qs := range *query_plan {
|
||||
msg := new(db.Message)
|
||||
|
|
@ -81,30 +84,34 @@ func (self *Executor) runQuery(database *db.Database, qry *query.Query) {
|
|||
self.service.Transport.Send(msg, step.GetLocation().ProcessId)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *Executor) RunPQL(database_name string, pql string) interface{} {
|
||||
func (self *Executor) RunPQL(database_name string, pql string) (interface{}, error) {
|
||||
database := self.service.Cluster.GetOrCreateDatabase(database_name)
|
||||
|
||||
// see if the outer query function is a custom query
|
||||
reserved_functions := stringSlice{"get", "set", "union", "intersect", "count", "top-n"}
|
||||
tokens, err := query.Lex(pql)
|
||||
if err != nil {
|
||||
spew.Dump(err)
|
||||
return nil, err
|
||||
}
|
||||
outer_token := tokens[0].Text
|
||||
|
||||
if reserved_functions.pos(outer_token) != -1 {
|
||||
|
||||
qry := query.QueryForTokens(tokens)
|
||||
qry, err := query.QueryForTokens(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go self.runQuery(database, qry)
|
||||
|
||||
var final interface{}
|
||||
final, err := self.service.Hold.Get(qry.Id, 10)
|
||||
final, err = self.service.Hold.Get(qry.Id, 10)
|
||||
if err != nil {
|
||||
spew.Dump(err)
|
||||
return nil, err
|
||||
}
|
||||
return final
|
||||
return final, nil
|
||||
|
||||
} else {
|
||||
plugins_dir := config.GetString("plugins")
|
||||
|
|
@ -113,7 +120,10 @@ func (self *Executor) RunPQL(database_name string, pql string) interface{} {
|
|||
query_list := GetMacro(plugins_file, filter).(query.PqlList)
|
||||
|
||||
for i, _ := range query_list {
|
||||
qry := query.QueryForPQL(query_list[i].PQL)
|
||||
qry, err := query.QueryForPQL(query_list[i].PQL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go self.runQuery(database, qry)
|
||||
query_list[i].Id = qry.Id
|
||||
}
|
||||
|
|
@ -128,7 +138,7 @@ func (self *Executor) RunPQL(database_name string, pql string) interface{} {
|
|||
final_result[query_list[i].Label] = final
|
||||
}
|
||||
|
||||
return final_result
|
||||
return final_result, nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,5 +25,5 @@ type Executorer interface {
|
|||
Close()
|
||||
Run()
|
||||
NewJob(*db.Message)
|
||||
RunPQL(string, string) interface{}
|
||||
RunPQL(string, string) (interface{}, error)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -77,4 +77,9 @@ func TestQueryParser(t *testing.T) {
|
|||
So(query.Subqueries[0].Operation, ShouldEqual, "get")
|
||||
So(query.Subqueries[0].Args, ShouldResemble, map[string]interface{}{"id": uint64(10), "frame": "general"})
|
||||
})
|
||||
Convey("Lists", t, func() {
|
||||
tokens, err := Lex("wat(50)")
|
||||
_, err = Parse(tokens)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ func TestQueryPlanner(t *testing.T) {
|
|||
})
|
||||
Convey("Get query plan - including parsing", t, func() {
|
||||
|
||||
query := QueryForPQL("get(10,general)")
|
||||
query, err := QueryForPQL("get(10,general)")
|
||||
So(err, ShouldEqual, nil)
|
||||
|
||||
database, fragment1 := basic_database()
|
||||
|
||||
|
|
@ -108,7 +109,8 @@ func TestQueryPlanner(t *testing.T) {
|
|||
})
|
||||
Convey("Union query plan - including parsing", t, func() {
|
||||
|
||||
query := QueryForPQL("union(get(10, general), get(20, general))")
|
||||
query, err := QueryForPQL("union(get(10, general), get(20, general))")
|
||||
So(err, ShouldEqual, nil)
|
||||
|
||||
database, fragment1 := basic_database()
|
||||
|
||||
|
|
@ -148,7 +150,8 @@ func TestQueryPlanner(t *testing.T) {
|
|||
})
|
||||
})
|
||||
Convey("Set query plan - including parsing", t, func() {
|
||||
query := QueryForPQL("set(10, general, 0, 100)")
|
||||
query, err := QueryForPQL("set(10, general, 0, 100)")
|
||||
So(err, ShouldEqual, nil)
|
||||
|
||||
database, fragment1 := basic_database()
|
||||
|
||||
|
|
@ -163,7 +166,8 @@ func TestQueryPlanner(t *testing.T) {
|
|||
So(*(qp[0].(SetQueryStep).Bitmap), ShouldResemble, db.Bitmap{10, "general", 0})
|
||||
})
|
||||
Convey("Top-n query plan - including parsing", t, func() {
|
||||
query := QueryForPQL("top-n(get(10, general), [1,2,3], 50)")
|
||||
query, err := QueryForPQL("top-n(get(10, general), [1,2,3], 50)")
|
||||
So(err, ShouldEqual, nil)
|
||||
|
||||
database, fragment1 := basic_database()
|
||||
|
||||
|
|
|
|||
|
|
@ -28,40 +28,43 @@ type Query struct {
|
|||
Subqueries []Query
|
||||
}
|
||||
|
||||
func QueryPlanForPQL(database *db.Database, pql string, destination *db.Location) *QueryPlan {
|
||||
func QueryPlanForPQL(database *db.Database, pql string, destination *db.Location) (*QueryPlan, error) {
|
||||
tokens, err := Lex(pql)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return QueryPlanForTokens(database, tokens, destination)
|
||||
}
|
||||
|
||||
func QueryForPQL(pql string) *Query {
|
||||
func QueryForPQL(pql string) (*Query, error) {
|
||||
tokens, err := Lex(pql)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return QueryForTokens(tokens)
|
||||
}
|
||||
|
||||
func QueryForTokens(tokens []Token) *Query {
|
||||
func QueryForTokens(tokens []Token) (*Query, error) {
|
||||
query, err := Parse(tokens)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
return nil, err
|
||||
}
|
||||
return query
|
||||
return query, nil
|
||||
}
|
||||
|
||||
func QueryPlanForTokens(database *db.Database, tokens []Token, destination *db.Location) *QueryPlan {
|
||||
query := QueryForTokens(tokens)
|
||||
func QueryPlanForTokens(database *db.Database, tokens []Token, destination *db.Location) (*QueryPlan, error) {
|
||||
query, err := QueryForTokens(tokens)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return QueryPlanForQuery(database, query, destination)
|
||||
}
|
||||
|
||||
func QueryPlanForQuery(database *db.Database, query *Query, destination *db.Location) *QueryPlan {
|
||||
func QueryPlanForQuery(database *db.Database, query *Query, destination *db.Location) (*QueryPlan, error) {
|
||||
query_planner := QueryPlanner{Database: database, Query: query}
|
||||
id := uuid.RandomUUID()
|
||||
query_plan := query_planner.Plan(query, &id, destination)
|
||||
return query_plan
|
||||
return query_plan, nil
|
||||
}
|
||||
|
||||
func TokensToString(tokens []Token) string {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue