Пример #1
0
// 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
	})
}
Пример #2
0
// 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)
	})
}
Пример #3
0
// 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
	})
}