diff --git a/db.go b/db.go new file mode 100644 index 0000000..9d8db20 --- /dev/null +++ b/db.go @@ -0,0 +1,72 @@ +package dbtyp + +import ( + "context" + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.DB = &DB[struct{}]{} + +type DB[T any] struct { + *sql.DB +} + +// Type converter + +func (v *DB[T]) ExecQueryer() *ExecQueryer[T] { + return &ExecQueryer[T]{i: v} +} + +func (v *DB[T]) Execer() *Execer[T] { + return &Execer[T]{i: v} +} + +func (v *DB[T]) Queryer() *Queryer[T] { + return &Queryer[T]{i: v} +} + +// Typed begin + +func (v *DB[T]) BeginT() (*Tx[T], error) { + tx, err := v.Begin() + + if err != nil { + return nil, err + } + + return &Tx[T]{Tx: tx}, nil +} + +func (v *DB[T]) BeginTxT(ctx context.Context, opts *sql.TxOptions) (*Tx[T], error) { + tx, err := v.BeginTx(ctx, opts) + + if err != nil { + return nil, err + } + + return &Tx[T]{Tx: tx}, nil +} + +// Typed prepare + +func (v *DB[T]) PrepareT(query string) (*Stmt[T], error) { + stmt, err := v.Prepare(query) + + if err != nil { + return nil, err + } + + return &Stmt[T]{Stmt: stmt}, nil +} + +func (v *DB[T]) PrepareContextT(ctx context.Context, query string) (*Stmt[T], error) { + stmt, err := v.PrepareContext(ctx, query) + + if err != nil { + return nil, err + } + + return &Stmt[T]{Stmt: stmt}, nil +} diff --git a/exec_queryer.go b/exec_queryer.go new file mode 100644 index 0000000..c8553be --- /dev/null +++ b/exec_queryer.go @@ -0,0 +1,50 @@ +package dbtyp + +import ( + "context" + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.ExecQueryer = &ExecQueryer[struct{}]{} + +type ExecQueryer[T any] struct { + i iface.ExecQueryer +} + +// Interface implement + +func (v *ExecQueryer[T]) Exec(query string, args ...any) (sql.Result, error) { + return v.i.Exec(query, args...) +} + +func (v *ExecQueryer[T]) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { + return v.i.ExecContext(ctx, query, args...) +} + +func (v *ExecQueryer[T]) Query(query string, args ...any) (*sql.Rows, error) { + return v.i.Query(query, args...) +} + +func (v *ExecQueryer[T]) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { + return v.i.QueryContext(ctx, query, args...) +} + +func (v *ExecQueryer[T]) QueryRow(query string, args ...any) *sql.Row { + return v.i.QueryRow(query, args...) +} + +func (v *ExecQueryer[T]) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row { + return v.i.QueryRowContext(ctx, query, args...) +} + +// Type converter + +func (v *ExecQueryer[T]) Execer() *Execer[T] { + return &Execer[T]{i: v.i} +} + +func (v *ExecQueryer[T]) Queryer() *Queryer[T] { + return &Queryer[T]{i: v.i} +} diff --git a/execer.go b/execer.go new file mode 100644 index 0000000..e06f9d2 --- /dev/null +++ b/execer.go @@ -0,0 +1,24 @@ +package dbtyp + +import ( + "context" + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.Execer = &Execer[struct{}]{} + +type Execer[T any] struct { + i iface.Execer +} + +// Interface implement + +func (v *Execer[T]) Exec(query string, args ...any) (sql.Result, error) { + return v.i.Exec(query, args...) +} + +func (v *Execer[T]) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { + return v.i.ExecContext(ctx, query, args...) +} diff --git a/iface/db.go b/iface/db.go new file mode 100644 index 0000000..a73ab73 --- /dev/null +++ b/iface/db.go @@ -0,0 +1,33 @@ +package iface + +import ( + "context" + "database/sql" + "database/sql/driver" + "time" +) + +var _ DB = &sql.DB{} + +type DB interface { + Begin() (*sql.Tx, error) + BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) + Close() error + Conn(ctx context.Context) (*sql.Conn, error) + Driver() driver.Driver + Exec(query string, args ...any) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) + Ping() error + PingContext(ctx context.Context) error + Prepare(query string) (*sql.Stmt, error) + PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) + Query(query string, args ...any) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) + QueryRow(query string, args ...any) *sql.Row + QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row + SetConnMaxIdleTime(d time.Duration) + SetConnMaxLifetime(d time.Duration) + SetMaxIdleConns(n int) + SetMaxOpenConns(n int) + Stats() sql.DBStats +} diff --git a/iface/exec_queryer.go b/iface/exec_queryer.go new file mode 100644 index 0000000..e59300e --- /dev/null +++ b/iface/exec_queryer.go @@ -0,0 +1,13 @@ +package iface + +import ( + "database/sql" +) + +var _ ExecQueryer = &sql.DB{} +var _ ExecQueryer = &sql.Tx{} + +type ExecQueryer interface { + Execer + Queryer +} diff --git a/iface/execer.go b/iface/execer.go new file mode 100644 index 0000000..eeb4c41 --- /dev/null +++ b/iface/execer.go @@ -0,0 +1,14 @@ +package iface + +import ( + "context" + "database/sql" +) + +var _ Execer = &sql.DB{} +var _ Execer = &sql.Tx{} + +type Execer interface { + Exec(query string, args ...any) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) +} diff --git a/iface/iface.go b/iface/iface.go deleted file mode 100644 index 42a35fc..0000000 --- a/iface/iface.go +++ /dev/null @@ -1,88 +0,0 @@ -package iface - -import ( - "context" - "database/sql" - "database/sql/driver" - "time" -) - -var _ DB = &sql.DB{} - -type DB interface { - Begin() (*sql.Tx, error) - BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) - Close() error - Conn(ctx context.Context) (*sql.Conn, error) - Driver() driver.Driver - Exec(query string, args ...any) (sql.Result, error) - ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) - Ping() error - PingContext(ctx context.Context) error - Prepare(query string) (*sql.Stmt, error) - PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) - Query(query string, args ...any) (*sql.Rows, error) - QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) - QueryRow(query string, args ...any) *sql.Row - QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row - SetConnMaxIdleTime(d time.Duration) - SetConnMaxLifetime(d time.Duration) - SetMaxIdleConns(n int) - SetMaxOpenConns(n int) - Stats() sql.DBStats -} - -var _ Tx = &sql.Tx{} - -type Tx interface { - Commit() error - Exec(query string, args ...any) (sql.Result, error) - ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) - Prepare(query string) (*sql.Stmt, error) - PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) - Query(query string, args ...any) (*sql.Rows, error) - QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) - QueryRow(query string, args ...any) *sql.Row - QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row - Rollback() error - Stmt(stmt *sql.Stmt) *sql.Stmt - StmtContext(ctx context.Context, stmt *sql.Stmt) *sql.Stmt -} - -var _ Stmt = &sql.Stmt{} - -type Stmt interface { - Close() error - Exec(args ...any) (sql.Result, error) - ExecContext(ctx context.Context, args ...any) (sql.Result, error) - Query(args ...any) (*sql.Rows, error) - QueryContext(ctx context.Context, args ...any) (*sql.Rows, error) - QueryRow(args ...any) *sql.Row - QueryRowContext(ctx context.Context, args ...any) *sql.Row -} - -var _ ExecQueryer = &sql.DB{} -var _ ExecQueryer = &sql.Tx{} - -type ExecQueryer interface { - Execer - Queryer -} - -var _ Execer = &sql.DB{} -var _ Execer = &sql.Tx{} - -type Execer interface { - Exec(query string, args ...any) (sql.Result, error) - ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) -} - -var _ Queryer = &sql.DB{} -var _ Queryer = &sql.Tx{} - -type Queryer interface { - Query(query string, args ...any) (*sql.Rows, error) - QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) - QueryRow(query string, args ...any) *sql.Row - QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row -} diff --git a/iface/queryer.go b/iface/queryer.go new file mode 100644 index 0000000..b5339dd --- /dev/null +++ b/iface/queryer.go @@ -0,0 +1,16 @@ +package iface + +import ( + "context" + "database/sql" +) + +var _ Queryer = &sql.DB{} +var _ Queryer = &sql.Tx{} + +type Queryer interface { + Query(query string, args ...any) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) + QueryRow(query string, args ...any) *sql.Row + QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row +} diff --git a/iface/stmt.go b/iface/stmt.go new file mode 100644 index 0000000..fa33803 --- /dev/null +++ b/iface/stmt.go @@ -0,0 +1,18 @@ +package iface + +import ( + "context" + "database/sql" +) + +var _ Stmt = &sql.Stmt{} + +type Stmt interface { + Close() error + Exec(args ...any) (sql.Result, error) + ExecContext(ctx context.Context, args ...any) (sql.Result, error) + Query(args ...any) (*sql.Rows, error) + QueryContext(ctx context.Context, args ...any) (*sql.Rows, error) + QueryRow(args ...any) *sql.Row + QueryRowContext(ctx context.Context, args ...any) *sql.Row +} diff --git a/iface/tx.go b/iface/tx.go new file mode 100644 index 0000000..7dfd120 --- /dev/null +++ b/iface/tx.go @@ -0,0 +1,23 @@ +package iface + +import ( + "context" + "database/sql" +) + +var _ Tx = &sql.Tx{} + +type Tx interface { + Commit() error + Exec(query string, args ...any) (sql.Result, error) + ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) + Prepare(query string) (*sql.Stmt, error) + PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) + Query(query string, args ...any) (*sql.Rows, error) + QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) + QueryRow(query string, args ...any) *sql.Row + QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row + Rollback() error + Stmt(stmt *sql.Stmt) *sql.Stmt + StmtContext(ctx context.Context, stmt *sql.Stmt) *sql.Stmt +} diff --git a/queryer.go b/queryer.go new file mode 100644 index 0000000..cbb1f8e --- /dev/null +++ b/queryer.go @@ -0,0 +1,32 @@ +package dbtyp + +import ( + "context" + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.Queryer = &Queryer[struct{}]{} + +type Queryer[T any] struct { + i iface.Queryer +} + +// Interface implement + +func (v *Queryer[T]) Query(query string, args ...any) (*sql.Rows, error) { + return v.i.Query(query, args...) +} + +func (v *Queryer[T]) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { + return v.i.QueryContext(ctx, query, args...) +} + +func (v *Queryer[T]) QueryRow(query string, args ...any) *sql.Row { + return v.i.QueryRow(query, args...) +} + +func (v *Queryer[T]) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row { + return v.i.QueryRowContext(ctx, query, args...) +} diff --git a/stmt.go b/stmt.go new file mode 100644 index 0000000..eefc4ef --- /dev/null +++ b/stmt.go @@ -0,0 +1,13 @@ +package dbtyp + +import ( + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.Stmt = &Stmt[struct{}]{} + +type Stmt[T any] struct { + *sql.Stmt +} diff --git a/tx.go b/tx.go new file mode 100644 index 0000000..c68bf84 --- /dev/null +++ b/tx.go @@ -0,0 +1,50 @@ +package dbtyp + +import ( + "context" + "database/sql" + + "github.com/winebarrel/dbtyp/iface" +) + +var _ iface.Tx = &Tx[struct{}]{} + +type Tx[T any] struct { + *sql.Tx +} + +// Type converter + +func (v *Tx[T]) ExecQueryer() *ExecQueryer[T] { + return &ExecQueryer[T]{i: v} +} + +func (v *Tx[T]) Execer() *Execer[T] { + return &Execer[T]{i: v} +} + +func (v *Tx[T]) Queryer() *Queryer[T] { + return &Queryer[T]{i: v} +} + +// Typed prepare + +func (v *Tx[T]) PrepareT(query string) (*Stmt[T], error) { + stmt, err := v.Prepare(query) + + if err != nil { + return nil, err + } + + return &Stmt[T]{Stmt: stmt}, nil +} + +func (v *Tx[T]) PrepareContextT(ctx context.Context, query string) (*Stmt[T], error) { + stmt, err := v.PrepareContext(ctx, query) + + if err != nil { + return nil, err + } + + return &Stmt[T]{Stmt: stmt}, nil +} diff --git a/types.go b/types.go deleted file mode 100644 index 9ff9dd5..0000000 --- a/types.go +++ /dev/null @@ -1,226 +0,0 @@ -package dbtyp - -import ( - "context" - "database/sql" - - "github.com/winebarrel/dbtyp/iface" -) - -///////////////////////////////////////////////////////////////////// -// DB -///////////////////////////////////////////////////////////////////// - -var _ iface.DB = &DB[struct{}]{} - -type DB[T any] struct { - *sql.DB -} - -// Type converter - -func (v *DB[T]) ExecQueryer() *ExecQueryer[T] { - return &ExecQueryer[T]{i: v} -} - -func (v *DB[T]) Execer() *Execer[T] { - return &Execer[T]{i: v} -} - -func (v *DB[T]) Queryer() *Queryer[T] { - return &Queryer[T]{i: v} -} - -// Typed begin - -func (v *DB[T]) BeginT() (*Tx[T], error) { - tx, err := v.Begin() - - if err != nil { - return nil, err - } - - return &Tx[T]{Tx: tx}, nil -} - -func (v *DB[T]) BeginTxT(ctx context.Context, opts *sql.TxOptions) (*Tx[T], error) { - tx, err := v.BeginTx(ctx, opts) - - if err != nil { - return nil, err - } - - return &Tx[T]{Tx: tx}, nil -} - -// Typed prepare - -func (v *DB[T]) PrepareT(query string) (*Stmt[T], error) { - stmt, err := v.Prepare(query) - - if err != nil { - return nil, err - } - - return &Stmt[T]{Stmt: stmt}, nil -} - -func (v *DB[T]) PrepareContextT(ctx context.Context, query string) (*Stmt[T], error) { - stmt, err := v.PrepareContext(ctx, query) - - if err != nil { - return nil, err - } - - return &Stmt[T]{Stmt: stmt}, nil -} - -///////////////////////////////////////////////////////////////////// -// Tx -///////////////////////////////////////////////////////////////////// - -var _ iface.Tx = &Tx[struct{}]{} - -type Tx[T any] struct { - *sql.Tx -} - -// Type converter - -func (v *Tx[T]) ExecQueryer() *ExecQueryer[T] { - return &ExecQueryer[T]{i: v} -} - -func (v *Tx[T]) Execer() *Execer[T] { - return &Execer[T]{i: v} -} - -func (v *Tx[T]) Queryer() *Queryer[T] { - return &Queryer[T]{i: v} -} - -// Typed prepare - -func (v *Tx[T]) PrepareT(query string) (*Stmt[T], error) { - stmt, err := v.Prepare(query) - - if err != nil { - return nil, err - } - - return &Stmt[T]{Stmt: stmt}, nil -} - -func (v *Tx[T]) PrepareContextT(ctx context.Context, query string) (*Stmt[T], error) { - stmt, err := v.PrepareContext(ctx, query) - - if err != nil { - return nil, err - } - - return &Stmt[T]{Stmt: stmt}, nil -} - -///////////////////////////////////////////////////////////////////// -// Stmt -///////////////////////////////////////////////////////////////////// - -var _ iface.Stmt = &Stmt[struct{}]{} - -type Stmt[T any] struct { - *sql.Stmt -} - -///////////////////////////////////////////////////////////////////// -// ExecQueryer -///////////////////////////////////////////////////////////////////// - -var _ iface.ExecQueryer = &ExecQueryer[struct{}]{} - -type ExecQueryer[T any] struct { - i iface.ExecQueryer -} - -// Interface implement - -func (v *ExecQueryer[T]) Exec(query string, args ...any) (sql.Result, error) { - return v.i.Exec(query, args...) -} - -func (v *ExecQueryer[T]) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { - return v.i.ExecContext(ctx, query, args...) -} - -func (v *ExecQueryer[T]) Query(query string, args ...any) (*sql.Rows, error) { - return v.i.Query(query, args...) -} - -func (v *ExecQueryer[T]) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { - return v.i.QueryContext(ctx, query, args...) -} - -func (v *ExecQueryer[T]) QueryRow(query string, args ...any) *sql.Row { - return v.i.QueryRow(query, args...) -} - -func (v *ExecQueryer[T]) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row { - return v.i.QueryRowContext(ctx, query, args...) -} - -// Type converter - -func (v *ExecQueryer[T]) Execer() *Execer[T] { - return &Execer[T]{i: v.i} -} - -func (v *ExecQueryer[T]) Queryer() *Queryer[T] { - return &Queryer[T]{i: v.i} -} - -///////////////////////////////////////////////////////////////////// -// Execer -///////////////////////////////////////////////////////////////////// - -var _ iface.Execer = &Execer[struct{}]{} - -type Execer[T any] struct { - i iface.Execer -} - -// Interface implement - -func (v *Execer[T]) Exec(query string, args ...any) (sql.Result, error) { - return v.i.Exec(query, args...) -} - -func (v *Execer[T]) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { - return v.i.ExecContext(ctx, query, args...) -} - -///////////////////////////////////////////////////////////////////// -// Queryer -///////////////////////////////////////////////////////////////////// - -var _ iface.Queryer = &Queryer[struct{}]{} - -type Queryer[T any] struct { - i iface.Queryer -} - -// Interface implement - -func (v *Queryer[T]) Query(query string, args ...any) (*sql.Rows, error) { - return v.i.Query(query, args...) -} - -func (v *Queryer[T]) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { - return v.i.QueryContext(ctx, query, args...) -} - -func (v *Queryer[T]) QueryRow(query string, args ...any) *sql.Row { - return v.i.QueryRow(query, args...) -} - -func (v *Queryer[T]) QueryRowContext(ctx context.Context, query string, args ...any) *sql.Row { - return v.i.QueryRowContext(ctx, query, args...) -}