-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathapi.go
executable file
·294 lines (209 loc) · 12.1 KB
/
api.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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
package dsc
import (
"database/sql"
"reflect"
"time"
)
//Scanner represents a datastore data scanner. This abstraction provides the ability to convert and assign datastore record of data to provided destination
type Scanner interface {
//Returns all columns specified in select statement.
Columns() ([]string, error)
//ColumnTypes return column types
ColumnTypes() ([]ColumnType, error)
//Scans datastore record data to convert and assign it to provided destinations, a destination needs to be pointer.
Scan(dest ...interface{}) error
}
//ColumnValueProvider provides column values
type ColumnValueProvider interface {
ColumnValues() ([]interface{}, error)
}
//RecordMapper represents a datastore record mapper, it is responsible for mapping data record into application abstraction.
type RecordMapper interface {
//Maps data record by passing to the scanner references to the application abstraction
Map(scanner Scanner) (interface{}, error)
}
//ParametrizedSQL represents a parmetrized SQL with its binding values, in order of occurrence.
type ParametrizedSQL struct {
SQL string //Sql
Values []interface{} //binding parameter values
Type int
}
//DmlProvider represents dml generator, which is responsible for providing parametrized sql, it takes operation type:
//SqlTypeInsert = 0
//SqlTypeUpdate = 1
//SqlTypeDelete = 2
// and instance to the application abstraction
type DmlProvider interface {
Get(operationType int, instance interface{}) *ParametrizedSQL
KeySetter
KeyGetter
}
//Manager represents datastore manager.
type Manager interface {
Config() *Config
//ConnectionProvider returns connection provider
ConnectionProvider() ConnectionProvider
//Execute executes provided sql, with the arguments, '?' is used as placeholder for and arguments
Execute(sql string, parameters ...interface{}) (sql.Result, error)
//ExecuteAll executes all provided sql
ExecuteAll(sqls []string) ([]sql.Result, error)
//ExecuteOnConnection executes sql on passed in connection, this allowes to maintain transaction if supported
ExecuteOnConnection(connection Connection, sql string, parameters []interface{}) (sql.Result, error)
//ExecuteAllOnConnection executes all sql on passed in connection, this allowes to maintain transaction if supported
ExecuteAllOnConnection(connection Connection, sqls []string) ([]sql.Result, error)
//ReadSingle fetches a single record of data, it takes pointer to the result, sql query, binding parameters, record to application instance mapper
ReadSingle(resultPointer interface{}, query string, parameters []interface{}, mapper RecordMapper) (success bool, err error)
//ReadSingleOnConnection fetches a single record of data on connection, it takes connection, pointer to the result, sql query, binding parameters, record to application instance mapper
ReadSingleOnConnection(connection Connection, resultPointer interface{}, query string, parameters []interface{}, mapper RecordMapper) (success bool, err error)
//ReadAll reads all records, it takes pointer to the result slice , sql query, binding parameters, record to application instance mapper
ReadAll(resultSlicePointer interface{}, query string, parameters []interface{}, mapper RecordMapper) error
//ReadAllOnConnection reads all records, it takes connection, pointer to the result slice , sql query, binding parameters, record to application instance mapper
ReadAllOnConnection(connection Connection, resultSlicePointer interface{}, query string, parameters []interface{}, mapper RecordMapper) error
//ReadAllWithHandler reads data for passed in query and parameters, for each row reading handler will be called, to continue reading next row it needs to return true
ReadAllWithHandler(query string, parameters []interface{}, readingHandler func(scanner Scanner) (toContinue bool, err error)) error
//ReadAllOnWithHandlerOnConnection reads data for passed in query and parameters, on connection, for each row reading handler will be called, to continue reading next row, it needs to return true
ReadAllOnWithHandlerOnConnection(connection Connection, query string, parameters []interface{}, readingHandler func(scanner Scanner) (toContinue bool, err error)) error
//ReadAllOnWithHandlerOnConnection persists all passed in data to the table, it uses dml provider to generate DML for each row.
PersistAll(slicePointer interface{}, table string, provider DmlProvider) (inserted int, updated int, err error)
//PersistAllOnConnection persists all passed in data on connection to the table, it uses dml provider to generate DML for each row.
PersistAllOnConnection(connection Connection, dataPointer interface{}, table string, provider DmlProvider) (inserted int, updated int, err error)
//PersistSingle persists single row into table, it uses dml provider to generate DML to the row.
PersistSingle(dataPointer interface{}, table string, provider DmlProvider) (inserted int, updated int, err error)
//PersistSingleOnConnection persists single row on connection into table, it uses dml provider to generate DML to the row.
PersistSingleOnConnection(connection Connection, dataPointer interface{}, table string, provider DmlProvider) (inserted int, updated int, err error)
//connection persists all all row of data to passed in table, it uses key setter to optionally set back autoincrement value, and func to generate parametrized sql for the row.
PersistData(connection Connection, data interface{}, table string, keySetter KeySetter, sqlProvider func(item interface{}) *ParametrizedSQL) (int, error)
//DeleteAll deletes all record for passed in slice pointer from table, it uses key provider to take id/key for the record.
DeleteAll(slicePointer interface{}, table string, keyProvider KeyGetter) (deleted int, err error)
//DeleteAllOnConnection deletes all record on connection for passed in slice pointer from table, it uses key provider to take id/key for the record.
DeleteAllOnConnection(connection Connection, resultPointer interface{}, table string, keyProvider KeyGetter) (deleted int, err error)
//DeleteSingle deletes single row of data from table, it uses key provider to take id/key for the record.
DeleteSingle(resultPointer interface{}, table string, keyProvider KeyGetter) (success bool, err error)
//DeleteSingleOnConnection deletes single row of data on connection from table, it uses key provider to take id/key for the record.
DeleteSingleOnConnection(connection Connection, resultPointer interface{}, table string, keyProvider KeyGetter) (success bool, err error)
//ClassifyDataAsInsertableOrUpdatable classifies records are inserable and what are updatable.
ClassifyDataAsInsertableOrUpdatable(connection Connection, slicePointer interface{}, table string, provider DmlProvider) (insertables, updatables []interface{}, err error)
//TableDescriptorRegistry returns Table Descriptor Registry
TableDescriptorRegistry() TableDescriptorRegistry
}
//DatastoreDialect represents datastore dialects.
type DatastoreDialect interface {
GetDatastores(manager Manager) ([]string, error)
GetTables(manager Manager, datastore string) ([]string, error)
DropTable(manager Manager, datastore string, table string) error
CreateTable(manager Manager, datastore string, table string, specification interface{}) error
CanCreateDatastore(manager Manager) bool
CreateDatastore(manager Manager, datastore string) error
CanDropDatastore(manager Manager) bool
DropDatastore(manager Manager, datastore string) error
GetCurrentDatastore(manager Manager) (string, error)
//GetSequence returns a sequence number
GetSequence(manager Manager, name string) (int64, error)
//GetKeyName returns a name of TableColumn name that is a key, or coma separated list if complex key
GetKeyName(manager Manager, datastore, table string) string
//GetColumns returns TableColumn info
GetColumns(manager Manager, datastore, table string) ([]Column, error)
//IsAutoincrement returns true if autoicrement
IsAutoincrement(manager Manager, datastore, table string) bool
//Flag if data store can batch batch
CanPersistBatch() bool
//BulkInsert type
BulkInsertType() string
//DisableForeignKeyCheck disables fk check
DisableForeignKeyCheck(manager Manager, connection Connection) error
//EnableForeignKeyCheck disables fk check
EnableForeignKeyCheck(manager Manager, connection Connection) error
//IsKeyCheckSwitchSessionLevel returns true if key check is controlled on connection level (as opposed to globally on table level)
IsKeyCheckSwitchSessionLevel() bool
//Normalizes sql i.e for placeholders: dsc uses '?' for placeholder if some dialect use difference this method should take care of it
NormalizeSQL(SQL string) string
//EachTable iterate all current connection manager datastore tables
EachTable(manager Manager, handler func(table string) error) error
//ShowCreateTable returns DDL showing create table statement or error
ShowCreateTable(manager Manager, table string) (string, error)
//Init initializes connection
Init(manager Manager, connection Connection) error
//CanHandleTransaction returns true if driver can handle transaction
CanHandleTransaction() bool
//Checks if database is online
Ping(manager Manager) error
}
type ColumnType interface {
// Length returns the TableColumn type length for variable length TableColumn types such
// as text and binary field types. If the type length is unbounded the value will
// be math.MaxInt64 (any database limits will still apply).
// If the TableColumn type is not variable length, such as an int, or if not supported
// by the driver ok is false.
Length() (length int64, ok bool)
// DecimalSize returns the scale and precision of a decimal type.
// If not applicable or if not supported ok is false.
DecimalSize() (precision, scale int64, ok bool)
// ScanType returns a Go type suitable for scanning into using Rows.Scan.
// If a driver does not support this property ScanType will return
// the type of an empty interface.
ScanType() reflect.Type
// Nullable returns whether the TableColumn may be null.
// If a driver does not support this property ok will be false.
Nullable() (nullable, ok bool)
// DatabaseTypeName returns the database system name of the TableColumn type. If an empty
// string is returned the driver type name is not supported.
// Consult your driver documentation for a list of driver data types. Length specifiers
// are not included.
// Common type include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", "INT", "BIGINT".
DatabaseTypeName() string
}
//Column represents TableColumn type interface (compabible with *sql.ColumnType
type Column interface {
ColumnType
// Name returns the name or alias of the TableColumn.
Name() string
}
//TransactionManager represents a transaction manager.
type TransactionManager interface {
Begin() error
Commit() error
Rollback() error
}
//Connection represents a datastore connection
type Connection interface {
Config() *Config
ConnectionPool() chan Connection
//Close closes connection or it returns it back to the pool
Close() error
CloseNow() error //closes connecition, it does not return it back to the pool
Unwrap(target interface{}) interface{}
LastUsed() *time.Time
SetLastUsed(ts *time.Time)
TransactionManager
}
//ConnectionProvider represents a datastore connection provider.
type ConnectionProvider interface {
Get() (Connection, error)
Config() *Config
ConnectionPool() chan Connection
SpawnConnectionIfNeeded()
NewConnection() (Connection, error)
Close() error
}
//ManagerFactory represents a manager factory.
type ManagerFactory interface {
//Creates manager, takes config pointer.
Create(config *Config) (Manager, error)
//Creates manager from url, can url needs to point to Config JSON.
CreateFromURL(url string) (Manager, error)
}
//ManagerRegistry represents a manager registry.
type ManagerRegistry interface {
Get(name string) Manager
Register(name string, manager Manager)
}
//KeySetter represents id/key mutator.
type KeySetter interface {
//SetKey sets autoincrement/sql value to the application domain instance.
SetKey(instance interface{}, seq int64)
}
//KeyGetter represents id/key accessor.
type KeyGetter interface {
//Key returns key/id for the the application domain instance.
Key(instance interface{}) []interface{}
}