-
Notifications
You must be signed in to change notification settings - Fork 22
/
column.go
150 lines (131 loc) · 3.9 KB
/
column.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
package schema
import (
"context"
"strings"
"github.com/apache/arrow/go/v13/arrow"
)
type ColumnList []Column
// ColumnResolver is called for each row received in TableResolver's data fetch.
// execution holds all relevant information regarding execution as well as the Column called.
// resource holds the current row we are resolving the column for.
type ColumnResolver func(ctx context.Context, meta ClientMeta, resource *Resource, c Column) error
// Column definition for Table
type Column struct {
// Name of column
Name string
// Value Type of column i.e String, UUID etc'
Type arrow.DataType
// Description about column, this description is added as a comment in the database
Description string
// Column Resolver allows to set your own data for a column; this can be an API call, setting multiple embedded values, etc
Resolver ColumnResolver
// IgnoreInTests is used to skip verifying the column is non-nil in integration tests.
// By default, integration tests perform a fetch for all resources in cloudquery's test account, and
// verify all columns are non-nil.
// If IgnoreInTests is true, verification is skipped for this column.
// Used when it is hard to create a reproducible environment with this column being non-nil (e.g. various error columns).
IgnoreInTests bool
// PrimaryKey requires the destinations supporting this to include this column into the primary key
PrimaryKey bool
// NotNull requires the destinations supporting this to mark this column as non-nullable
NotNull bool
// IncrementalKey is a flag that indicates if the column is used as part of an incremental key.
// It is mainly used for documentation purposes, but may also be used as part of ensuring that
// migrations are done correctly.
IncrementalKey bool
// Unique requires the destinations supporting this to mark this column as unique
Unique bool
}
// NewColumnFromArrowField creates a new Column from an arrow.Field
// arrow.Field is a low-level representation of a CloudQuery column
// that can be sent over the wire in a cross-language way.
func NewColumnFromArrowField(f arrow.Field) Column {
column := Column{
Name: f.Name,
Type: f.Type,
NotNull: !f.Nullable,
}
v, ok := f.Metadata.GetValue(MetadataPrimaryKey)
column.PrimaryKey = ok && v == MetadataTrue
v, ok = f.Metadata.GetValue(MetadataUnique)
column.Unique = ok && v == MetadataTrue
v, ok = f.Metadata.GetValue(MetadataIncremental)
column.IncrementalKey = ok && v == MetadataTrue
return column
}
func (c Column) ToArrowField() arrow.Field {
mdKV := map[string]string{
MetadataPrimaryKey: MetadataFalse,
MetadataUnique: MetadataFalse,
MetadataIncremental: MetadataFalse,
}
if c.PrimaryKey {
mdKV[MetadataPrimaryKey] = MetadataTrue
}
if c.Unique {
mdKV[MetadataUnique] = MetadataTrue
}
if c.IncrementalKey {
mdKV[MetadataIncremental] = MetadataTrue
}
return arrow.Field{
Name: c.Name,
Type: c.Type,
Nullable: !c.NotNull,
Metadata: arrow.MetadataFrom(mdKV),
}
}
func (c Column) String() string {
var sb strings.Builder
sb.WriteString(c.Name)
sb.WriteString(":")
sb.WriteString(c.Type.String())
if c.PrimaryKey {
sb.WriteString(":PK")
}
if c.NotNull {
sb.WriteString(":NotNull")
}
if c.Unique {
sb.WriteString(":Unique")
}
if c.IncrementalKey {
sb.WriteString(":IncrementalKey")
}
return sb.String()
}
func (c ColumnList) Index(col string) int {
for i, c := range c {
if c.Name == col {
return i
}
}
return -1
}
func (c ColumnList) Names() []string {
ret := make([]string, len(c))
for i := range c {
ret[i] = c[i].Name
}
return ret
}
func (c ColumnList) Get(name string) *Column {
for i := range c {
if c[i].Name == name {
return &c[i]
}
}
return nil
}
func (c ColumnList) String() string {
var sb strings.Builder
sb.WriteString("[")
for i, col := range c {
sb.WriteString(col.String())
if i != len(c)-1 {
sb.WriteString(", ")
}
}
sb.WriteString("]")
return sb.String()
}