@@ -33,9 +33,13 @@ type Data struct {
33
33
}
34
34
35
35
type table struct {
36
- Name string
37
- SQL string
38
- Values []string
36
+ Name string
37
+ Err error
38
+
39
+ data * Data
40
+ rows * sql.Rows
41
+ types []reflect.Type
42
+ values []interface {}
39
43
}
40
44
41
45
type metaData struct {
@@ -68,22 +72,22 @@ const tableTmpl = `
68
72
-- Table structure for table {{ .Name }}
69
73
--
70
74
71
- DROP TABLE IF EXISTS {{ .Name }};
75
+ DROP TABLE IF EXISTS {{ .NameEsc }};
72
76
/*!40101 SET @saved_cs_client = @@character_set_client */;
73
77
SET character_set_client = utf8mb4 ;
74
- {{ .SQL }};
78
+ {{ .CreateSQL }};
75
79
/*!40101 SET character_set_client = @saved_cs_client */;
76
80
77
81
--
78
82
-- Dumping data for table {{ .Name }}
79
83
--
80
84
81
- LOCK TABLES {{ .Name }} WRITE;
85
+ LOCK TABLES {{ .NameEsc }} WRITE;
82
86
/*!40000 ALTER TABLE {{ .Name }} DISABLE KEYS */;
83
87
{{- if .Values }}
84
88
INSERT INTO {{ .Name }} VALUES
85
- {{- range $index, $element := .Values -}}
86
- {{- if $index }},{{ else }} {{ end -}}{{ $element }}
89
+ {{- range .Next -}}
90
+ , {{ end -}}{{ .RowValues }}
87
91
{{- end -}};
88
92
{{- end }}
89
93
/*!40000 ALTER TABLE {{ .Name }} ENABLE KEYS */;
@@ -237,112 +241,128 @@ func (data *metaData) updateServerVersion(db *sql.DB) (err error) {
237
241
// MARK: create methods
238
242
239
243
func (data * Data ) createTable (name string ) (* table , error ) {
240
- var err error
241
- t := & table {Name : "`" + name + "`" }
242
-
243
- if t .SQL , err = data .createTableSQL (name ); err != nil {
244
- return nil , err
245
- }
246
-
247
- if t .Values , err = data .createTableValues (name ); err != nil {
248
- return nil , err
244
+ t := & table {
245
+ Name : name ,
246
+ data : data ,
249
247
}
250
248
251
249
return t , nil
252
250
}
253
251
254
- func (data * Data ) createTableSQL (name string ) (string , error ) {
252
+ func (table * table ) NameEsc () string {
253
+ return "`" + table .Name + "`"
254
+ }
255
+
256
+ func (table * table ) CreateSQL () (string , error ) {
255
257
var tableReturn , tableSQL sql.NullString
256
- err := data .Connection .QueryRow ("SHOW CREATE TABLE `" + name + "`" ).Scan (& tableReturn , & tableSQL )
258
+ err := table . data .Connection .QueryRow ("SHOW CREATE TABLE " + table . NameEsc () ).Scan (& tableReturn , & tableSQL )
257
259
258
260
if err != nil {
259
261
return "" , err
260
262
}
261
- if tableReturn .String != name {
263
+ if tableReturn .String != table . Name {
262
264
return "" , errors .New ("Returned table is not the same as requested table" )
263
265
}
264
266
265
267
return tableSQL .String , nil
266
268
}
267
269
268
- func (data * Data ) createTableValues (name string ) ([]string , error ) {
269
- rows , err := data .Connection .Query ("SELECT * FROM `" + name + "`" )
270
+ // defer rows.Close()
271
+ func (table * table ) Init () (err error ) {
272
+ if len (table .types ) != 0 {
273
+ return errors .New ("can't init twice" )
274
+ }
275
+
276
+ table .rows , err = table .data .Connection .Query ("SELECT * FROM " + table .NameEsc ())
270
277
if err != nil {
271
- return nil , err
278
+ return err
272
279
}
273
- defer rows .Close ()
274
280
275
- columns , err := rows .Columns ()
281
+ columns , err := table . rows .Columns ()
276
282
if err != nil {
277
- return nil , err
283
+ return err
278
284
}
279
285
if len (columns ) == 0 {
280
- return nil , errors .New ("No columns in table " + name + "." )
286
+ return errors .New ("No columns in table " + table . Name + "." )
281
287
}
282
288
283
- dataText := make ([]string , 0 )
284
- tt , err := rows .ColumnTypes ()
289
+ tt , err := table .rows .ColumnTypes ()
285
290
if err != nil {
286
- return nil , err
291
+ return err
287
292
}
288
293
289
- types : = make ([]reflect.Type , len (tt ))
294
+ table . types = make ([]reflect.Type , len (tt ))
290
295
for i , tp := range tt {
291
296
st := tp .ScanType ()
292
297
if tp .DatabaseTypeName () == "BLOB" {
293
- types [i ] = reflect .TypeOf (sql.RawBytes {})
298
+ table . types [i ] = reflect .TypeOf (sql.RawBytes {})
294
299
} else if st != nil && (st .Kind () == reflect .Int ||
295
300
st .Kind () == reflect .Int8 ||
296
301
st .Kind () == reflect .Int16 ||
297
302
st .Kind () == reflect .Int32 ||
298
303
st .Kind () == reflect .Int64 ) {
299
- types [i ] = reflect .TypeOf (sql.NullInt64 {})
304
+ table . types [i ] = reflect .TypeOf (sql.NullInt64 {})
300
305
} else {
301
- types [i ] = reflect .TypeOf (sql.NullString {})
306
+ table . types [i ] = reflect .TypeOf (sql.NullString {})
302
307
}
303
308
}
304
- values : = make ([]interface {}, len (tt ))
305
- for i := range values {
306
- values [i ] = reflect .New (types [i ]).Interface ()
309
+ table . values = make ([]interface {}, len (tt ))
310
+ for i := range table . values {
311
+ table . values [i ] = reflect .New (table . types [i ]).Interface ()
307
312
}
308
- for rows .Next () {
309
- if err := rows .Scan (values ... ); err != nil {
310
- return dataText , err
313
+ return nil
314
+ }
315
+
316
+ func (table * table ) Next () bool {
317
+ if table .rows == nil {
318
+ if err := table .Init (); err != nil {
319
+ table .Err = err
320
+ return false
321
+ }
322
+ } else if table .rows .Next () {
323
+ if err := table .rows .Scan (table .values ... ); err != nil {
324
+ table .Err = err
325
+ return false
311
326
}
327
+ } else {
328
+ table .rows .Close ()
329
+ table .rows = nil
330
+ return false
331
+ }
332
+ return true
333
+ }
334
+
335
+ func (table * table ) RowValues () (string , error ) {
336
+ dataStrings := make ([]string , len (table .values ))
312
337
313
- dataStrings := make ([]string , len (columns ))
314
-
315
- for key , value := range values {
316
- if value == nil {
317
- dataStrings [key ] = nullType
318
- } else {
319
- switch s := value .(type ) {
320
- case * sql.NullString :
321
- if s .Valid {
322
- dataStrings [key ] = "'" + sanitize (s .String ) + "'"
323
- } else {
324
- dataStrings [key ] = nullType
325
- }
326
- case * sql.NullInt64 :
327
- if s .Valid {
328
- dataStrings [key ] = fmt .Sprintf ("%d" , s .Int64 )
329
- } else {
330
- dataStrings [key ] = nullType
331
- }
332
- case * sql.RawBytes :
333
- if len (* s ) == 0 {
334
- dataStrings [key ] = nullType
335
- } else {
336
- dataStrings [key ] = "_binary '" + sanitize (string (* s )) + "'"
337
- }
338
- default :
339
- dataStrings [key ] = fmt .Sprint ("'" , value , "'" )
338
+ for key , value := range table .values {
339
+ if value == nil {
340
+ dataStrings [key ] = nullType
341
+ } else {
342
+ switch s := value .(type ) {
343
+ case * sql.NullString :
344
+ if s .Valid {
345
+ dataStrings [key ] = "'" + sanitize (s .String ) + "'"
346
+ } else {
347
+ dataStrings [key ] = nullType
340
348
}
349
+ case * sql.NullInt64 :
350
+ if s .Valid {
351
+ dataStrings [key ] = fmt .Sprintf ("%d" , s .Int64 )
352
+ } else {
353
+ dataStrings [key ] = nullType
354
+ }
355
+ case * sql.RawBytes :
356
+ if len (* s ) == 0 {
357
+ dataStrings [key ] = nullType
358
+ } else {
359
+ dataStrings [key ] = "_binary '" + sanitize (string (* s )) + "'"
360
+ }
361
+ default :
362
+ dataStrings [key ] = fmt .Sprint ("'" , value , "'" )
341
363
}
342
364
}
343
-
344
- dataText = append (dataText , "(" + strings .Join (dataStrings , "," )+ ")" )
345
365
}
346
366
347
- return dataText , rows .Err ()
367
+ return "(" + strings . Join ( dataStrings , "," ) + ")" , table . rows .Err ()
348
368
}
0 commit comments