Skip to content

Commit 04b2c71

Browse files
sqdkChristian Probst
authored andcommitted
Disable "automagic" mapping of tablemap.Version
Adding a table from a struct containing a member with name "Version" and type other than int results in a panic: 2015/01/27 15:42:57 http: panic serving 127.0.0.1:60027: reflect: call of reflect.Value.Int on string Value goroutine 23 [running]: net/http.func·011() c:/go/src/pkg/net/http/server.go:1100 +0xbe runtime.panic(0x7059e0, 0xc082007420) c:/go/src/pkg/runtime/panic.c:248 +0x1d3 reflect.Value.Int(0x697be0, 0xc082016ca0, 0x0, 0x186, 0x77e3d0) c:/go/src/pkg/reflect/value.go:1053 +0xc3 github.com/coopernurse/gorp.bindPlan.createBindInstance(0xc08205ef00, 0x162, 0xc08201e400, 0x12, 0x20, 0x0, 0x0, 0x0, 0x77e3d0, 0x7, ...) C:/Users/Christian/Google Drive/Development/go/src/github.com/coopernurse/gorp/gorp.go:289 +0x177 github.com/coopernurse/gorp.(*TableMap).bindInsert(0xc082020b40, 0x761280, 0xc082016c60, 0x0, 0x196, 0x0, 0x0, 0x0, 0x0, 0x0, ...) C:/Users/Christian/Google Drive/Development/go/src/github.com/coopernurse/gorp/gorp.go:394 +0x6e0 github.com/coopernurse/gorp.insert(0xc0820104e0, 0x181da0, 0xc0820104e0, 0x3a3a38, 0x1, 0x1, 0x0, 0x0) C:/Users/Christian/Google Drive/Development/go/src/github.com/coopernurse/gorp/gorp.go:1913 +0x2dc github.com/coopernurse/gorp.(*DbMap).Insert(0xc0820104e0, 0x3a3a38, 0x1, 0x1, 0x0, 0x0) C:/Users/Christian/Google Drive/Development/go/src/github.com/coopernurse/gorp/gorp.go:955 +0x97 From my POV, this is convention over configuration, just the wrong way around. My proposed solution is to disable setting the version ColMap in AddTable(i interface{}), forcing the developer to manually set the version column name by using SetVersionCol(). This is a crude fix, but it shows the problem and how to solve it. Update gorp_test.go Fixed tests by using SetVersionCol on person tablemap Remove maintainers notice (since PR is closed). Add google group and irc channel to Help/Support section Use #gorp as channel Add gopkg.in versioned releases information. Also made the markdown headings consistently use prefixed #'s, no suffix. Change coopernurse/gorp to go-gorp/gorp in Makefile, godoc and comments. Extended the Exec functionality so that it can be used with named parameters. Unexport the Executor Removed version column detection in readStructColumns Update gorp.go Added warning telling users that automatic mapping of Version struct members to version column in database (optimistic locking) will be removed in V2 Update gorp.go Changed log output to stderr Added migration guide and notes Added migration guide and notes about change in behaviour in Optimistic locking. Update README.md Update gorp.go Corrected vim gone wild
1 parent 0a7ddd4 commit 04b2c71

File tree

4 files changed

+131
-74
lines changed

4 files changed

+131
-74
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
include $(GOROOT)/src/Make.inc
22

3-
TARG = github.com/coopernurse/gorp
3+
TARG = github.com/go-gorp/gorp
44
GOFILES = gorp.go dialect.go
55

66
include $(GOROOT)/src/Make.pkg

README.md

Lines changed: 64 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,18 @@
1-
# Go Relational Persistence #
1+
# Go Relational Persistence
22

33
[![build status](https://secure.travis-ci.org/go-gorp/gorp.png)](http://travis-ci.org/go-gorp/gorp)
44

5-
## Call for Maintainers
6-
7-
Dec 7 2014
8-
9-
I've been slacking on keeping up with issues and PRs. I know there are
10-
many of you out there who have active forks and some good ideas on how to
11-
push the project forward. If you'd like to step up and either be added as
12-
a committer to this repo, or would like to become the new canonical fork
13-
of the project, please comment on #211 here:
14-
15-
https://github.com/go-gorp/gorp/issues/211
16-
17-
Thank you!
18-
19-
20-
----
21-
22-
I hesitate to call gorp an ORM. Go doesn't really have objects, at least
23-
not in the classic Smalltalk/Java sense. There goes the "O". gorp doesn't
24-
know anything about the relationships between your structs (at least not
25-
yet). So the "R" is questionable too (but I use it in the name because,
5+
I hesitate to call gorp an ORM. Go doesn't really have objects, at least
6+
not in the classic Smalltalk/Java sense. There goes the "O". gorp doesn't
7+
know anything about the relationships between your structs (at least not
8+
yet). So the "R" is questionable too (but I use it in the name because,
269
well, it seemed more clever).
2710

2811
The "M" is alive and well. Given some Go structs and a database, gorp
2912
should remove a fair amount of boilerplate busy-work from your code.
3013

31-
I hope that gorp saves you time, minimizes the drudgery of getting data
32-
in and out of your database, and helps your code focus on algorithms,
14+
I hope that gorp saves you time, minimizes the drudgery of getting data
15+
in and out of your database, and helps your code focus on algorithms,
3316
not infrastructure.
3417

3518
* Bind struct fields to table columns via API or tag
@@ -47,21 +30,33 @@ not infrastructure.
4730
* Use positional or named bind parameters in custom SELECT queries
4831
* Optional optimistic locking using a version column (for update/deletes)
4932

50-
## Installation ##
33+
## Installation
5134

5235
# install the library:
53-
go get github.com/go-gorp/gorp
36+
go get gopkg.in/gorp.v1
5437

5538
// use in your .go code:
5639
import (
57-
"github.com/go-gorp/gorp"
40+
"gopkg.in/gorp.v1"
5841
)
5942

60-
## API Documentation ##
43+
## Versioning
44+
45+
This project provides a stable release (v1.x tags) and a bleeding edge codebase (master).
46+
47+
`gopkg.in/gorp.v1` points to the latest v1.x tag. The API's for v1 are stable and shouldn't change. Development takes place at the master branch. Althought the code in master should always compile and test successfully, it might break API's. We aim to maintain backwards compatibility, but API's and behaviour might be changed to fix a bug. Also note that API's that are new in the master branch can change until released as v2.
6148

62-
Full godoc output from the latest code in master is available here:
49+
If you want to use bleeding edge, use `github.com/go-gorp/gorp` as import path.
6350

64-
http://godoc.org/github.com/go-gorp/gorp
51+
## API Documentation
52+
53+
Full godoc output from the latest v1 release is available here:
54+
55+
https://godoc.org/gopkg.in/gorp.v1
56+
57+
For the latest code in master:
58+
59+
https://godoc.org/github.com/go-gorp/gorp
6560

6661
## Quickstart
6762

@@ -70,7 +65,7 @@ package main
7065

7166
import (
7267
"database/sql"
73-
"github.com/go-gorp/gorp"
68+
"gopkg.in/gorp.v1"
7469
_ "github.com/mattn/go-sqlite3"
7570
"log"
7671
"time"
@@ -183,9 +178,9 @@ func checkErr(err error, msg string) {
183178
}
184179
```
185180

186-
## Examples ##
181+
## Examples
187182

188-
### Mapping structs to tables ###
183+
### Mapping structs to tables
189184

190185
First define some types:
191186

@@ -248,7 +243,7 @@ t2 := dbmap.AddTableWithName(Person{}, "person_test").SetKeys(true, "Id")
248243
t3 := dbmap.AddTableWithName(Product{}, "product_test").SetKeys(true, "Id")
249244
```
250245

251-
### Struct Embedding ###
246+
### Struct Embedding
252247

253248
gorp supports embedding structs. For example:
254249

@@ -287,7 +282,7 @@ dbmap.CreateTablesIfNotExists()
287282
dbmap.DropTables()
288283
```
289284

290-
### SQL Logging ###
285+
### SQL Logging
291286

292287
Optionally you can pass in a logger to trace all SQL statements.
293288
I recommend enabling this initially while you're getting the feel for what
@@ -306,7 +301,7 @@ dbmap.TraceOn("[gorp]", log.New(os.Stdout, "myapp:", log.Lmicroseconds))
306301
dbmap.TraceOff()
307302
```
308303

309-
### Insert ###
304+
### Insert
310305

311306
```go
312307
// Must declare as pointers so optional callback hooks
@@ -322,7 +317,7 @@ err := dbmap.Insert(inv1, inv2)
322317
fmt.Printf("inv1.Id=%d inv2.Id=%d\n", inv1.Id, inv2.Id)
323318
```
324319

325-
### Update ###
320+
### Update
326321

327322
Continuing the above example, use the `Update` method to modify an Invoice:
328323

@@ -331,7 +326,7 @@ Continuing the above example, use the `Update` method to modify an Invoice:
331326
count, err := dbmap.Update(inv1)
332327
```
333328

334-
### Delete ###
329+
### Delete
335330

336331
If you have primary key(s) defined for a struct, you can use the `Delete`
337332
method to remove rows:
@@ -340,7 +335,7 @@ method to remove rows:
340335
count, err := dbmap.Delete(inv1)
341336
```
342337

343-
### Select by Key ###
338+
### Select by Key
344339

345340
Use the `Get` method to fetch a single row by primary key. It returns
346341
nil if no row is found.
@@ -351,9 +346,9 @@ obj, err := dbmap.Get(Invoice{}, 99)
351346
inv := obj.(*Invoice)
352347
```
353348

354-
### Ad Hoc SQL ###
349+
### Ad Hoc SQL
355350

356-
#### SELECT ####
351+
#### SELECT
357352

358353
`Select()` and `SelectOne()` provide a simple way to bind arbitrary queries to a slice
359354
or a single struct.
@@ -413,7 +408,7 @@ if reflect.DeepEqual(list[0], expected) {
413408
}
414409
```
415410

416-
#### SELECT string or int64 ####
411+
#### SELECT string or int64
417412

418413
gorp provides a few convenience methods for selecting a single string or int64.
419414

@@ -426,7 +421,7 @@ s, err := dbmap.SelectStr("select name from foo where blah=?", blahVal)
426421

427422
```
428423

429-
#### Named bind parameters ####
424+
#### Named bind parameters
430425

431426
You may use a map or struct to bind parameters by name. This is currently
432427
only supported in SELECT queries.
@@ -438,15 +433,15 @@ _, err := dbm.Select(&dest, "select * from Foo where name = :name and age = :age
438433
})
439434
```
440435

441-
#### UPDATE / DELETE ####
436+
#### UPDATE / DELETE
442437

443438
You can execute raw SQL if you wish. Particularly good for batch operations.
444439

445440
```go
446441
res, err := dbmap.Exec("delete from invoice_test where PersonId=?", 10)
447442
```
448443

449-
### Transactions ###
444+
### Transactions
450445

451446
You can batch operations into a transaction:
452447

@@ -467,7 +462,7 @@ func InsertInv(dbmap *DbMap, inv *Invoice, per *Person) error {
467462
}
468463
```
469464

470-
### Hooks ###
465+
### Hooks
471466

472467
Use hooks to update data before/after saving to the db. Good for timestamps:
473468

@@ -512,7 +507,9 @@ Full list of hooks that you can implement:
512507

513508
func (p *MyStruct) PostUpdate(s gorp.SqlExecutor) error
514509

515-
### Optimistic Locking ###
510+
### Optimistic Locking
511+
512+
#### Note that this behaviour has changed in v2. See [Migration Guide](#migration-guide).
516513

517514
gorp provides a simple optimistic locking feature, similar to Java's JPA, that
518515
will raise an error if you try to update/delete a row whose `version` column
@@ -565,7 +562,7 @@ if ok {
565562
}
566563
```
567564

568-
## Database Drivers ##
565+
## Database Drivers
569566

570567
gorp uses the Go 1 `database/sql` package. A full list of compliant drivers is available here:
571568

@@ -590,9 +587,9 @@ Note that these databases are not covered by CI and I (@coopernurse) have no goo
590587
test them locally. So please try them and send patches as needed, but expect a bit more
591588
unpredicability.
592589

593-
## Known Issues ##
590+
## Known Issues
594591

595-
### SQL placeholder portability ###
592+
### SQL placeholder portability
596593

597594
Different databases use different strings to indicate variable placeholders in
598595
prepared SQL statements. Unlike some database abstraction layers (such as JDBC),
@@ -617,7 +614,7 @@ err := dbmap.SelectOne(&val, "select * from foo where id = :id",
617614
map[string]interface{} { "id": 30})
618615
```
619616

620-
### time.Time and time zones ###
617+
### time.Time and time zones
621618

622619
gorp will pass `time.Time` fields through to the `database/sql` driver, but note that
623620
the behavior of this type varies across database drivers.
@@ -627,7 +624,7 @@ MySQL users should be especially cautious. See: https://github.com/ziutek/mymys
627624
To avoid any potential issues with timezone/DST, consider using an integer field for time
628625
data and storing UNIX time.
629626

630-
## Running the tests ##
627+
## Running the tests
631628

632629
The included tests may be run against MySQL, Postgresql, or sqlite3.
633630
You must set two environment variables so the test code knows which driver to
@@ -649,19 +646,28 @@ Valid `GORP_TEST_DIALECT` values are: "mysql", "postgres", "sqlite3"
649646
See the `test_all.sh` script for examples of all 3 databases. This is the script I run
650647
locally to test the library.
651648

652-
## Performance ##
649+
## Performance
650+
651+
gorp uses reflection to construct SQL queries and bind parameters. See the BenchmarkNativeCrud vs BenchmarkGorpCrud in gorp_test.go for a simple perf test. On my MacBook Pro gorp is about 2-3% slower than hand written SQL.
652+
653+
## Migration guide
654+
#### Pre-v2 to v2
655+
Automatic mapping of the version column used in optimistic locking has been removed as it could cause problems if the type was not int. The version column must now explicitly be set with tablemap.SetVersionCol().
656+
657+
## Help/Support
653658

654-
gorp uses reflection to construct SQL queries and bind parameters. See the BenchmarkNativeCrud vs BenchmarkGorpCrud in gorp_test.go for a simple perf test. On my MacBook Pro gorp is about 2-3% slower than hand written SQL.
659+
IRC: #gorp
660+
Mailing list: [email protected]
661+
Bugs/Enhancements: Create a github issue
655662

656663
## Pull requests / Contributions
657664

658665
Contributions are very welcome. Please follow these guidelines:
659666

660-
* Fork the `develop` branch and issue pull requests targeting the `develop` branch
661-
* If you don't do this, I'll likely cherry pick your commit into develop
662-
* If you are adding an enhancement, please open an issue first with your proposed change.
667+
* Fork the `master` branch and issue pull requests targeting the `master` branch
668+
* If you are adding an enhancement, please open an issue first with your proposed change.
663669
* Changes that break backwards compatibility in the public API are only accepted after we
664-
discuss on a GitHub issue for a while.
670+
discuss on a GitHub issue for a while.
665671

666672
Thanks!
667673

0 commit comments

Comments
 (0)