From 32bc33942f21284be6c9a4c5417d86a7225e1e2e Mon Sep 17 00:00:00 2001 From: Agniva De Sarker Date: Fri, 4 Jun 2021 14:24:22 +0530 Subject: [PATCH] DB driver: Add wrapper structs for low-level objects (#17709) This is a necessary step for adding the RPC communication because each method call of each object needs to go through the RPC layer. Hence doing this part in a separate PR rather than heaping everything in a single PR. 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 ``` --- shared/driver/conn.go | 31 +++++++------ shared/driver/objects.go | 98 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 116 insertions(+), 13 deletions(-) create mode 100644 shared/driver/objects.go diff --git a/shared/driver/conn.go b/shared/driver/conn.go index 4c7824bf1b..196a1ad892 100644 --- a/shared/driver/conn.go +++ b/shared/driver/conn.go @@ -40,41 +40,46 @@ func (c *Conn) Begin() (tx driver.Tx, err error) { return tx, err } -func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (tx driver.Tx, err error) { +func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (_ driver.Tx, err error) { + t := &wrapperTx{} err = c.conn.Raw(func(innerConn interface{}) error { - tx, err = innerConn.(driver.ConnBeginTx).BeginTx(ctx, opts) + t.Tx, err = innerConn.(driver.ConnBeginTx).BeginTx(ctx, opts) return err }) - return tx, err + return t, err } -func (c *Conn) Prepare(q string) (stmt driver.Stmt, err error) { +func (c *Conn) Prepare(q string) (_ driver.Stmt, err error) { + st := &wrapperStmt{} err = c.conn.Raw(func(innerConn interface{}) error { - stmt, err = innerConn.(driver.Conn).Prepare(q) + st.Stmt, err = innerConn.(driver.Conn).Prepare(q) return err }) - return stmt, err + return st, err } -func (c *Conn) PrepareContext(ctx context.Context, q string) (stmt driver.Stmt, err error) { +func (c *Conn) PrepareContext(ctx context.Context, q string) (_ driver.Stmt, err error) { + st := &wrapperStmt{} err = c.conn.Raw(func(innerConn interface{}) error { - stmt, err = innerConn.(driver.ConnPrepareContext).PrepareContext(ctx, q) + st.Stmt, err = innerConn.(driver.ConnPrepareContext).PrepareContext(ctx, q) return err }) - return stmt, err + return st, err } -func (c *Conn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (res driver.Result, err error) { +func (c *Conn) ExecContext(ctx context.Context, q string, args []driver.NamedValue) (_ driver.Result, err error) { + res := &wrapperResult{} err = c.conn.Raw(func(innerConn interface{}) error { - res, err = innerConn.(driver.ExecerContext).ExecContext(ctx, q, args) + res.Result, 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) { +func (c *Conn) QueryContext(ctx context.Context, q string, args []driver.NamedValue) (_ driver.Rows, err error) { + rows := &wrapperRows{} err = c.conn.Raw(func(innerConn interface{}) error { - rows, err = innerConn.(driver.QueryerContext).QueryContext(ctx, q, args) + rows.Rows, err = innerConn.(driver.QueryerContext).QueryContext(ctx, q, args) return err }) return rows, err diff --git a/shared/driver/objects.go b/shared/driver/objects.go new file mode 100644 index 0000000000..008c189ccf --- /dev/null +++ b/shared/driver/objects.go @@ -0,0 +1,98 @@ +// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. +// See LICENSE.txt for license information. + +package driver + +import ( + "context" + "database/sql/driver" + "reflect" +) + +type wrapperTx struct { + driver.Tx +} + +func (t *wrapperTx) Commit() error { + return t.Tx.Commit() +} + +func (t *wrapperTx) Rollback() error { + return t.Tx.Rollback() +} + +type wrapperStmt struct { + driver.Stmt +} + +func (s *wrapperStmt) Close() error { + return s.Stmt.Close() +} + +func (s *wrapperStmt) NumInput() int { + return s.Stmt.NumInput() +} + +func (s *wrapperStmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { + return s.Stmt.(driver.StmtExecContext).ExecContext(ctx, args) +} + +func (s *wrapperStmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { + return s.Stmt.(driver.StmtQueryContext).QueryContext(ctx, args) +} + +type wrapperResult struct { + driver.Result +} + +func (r *wrapperResult) LastInsertId() (int64, error) { + return r.Result.LastInsertId() +} + +func (r *wrapperResult) RowsAffected() (int64, error) { + return r.Result.RowsAffected() +} + +type wrapperRows struct { + driver.Rows +} + +func (r *wrapperRows) Columns() []string { + return r.Rows.Columns() +} + +func (r *wrapperRows) Close() error { + return r.Rows.Close() +} + +func (r *wrapperRows) Next(dest []driver.Value) error { + return r.Rows.Next(dest) +} + +func (r *wrapperRows) HasNextResultSet() bool { + return r.Rows.(driver.RowsNextResultSet).HasNextResultSet() +} + +func (r *wrapperRows) NextResultSet() error { + return r.Rows.(driver.RowsNextResultSet).NextResultSet() +} + +func (r *wrapperRows) ColumnTypeScanType(index int) reflect.Type { + return r.Rows.(driver.RowsColumnTypeScanType).ColumnTypeScanType(index) +} + +func (r *wrapperRows) ColumnTypeDatabaseTypeName(index int) string { + return r.Rows.(driver.RowsColumnTypeDatabaseTypeName).ColumnTypeDatabaseTypeName(index) +} + +func (r *wrapperRows) ColumnTypeLength(index int) (length int64, ok bool) { + return r.Rows.(driver.RowsColumnTypeLength).ColumnTypeLength(index) +} + +func (r *wrapperRows) ColumnTypeNullable(index int) (nullable, ok bool) { + return r.Rows.(driver.RowsColumnTypeNullable).ColumnTypeNullable(index) +} + +func (r *wrapperRows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool) { + return r.Rows.(driver.RowsColumnTypePrecisionScale).ColumnTypePrecisionScale(index) +}