github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/database/sql/driver/driver.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package driverは、package sqlによって使用されるデータベースドライバが実装するインターフェースを定義します。
     6  //
     7  // ほとんどのコードは、[database/sql] パッケージを使用するべきです。
     8  //
     9  // ドライバのインターフェースは時間の経過とともに進化してきました。ドライバは [Connector] と [DriverContext] のインターフェースを実装する必要があります。
    10  // Connector.ConnectとDriver.Openメソッドは、決して [ErrBadConn] を返してはいけません。
    11  // [ErrBadConn] は、 [Validator] 、 [SessionResetter] 、または接続が既に無効な(閉じられたなど)状態にある場合にのみ返されるべきです。
    12  //
    13  // すべての [Conn] の実装は、以下のインターフェースを実装する必要があります:
    14  // [Pinger] 、 [SessionResetter] 、および [Validator] 。
    15  //
    16  // 名前付きパラメータやコンテキストがサポートされている場合、ドライバの [Conn] は以下を実装する必要があります:
    17  // [ExecerContext] 、 [QueryerContext] 、 [ConnPrepareContext] 、および [ConnBeginTx] 。
    18  //
    19  // カスタムデータ型をサポートするためには、 [NamedValueChecker] を実装します。 [NamedValueChecker] は、CheckNamedValueから [ErrRemoveArgument] を返すことで、クエリごとのオプションをパラメータとして受け入れることも可能にします。
    20  //
    21  // 複数の結果セットがサポートされている場合、 [Rows] は [RowsNextResultSet] を実装する必要があります。
    22  // ドライバが返された結果に含まれる型を説明する方法を知っている場合、以下のインターフェースを実装する必要があります:
    23  // [RowsColumnTypeScanType] 、 [RowsColumnTypeDatabaseTypeName] 、 [RowsColumnTypeLength] 、 [RowsColumnTypeNullable] 、および [RowsColumnTypePrecisionScale] 。
    24  // ある行の値は、Rows型を返すこともあり、それはデータベースカーソル値を表すことができます。
    25  //
    26  // [Conn] が [Validator] を実装している場合には、接続が使用後に接続プールに返される前にIsValidメソッドが呼び出されます。
    27  // コネクションプールのエントリーが [SessionResetter] を実装している場合には、別のクエリに再利用される前にResetSessionが呼び出されます。
    28  // 接続が接続プールに返されないで直接再利用される場合は、再利用の前にResetSessionが呼び出されますが、IsValidは呼び出されません。
    29  package driver
    30  
    31  import (
    32  	"github.com/shogo82148/std/context"
    33  	"github.com/shogo82148/std/errors"
    34  	"github.com/shogo82148/std/reflect"
    35  )
    36  
    37  // Valueは、ドライバが扱える必要がある値です。
    38  // nil、データベースドライバの [NamedValueChecker] インターフェースで扱われる型、または次のいずれかの型のインスタンスです:
    39  //
    40  //	int64
    41  //	float64
    42  //	bool
    43  //	[]byte
    44  //	string
    45  //	time.Time
    46  //
    47  // ドライバがカーソルをサポートしている場合、返されたValueはこのパッケージの [Rows] インターフェースも実装する場合があります。
    48  // これは、ユーザが "select cursor(select * from my_table) from dual" のようなカーソルを選択した場合に使用されます。
    49  // セレクトの [Rows] がクローズされると、カーソルの [Rows] もクローズされます。
    50  type Value any
    51  
    52  // NamedValueは値の名前と値を保持します。
    53  type NamedValue struct {
    54  
    55  	// もし Name が空でなければ、パラメータの識別子に使用されるべきであり、
    56  	// 順序位置ではないです。
    57  	//
    58  	// Name にはシンボルのプレフィックスはつきません。
    59  	Name string
    60  
    61  	// パラメータの序数位置は常に1から始まります。
    62  	Ordinal int
    63  
    64  	// Valueはパラメーターの値です。
    65  	Value Value
    66  }
    67  
    68  // Driverはデータベースドライバーによって実装される必要があるインターフェースです。
    69  //
    70  // データベースドライバーは、コンテキストへのアクセスと、接続プールの名前の解析を一度だけ行うために、
    71  // 接続ごとに一度ずつではなく、 [DriverContext] を実装することもできます。
    72  type Driver interface {
    73  	Open(name string) (Conn, error)
    74  }
    75  
    76  // もし [Driver] が DriverContext を実装している場合、[database/sql.DB] はOpenConnectorを呼び出して [Connector] を取得し、
    77  // その [Connector] のConnectメソッドを呼び出して必要な接続を取得します。
    78  // これにより、接続ごとに [Driver] のOpenメソッドを呼び出すのではなく、名前を1回だけ解析することができ、
    79  // またper-[Conn] コンテキストにアクセスすることもできます。
    80  type DriverContext interface {
    81  	OpenConnector(name string) (Connector, error)
    82  }
    83  
    84  // コネクタは、固定の構成でドライバを表し、複数のゴルーチンで使用するための同等の接続を作成できます。
    85  //
    86  // コネクタは [database/sql.OpenDB] に渡すことができ、ドライバは独自の [database/sql.DB] コンストラクタを実装するため、また、 [DriverContext] のOpenConnectorメソッドによって返されることができます。
    87  // これにより、ドライバはコンテキストへのアクセスとドライバ構成の繰り返し解析を避けることができます。
    88  //
    89  // コネクタが [io.Closer] を実装している場合、sqlパッケージの [database/sql.DB.Close] メソッドはCloseを呼び出し、エラー(あれば)を返します。
    90  type Connector interface {
    91  	Connect(context.Context) (Conn, error)
    92  
    93  	Driver() Driver
    94  }
    95  
    96  // ErrSkipは、一部のオプションのインタフェースメソッドによって、高速経路が利用できないことを実行時に示すために返される場合があります。sqlパッケージは、オプションのインタフェースが実装されていないかのように続行する必要があります。ErrSkipは、明示的に文書化されている場所でのみサポートされます。
    97  var ErrSkip = errors.New("driver: skip fast-path; continue as if unimplemented")
    98  
    99  // ErrBadConnは、ドライバが driver.[Conn] が不良な状態であることを示すために、
   100  // [database/sql] パッケージに返すべきです(たとえば、サーバーが接続を早期に閉じたなど)。
   101  // また、[database/sql] パッケージは新しい接続で再試行する必要があります。
   102  //
   103  // 重複した操作を防ぐために、可能性がある場合には、ErrBadConnを返してはいけません。
   104  // データベースサーバーが操作を実行した可能性があっても、ErrBadConnは返してはいけません。
   105  //
   106  // エラーは [errors.Is] を使用してチェックされます。エラーは
   107  // ErrBadConnをラップするか、Is(error) boolメソッドを実装することがあります。
   108  var ErrBadConn = errors.New("driver: bad connection")
   109  
   110  // Pingerは [Conn] によって実装される可能性のあるオプションのインターフェースです。
   111  //
   112  // [Conn] がPingerを実装していない場合、 [database/sql.DB.Ping] および [database/sql.DB.PingContext] は少なくとも1つの [Conn] が利用可能かどうかを確認します。
   113  //
   114  // Conn.Pingが [ErrBadConn] を返す場合、 [database/sql.DB.Ping] および [database/sql.DB.PingContext] は [Conn] をプールから削除します。
   115  type Pinger interface {
   116  	Ping(ctx context.Context) error
   117  }
   118  
   119  // Execerは [Conn] によって実装されるかもしれないオプションのインターフェースです。
   120  //
   121  // もし [Conn] が [ExecerContext] または [Execer] のどちらの実装も持っていない場合、
   122  // [database/sql.DB.Exec] はまずクエリを準備し、ステートメントを実行し、そしてステートメントを閉じます。
   123  //
   124  // Execは [ErrSkip] を返す場合があります。
   125  //
   126  // Deprecated: ドライバは代わりに [ExecerContext] を実装するべきです。
   127  type Execer interface {
   128  	Exec(query string, args []Value) (Result, error)
   129  }
   130  
   131  // ExecerContextは [Conn] によって実装されるかもしれないオプションのインターフェースです。
   132  //
   133  // [Conn] が [ExecerContext] を実装していない場合、[database/sql.DB.Exec] は [Execer] にフォールバックします。
   134  // もしConnがExecerも実装していない場合、[database/sql.DB.Exec] はまずクエリを準備し、ステートメントを実行してからステートメントを閉じます。
   135  //
   136  // ExecContextは [ErrSkip] を返すことがあります。
   137  //
   138  // ExecContextはコンテキストのタイムアウトを尊重し、コンテキストがキャンセルされたら返ります。
   139  type ExecerContext interface {
   140  	ExecContext(ctx context.Context, query string, args []NamedValue) (Result, error)
   141  }
   142  
   143  // Queryerは [Conn] によって実装されるかもしれないオプションのインターフェースです。
   144  //
   145  // [Conn] が [QueryerContext] も [Queryer] でも実装していない場合、 [database/sql.DB.Query] はまずクエリを準備し、ステートメントを実行してからステートメントを閉じます。
   146  //
   147  // Queryは [ErrSkip] を返すことがあります。
   148  //
   149  // Deprecated: ドライバは代わりに [QueryerContext] を実装するべきです。
   150  type Queryer interface {
   151  	Query(query string, args []Value) (Rows, error)
   152  }
   153  
   154  // QueryerContextは、[Conn] によって実装されるかもしれないオプションのインターフェースです。
   155  //
   156  // [Conn] がQueryerContextを実装していない場合、 [database/sql.DB.Query] は [Queryer] にフォールバックします。
   157  // もし、Connが [Queryer] を実装していない場合、 [database/sql.DB.Query] はまずクエリを準備し、ステートメントを実行してからステートメントを閉じます。
   158  //
   159  // QueryContextは [ErrSkip] を返す場合があります。
   160  //
   161  // QueryContextはコンテキストのタイムアウトに従う必要があり、コンテキストがキャンセルされた場合にreturnします。
   162  type QueryerContext interface {
   163  	QueryContext(ctx context.Context, query string, args []NamedValue) (Rows, error)
   164  }
   165  
   166  // Connはデータベースへの接続です。同時に複数のゴルーチンで使用されません。
   167  //
   168  // Connは状態を保持していると想定されています。
   169  type Conn interface {
   170  	Prepare(query string) (Stmt, error)
   171  
   172  	Close() error
   173  
   174  	Begin() (Tx, error)
   175  }
   176  
   177  // ConnPrepareContextはコンテキストを使用して [Conn] インターフェースを拡張します。
   178  type ConnPrepareContext interface {
   179  	PrepareContext(ctx context.Context, query string) (Stmt, error)
   180  }
   181  
   182  // IsolationLevelは [TxOptions] に保存されるトランザクション分離レベルです。
   183  //
   184  // この型は、[database/sql.IsolationLevel] と一緒に定義された値と同じものと考えられるべきです。
   185  type IsolationLevel int
   186  
   187  // TxOptionsはトランザクションのオプションを保持します。
   188  //
   189  // この型は [database/sql.TxOptions] と同一と見なされるべきです。
   190  type TxOptions struct {
   191  	Isolation IsolationLevel
   192  	ReadOnly  bool
   193  }
   194  
   195  // ConnBeginTxは、コンテキストと [TxOptions] を追加して [Conn] インタフェースを拡張します。
   196  type ConnBeginTx interface {
   197  	BeginTx(ctx context.Context, opts TxOptions) (Tx, error)
   198  }
   199  
   200  // SessionResetterは、 [Conn] によって実装される可能性があります。これにより、ドライバは接続に関連付けられたセッション状態をリセットし、悪い接続を通知することができます。
   201  type SessionResetter interface {
   202  	ResetSession(ctx context.Context) error
   203  }
   204  
   205  // Validatorは、 [Conn] によって実装されることがあります。これにより、ドライバーは接続が有効であるか、破棄すべきかを示すことができます。
   206  //
   207  // 実装されている場合、ドライバーはクエリから基礎となるエラーを返すことができます。たとえ接続プールによって接続が破棄されるべきであってもです。
   208  type Validator interface {
   209  	IsValid() bool
   210  }
   211  
   212  // Resultはクエリの実行結果です。
   213  type Result interface {
   214  	LastInsertId() (int64, error)
   215  
   216  	RowsAffected() (int64, error)
   217  }
   218  
   219  // Stmtはプリペアドステートメントです。これは [Conn] にバインドされており、複数のゴルーチンで同時に使用されません。
   220  type Stmt interface {
   221  	Close() error
   222  
   223  	NumInput() int
   224  
   225  	Exec(args []Value) (Result, error)
   226  
   227  	Query(args []Value) (Rows, error)
   228  }
   229  
   230  // StmtExecContextはコンテキストを提供することにより、 [Stmt] インターフェースを拡張します。
   231  type StmtExecContext interface {
   232  	ExecContext(ctx context.Context, args []NamedValue) (Result, error)
   233  }
   234  
   235  // StmtQueryContextはコンテキストを持つQueryを提供することにより、 [Stmt] インターフェースを強化します。
   236  type StmtQueryContext interface {
   237  	QueryContext(ctx context.Context, args []NamedValue) (Rows, error)
   238  }
   239  
   240  // ErrRemoveArgumentは、 [NamedValueChecker] から返されることがあります。
   241  // これは、[database/sql] パッケージに対して引数をドライバのクエリインターフェースに渡さないよう指示するためです。
   242  // クエリ固有のオプションやSQLクエリ引数ではない構造体を受け入れる場合に返します。
   243  var ErrRemoveArgument = errors.New("driver: remove argument from query")
   244  
   245  // NamedValueCheckerは [Conn] または [Stmt] によってオプションで実装されることがあります。これにより、ドライバはデフォルトの [Value] タイプを超えたGoおよびデータベースのタイプを処理するための制御を提供します。
   246  //
   247  // [database/sql] パッケージは、値チェッカーを以下の順序でチェックし、最初に一致したもので停止します: Stmt.NamedValueChecker、Conn.NamedValueChecker、Stmt.ColumnConverter、 [DefaultParameterConverter] 。
   248  //
   249  // CheckNamedValueが [ErrRemoveArgument] を返す場合、 [NamedValue] は最終的なクエリ引数に含まれません。これはクエリ自体に特殊なオプションを渡すために使用される場合があります。
   250  //
   251  // [ErrSkip] が返された場合、列コンバーターのエラーチェックパスが引数に使用されます。ドライバは、独自の特殊なケースを使い果たした後に [ErrSkip] を返すことを望むかもしれません。
   252  type NamedValueChecker interface {
   253  	CheckNamedValue(*NamedValue) error
   254  }
   255  
   256  // ColumnConverterは、ステートメントが自身の列の型を認識しており、任意の型からドライバーの [Value] に変換できる場合、Stmtによってオプションで実装されることがあります。
   257  // Deprecated: ドライバーは [NamedValueChecker] を実装する必要があります。
   258  type ColumnConverter interface {
   259  	ColumnConverter(idx int) ValueConverter
   260  }
   261  
   262  // Rowsは実行されたクエリの結果に対するイテレータです。
   263  type Rows interface {
   264  	Columns() []string
   265  
   266  	Close() error
   267  
   268  	Next(dest []Value) error
   269  }
   270  
   271  // RowsNextResultSetは、ドライバに次の結果セットに進むようにシグナルを送る方法を提供するために [Rows] インターフェースを拡張しています。
   272  type RowsNextResultSet interface {
   273  	Rows
   274  
   275  	HasNextResultSet() bool
   276  
   277  	NextResultSet() error
   278  }
   279  
   280  // RowsColumnTypeScanTypeは、 [Rows] によって実装されるかもしれません。スキャンに使用できる値の型を返す必要があります。例えば、データベースのカラムタイプが「bigint」の場合、これは「 [reflect.TypeOf](int64(0)) 」を返すべきです。
   281  type RowsColumnTypeScanType interface {
   282  	Rows
   283  	ColumnTypeScanType(index int) reflect.Type
   284  }
   285  
   286  // RowsColumnTypeDatabaseTypeNameは [Rows] によって実装されるかもしれません。長さを除いたデータベースシステムのタイプ名を返す必要があります。タイプ名は大文字であるべきです。
   287  // 返される型の例: "VARCHAR", "NVARCHAR", "VARCHAR2", "CHAR", "TEXT",
   288  // "DECIMAL", "SMALLINT", "INT", "BIGINT", "BOOL", "[]BIGINT", "JSONB", "XML",
   289  // "TIMESTAMP"。
   290  type RowsColumnTypeDatabaseTypeName interface {
   291  	Rows
   292  	ColumnTypeDatabaseTypeName(index int) string
   293  }
   294  
   295  // RowsColumnTypeLengthは、 [Rows] によって実装されるかもしれません。カラムが可変長の場合、カラムタイプの長さを返す必要があります。カラムが可変長のタイプでない場合、okはfalseを返す必要があります。
   296  // システムの制限以外で長さが制限されていない場合、[math.MaxInt64] を返す必要があります。以下は、さまざまなタイプの戻り値の例です:
   297  //
   298  //	TEXT          (math.MaxInt64, true)
   299  //	varchar(10)   (10, true)
   300  //	nvarchar(10)  (10, true)
   301  //	decimal       (0, false)
   302  //	int           (0, false)
   303  //	bytea(30)     (30, true)
   304  type RowsColumnTypeLength interface {
   305  	Rows
   306  	ColumnTypeLength(index int) (length int64, ok bool)
   307  }
   308  
   309  // RowsColumnTypeNullableは、 [Rows] によって実装される可能性があります。カラムがnullである可能性がある場合は、nullableの値をtrueにする必要があります。カラムがnullでないことが確認されている場合は、falseにする必要があります。
   310  // カラムのヌラビリティが不明な場合は、okをfalseにしてください。
   311  type RowsColumnTypeNullable interface {
   312  	Rows
   313  	ColumnTypeNullable(index int) (nullable, ok bool)
   314  }
   315  
   316  // RowsColumnTypePrecisionScaleは [Rows] によって実装されるかもしれません。それはデシマル型の精度とスケールを返すべきです。該当しない場合、okはfalseであるべきです。
   317  // 以下に、さまざまな型の戻り値の例を示します:
   318  //
   319  //	decimal(38, 4)    (38, 4, true)
   320  //	int               (0, 0, false)
   321  //	decimal           (math.MaxInt64, math.MaxInt64, true)
   322  type RowsColumnTypePrecisionScale interface {
   323  	Rows
   324  	ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool)
   325  }
   326  
   327  // Txはトランザクションです。
   328  type Tx interface {
   329  	Commit() error
   330  	Rollback() error
   331  }
   332  
   333  // RowsAffectedは、行数を変更するINSERTまたはUPDATE操作に対する [Result] を実装します。
   334  type RowsAffected int64
   335  
   336  var _ Result = RowsAffected(0)
   337  
   338  func (RowsAffected) LastInsertId() (int64, error)
   339  
   340  func (v RowsAffected) RowsAffected() (int64, error)
   341  
   342  // ResultNoRowsは、DDLコマンド(CREATE TABLEなど)が成功した場合にドライバーが返すための事前定義された [Result] です。これは、LastInsertIdと [RowsAffected] の両方に対してエラーを返します。
   343  var ResultNoRows noRows
   344  
   345  var _ Result = noRows{}