http urls monitor.

wrapper.go 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // Copyright (c) 2012-present The upper.io/db authors. All rights reserved.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining
  4. // a copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to
  8. // permit persons to whom the Software is furnished to do so, subject to
  9. // the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be
  12. // included in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  15. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  17. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  18. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  19. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  20. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. package sqlbuilder
  22. import (
  23. "context"
  24. "database/sql"
  25. "fmt"
  26. "sync"
  27. "upper.io/db.v3"
  28. )
  29. var (
  30. adapters map[string]*AdapterFuncMap
  31. adaptersMu sync.RWMutex
  32. )
  33. func init() {
  34. adapters = make(map[string]*AdapterFuncMap)
  35. }
  36. // Tx represents a transaction on a SQL database. A transaction is like a
  37. // regular Database except it has two extra methods: Commit and Rollback.
  38. //
  39. // A transaction needs to be committed (with Commit) to make changes permanent,
  40. // changes can be discarded before committing by rolling back (with Rollback).
  41. // After either committing or rolling back a transaction it can not longer be
  42. // used and it's automatically closed.
  43. type Tx interface {
  44. // All db.Database methods are available on transaction sessions. They will
  45. // run on the same transaction.
  46. db.Database
  47. // All SQLBuilder methods are available on transaction sessions. They will
  48. // run on the same transaction.
  49. SQLBuilder
  50. // db.Tx adds Commit and Rollback methods to the transaction.
  51. db.Tx
  52. // Context returns the context used as default for queries on this transaction.
  53. // If no context has been set, a default context.Background() is returned.
  54. Context() context.Context
  55. // WithContext returns a copy of the transaction that uses the given context
  56. // as default. Copies are safe to use concurrently but they're backed by the
  57. // same *sql.Tx, so any copy may commit or rollback the parent transaction.
  58. WithContext(context.Context) Tx
  59. // SetTxOptions sets the default TxOptions that is going to be used for new
  60. // transactions created in the session.
  61. SetTxOptions(sql.TxOptions)
  62. // TxOptions returns the defaultx TxOptions.
  63. TxOptions() *sql.TxOptions
  64. }
  65. // Database represents a SQL database.
  66. type Database interface {
  67. // All db.Database methods are available on this session.
  68. db.Database
  69. // All SQLBuilder methods are available on this session.
  70. SQLBuilder
  71. // NewTx creates and returns a transaction that runs on the given context.
  72. // If a nil context is given, then the transaction will use the session's
  73. // default context. The user is responsible for committing or rolling back
  74. // the session.
  75. NewTx(ctx context.Context) (Tx, error)
  76. // Tx creates a new transaction that is passed as argument to the fn
  77. // function. The fn function defines a transactional operation. If the fn
  78. // function returns nil, the transaction is committed, else the transaction
  79. // is rolled back. The transaction session is closed after the function
  80. // exits, regardless of the error value returned by fn.
  81. Tx(ctx context.Context, fn func(sess Tx) error) error
  82. // Context returns the context used as default for queries on this session
  83. // and for new transactions. If no context has been set, a default
  84. // context.Background() is returned.
  85. Context() context.Context
  86. // WithContext returns a copy of the session that uses the given context as
  87. // default. Copies are safe to use concurrently but they're backed by the
  88. // same *sql.DB. You may close a copy at any point but that won't close the
  89. // parent session.
  90. WithContext(context.Context) Database
  91. // SetTxOptions sets the default TxOptions that is going to be used for new
  92. // transactions created in the session.
  93. SetTxOptions(sql.TxOptions)
  94. // TxOptions returns the defaultx TxOptions.
  95. TxOptions() *sql.TxOptions
  96. }
  97. // AdapterFuncMap is a struct that defines a set of functions that adapters
  98. // need to provide.
  99. type AdapterFuncMap struct {
  100. New func(sqlDB *sql.DB) (Database, error)
  101. NewTx func(sqlTx *sql.Tx) (Tx, error)
  102. Open func(settings db.ConnectionURL) (Database, error)
  103. }
  104. // RegisterAdapter registers a SQL database adapter. This function must be
  105. // called from adapter packages upon initialization. RegisterAdapter calls
  106. // RegisterAdapter automatically.
  107. func RegisterAdapter(name string, adapter *AdapterFuncMap) {
  108. adaptersMu.Lock()
  109. defer adaptersMu.Unlock()
  110. if name == "" {
  111. panic(`Missing adapter name`)
  112. }
  113. if _, ok := adapters[name]; ok {
  114. panic(`db.RegisterAdapter() called twice for adapter: ` + name)
  115. }
  116. adapters[name] = adapter
  117. db.RegisterAdapter(name, &db.AdapterFuncMap{
  118. Open: func(settings db.ConnectionURL) (db.Database, error) {
  119. return adapter.Open(settings)
  120. },
  121. })
  122. }
  123. // adapter returns SQL database functions.
  124. func adapter(name string) AdapterFuncMap {
  125. adaptersMu.RLock()
  126. defer adaptersMu.RUnlock()
  127. if fn, ok := adapters[name]; ok {
  128. return *fn
  129. }
  130. return missingAdapter(name)
  131. }
  132. // Open opens a SQL database.
  133. func Open(adapterName string, settings db.ConnectionURL) (Database, error) {
  134. return adapter(adapterName).Open(settings)
  135. }
  136. // New wraps an active *sql.DB session and returns a SQLBuilder database. The
  137. // adapter needs to be imported to the blank namespace in order for it to be
  138. // used here.
  139. //
  140. // This method is internally used by upper-db to create a builder backed by the
  141. // given database. You may want to use your adapter's New function instead of
  142. // this one.
  143. func New(adapterName string, sqlDB *sql.DB) (Database, error) {
  144. return adapter(adapterName).New(sqlDB)
  145. }
  146. // NewTx wraps an active *sql.Tx transation and returns a SQLBuilder
  147. // transaction. The adapter needs to be imported to the blank namespace in
  148. // order for it to be used.
  149. //
  150. // This method is internally used by upper-db to create a builder backed by the
  151. // given transaction. You may want to use your adapter's NewTx function
  152. // instead of this one.
  153. func NewTx(adapterName string, sqlTx *sql.Tx) (Tx, error) {
  154. return adapter(adapterName).NewTx(sqlTx)
  155. }
  156. func missingAdapter(name string) AdapterFuncMap {
  157. err := fmt.Errorf("upper: Missing SQL adapter %q, forgot to import?", name)
  158. return AdapterFuncMap{
  159. New: func(*sql.DB) (Database, error) {
  160. return nil, err
  161. },
  162. NewTx: func(*sql.Tx) (Tx, error) {
  163. return nil, err
  164. },
  165. Open: func(db.ConnectionURL) (Database, error) {
  166. return nil, err
  167. },
  168. }
  169. }