1
1
package sql
2
2
3
3
import (
4
- "errors"
5
4
"fmt"
6
- "reflect"
7
5
)
8
6
7
+ // Catalog holds databases, tables and functions.
9
8
type Catalog struct {
10
- Databases [] Database
11
- Functions map [ string ] * FunctionEntry
9
+ Databases
10
+ FunctionRegistry
12
11
}
13
12
13
+ // NewCatalog returns a new empty Catalog.
14
14
func NewCatalog () * Catalog {
15
15
return & Catalog {
16
- Functions : map [string ]* FunctionEntry {},
16
+ Databases : Databases {},
17
+ FunctionRegistry : NewFunctionRegistry (),
17
18
}
18
19
}
19
20
20
- func (c Catalog ) Database (name string ) (Database , error ) {
21
- for _ , db := range c .Databases {
21
+ // Databases is a collection of Database.
22
+ type Databases []Database
23
+
24
+ // Database returns the Database with the given name if it exists.
25
+ func (d Databases ) Database (name string ) (Database , error ) {
26
+ for _ , db := range d {
22
27
if db .Name () == name {
23
28
return db , nil
24
29
}
@@ -27,8 +32,9 @@ func (c Catalog) Database(name string) (Database, error) {
27
32
return nil , fmt .Errorf ("database not found: %s" , name )
28
33
}
29
34
30
- func (c Catalog ) Table (dbName string , tableName string ) (Table , error ) {
31
- db , err := c .Database (dbName )
35
+ // Table returns the Table with the given name if it exists.
36
+ func (d Databases ) Table (dbName string , tableName string ) (Table , error ) {
37
+ db , err := d .Database (dbName )
32
38
if err != nil {
33
39
return nil , err
34
40
}
@@ -41,101 +47,3 @@ func (c Catalog) Table(dbName string, tableName string) (Table, error) {
41
47
42
48
return table , nil
43
49
}
44
-
45
- func (c Catalog ) RegisterFunction (name string , f interface {}) error {
46
- e , err := inspectFunction (f )
47
- if err != nil {
48
- return err
49
- }
50
-
51
- c .Functions [name ] = e
52
- return nil
53
- }
54
-
55
- func (c Catalog ) Function (name string ) (* FunctionEntry , error ) {
56
- e , ok := c .Functions [name ]
57
- if ! ok {
58
- return nil , fmt .Errorf ("function not found: %s" , name )
59
- }
60
-
61
- return e , nil
62
- }
63
-
64
- type FunctionEntry struct {
65
- v reflect.Value
66
- }
67
-
68
- func (e * FunctionEntry ) Build (args ... Expression ) (Expression , error ) {
69
- t := e .v .Type ()
70
- if ! t .IsVariadic () && len (args ) != t .NumIn () {
71
- return nil , fmt .Errorf ("expected %d args, got %d" ,
72
- t .NumIn (), len (args ))
73
- }
74
-
75
- if t .IsVariadic () && len (args ) < t .NumIn ()- 1 {
76
- return nil , fmt .Errorf ("expected at least %d args, got %d" ,
77
- t .NumIn (), len (args ))
78
- }
79
-
80
- var in []reflect.Value
81
- for _ , arg := range args {
82
- in = append (in , reflect .ValueOf (arg ))
83
- }
84
-
85
- out := e .v .Call (in )
86
- if len (out ) != 1 {
87
- return nil , fmt .Errorf ("expected 1 return value, got %d: " , len (out ))
88
- }
89
-
90
- expr , ok := out [0 ].Interface ().(Expression )
91
- if ! ok {
92
- return nil , errors .New ("return value doesn't implement Expression" )
93
- }
94
-
95
- return expr , nil
96
- }
97
-
98
- var (
99
- expressionType = buildExpressionType ()
100
- expressionSliceType = buildExpressionSliceType ()
101
- )
102
-
103
- func buildExpressionType () reflect.Type {
104
- var v Expression
105
- return reflect .ValueOf (& v ).Elem ().Type ()
106
- }
107
-
108
- func buildExpressionSliceType () reflect.Type {
109
- var v []Expression
110
- return reflect .ValueOf (& v ).Elem ().Type ()
111
- }
112
-
113
- func inspectFunction (f interface {}) (* FunctionEntry , error ) {
114
- v := reflect .ValueOf (f )
115
- t := v .Type ()
116
- if t .Kind () != reflect .Func {
117
- return nil , fmt .Errorf ("expected function, got: %s" , t .Kind ())
118
- }
119
-
120
- if t .NumOut () != 1 {
121
- return nil , errors .New ("function builders must return a single Expression" )
122
- }
123
-
124
- out := t .Out (0 )
125
- if ! out .Implements (expressionType ) {
126
- return nil , fmt .Errorf ("return value doesn't implement Expression: %s" , out )
127
- }
128
-
129
- for i := 0 ; i < t .NumIn (); i ++ {
130
- in := t .In (i )
131
- if i == t .NumIn ()- 1 && t .IsVariadic () && in == expressionSliceType {
132
- continue
133
- }
134
-
135
- if in != expressionType {
136
- return nil , fmt .Errorf ("input argument %d is not a Expression" , i )
137
- }
138
- }
139
-
140
- return & FunctionEntry {v }, nil
141
- }
0 commit comments