Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Зачем и как написать свой database/sql драйвер

Зачем и как написать свой database/sql драйвер

Alexey Palazhchenko

December 07, 2018
Tweet

More Decks by Alexey Palazhchenko

Other Decks in Programming

Transcript

  1. Зачем? • Написание нового драйвера для SQL СУБД • или

    исправление существующего • Написание «наддрайвера»
  2. Зачем? • Написание нового драйвера для SQL СУБД • или

    исправление существующего • Написание «наддрайвера» • для observability и отладки
  3. Зачем? • Написание нового драйвера для SQL СУБД • или

    исправление существующего • Написание «наддрайвера» • для observability и отладки • Написание драйвера для NoSQL СУБД
  4. Зачем? • Написание нового драйвера для SQL СУБД • или

    исправление существующего • Написание «наддрайвера» • для observability и отладки • Написание драйвера для NoSQL СУБД • или даже не для СУБД
  5. Зачем? • Написание нового драйвера для SQL СУБД • https://github.com/AlekSi/mysqlx

    • Написание «наддрайвера» • https://github.com/luna-duclos/instrumentedsql • Написание драйвера для NoSQL СУБД • https://github.com/AlekSi/sqlcsv
  6. • func IsScanValue(v interface{}) bool • func IsValue(v interface{}) bool

    • type ColumnConverter • type Conn • type Driver • type Execer • type NotNull • func (n NotNull) ConvertValue(v interface{}) (Value, error) • type Null • func (n Null) ConvertValue(v interface{}) (Value, error) • type Result • type Rows • type RowsAffected • func (RowsAffected) LastInsertId() (int64, error) • func (v RowsAffected) RowsAffected() (int64, error) • type Stmt • type Tx • type Value • type ValueConverter • type Valuer
  7. • func IsScanValue(v interface{}) bool • func IsValue(v interface{}) bool

    • type ColumnConverter • type Conn • type ConnBeginTx • type ConnPrepareContext • type Connector • type Driver • type DriverContext • type Execer • type ExecerContext • type IsolationLevel • type NamedValue • type NamedValueChecker • type NotNull • func (n NotNull) ConvertValue(v interface{}) (Value, error) • type Null • func (n Null) ConvertValue(v interface{}) (Value, error) • type Pinger • type Queryer • type QueryerContext • type Result • type Rows • type RowsAffected • func (RowsAffected) LastInsertId() (int64, error) • func (v RowsAffected) RowsAffected() (int64, error) • type RowsColumnTypeDatabaseTypeName • type RowsColumnTypeLength • type RowsColumnTypeNullable • type RowsColumnTypePrecisionScale • type RowsColumnTypeScanType • type RowsNextResultSet • type SessionResetter • type Stmt • type StmtExecContext • type StmtQueryContext • type Tx • type TxOptions • type Value • type ValueConverter • type Valuer
  8. 3 источника знаний • Код database/sql и database/sql/driver • Код

    существующих драйверов • но полно плохого и старого
  9. 3 источника знаний • Код database/sql и database/sql/driver • Код

    существующих драйверов • но полно плохого и старого • Кровь, пот и падающий прод
  10. Driver // Database drivers
 // may implement DriverContext […]
 type

    Driver interface {
 Open(name string) (Conn, error)
 }
  11. Conn type Conn interface {
 Prepare(query string) (Stmt, error)
 Close()

    error
 
 // Deprecated: Drivers should
 // implement ConnBeginTx instead
 // (or additionally).
 Begin() (Tx, error)
 }
  12. Stmt type Stmt interface {
 Close() error
 
 // NumInput

    may also return -1 […]
 NumInput() int
 
 // Deprecated: Drivers should implement
 // StmtExecContext instead (or additionally).
 Exec(args []Value) (Result, error)
 // Deprecated: Drivers should implement
 // StmtQueryContext instead (or additionally).
 Query(args []Value) (Rows, error)
 }
  13. Value Value is a value that drivers must be able

    to handle. It is either nil, a type handled by a database driver's NamedValueChecker interface, or an instance of one of these types:
 int64
 float64
 bool
 []byte
 string
 time.Time type Value interface{}
  14. ErrBadConn ErrBadConn should be returned by a driver to signal

    to the sql package that a driver.Conn is in a bad state […] and the sql package should retry on a new connection. var ErrBadConn = errors.New("[…]")
  15. Минимум • driver.Open(name string) (Conn, error) • conn.Prepare(query string) (Stmt,

    error) • stmt.Exec(args []Value) (Result, error) • stmt.Query(args []Value) (Rows, error) • rows.Next(dest []Value) error
  16. QueryerContext If a Conn does not implement QueryerContext […] DB.Query

    will first prepare a query, execute the statement, and then close the statement. QueryerContext may return ErrSkip. type QueryerContext interface {
 QueryContext(context.Context, string,
 []NamedValue) (Rows, error)
 }
  17. ErrSkip ErrSkip may be returned by some optional interfaces' methods

    to indicate at runtime that the fast path is unavailable and the sql package should continue as if the optional interface was not implemented. ErrSkip is only supported where explicitly documented. var ErrSkip = errors.New("[…]")
  18. Valuer и Scanner type JSON []byte func (j JSON) Value()

    (driver.Value, error)
 func (j *JSON) Scan(value interface{}) error var _ driver.Valuer = JSON{}
 var _ sql.Scanner = &JSON{}
  19. Опциональные интерфейсы func (c wrappedConn) Query(query string,
 args []driver.Value)
 (driver.Rows,

    error) {
 
 queryer, ok := c.parent.(driver.Queryer)
 if ok {
 return queryer.Query(query, args)
 }
 // ???
  20. Опциональные интерфейсы func (c wrappedConn) Query(query string,
 args []driver.Value)
 (driver.Rows,

    error) {
 
 queryer, ok := c.parent.(driver.Queryer)
 if ok {
 return queryer.Query(query, args)
 }
 return nil, driver.ErrSkip
  21. Context // Deprecated: Drivers should implement ExecerContext instead.
 type Execer

    interface {
 Exec(string, []Value) (Result, error)
 } type ExecerContext interface {
 ExecContext(ctx, string, []NamedValue)
 (Result, error)
 }
  22. Тестируйте • На реальных системах, с минимумом моков • На

    всех комбинациях Go и версий систем • Docker Compose отлично для этого подходит
  23. Работа в Percona Писать Open Source за деньги https://www.percona.com
 /about-percona


    /careers
 /golang-software-engineer Go Software Engineer
 Distributed / remote
 $2500-$4000
  24. GopherCon Russia 2019 13 апреля, Москва • Приём заявок на

    доклады открыт! • Первые билеты по цене прошлого года уже в продаже! https://www.gophercon-russia.ru