Skip to content

Commit 5398634

Browse files
committed
io.ReadCloser + doc
1 parent 7205943 commit 5398634

File tree

2 files changed

+23
-16
lines changed

2 files changed

+23
-16
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,9 +144,9 @@ For this feature you need direct access to the package. Therefore you must chang
144144
import "github.com/go-sql-driver/mysql"
145145
```
146146

147-
Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (reccommended) or the whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` (might be insecure).
147+
Files must be whitelisted by registering them with `mysql.RegisterLocalFile(filepath)` (reccommended) or the Whitelist check must be deactivated by using the DSN parameter `allowAllFiles=true` (might be insecure).
148148

149-
`io.Reader`s must be registered with `mysql.RegisterReader(name, reader)`. They are available with the filepath `Reader::<name>` then.
149+
To use a `io.Reader` a handler function must be registered with `mysql.RegisterReaderHandler(name, handler)` which returns a `io.Reader` or `io.ReadCloser`. The Reader is available with the filepath `Reader::<name>` then.
150150

151151
See also the [godoc of Go-MySQL-Driver](http://godoc.org/github.com/go-sql-driver/mysql "golang mysql driver documentation")
152152

infile.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ func RegisterLocalFile(filepath string) {
3535
fileRegister[filepath] = true
3636
}
3737

38-
// RegisterReader registers a io.Reader so that it can be used by
39-
// "LOAD DATA LOCAL INFILE Reader::<name>".
40-
// The use of io.Reader in this context is NOT safe for concurrency!
41-
func RegisterReaderHandler(name string, cb func() io.Reader) {
42-
readerRegister[name] = cb
38+
// RegisterReaderHandler registers a handler function which is used
39+
// to receive a io.Reader.
40+
// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::<name>".
41+
// If the handler returns a io.ReadCloser Close() is called when the
42+
// request is finished.
43+
func RegisterReaderHandler(name string, handler func() io.Reader) {
44+
readerRegister[name] = handler
4345
}
4446

4547
func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
@@ -48,9 +50,9 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
4850

4951
if strings.HasPrefix(name, "Reader::") { // io.Reader
5052
name = name[8:]
51-
cb, inMap := readerRegister[name]
52-
if cb != nil {
53-
rdr = cb()
53+
handler, inMap := readerRegister[name]
54+
if handler != nil {
55+
rdr = handler()
5456
}
5557
if rdr == nil {
5658
if !inMap {
@@ -59,19 +61,24 @@ func (mc *mysqlConn) handleInFileRequest(name string) (err error) {
5961
err = fmt.Errorf("Reader '%s' is <nil>", name)
6062
}
6163
}
62-
6364
} else { // File
6465
if fileRegister[name] || mc.cfg.params[`allowAllFiles`] == `true` {
65-
var file *os.File
66-
file, err = os.Open(name)
67-
defer file.Close()
68-
69-
rdr = file
66+
rdr, err = os.Open(name)
7067
} else {
7168
err = fmt.Errorf("Local File '%s' is not registered. Use the DSN parameter 'allowAllFiles=true' to allow all files", name)
7269
}
7370
}
7471

72+
if rdc, ok := rdr.(io.ReadCloser); ok {
73+
defer func() {
74+
if err == nil {
75+
err = rdc.Close()
76+
} else {
77+
rdc.Close()
78+
}
79+
}()
80+
}
81+
7582
// send content packets
7683
var ioErr error
7784
if err == nil {

0 commit comments

Comments
 (0)