Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(1817)

Side by Side Diff: src/pkg/database/sql/fakedb_test.go

Issue 8836045: code review 8836045: database/sql: fix driver Conn refcounting with prepared... (Closed)
Patch Set: diff -r 0c16e97c7587 https://go.googlecode.com/hg/ Created 11 years, 11 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/pkg/database/sql/sql.go » ('j') | src/pkg/database/sql/sql.go » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5 package sql
6 6
7 import ( 7 import (
8 "database/sql/driver" 8 "database/sql/driver"
9 "errors" 9 "errors"
10 "fmt" 10 "fmt"
(...skipping 17 matching lines...) Expand all
28 // 28 //
29 // WIPE 29 // WIPE
30 // CREATE|<tablename>|<col>=<type>,<col>=<type>,... 30 // CREATE|<tablename>|<col>=<type>,<col>=<type>,...
31 // where types are: "string", [u]int{8,16,32,64}, "bool" 31 // where types are: "string", [u]int{8,16,32,64}, "bool"
32 // INSERT|<tablename>|col=val,col2=val2,col3=? 32 // INSERT|<tablename>|col=val,col2=val2,col3=?
33 // SELECT|<tablename>|projectcol1,projectcol2|filtercol=?,filtercol2=? 33 // SELECT|<tablename>|projectcol1,projectcol2|filtercol=?,filtercol2=?
34 // 34 //
35 // When opening a fakeDriver's database, it starts empty with no 35 // When opening a fakeDriver's database, it starts empty with no
36 // tables. All tables and data are stored in memory only. 36 // tables. All tables and data are stored in memory only.
37 type fakeDriver struct { 37 type fakeDriver struct {
38 » mu sync.Mutex 38 » mu sync.Mutex // guards all 4 fields
39 » openCount int 39 » openCount int // conn opens
40 » dbs map[string]*fakeDB 40 » closeCount int // conn closes
41 » dbs map[string]*fakeDB
41 } 42 }
42 43
43 type fakeDB struct { 44 type fakeDB struct {
44 name string 45 name string
45 46
46 mu sync.Mutex 47 mu sync.Mutex
47 free []*fakeConn 48 free []*fakeConn
48 tables map[string]*table 49 tables map[string]*table
49 badConn bool 50 badConn bool
50 } 51 }
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 244
244 var testStrictClose *testing.T 245 var testStrictClose *testing.T
245 246
246 // setStrictFakeConnClose sets the t to Errorf on when fakeConn.Close 247 // setStrictFakeConnClose sets the t to Errorf on when fakeConn.Close
247 // fails to close. If nil, the check is disabled. 248 // fails to close. If nil, the check is disabled.
248 func setStrictFakeConnClose(t *testing.T) { 249 func setStrictFakeConnClose(t *testing.T) {
249 testStrictClose = t 250 testStrictClose = t
250 } 251 }
251 252
252 func (c *fakeConn) Close() (err error) { 253 func (c *fakeConn) Close() (err error) {
254 drv := fdriver.(*fakeDriver)
253 defer func() { 255 defer func() {
254 if err != nil && testStrictClose != nil { 256 if err != nil && testStrictClose != nil {
255 testStrictClose.Errorf("failed to close a test fakeConn: %v", err) 257 testStrictClose.Errorf("failed to close a test fakeConn: %v", err)
256 } 258 }
257 hookPostCloseConn.Lock() 259 hookPostCloseConn.Lock()
258 fn := hookPostCloseConn.fn 260 fn := hookPostCloseConn.fn
259 hookPostCloseConn.Unlock() 261 hookPostCloseConn.Unlock()
260 if fn != nil { 262 if fn != nil {
261 fn(c, err) 263 fn(c, err)
262 } 264 }
265 if err == nil {
266 drv.mu.Lock()
267 drv.closeCount++
268 drv.mu.Unlock()
269 }
263 }() 270 }()
264 if c.currTx != nil { 271 if c.currTx != nil {
265 return errors.New("can't close fakeConn; in a Transaction") 272 return errors.New("can't close fakeConn; in a Transaction")
266 } 273 }
267 if c.db == nil { 274 if c.db == nil {
268 return errors.New("can't close fakeConn; already closed") 275 return errors.New("can't close fakeConn; already closed")
269 } 276 }
270 if c.stmtsMade > c.stmtsClosed { 277 if c.stmtsMade > c.stmtsClosed {
271 return errors.New("can't close; dangling statement(s)") 278 return errors.New("can't close; dangling statement(s)")
272 } 279 }
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 return driver.DefaultParameterConverter 459 return driver.DefaultParameterConverter
453 } 460 }
454 return s.placeholderConverter[idx] 461 return s.placeholderConverter[idx]
455 } 462 }
456 463
457 func (s *fakeStmt) Close() error { 464 func (s *fakeStmt) Close() error {
458 if s.c == nil { 465 if s.c == nil {
459 panic("nil conn in fakeStmt.Close") 466 panic("nil conn in fakeStmt.Close")
460 } 467 }
461 if s.c.db == nil { 468 if s.c.db == nil {
462 » » panic("in fakeSmt.Close, conn's db is nil (already closed)") 469 » » panic("in fakeStmt.Close, conn's db is nil (already closed)")
463 } 470 }
464 if !s.closed { 471 if !s.closed {
465 s.c.incrStat(&s.c.stmtsClosed) 472 s.c.incrStat(&s.c.stmtsClosed)
466 s.closed = true 473 s.closed = true
467 } 474 }
468 return nil 475 return nil
469 } 476 }
470 477
471 var errClosed = errors.New("fakedb: statement has been closed") 478 var errClosed = errors.New("fakedb: statement has been closed")
472 479
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 if len(args) != s.placeholders { 552 if len(args) != s.placeholders {
546 panic("error in pkg db; should only get here if size is correct" ) 553 panic("error in pkg db; should only get here if size is correct" )
547 } 554 }
548 555
549 db.mu.Lock() 556 db.mu.Lock()
550 t, ok := db.table(s.table) 557 t, ok := db.table(s.table)
551 db.mu.Unlock() 558 db.mu.Unlock()
552 if !ok { 559 if !ok {
553 return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table ) 560 return nil, fmt.Errorf("fakedb: table %q doesn't exist", s.table )
554 } 561 }
562
563 if s.table == "magicquery" {
564 if len(s.whereCol) == 2 && s.whereCol[0] == "op" && s.whereCol[1 ] == "millis" {
565 if args[0] == "sleep" {
566 time.Sleep(time.Duration(args[1].(int64)) * time .Millisecond)
567 }
568 }
569 }
570
555 t.mu.Lock() 571 t.mu.Lock()
556 defer t.mu.Unlock() 572 defer t.mu.Unlock()
557 573
558 colIdx := make(map[string]int) // select column name -> column index in table 574 colIdx := make(map[string]int) // select column name -> column index in table
559 for _, name := range s.colName { 575 for _, name := range s.colName {
560 idx := t.columnIndex(name) 576 idx := t.columnIndex(name)
561 if idx == -1 { 577 if idx == -1 {
562 return nil, fmt.Errorf("fakedb: unknown column name %q", name) 578 return nil, fmt.Errorf("fakedb: unknown column name %q", name)
563 } 579 }
564 colIdx[name] = idx 580 colIdx[name] = idx
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 // TODO(coopernurse): add type-specific converter 732 // TODO(coopernurse): add type-specific converter
717 return driver.NotNull{Converter: driver.DefaultParameterConverte r} 733 return driver.NotNull{Converter: driver.DefaultParameterConverte r}
718 case "nullfloat64": 734 case "nullfloat64":
719 // TODO(coopernurse): add type-specific converter 735 // TODO(coopernurse): add type-specific converter
720 return driver.Null{Converter: driver.DefaultParameterConverter} 736 return driver.Null{Converter: driver.DefaultParameterConverter}
721 case "datetime": 737 case "datetime":
722 return driver.DefaultParameterConverter 738 return driver.DefaultParameterConverter
723 } 739 }
724 panic("invalid fakedb column type of " + typ) 740 panic("invalid fakedb column type of " + typ)
725 } 741 }
OLDNEW
« no previous file with comments | « no previous file | src/pkg/database/sql/sql.go » ('j') | src/pkg/database/sql/sql.go » ('J')

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b