@@ -3,10 +3,11 @@ package export
3
3
import (
4
4
"context"
5
5
"fmt"
6
- "io"
7
6
"os"
8
7
"path"
9
- "sync"
8
+
9
+ "github.com/pingcap/dumpling/v4/log"
10
+ "go.uber.org/zap"
10
11
)
11
12
12
13
type Writer interface {
@@ -25,91 +26,58 @@ func NewSimpleWriter(config *Config) (Writer, error) {
25
26
}
26
27
27
28
func (f * SimpleWriter ) WriteDatabaseMeta (ctx context.Context , db , createSQL string ) error {
28
- fileName := path .Join (f .cfg .OutputDirPath , fmt .Sprintf ("%s-schema-create.sql" , db ))
29
- fsStringWriter := NewFileSystemStringWriter (fileName , false )
30
- meta := & metaData {
31
- target : db ,
32
- metaSQL : createSQL ,
33
- }
34
- return WriteMeta (meta , fsStringWriter )
29
+ fileName := fmt .Sprintf ("%s-schema-create.sql" , db )
30
+ filePath := path .Join (f .cfg .OutputDirPath , fileName )
31
+ return writeMetaToFile (db , createSQL , filePath )
35
32
}
36
33
37
34
func (f * SimpleWriter ) WriteTableMeta (ctx context.Context , db , table , createSQL string ) error {
38
- fileName := path .Join (f .cfg .OutputDirPath , fmt .Sprintf ("%s.%s-schema.sql" , db , table ))
39
- fsStringWriter := NewFileSystemStringWriter (fileName , false )
40
- meta := & metaData {
41
- target : table ,
42
- metaSQL : createSQL ,
43
- }
44
- return WriteMeta (meta , fsStringWriter )
35
+ fileName := fmt .Sprintf ("%s.%s-schema.sql" , db , table )
36
+ filePath := path .Join (f .cfg .OutputDirPath , fileName )
37
+ return writeMetaToFile (db , createSQL , filePath )
45
38
}
46
39
47
40
func (f * SimpleWriter ) WriteTableData (ctx context.Context , ir TableDataIR ) error {
41
+ log .Zap ().Debug ("start dumping table..." , zap .String ("table" , ir .TableName ()))
48
42
if f .cfg .FileSize == UnspecifiedSize {
49
43
fileName := path .Join (f .cfg .OutputDirPath , fmt .Sprintf ("%s.%s.sql" , ir .DatabaseName (), ir .TableName ()))
50
- fsStringWriter := NewFileSystemStringWriter (fileName , true )
51
- return WriteInsert (ir , fsStringWriter )
44
+ fileWriter , tearDown := buildLazyFileWriter (fileName )
45
+ defer tearDown ()
46
+ return WriteInsert (ir , fileWriter )
52
47
}
53
48
54
- ir = splitTableDataIntoChunks (ir , f .cfg .FileSize )
55
- for chunkCount := 0 ; ; /* loop */ chunkCount += 1 {
56
- fileName := path .Join (f .cfg .OutputDirPath , fmt .Sprintf ("%s.%s.%3d.sql" , ir .DatabaseName (), ir .TableName (), chunkCount ))
57
- fsStringWriter := newInterceptStringWriter (NewFileSystemStringWriter (fileName , true ))
58
- err := WriteInsert (ir , fsStringWriter )
49
+ chunks := splitTableDataIntoChunks (ir , f .cfg .FileSize )
50
+ chunkCount := 0
51
+ for {
52
+ fileName := fmt .Sprintf ("%s.%s.%d.sql" , ir .DatabaseName (), ir .TableName (), chunkCount )
53
+ filePath := path .Join (f .cfg .OutputDirPath , fileName )
54
+ fileWriter , tearDown := buildLazyFileWriter (filePath )
55
+ intWriter := & InterceptStringWriter {StringWriter : fileWriter }
56
+ err := WriteInsert (chunks , intWriter )
57
+ tearDown ()
59
58
if err != nil {
60
59
return err
61
60
}
62
- if fsStringWriter .writeNothingYet {
61
+
62
+ if ! intWriter .SomethingIsWritten {
63
63
break
64
64
}
65
+ chunkCount += 1
65
66
}
67
+ log .Zap ().Debug ("dumping table successfully" ,
68
+ zap .String ("table" , ir .TableName ()))
66
69
return nil
67
70
}
68
71
69
- type FileSystemStringWriter struct {
70
- path string
71
-
72
- file * os.File
73
- once sync.Once
74
- err error
75
- }
76
-
77
- func (w * FileSystemStringWriter ) initFileHandle () {
78
- w .file , w .err = os .OpenFile (w .path , os .O_CREATE | os .O_WRONLY , 0755 )
79
- }
80
-
81
- func (w * FileSystemStringWriter ) WriteString (str string ) (int , error ) {
82
- if w .err != nil {
83
- return 0 , w .err
72
+ func writeMetaToFile (target , metaSQL , path string ) error {
73
+ fileWriter , tearDown , err := buildFileWriter (path )
74
+ if err != nil {
75
+ return err
84
76
}
85
- w .once .Do (w .initFileHandle )
86
- return w .file .WriteString (str )
87
- }
77
+ defer tearDown ()
88
78
89
- func NewFileSystemStringWriter (path string , lazyHandleCreation bool ) * FileSystemStringWriter {
90
- w := & FileSystemStringWriter {path : path }
91
- if ! lazyHandleCreation {
92
- w .once .Do (w .initFileHandle )
93
- }
94
- return w
95
- }
96
-
97
- type interceptStringWriter struct {
98
- sw io.StringWriter
99
- writeNothingYet bool
100
- }
101
-
102
- func (i * interceptStringWriter ) WriteString (str string ) (int , error ) {
103
- writtenBytes , err := i .sw .WriteString (str )
104
- if writtenBytes != 0 {
105
- i .writeNothingYet = false
106
- }
107
- return writtenBytes , err
108
- }
109
-
110
- func newInterceptStringWriter (sw io.StringWriter ) * interceptStringWriter {
111
- return & interceptStringWriter {
112
- sw : sw ,
113
- writeNothingYet : true ,
114
- }
79
+ return WriteMeta (& metaData {
80
+ target : target ,
81
+ metaSQL : metaSQL ,
82
+ }, fileWriter )
115
83
}
0 commit comments