LEFT | RIGHT |
1 // Copyright 2011 The Go Authors. All rights reserved. | 1 // Copyright 2011 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 // Package sql provides a generic interface around SQL (or SQL-like) | 5 // Package sql provides a generic interface around SQL (or SQL-like) |
6 // databases. | 6 // databases. |
7 package sql | 7 package sql |
8 | 8 |
9 import ( | 9 import ( |
10 "database/sql/driver" | 10 "database/sql/driver" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 // row. In such a case, QueryRow returns a placeholder *Row value that | 172 // row. In such a case, QueryRow returns a placeholder *Row value that |
173 // defers this error until a Scan. | 173 // defers this error until a Scan. |
174 var ErrNoRows = errors.New("sql: no rows in result set") | 174 var ErrNoRows = errors.New("sql: no rows in result set") |
175 | 175 |
176 // DB is a database handle. It's safe for concurrent use by multiple | 176 // DB is a database handle. It's safe for concurrent use by multiple |
177 // goroutines. | 177 // goroutines. |
178 type DB struct { | 178 type DB struct { |
179 driver driver.Driver | 179 driver driver.Driver |
180 dsn string | 180 dsn string |
181 | 181 |
182 » mu sync.Mutex // protects freeConn and closed | 182 » mu sync.Mutex // protects freeConn and closed |
183 » freeConn []driver.Conn | 183 » freeConn []driver.Conn |
184 » closed bool | 184 » closed bool |
185 » postConnQuery string | 185 » postConnArgs []driver.Value |
186 » postConnArgs []interface{} | |
187 } | 186 } |
188 | 187 |
189 // Open opens a database specified by its database driver name and a | 188 // Open opens a database specified by its database driver name and a |
190 // driver-specific data source name, usually consisting of at least a | 189 // driver-specific data source name, usually consisting of at least a |
191 // database name and connection information. | 190 // database name and connection information. |
192 // | 191 // |
193 // Most users will open a database via a driver-specific connection | 192 // Most users will open a database via a driver-specific connection |
194 // helper function that returns a *DB. | 193 // helper function that returns a *DB. |
195 func Open(driverName, dataSourceName string) (*DB, error) { | 194 func Open(driverName, dataSourceName string, args ...driver.Value) (*DB, error)
{ |
196 driver, ok := drivers[driverName] | 195 driver, ok := drivers[driverName] |
197 if !ok { | 196 if !ok { |
198 return nil, fmt.Errorf("sql: unknown driver %q (forgotten import
?)", driverName) | 197 return nil, fmt.Errorf("sql: unknown driver %q (forgotten import
?)", driverName) |
199 } | 198 } |
200 » return &DB{driver: driver, dsn: dataSourceName}, nil | 199 » return &DB{driver: driver, dsn: dataSourceName, postConnArgs: args}, nil |
201 } | |
202 | |
203 // query will be executed after a conn was connected. | |
204 func (db *DB) PostConn(query string, args ...interface{}) { | |
205 » db.postConnQuery = query | |
206 » db.postConnArgs = args | |
207 } | 200 } |
208 | 201 |
209 // Close closes the database, releasing any open resources. | 202 // Close closes the database, releasing any open resources. |
210 func (db *DB) Close() error { | 203 func (db *DB) Close() error { |
211 db.mu.Lock() | 204 db.mu.Lock() |
212 defer db.mu.Unlock() | 205 defer db.mu.Unlock() |
213 var err error | 206 var err error |
214 for _, c := range db.freeConn { | 207 for _, c := range db.freeConn { |
215 err1 := c.Close() | 208 err1 := c.Close() |
216 if err1 != nil { | 209 if err1 != nil { |
(...skipping 19 matching lines...) Expand all Loading... |
236 db.mu.Unlock() | 229 db.mu.Unlock() |
237 return nil, errors.New("sql: database is closed") | 230 return nil, errors.New("sql: database is closed") |
238 } | 231 } |
239 if n := len(db.freeConn); n > 0 { | 232 if n := len(db.freeConn); n > 0 { |
240 conn := db.freeConn[n-1] | 233 conn := db.freeConn[n-1] |
241 db.freeConn = db.freeConn[:n-1] | 234 db.freeConn = db.freeConn[:n-1] |
242 db.mu.Unlock() | 235 db.mu.Unlock() |
243 return conn, nil | 236 return conn, nil |
244 } | 237 } |
245 db.mu.Unlock() | 238 db.mu.Unlock() |
246 » ci, err := db.driver.Open(db.dsn) | 239 » return db.driver.Open(db.dsn, db.postConnArgs) |
247 » if err != nil { | |
248 » » return nil, err | |
249 » } | |
250 | |
251 » if db.postConnQuery == "" && db.postConnArgs == nil { | |
252 » » return ci, nil | |
253 » } | |
254 » if c, ok := ci.(driver.Conn); ok { | |
255 » » stmt, err := c.Prepare(db.postConnQuery) | |
256 » » if err != nil { | |
257 » » » if err != driver.ErrSkip { | |
258 » » » » if err != nil { | |
259 » » » » » return nil, err | |
260 » » » » } | |
261 » » » } | |
262 » » } | |
263 » » _, err = stmt.Exec(db.postConnArgs) | |
264 » » if err != nil { | |
265 » » » return nil, err | |
266 » » } | |
267 » } | |
268 » return ci, nil | |
269 } | 240 } |
270 | 241 |
271 func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) { | 242 func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) { |
272 db.mu.Lock() | 243 db.mu.Lock() |
273 defer db.mu.Unlock() | 244 defer db.mu.Unlock() |
274 for n, conn := range db.freeConn { | 245 for n, conn := range db.freeConn { |
275 if conn == wanted { | 246 if conn == wanted { |
276 db.freeConn[n] = db.freeConn[len(db.freeConn)-1] | 247 db.freeConn[n] = db.freeConn[len(db.freeConn)-1] |
277 db.freeConn = db.freeConn[:len(db.freeConn)-1] | 248 db.freeConn = db.freeConn[:len(db.freeConn)-1] |
278 return wanted, true | 249 return wanted, true |
(...skipping 746 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1025 | 996 |
1026 // A Result summarizes an executed SQL command. | 997 // A Result summarizes an executed SQL command. |
1027 type Result interface { | 998 type Result interface { |
1028 LastInsertId() (int64, error) | 999 LastInsertId() (int64, error) |
1029 RowsAffected() (int64, error) | 1000 RowsAffected() (int64, error) |
1030 } | 1001 } |
1031 | 1002 |
1032 type result struct { | 1003 type result struct { |
1033 driver.Result | 1004 driver.Result |
1034 } | 1005 } |
LEFT | RIGHT |