github.com/octohelm/storage@v0.0.0-20240516030302-1ac2cc1ea347/internal/sql/adapter/adapter.go (about)

     1  package adapter
     2  
     3  import (
     4  	"context"
     5  	"database/sql"
     6  	"net/url"
     7  	"sync"
     8  	"time"
     9  
    10  	"github.com/pkg/errors"
    11  
    12  	"github.com/octohelm/storage/pkg/sqlbuilder"
    13  )
    14  
    15  type DB interface {
    16  	Exec(ctx context.Context, expr sqlbuilder.SqlExpr) (sql.Result, error)
    17  	Query(ctx context.Context, expr sqlbuilder.SqlExpr) (*sql.Rows, error)
    18  	Transaction(ctx context.Context, action func(ctx context.Context) error) error
    19  	Close() error
    20  }
    21  
    22  type Connector interface {
    23  	Open(ctx context.Context, dsn *url.URL) (Adapter, error)
    24  }
    25  
    26  type Adapter interface {
    27  	DB
    28  	DriverName() string
    29  	Dialect() Dialect
    30  	Catalog(ctx context.Context) (*sqlbuilder.Tables, error)
    31  }
    32  
    33  type Dialect interface {
    34  	CreateTableIsNotExists(t sqlbuilder.Table) []sqlbuilder.SqlExpr
    35  	DropTable(t sqlbuilder.Table) sqlbuilder.SqlExpr
    36  	TruncateTable(t sqlbuilder.Table) sqlbuilder.SqlExpr
    37  
    38  	AddColumn(col sqlbuilder.Column) sqlbuilder.SqlExpr
    39  	RenameColumn(col sqlbuilder.Column, target sqlbuilder.Column) sqlbuilder.SqlExpr
    40  	ModifyColumn(col sqlbuilder.Column, prev sqlbuilder.Column) sqlbuilder.SqlExpr
    41  	DropColumn(col sqlbuilder.Column) sqlbuilder.SqlExpr
    42  
    43  	AddIndex(key sqlbuilder.Key) sqlbuilder.SqlExpr
    44  	DropIndex(key sqlbuilder.Key) sqlbuilder.SqlExpr
    45  
    46  	DataType(columnDef sqlbuilder.ColumnDef) sqlbuilder.SqlExpr
    47  }
    48  
    49  type DBSetting interface {
    50  	SetMaxOpenConns(n int)
    51  	SetMaxIdleConns(n int)
    52  	SetConnMaxLifetime(t time.Duration)
    53  }
    54  
    55  var adapters = sync.Map{}
    56  
    57  func Register(a Adapter, aliases ...string) {
    58  	adapters.Store(a.DriverName(), a)
    59  	for i := range aliases {
    60  		adapters.Store(aliases[i], a)
    61  	}
    62  }
    63  
    64  func Open(ctx context.Context, dsn string) (a Adapter, err error) {
    65  	u, err := url.Parse(dsn)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	adapters.Range(func(key, value any) bool {
    71  		if key.(string) == u.Scheme {
    72  			a, err = value.(Connector).Open(ctx, u)
    73  			return false
    74  		}
    75  		return true
    76  	})
    77  
    78  	if a == nil && err == nil {
    79  		return nil, errors.Errorf("missing adapter for %s", u.Scheme)
    80  	}
    81  
    82  	return
    83  }