Skip to content

Commit 34666eb

Browse files
committed
WIP 1
1 parent 6cb5948 commit 34666eb

File tree

1 file changed

+90
-70
lines changed

1 file changed

+90
-70
lines changed

dump.go

Lines changed: 90 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ type Data struct {
3333
}
3434

3535
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{}
3943
}
4044

4145
type metaData struct {
@@ -68,22 +72,22 @@ const tableTmpl = `
6872
-- Table structure for table {{ .Name }}
6973
--
7074
71-
DROP TABLE IF EXISTS {{ .Name }};
75+
DROP TABLE IF EXISTS {{ .NameEsc }};
7276
/*!40101 SET @saved_cs_client = @@character_set_client */;
7377
SET character_set_client = utf8mb4 ;
74-
{{ .SQL }};
78+
{{ .CreateSQL }};
7579
/*!40101 SET character_set_client = @saved_cs_client */;
7680
7781
--
7882
-- Dumping data for table {{ .Name }}
7983
--
8084
81-
LOCK TABLES {{ .Name }} WRITE;
85+
LOCK TABLES {{ .NameEsc }} WRITE;
8286
/*!40000 ALTER TABLE {{ .Name }} DISABLE KEYS */;
8387
{{- if .Values }}
8488
INSERT INTO {{ .Name }} VALUES
85-
{{- range $index, $element := .Values -}}
86-
{{- if $index }},{{ else }} {{ end -}}{{ $element }}
89+
{{- range .Next -}}
90+
, {{ end -}}{{ .RowValues }}
8791
{{- end -}};
8892
{{- end }}
8993
/*!40000 ALTER TABLE {{ .Name }} ENABLE KEYS */;
@@ -237,112 +241,128 @@ func (data *metaData) updateServerVersion(db *sql.DB) (err error) {
237241
// MARK: create methods
238242

239243
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,
249247
}
250248

251249
return t, nil
252250
}
253251

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) {
255257
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)
257259

258260
if err != nil {
259261
return "", err
260262
}
261-
if tableReturn.String != name {
263+
if tableReturn.String != table.Name {
262264
return "", errors.New("Returned table is not the same as requested table")
263265
}
264266

265267
return tableSQL.String, nil
266268
}
267269

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())
270277
if err != nil {
271-
return nil, err
278+
return err
272279
}
273-
defer rows.Close()
274280

275-
columns, err := rows.Columns()
281+
columns, err := table.rows.Columns()
276282
if err != nil {
277-
return nil, err
283+
return err
278284
}
279285
if len(columns) == 0 {
280-
return nil, errors.New("No columns in table " + name + ".")
286+
return errors.New("No columns in table " + table.Name + ".")
281287
}
282288

283-
dataText := make([]string, 0)
284-
tt, err := rows.ColumnTypes()
289+
tt, err := table.rows.ColumnTypes()
285290
if err != nil {
286-
return nil, err
291+
return err
287292
}
288293

289-
types := make([]reflect.Type, len(tt))
294+
table.types = make([]reflect.Type, len(tt))
290295
for i, tp := range tt {
291296
st := tp.ScanType()
292297
if tp.DatabaseTypeName() == "BLOB" {
293-
types[i] = reflect.TypeOf(sql.RawBytes{})
298+
table.types[i] = reflect.TypeOf(sql.RawBytes{})
294299
} else if st != nil && (st.Kind() == reflect.Int ||
295300
st.Kind() == reflect.Int8 ||
296301
st.Kind() == reflect.Int16 ||
297302
st.Kind() == reflect.Int32 ||
298303
st.Kind() == reflect.Int64) {
299-
types[i] = reflect.TypeOf(sql.NullInt64{})
304+
table.types[i] = reflect.TypeOf(sql.NullInt64{})
300305
} else {
301-
types[i] = reflect.TypeOf(sql.NullString{})
306+
table.types[i] = reflect.TypeOf(sql.NullString{})
302307
}
303308
}
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()
307312
}
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
311326
}
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))
312337

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
340348
}
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, "'")
341363
}
342364
}
343-
344-
dataText = append(dataText, "("+strings.Join(dataStrings, ",")+")")
345365
}
346366

347-
return dataText, rows.Err()
367+
return "(" + strings.Join(dataStrings, ",") + ")", table.rows.Err()
348368
}

0 commit comments

Comments
 (0)