|
| 1 | +package sqldb |
| 2 | + |
| 3 | +import ( |
| 4 | + "database/sql" |
| 5 | + "time" |
| 6 | +) |
| 7 | + |
| 8 | +type configuration struct { |
| 9 | + txOptions *sql.TxOptions |
| 10 | + splitStatement bool |
| 11 | + panicOnBindError bool |
| 12 | + stackTraceOnError bool |
| 13 | + parameterPrefix string |
| 14 | + retrySleep time.Duration |
| 15 | +} |
| 16 | + |
| 17 | +func NewPool(handle *sql.DB, options ...option) ConnectionPool { |
| 18 | + var config configuration |
| 19 | + Options.apply(options...)(&config) |
| 20 | + return newPool(handle, config) |
| 21 | +} |
| 22 | +func NewBindingPool(handle *sql.DB, options ...option) BindingConnectionPool { |
| 23 | + var config configuration |
| 24 | + Options.apply(options...)(&config) |
| 25 | + return newBindingPool(handle, config) |
| 26 | +} |
| 27 | +func newPool(handle *sql.DB, config configuration) ConnectionPool { |
| 28 | + var pool ConnectionPool = NewLibraryConnectionPoolAdapter(handle, config.txOptions) |
| 29 | + |
| 30 | + if config.splitStatement { |
| 31 | + pool = NewSplitStatementConnectionPool(pool, config.parameterPrefix) |
| 32 | + } |
| 33 | + |
| 34 | + if config.stackTraceOnError { |
| 35 | + pool = NewStackTraceConnectionPool(pool) |
| 36 | + } |
| 37 | + |
| 38 | + return pool |
| 39 | +} |
| 40 | +func newBindingPool(handle *sql.DB, config configuration) BindingConnectionPool { |
| 41 | + inner := newPool(handle, config) |
| 42 | + var pool BindingConnectionPool = NewBindingConnectionPoolAdapter(inner, config.panicOnBindError) |
| 43 | + |
| 44 | + if config.retrySleep > 0 { |
| 45 | + pool = NewRetryBindingConnectionPool(pool, config.retrySleep) |
| 46 | + } |
| 47 | + |
| 48 | + return pool |
| 49 | +} |
| 50 | + |
| 51 | +var Options singleton |
| 52 | + |
| 53 | +type singleton struct{} |
| 54 | +type option func(*configuration) |
| 55 | + |
| 56 | +func (singleton) TxOptions(value *sql.TxOptions) option { |
| 57 | + return func(this *configuration) { this.txOptions = value } |
| 58 | +} |
| 59 | +func (singleton) PanicOnBindError(value bool) option { |
| 60 | + return func(this *configuration) { this.panicOnBindError = value } |
| 61 | +} |
| 62 | +func (singleton) MySQL() option { |
| 63 | + return func(this *configuration) { this.splitStatement = true; this.parameterPrefix = "?" } |
| 64 | +} |
| 65 | +func (singleton) ParameterPrefix(value string) option { |
| 66 | + return func(this *configuration) { this.parameterPrefix = value } |
| 67 | +} |
| 68 | +func (singleton) SplitStatement(value bool) option { |
| 69 | + return func(this *configuration) { this.splitStatement = value } |
| 70 | +} |
| 71 | +func (singleton) RetrySleep(value time.Duration) option { |
| 72 | + return func(this *configuration) { this.retrySleep = value } |
| 73 | +} |
| 74 | +func (singleton) StackTraceErrDiagnostics(value bool) option { |
| 75 | + return func(this *configuration) { this.stackTraceOnError = value } |
| 76 | +} |
| 77 | + |
| 78 | +func (singleton) apply(options ...option) option { |
| 79 | + return func(this *configuration) { |
| 80 | + for _, option := range Options.defaults(options...) { |
| 81 | + option(this) |
| 82 | + } |
| 83 | + } |
| 84 | +} |
| 85 | +func (singleton) defaults(options ...option) []option { |
| 86 | + var defaultTxOptions = &sql.TxOptions{Isolation: sql.LevelReadCommitted} |
| 87 | + const defaultStackTraceErrDiagnostics = true |
| 88 | + const defaultPanicOnBindError = true |
| 89 | + const defaultSplitStatement = true |
| 90 | + const defaultParameterPrefix = "?" |
| 91 | + const defaultRetrySleep = 0 |
| 92 | + |
| 93 | + return append([]option{ |
| 94 | + Options.TxOptions(defaultTxOptions), |
| 95 | + Options.PanicOnBindError(defaultPanicOnBindError), |
| 96 | + Options.StackTraceErrDiagnostics(defaultStackTraceErrDiagnostics), |
| 97 | + Options.ParameterPrefix(defaultParameterPrefix), |
| 98 | + Options.SplitStatement(defaultSplitStatement), |
| 99 | + Options.RetrySleep(defaultRetrySleep), |
| 100 | + }, options...) |
| 101 | +} |
0 commit comments