1package clause
2
3// Interface clause interface
4type Interface interface {
5	Name() string
6	Build(Builder)
7	MergeClause(*Clause)
8}
9
10// ClauseBuilder clause builder, allows to customize how to build clause
11type ClauseBuilder func(Clause, Builder)
12
13type Writer interface {
14	WriteByte(byte) error
15	WriteString(string) (int, error)
16}
17
18// Builder builder interface
19type Builder interface {
20	Writer
21	WriteQuoted(field interface{})
22	AddVar(Writer, ...interface{})
23}
24
25// Clause
26type Clause struct {
27	Name                string // WHERE
28	BeforeExpression    Expression
29	AfterNameExpression Expression
30	AfterExpression     Expression
31	Expression          Expression
32	Builder             ClauseBuilder
33}
34
35// Build build clause
36func (c Clause) Build(builder Builder) {
37	if c.Builder != nil {
38		c.Builder(c, builder)
39	} else if c.Expression != nil {
40		if c.BeforeExpression != nil {
41			c.BeforeExpression.Build(builder)
42			builder.WriteByte(' ')
43		}
44
45		if c.Name != "" {
46			builder.WriteString(c.Name)
47			builder.WriteByte(' ')
48		}
49
50		if c.AfterNameExpression != nil {
51			c.AfterNameExpression.Build(builder)
52			builder.WriteByte(' ')
53		}
54
55		c.Expression.Build(builder)
56
57		if c.AfterExpression != nil {
58			builder.WriteByte(' ')
59			c.AfterExpression.Build(builder)
60		}
61	}
62}
63
64const (
65	PrimaryKey   string = "~~~py~~~" // primary key
66	CurrentTable string = "~~~ct~~~" // current table
67	Associations string = "~~~as~~~" // associations
68)
69
70var (
71	currentTable  = Table{Name: CurrentTable}
72	PrimaryColumn = Column{Table: CurrentTable, Name: PrimaryKey}
73)
74
75// Column quote with name
76type Column struct {
77	Table string
78	Name  string
79	Alias string
80	Raw   bool
81}
82
83// Table quote with name
84type Table struct {
85	Name  string
86	Alias string
87	Raw   bool
88}
89