Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

226 lines (211 sloc) 4.969 kb
package mysql
import (
"bufio"
"errors"
"fmt"
"io"
"os"
"strings"
"unicode"
)
func syntaxError(ln int) error {
return fmt.Errorf("syntax error at line: %d", ln)
}
// Creates new conneection handler using configuration in cfgFile. Returns
// connection handler and map contains unknown options.
//
// Config file format(example):
//
// # mymysql options (if some option isn't specified it defaults to "")
//
// DbRaddr 127.0.0.1:3306
// # DbRaddr /var/run/mysqld/mysqld.sock
// DbUser testuser
// DbPass TestPasswd9
// # optional: DbName test
// # optional: DbEncd utf8
// # optional: DbLaddr 127.0.0.1
//
// # Your options (returned in unk)
//
// MyOpt some text
func NewFromCF(cfgFile string) (con Conn, unk map[string]string, err error) {
var cf *os.File
cf, err = os.Open(cfgFile)
if err != nil {
return
}
br := bufio.NewReader(cf)
um := make(map[string]string)
var proto, laddr, raddr, user, pass, name, encd string
for i := 1; ; i++ {
buf, isPrefix, e := br.ReadLine()
if e != nil {
if e == io.EOF {
break
}
err = e
return
}
l := string(buf)
if isPrefix {
err = fmt.Errorf("line %d is too long", i)
return
}
l = strings.TrimFunc(l, unicode.IsSpace)
if len(l) == 0 || l[0] == '#' {
continue
}
n := strings.IndexFunc(l, unicode.IsSpace)
if n == -1 {
err = fmt.Errorf("syntax error at line: %d", i)
return
}
v := l[:n]
l = strings.TrimLeftFunc(l[n:], unicode.IsSpace)
switch v {
case "DbLaddr":
laddr = l
case "DbRaddr":
raddr = l
proto = "tcp"
if strings.IndexRune(l, ':') == -1 {
proto = "unix"
}
case "DbUser":
user = l
case "DbPass":
pass = l
case "DbName":
name = l
case "DbEncd":
encd = l
default:
um[v] = l
}
}
if raddr == "" {
err = errors.New("DbRaddr option is empty")
return
}
unk = um
if name != "" {
con = New(proto, laddr, raddr, user, pass, name)
} else {
con = New(proto, laddr, raddr, user, pass)
}
if encd != "" {
con.Register(fmt.Sprintf("SET NAMES %s", encd))
}
return
}
// Calls Start and next calls GetRow as long as it reads all rows from the
// result. Next it returns all readed rows as the slice of rows.
func Query(c Conn, sql string, params ...interface{}) (rows []Row, res Result, err error) {
res, err = c.Start(sql, params...)
if err != nil {
return
}
rows, err = GetRows(res)
return
}
// Calls Start and next calls GetFirstRow
func QueryFirst(c Conn, sql string, params ...interface{}) (row Row, res Result, err error) {
res, err = c.Start(sql, params...)
if err != nil {
return
}
row, err = GetFirstRow(res)
return
}
// Calls Start and next calls GetLastRow
func QueryLast(c Conn, sql string, params ...interface{}) (row Row, res Result, err error) {
res, err = c.Start(sql, params...)
if err != nil {
return
}
row, err = GetLastRow(res)
return
}
// Calls Run and next call GetRow as long as it reads all rows from the
// result. Next it returns all readed rows as the slice of rows.
func Exec(s Stmt, params ...interface{}) (rows []Row, res Result, err error) {
res, err = s.Run(params...)
if err != nil {
return
}
rows, err = GetRows(res)
return
}
// Calls Run and next call GetFirstRow
func ExecFirst(s Stmt, params ...interface{}) (row Row, res Result, err error) {
res, err = s.Run(params...)
if err != nil {
return
}
row, err = GetFirstRow(res)
return
}
// Calls Run and next call GetLastRow
func ExecLast(s Stmt, params ...interface{}) (row Row, res Result, err error) {
res, err = s.Run(params...)
if err != nil {
return
}
row, err = GetLastRow(res)
return
}
// Calls r.MakeRow and next r.ScanRow. Doesn't return io.EOF error (returns nil
// row insted).
func GetRow(r Result) (Row, error) {
row := r.MakeRow()
err := r.ScanRow(row)
if err != nil {
if err == io.EOF {
return nil, nil
}
return nil, err
}
return row, nil
}
// Reads all rows from result and returns them as slice.
func GetRows(r Result) (rows []Row, err error) {
var row Row
for {
row, err = r.GetRow()
if err != nil || row == nil {
break
}
rows = append(rows, row)
}
return
}
// Returns last row and discard others
func GetLastRow(r Result) (Row, error) {
row := r.MakeRow()
err := r.ScanRow(row)
for err == nil {
err = r.ScanRow(row)
}
if err == io.EOF {
return row, nil
}
return nil, err
}
// Read all unreaded rows and discard them. This function is useful if you
// don't want to use the remaining rows. It has an impact only on current
// result. If there is multi result query, you must use NextResult method and
// read/discard all rows in this result, before use other method that sends
// data to the server. You can't use this function if last GetRow returned nil.
func End(r Result) error {
_, err := GetLastRow(r)
return err
}
// Returns first row and discard others
func GetFirstRow(r Result) (row Row, err error) {
row, err = r.GetRow()
if err == nil && row != nil {
err = r.End()
}
return
}
Jump to Line
Something went wrong with that request. Please try again.