// AddSQLRelHandlers provides handlers for sql special keys tags func AddSQLRelHandlers(op *parser.OPFactory) { op.Add("with", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value").([]string) return []string{fmt.Sprintf("{{table}}.%s = {{parentTable}}.%s", val[0], val[1])}, nil }) }
// TableBuilder provides a simple sql parser func TableBuilder(op, specs *parser.OPFactory) flux.Reactor { return adaptors.QueryAdaptor(func(r flux.Reactor, gs ds.Graphs) { mo, err := adaptors.DFGraph(gs) if err != nil { r.ReplyError(err) return } recordSize := gs.Length() _ = recordSize var tables Tables for mo.Next() == nil { uo := mo.Node().(*parser.ParseNode) //create a table for this record table := &Table{ Key: uo.Key, Name: uo.Name(), Parent: uo.Parent, PKey: uo.PKey, Attrs: uo.Attr.All(), Node: uo, Graph: gs, } tables = append(tables, table) rules := uo.Rules if table.Parent != "" { if !rules.Has(relationKey) { r.ReplyError(fmt.Errorf("Query for '%s' is a subroot/child of '%s' and needs a '%s(with: [childkey parentkey])' in its conditions for proper evaluation e.g '%s(with: [user_id id])'", table.Name, table.Parent, table.Name, table.Name)) // col := parser.NewCondition("with") // col.Set("value", []string{fmt.Sprintf("%s_id", strings.ToLower(table.Parent)), "id"}) // rules.Set(relationKey, []parser.Collector{col}) return } } for _, val := range specialKeys { if !rules.Has(val) { continue } co, err := rules.Get(val) if err != nil && len(co) <= 0 { return } cod := co[0] // table.Keys[val] = co[0].Get("value") if kos, err := specs.Process(val, val, cod); err == nil { table.Conditions = append(table.Conditions, kos...) } rules.Remove(val) } rules.EachCondition(func(name string, c parser.Collector, stop func()) { co, err := op.Process(c.Get("type").(string), name, c) if err != nil { r.ReplyError(err) stop() } table.Conditions = append(table.Conditions, co...) }) records := uo.Records //add the record to the column list table.Columns = append(table.Columns, records.Keys()...) //process the records constraints records.EachCondition(func(name string, c parser.Collector, stop func()) { co, err := op.Process(c.Get("type").(string), name, c) if err != nil { r.ReplyError(err) stop() } table.Conditions = append(table.Conditions, co...) }) } //deliver the table for building r.Reply(tables) }) }
// AddSQLQueryHandlers adds handlers for sql query parameters to a OPFactory func AddSQLQueryHandlers(op *parser.OPFactory) { //these are used to generate the where clause statement section op.Add("id", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value") return []string{fmt.Sprintf("{{table}}.%s = %s", name, val)}, nil }) op.Add("gte", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value").(int) return []string{fmt.Sprintf("{{table}}.%s => %d", name, val)}, nil }) op.Add("gt", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value").(int) return []string{fmt.Sprintf("{{table}}.%s > %d", name, val)}, nil }) op.Add("lte", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value").(int) return []string{fmt.Sprintf("{{table}}.%s <= %d", name, val)}, nil }) op.Add("lt", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value").(int) return []string{fmt.Sprintf("{{table}}.%s < %d", name, val)}, nil }) op.Add("in", func(name string, c parser.Collector) ([]string, error) { if !c.Has("range") { return nil, ErrNoValue } var inwords []string ranges := c.Get("range").([]string) for _, ins := range ranges { inwords = append(inwords, fmt.Sprintf("{{table}}.%s = %s", name, ins)) } return []string{strings.Join(inwords, "\nOR ")}, nil }) op.Add("is", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value") return []string{fmt.Sprintf("{{table}}.%s = %s", name, val)}, nil }) op.Add("isnot", func(name string, c parser.Collector) ([]string, error) { if !c.Has("value") { return nil, ErrNoValue } val := c.Get("value") return []string{fmt.Sprintf("{{table}}.%s != %s", name, val)}, nil }) op.Add("range", func(name string, c parser.Collector) ([]string, error) { if !c.Has("max") && !c.Has("min") { return nil, ErrNoValue } max := c.Get("max") maxso := fmt.Sprintf("{{table}}.%s => %d", name, max) min := c.Get("min") minso := fmt.Sprintf("{{table}}.%s <= %d", name, min) // orange := strings.Join([]string{minso, maxso}, "\nOR\n") return []string{minso, maxso}, nil }) }