// Go MySQL Driver - A MySQL-Driver for Go's database/sql package//// Copyright 2013 The Go-MySQL-Driver Authors. All rights reserved.//// This Source Code Form is subject to the terms of the Mozilla Public// License, v. 2.0. If a copy of the MPL was not distributed with this file,// You can obtain one at http://mozilla.org/MPL/2.0/.package mysqlimport ()var ( fileRegister map[string]bool fileRegisterLock sync.RWMutex readerRegister map[string]func() io.Reader readerRegisterLock sync.RWMutex)// RegisterLocalFile adds the given file to the file allowlist,// so that it can be used by "LOAD DATA LOCAL INFILE <filepath>".// Alternatively you can allow the use of all local files with// the DSN parameter 'allowAllFiles=true'//// filePath := "/home/gopher/data.csv"// mysql.RegisterLocalFile(filePath)// err := db.Exec("LOAD DATA LOCAL INFILE '" + filePath + "' INTO TABLE foo")// if err != nil {// ...func ( string) {fileRegisterLock.Lock()// lazy map initiffileRegister == nil {fileRegister = make(map[string]bool) }fileRegister[strings.Trim(, `"`)] = truefileRegisterLock.Unlock()}// DeregisterLocalFile removes the given filepath from the allowlist.func ( string) {fileRegisterLock.Lock()delete(fileRegister, strings.Trim(, `"`))fileRegisterLock.Unlock()}// RegisterReaderHandler registers a handler function which is used// to receive a io.Reader.// The Reader can be used by "LOAD DATA LOCAL INFILE Reader::<name>".// If the handler returns a io.ReadCloser Close() is called when the// request is finished.//// mysql.RegisterReaderHandler("data", func() io.Reader {// var csvReader io.Reader // Some Reader that returns CSV data// ... // Open Reader here// return csvReader// })// err := db.Exec("LOAD DATA LOCAL INFILE 'Reader::data' INTO TABLE foo")// if err != nil {// ...func ( string, func() io.Reader) {readerRegisterLock.Lock()// lazy map initifreaderRegister == nil {readerRegister = make(map[string]func() io.Reader) }readerRegister[] = readerRegisterLock.Unlock()}// DeregisterReaderHandler removes the ReaderHandler function with// the given name from the registry.func ( string) {readerRegisterLock.Lock()delete(readerRegister, )readerRegisterLock.Unlock()}func deferredClose( *error, io.Closer) { := .Close()if * == nil { * = }}const defaultPacketSize = 16 * 1024// 16KB is small enough for disk readahead and large enough for TCPfunc ( *mysqlConn) ( string) ( error) {vario.Readervar []byte := defaultPacketSizeif .maxWriteSize < { = .maxWriteSize }if := strings.Index(, "Reader::"); == 0 || ( > 0 && [-1] == '/') { // io.Reader// The server might return an an absolute path. See issue #355. = [+8:]readerRegisterLock.RLock() , := readerRegister[]readerRegisterLock.RUnlock()if { = ()if != nil {if , := .(io.Closer); {deferdeferredClose(&, ) } } else { = fmt.Errorf("Reader '%s' is <nil>", ) } } else { = fmt.Errorf("Reader '%s' is not registered", ) } } else { // File = strings.Trim(, `"`)fileRegisterLock.RLock() := fileRegister[]fileRegisterLock.RUnlock()if .cfg.AllowAllFiles || {var *os.Filevaros.FileInfoif , = os.Open(); == nil {deferdeferredClose(&, )// get file sizeif , = .Stat(); == nil { = if := int(.Size()); < { = } } } } else { = fmt.Errorf("local file '%s' is not registered", ) } }// send content packets // if packetSize == 0, the Reader contains no dataif == nil && > 0 { := make([]byte, 4+)varintfor == nil { , = .Read([4:])if > 0 {if := .writePacket([:4+]); != nil {return } } }if == io.EOF { = nil } }// send empty packet (termination)if == nil { = make([]byte, 4) }if := .writePacket([:4]); != nil {return }// read OK packetif == nil {return .readResultOK() } .readPacket()return}
The pages are generated with Goldsv0.6.7. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.