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 | 5 package sql |
6 | 6 |
7 import ( | 7 import ( |
8 "errors" | 8 "errors" |
9 "fmt" | 9 "fmt" |
10 "io" | 10 "io" |
(...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 tx.c.currTx = nil | 506 tx.c.currTx = nil |
507 return nil | 507 return nil |
508 } | 508 } |
509 | 509 |
510 type rowsCursor struct { | 510 type rowsCursor struct { |
511 cols []string | 511 cols []string |
512 pos int | 512 pos int |
513 rows []*row | 513 rows []*row |
514 closed bool | 514 closed bool |
515 | 515 |
516 » // a clone of slices to give out to clients, indexes by the | 516 » // a clone of slices to give out to clients, indexed by the |
517 // the original slice's first byte address. we clone them | 517 // the original slice's first byte address. we clone them |
518 // just so we're able to corrupt them on close. | 518 // just so we're able to corrupt them on close. |
519 bytesClone map[*byte][]byte | 519 bytesClone map[*byte][]byte |
520 | |
521 // set of bytes to intentionally corrupt on close, simulating | |
522 // this memory being no longer valid. (per the contract on | |
523 // reusing []byte between driver and user code). we only | |
524 // corrupt stuff from bytesClone, though, never the original | |
525 // copy of the data. | |
526 toCorrupt map[*byte]bool | |
527 } | 520 } |
528 | 521 |
529 func (rc *rowsCursor) Close() error { | 522 func (rc *rowsCursor) Close() error { |
530 if !rc.closed { | 523 if !rc.closed { |
531 » » for bp := range rc.toCorrupt { | 524 » » for _, bs := range rc.bytesClone { |
532 » » » *bp = 255 | 525 » » » bs[0] = 255 // first byte corrupted |
533 } | 526 } |
534 } | 527 } |
535 rc.closed = true | 528 rc.closed = true |
536 return nil | 529 return nil |
537 } | 530 } |
538 | 531 |
539 func (rc *rowsCursor) Columns() []string { | 532 func (rc *rowsCursor) Columns() []string { |
540 return rc.cols | 533 return rc.cols |
541 } | 534 } |
542 | 535 |
543 func (rc *rowsCursor) Next(dest []interface{}) error { | 536 func (rc *rowsCursor) Next(dest []interface{}) error { |
544 if rc.closed { | 537 if rc.closed { |
545 return errors.New("fakedb: cursor is closed") | 538 return errors.New("fakedb: cursor is closed") |
546 } | 539 } |
547 rc.pos++ | 540 rc.pos++ |
548 if rc.pos >= len(rc.rows) { | 541 if rc.pos >= len(rc.rows) { |
549 return io.EOF // per interface spec | 542 return io.EOF // per interface spec |
550 } | 543 } |
551 for i, v := range rc.rows[rc.pos].cols { | 544 for i, v := range rc.rows[rc.pos].cols { |
552 // TODO(bradfitz): convert to subset types? naah, I | 545 // TODO(bradfitz): convert to subset types? naah, I |
553 // think the subset types should only be input to | 546 // think the subset types should only be input to |
554 // driver, but the sql package should be able to handle | 547 // driver, but the sql package should be able to handle |
555 // a wider range of types coming out of drivers. all | 548 // a wider range of types coming out of drivers. all |
556 // for ease of drivers, and to prevent drivers from | 549 // for ease of drivers, and to prevent drivers from |
557 // messing up conversions or doing them differently. | 550 // messing up conversions or doing them differently. |
558 dest[i] = v | 551 dest[i] = v |
559 | 552 |
560 if bs, ok := v.([]byte); ok { | 553 if bs, ok := v.([]byte); ok { |
561 » » » if rc.toCorrupt == nil { | 554 » » » if rc.bytesClone == nil { |
562 » » » » rc.toCorrupt = make(map[*byte]bool) | |
563 rc.bytesClone = make(map[*byte][]byte) | 555 rc.bytesClone = make(map[*byte][]byte) |
564 } | 556 } |
565 clone, ok := rc.bytesClone[&bs[0]] | 557 clone, ok := rc.bytesClone[&bs[0]] |
566 if !ok { | 558 if !ok { |
567 clone = make([]byte, len(bs)) | 559 clone = make([]byte, len(bs)) |
568 copy(clone, bs) | 560 copy(clone, bs) |
569 rc.bytesClone[&bs[0]] = clone | 561 rc.bytesClone[&bs[0]] = clone |
570 } | 562 } |
571 rc.toCorrupt[&clone[0]] = true | |
572 dest[i] = clone | 563 dest[i] = clone |
573 } | 564 } |
574 } | 565 } |
575 return nil | 566 return nil |
576 } | 567 } |
577 | 568 |
578 func converterForType(typ string) driver.ValueConverter { | 569 func converterForType(typ string) driver.ValueConverter { |
579 switch typ { | 570 switch typ { |
580 case "bool": | 571 case "bool": |
581 return driver.Bool | 572 return driver.Bool |
582 case "int32": | 573 case "int32": |
583 return driver.Int32 | 574 return driver.Int32 |
584 case "string": | 575 case "string": |
585 return driver.String | 576 return driver.String |
586 } | 577 } |
587 panic("invalid fakedb column type of " + typ) | 578 panic("invalid fakedb column type of " + typ) |
588 } | 579 } |
LEFT | RIGHT |