123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- package mysql
- import (
- "context"
- "database/sql"
- "database/sql/driver"
- )
- func (mc *mysqlConn) Ping(ctx context.Context) (err error) {
- if mc.closed.IsSet() {
- errLog.Print(ErrInvalidConn)
- return driver.ErrBadConn
- }
- if err = mc.watchCancel(ctx); err != nil {
- return
- }
- defer mc.finish()
- if err = mc.writeCommandPacket(comPing); err != nil {
- return
- }
- return mc.readResultOK()
- }
- func (mc *mysqlConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error) {
- if err := mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- defer mc.finish()
- if sql.IsolationLevel(opts.Isolation) != sql.LevelDefault {
- level, err := mapIsolationLevel(opts.Isolation)
- if err != nil {
- return nil, err
- }
- err = mc.exec("SET TRANSACTION ISOLATION LEVEL " + level)
- if err != nil {
- return nil, err
- }
- }
- return mc.begin(opts.ReadOnly)
- }
- func (mc *mysqlConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) {
- dargs, err := namedValueToValue(args)
- if err != nil {
- return nil, err
- }
- if err := mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- rows, err := mc.query(query, dargs)
- if err != nil {
- mc.finish()
- return nil, err
- }
- rows.finish = mc.finish
- return rows, err
- }
- func (mc *mysqlConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) {
- dargs, err := namedValueToValue(args)
- if err != nil {
- return nil, err
- }
- if err := mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- defer mc.finish()
- return mc.Exec(query, dargs)
- }
- func (mc *mysqlConn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) {
- if err := mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- stmt, err := mc.Prepare(query)
- mc.finish()
- if err != nil {
- return nil, err
- }
- select {
- default:
- case <-ctx.Done():
- stmt.Close()
- return nil, ctx.Err()
- }
- return stmt, nil
- }
- func (stmt *mysqlStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) {
- dargs, err := namedValueToValue(args)
- if err != nil {
- return nil, err
- }
- if err := stmt.mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- rows, err := stmt.query(dargs)
- if err != nil {
- stmt.mc.finish()
- return nil, err
- }
- rows.finish = stmt.mc.finish
- return rows, err
- }
- func (stmt *mysqlStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) {
- dargs, err := namedValueToValue(args)
- if err != nil {
- return nil, err
- }
- if err := stmt.mc.watchCancel(ctx); err != nil {
- return nil, err
- }
- defer stmt.mc.finish()
- return stmt.Exec(dargs)
- }
- func (mc *mysqlConn) watchCancel(ctx context.Context) error {
- if mc.watching {
-
-
- mc.cleanup()
- return nil
- }
- if ctx.Done() == nil {
- return nil
- }
- mc.watching = true
- select {
- default:
- case <-ctx.Done():
- return ctx.Err()
- }
- if mc.watcher == nil {
- return nil
- }
- mc.watcher <- ctx
- return nil
- }
- func (mc *mysqlConn) startWatcher() {
- watcher := make(chan mysqlContext, 1)
- mc.watcher = watcher
- finished := make(chan struct{})
- mc.finished = finished
- go func() {
- for {
- var ctx mysqlContext
- select {
- case ctx = <-watcher:
- case <-mc.closech:
- return
- }
- select {
- case <-ctx.Done():
- mc.cancel(ctx.Err())
- case <-finished:
- case <-mc.closech:
- return
- }
- }
- }()
- }
- func (mc *mysqlConn) CheckNamedValue(nv *driver.NamedValue) (err error) {
- nv.Value, err = converter{}.ConvertValue(nv.Value)
- return
- }
- func (mc *mysqlConn) ResetSession(ctx context.Context) error {
- if mc.closed.IsSet() {
- return driver.ErrBadConn
- }
- return nil
- }
|