Skip to content

Instantly share code, notes, and snippets.

@danbrakeley
Last active January 27, 2016 15:57
Show Gist options
  • Save danbrakeley/2c2a6a3751d22127071d to your computer and use it in GitHub Desktop.
Save danbrakeley/2c2a6a3751d22127071d to your computer and use it in GitHub Desktop.
gorm_bug_with_updates.go
package main
import (
_ "database/sql"
"log"
_ "github.com/go-sql-driver/mysql"
"github.com/jinzhu/gorm"
)
type User struct {
ID int
Name string
TagForeign []TagForeign
TagComposite []TagComposite
NoTagForeign []NoTagForeign
NoTagComposite []NoTagComposite
}
type TagForeign struct {
UserID int `gorm:"primary_key"`
Tag string
}
type TagComposite struct {
UserID int `gorm:"primary_key"`
Selection string `gorm:"primary_key"`
Index int
}
type NoTagForeign struct {
UserID int
Tag string
}
type NoTagComposite struct {
UserID int
Selection string
Index int
}
func main() {
db, err := gorm.Open("mysql", "root@/mysql?parseTime=true")
if err != nil {
log.Fatal(err)
}
db.LogMode(true)
db.Exec("DROP DATABASE IF EXISTS test")
db.Exec("CREATE DATABASE test")
db, err = gorm.Open("mysql", "root@/test?parseTime=true")
if err != nil {
log.Fatal(err)
}
db.LogMode(true)
db.Exec("CREATE TABLE `users` (`id` INT AUTO_INCREMENT, `name` varchar(255), PRIMARY KEY (`id`))")
db.Exec("CREATE TABLE `tag_foreigns` (`user_id` INT,`tag` varchar(255) )")
db.Exec("CREATE TABLE `tag_composites` (`user_id` INT,`selection` varchar(255), `index` INT, PRIMARY KEY (`user_id`,`selection`))")
db.Exec("CREATE TABLE `no_tag_foreigns` (`user_id` INT,`tag` varchar(255) )")
db.Exec("CREATE TABLE `no_tag_composites` (`user_id` INT,`selection` varchar(255), `index` INT, PRIMARY KEY (`user_id`,`selection`))")
user := &User{Name: "foreign tagged", TagForeign: []TagForeign{{Tag: "tag1"}, {Tag: "tag2"}}}
db.Create(user)
// The following fails to add anything to the tag_foreigns table
user.TagForeign[0].Tag = "tag3"
db.Save(user)
user = &User{Name: "foreign notag", NoTagForeign: []NoTagForeign{{Tag: "notag1"}, {Tag: "notag2"}}}
db.Create(user)
// After the following 2 lines, no_tag_foreigns will have 4 rows! "notag1", "notag2", "notag3", and another "notag2"
user.NoTagForeign[0].Tag = "notag3"
db.Save(user)
user = &User{Name: "compound tagged", TagComposite: []TagComposite{{Selection: "menu1", Index: 11}, {Selection: "menu2", Index: 12}}}
db.Create(user)
// The following fails to add anything to the tag_composites table
user.TagComposite[0].Selection = "menu3"
user.TagComposite[0].Index = 13
db.Save(user)
user = &User{Name: "compound notag", NoTagComposite: []NoTagComposite{{Selection: "nomenu1", Index: 21}, {Selection: "nomenu2", Index: 22}}}
db.Create(user)
// The following inserts {nomenu3, 23}, then fails to re-insert the nomenu2 key:
// Error 1062: Duplicate entry '4-nomenu2' for key 'PRIMARY'
user.NoTagComposite[0].Selection = "nomenu3"
user.NoTagComposite[0].Index = 23
db.Save(user)
}
[2016-01-27 10:54:25] [21.93ms] DROP DATABASE IF EXISTS test
[2016-01-27 10:54:25] [0.61ms] CREATE DATABASE test
[2016-01-27 10:54:25] [16.50ms] CREATE TABLE `users` (`id` INT AUTO_INCREMENT, `name` varchar(255), PRIMARY KEY (`id`))
[2016-01-27 10:54:25] [8.60ms] CREATE TABLE `tag_foreigns` (`user_id` INT,`tag` varchar(255) )
[2016-01-27 10:54:25] [8.88ms] CREATE TABLE `tag_composites` (`user_id` INT,`selection` varchar(255), `index` INT, PRIMARY KEY (`user_id`,`selection`))
[2016-01-27 10:54:25] [6.69ms] CREATE TABLE `no_tag_foreigns` (`user_id` INT,`tag` varchar(255) )
[2016-01-27 10:54:25] [6.44ms] CREATE TABLE `no_tag_composites` (`user_id` INT,`selection` varchar(255), `index` INT, PRIMARY KEY (`user_id`,`selection`))
[2016-01-27 10:54:25] [0.76ms] INSERT INTO `users` (`name`) VALUES ('foreign tagged')
[2016-01-27 10:54:25] [0.85ms] UPDATE `tag_foreigns` SET `tag` = 'tag1' WHERE (`user_id` = '1')
[2016-01-27 10:54:25] [0.71ms] UPDATE `tag_foreigns` SET `tag` = 'tag2' WHERE (`user_id` = '1')
[2016-01-27 10:54:25] [0.44ms] UPDATE `users` SET `name` = 'foreign tagged' WHERE (`id` = '1')
[2016-01-27 10:54:25] [0.58ms] UPDATE `tag_foreigns` SET `tag` = 'tag3' WHERE (`user_id` = '1')
[2016-01-27 10:54:25] [0.70ms] UPDATE `tag_foreigns` SET `tag` = 'tag2' WHERE (`user_id` = '1')
[2016-01-27 10:54:25] [0.38ms] INSERT INTO `users` (`name`) VALUES ('foreign notag')
[2016-01-27 10:54:25] [0.59ms] INSERT INTO `no_tag_foreigns` (`user_id`,`tag`) VALUES ('2','notag1')
[2016-01-27 10:54:25] [0.42ms] INSERT INTO `no_tag_foreigns` (`user_id`,`tag`) VALUES ('2','notag2')
[2016-01-27 10:54:25] [0.32ms] UPDATE `users` SET `name` = 'foreign notag' WHERE (`id` = '2')
[2016-01-27 10:54:25] [0.73ms] INSERT INTO `no_tag_foreigns` (`user_id`,`tag`) VALUES ('2','notag3')
[2016-01-27 10:54:25] [0.57ms] INSERT INTO `no_tag_foreigns` (`user_id`,`tag`) VALUES ('2','notag2')
[2016-01-27 10:54:25] [0.33ms] INSERT INTO `users` (`name`) VALUES ('compound tagged')
[2016-01-27 10:54:25] [0.65ms] UPDATE `tag_composites` SET `index` = '11' WHERE (`user_id` = '3') AND (`selection` = 'menu1')
[2016-01-27 10:54:25] [0.37ms] UPDATE `tag_composites` SET `index` = '12' WHERE (`user_id` = '3') AND (`selection` = 'menu2')
[2016-01-27 10:54:25] [0.85ms] UPDATE `users` SET `name` = 'compound tagged' WHERE (`id` = '3')
[2016-01-27 10:54:25] [0.43ms] UPDATE `tag_composites` SET `index` = '13' WHERE (`user_id` = '3') AND (`selection` = 'menu3')
[2016-01-27 10:54:25] [0.39ms] UPDATE `tag_composites` SET `index` = '12' WHERE (`user_id` = '3') AND (`selection` = 'menu2')
[2016-01-27 10:54:25] [0.29ms] INSERT INTO `users` (`name`) VALUES ('compound notag')
[2016-01-27 10:54:25] [0.52ms] INSERT INTO `no_tag_composites` (`user_id`,`selection`,`index`) VALUES ('4','nomenu1','21')
[2016-01-27 10:54:25] [0.85ms] INSERT INTO `no_tag_composites` (`user_id`,`selection`,`index`) VALUES ('4','nomenu2','22')
[2016-01-27 10:54:25] [0.29ms] UPDATE `users` SET `name` = 'compound notag' WHERE (`id` = '4')
[2016-01-27 10:54:25] [0.34ms] INSERT INTO `no_tag_composites` (`selection`,`index`,`user_id`) VALUES ('nomenu3','23','4')
[2016-01-27 10:54:25] Error 1062: Duplicate entry '4-nomenu2' for key 'PRIMARY'
[2016-01-27 10:54:25] [0.86ms] INSERT INTO `no_tag_composites` (`user_id`,`selection`,`index`) VALUES ('4','nomenu2','22')
[2016-01-27 10:54:25] Error 1062: Duplicate entry '4-nomenu2' for key 'PRIMARY'
mysql> SELECT * FROM users;
+----+-----------------+
| id | name |
+----+-----------------+
| 1 | foreign tagged |
| 2 | foreign notag |
| 3 | compound tagged |
| 4 | compound notag |
+----+-----------------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM tag_foreigns;
Empty set (0.00 sec)
mysql> SELECT * FROM tag_composites;
Empty set (0.01 sec)
mysql> SELECT * FROM no_tag_foreigns;
+---------+--------+
| user_id | tag |
+---------+--------+
| 2 | notag1 |
| 2 | notag2 |
| 2 | notag3 |
| 2 | notag2 |
+---------+--------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM no_tag_composites;
+---------+-----------+-------+
| user_id | selection | index |
+---------+-----------+-------+
| 4 | nomenu1 | 21 |
| 4 | nomenu2 | 22 |
+---------+-----------+-------+
2 rows in set (0.00 sec)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment