Pass-through DB Driver implementation (#17685)

* Pass-through DB Driver implementation

This is the first step in implementing a DB layer via RPC.

The plan is to migrate the mattermost-plugin-api to use
this DB connector so that all queries start to get
routed through this library.

And then we will add the DB query capability to the plugin RPC
API and route all queries via RPC. At that point, this will be
completely transparent to all plugins because they will already
be using the DB connector and everything will be behind the scenes
for them.

https://focalboard-community.octo.mattermost.com/workspace/zyoahc9uapdn3xdptac6jb69ic?id=285b80a3-257d-41f6-8cf4-ed80ca9d92e5&v=495cdb4d-c13a-4992-8eb9-80cfee2819a4&c=c7386db7-65fd-469b-8bcf-8dc8f8e61e4f

```release-note
NONE
```

* remove deprecated interfaces
Этот коммит содержится в:
Agniva De Sarker
2021-05-27 14:59:06 +05:30
коммит произвёл GitHub
родитель ff2fe1e62c
Коммит e35c78cac2
4 изменённых файлов: 222 добавлений и 13 удалений

93
shared/driver/conn.go Обычный файл
Просмотреть файл

@@ -0,0 +1,93 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package driver
import (
"context"
"database/sql"
"database/sql/driver"
)
// Conn is a DB driver conn implementation
// which will just pass-through all queries to its
// underlying connection.
type Conn struct {
conn *sql.Conn
}
// driverConn is a super-interface combining the basic
// driver.Conn interface with some new additions later.
type driverConn interface {
driver.Conn
driver.ConnBeginTx
driver.ConnPrepareContext
driver.ExecerContext
driver.QueryerContext
driver.Pinger
}
var (
// Compile-time check to ensure Conn implements the interface.
_ driverConn = &Conn{}
)
func (c *Conn) Begin() (tx driver.Tx, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
tx, err = innerConn.(driver.Conn).Begin() //nolint:staticcheck
return err
})
return tx, err
}
func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (tx driver.Tx, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
tx, err = innerConn.(driver.ConnBeginTx).BeginTx(ctx, opts)
return err
})
return tx, err
}
func (c *Conn) Prepare(q string) (stmt driver.Stmt, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
stmt, err = innerConn.(driver.Conn).Prepare(q)
return err
})
return stmt, err
}
func (c *Conn) PrepareContext(ctx context.Context, q string) (stmt driver.Stmt, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
stmt, err = innerConn.(driver.ConnPrepareContext).PrepareContext(ctx, q)
return err
})
return stmt, err
}
func (c *Conn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (res driver.Result, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
res, err = innerConn.(driver.ExecerContext).ExecContext(ctx, q, args)
return err
})
return res, err
}
func (c *Conn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (rows driver.Rows, err error) {
err = c.conn.Raw(func(innerConn interface{}) error {
rows, err = innerConn.(driver.QueryerContext).QueryContext(ctx, q, args)
return err
})
return rows, err
}
func (c *Conn) Ping(ctx context.Context) error {
return c.conn.Raw(func(innerConn interface{}) error {
return innerConn.(driver.Pinger).Ping(ctx)
})
}
func (c *Conn) Close() error {
return c.conn.Raw(func(innerConn interface{}) error {
return innerConn.(driver.Conn).Close()
})
}

57
shared/driver/driver.go Обычный файл
Просмотреть файл

@@ -0,0 +1,57 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package driver
import (
"context"
"database/sql"
"database/sql/driver"
)
var (
// Compile-time check to ensure Connector implements the interface.
_ driver.Connector = &Connector{}
)
// Connector is the DB connector which is used to
// initialize the underlying DB.
type Connector struct {
driverName string
dsn string
db *sql.DB
}
func NewConnector(driverName, dsn string) (*Connector, error) {
db, err := sql.Open(driverName, dsn)
if err != nil {
return nil, err
}
return &Connector{
driverName: driverName,
dsn: dsn,
db: db,
}, nil
}
func (c *Connector) Connect(ctx context.Context) (driver.Conn, error) {
conn, err := c.db.Conn(ctx)
if err != nil {
return nil, err
}
return &Conn{conn: conn}, nil
}
func (c *Connector) Driver() driver.Driver {
return &Driver{c: c}
}
// Driver is a DB driver implementation.
type Driver struct {
c *Connector
}
func (d Driver) Open(name string) (driver.Conn, error) {
return d.c.Connect(context.Background())
}