forked from stephenafamo/bob
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwindow.go
108 lines (85 loc) · 2 KB
/
window.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package clause
import (
"io"
"github.com/stephenafamo/bob"
)
type IWindow interface {
SetFrom(string)
AddPartitionBy(...any)
AddOrderBy(...any)
SetMode(string)
SetStart(any)
SetEnd(any)
SetExclusion(string)
}
type WindowDef struct {
From string // an existing window name
orderBy []any
partitionBy []any
Frame
}
func (wi WindowDef) Valid() bool {
if wi.From != "" {
return true
}
if len(wi.orderBy) != 0 {
return true
}
if len(wi.partitionBy) != 0 {
return true
}
if wi.Frame.Defined {
return true
}
return false
}
func (wi *WindowDef) SetFrom(from string) {
wi.From = from
}
func (wi *WindowDef) AddPartitionBy(condition ...any) {
wi.partitionBy = append(wi.partitionBy, condition...)
}
func (wi *WindowDef) AddOrderBy(order ...any) {
wi.orderBy = append(wi.orderBy, order...)
}
func (wi WindowDef) WriteSQL(w io.Writer, d bob.Dialect, start int) ([]any, error) {
if wi.From != "" {
w.Write([]byte(wi.From))
w.Write([]byte(" "))
}
args, err := bob.ExpressSlice(w, d, start, wi.partitionBy, "PARTITION BY ", ", ", " ")
if err != nil {
return nil, err
}
orderArgs, err := bob.ExpressSlice(w, d, start, wi.orderBy, "ORDER BY ", ", ", "")
if err != nil {
return nil, err
}
args = append(args, orderArgs...)
frameArgs, err := bob.ExpressIf(w, d, start, wi.Frame, wi.Frame.Defined, " ", "")
if err != nil {
return nil, err
}
args = append(args, frameArgs...)
return args, nil
}
type NamedWindow struct {
Name string
Definition any
}
func (n NamedWindow) WriteSQL(w io.Writer, d bob.Dialect, start int) ([]any, error) {
w.Write([]byte(n.Name))
w.Write([]byte(" AS ("))
args, err := bob.Express(w, d, start, n.Definition)
w.Write([]byte(")"))
return args, err
}
type Windows struct {
Windows []NamedWindow
}
func (wi *Windows) AppendWindow(w NamedWindow) {
wi.Windows = append(wi.Windows, w)
}
func (wi Windows) WriteSQL(w io.Writer, d bob.Dialect, start int) ([]any, error) {
return bob.ExpressSlice(w, d, start, wi.Windows, "WINDOW ", ", ", "")
}