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{}