190039b6 by Kyle McCullough

Add a ReadOrCreate method:

m := &User{Name: "Kyle"}
// Returns a boolean indicating whether the object was created,
// the primary key of the object, or an error.
created, id, err := orm.ReadOrCreate(m, "Name")
1 parent edf79825
...@@ -74,6 +74,20 @@ func (o *orm) Read(md interface{}, cols ...string) error { ...@@ -74,6 +74,20 @@ func (o *orm) Read(md interface{}, cols ...string) error {
74 return nil 74 return nil
75 } 75 }
76 76
77 // Try to read a row from the database, or insert one if it doesn't exist
78 func (o *orm) ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) {
79 cols = append([]string{col1}, cols...)
80 mi, ind := o.getMiInd(md, true)
81 err := o.alias.DbBaser.Read(o.db, mi, ind, o.alias.TZ, cols)
82 if err == ErrNoRows {
83 // Create
84 id, err := o.Insert(md)
85 return (err == nil), id, err
86 }
87
88 return false, ind.Field(mi.fields.pk.fieldIndex).Int(), err
89 }
90
77 // insert model data to database 91 // insert model data to database
78 func (o *orm) Insert(md interface{}) (int64, error) { 92 func (o *orm) Insert(md interface{}) (int64, error) {
79 mi, ind := o.getMiInd(md, true) 93 mi, ind := o.getMiInd(md, true)
......
...@@ -1642,3 +1642,41 @@ func TestTransaction(t *testing.T) { ...@@ -1642,3 +1642,41 @@ func TestTransaction(t *testing.T) {
1642 throwFail(t, AssertIs(num, 1)) 1642 throwFail(t, AssertIs(num, 1))
1643 1643
1644 } 1644 }
1645
1646 func TestReadOrCreate(t *testing.T) {
1647 u := &User{
1648 UserName: "Kyle",
1649 Email: "kylemcc@gmail.com",
1650 Password: "other_pass",
1651 Status: 7,
1652 IsStaff: false,
1653 IsActive: true,
1654 }
1655
1656 created, pk, err := dORM.ReadOrCreate(u, "UserName")
1657 throwFail(t, err)
1658 throwFail(t, AssertIs(created, true))
1659 throwFail(t, AssertIs(u.UserName, "Kyle"))
1660 throwFail(t, AssertIs(u.Email, "kylemcc@gmail.com"))
1661 throwFail(t, AssertIs(u.Password, "other_pass"))
1662 throwFail(t, AssertIs(u.Status, 7))
1663 throwFail(t, AssertIs(u.IsStaff, false))
1664 throwFail(t, AssertIs(u.IsActive, true))
1665 throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), u.Created.In(DefaultTimeLoc), test_Date))
1666 throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), u.Updated.In(DefaultTimeLoc), test_DateTime))
1667
1668 nu := &User{UserName: u.UserName, Email: "someotheremail@gmail.com"}
1669 created, pk, err = dORM.ReadOrCreate(nu, "UserName")
1670 throwFail(t, err)
1671 throwFail(t, AssertIs(created, false))
1672 throwFail(t, AssertIs(nu.Id, u.Id))
1673 throwFail(t, AssertIs(pk, u.Id))
1674 throwFail(t, AssertIs(nu.UserName, u.UserName))
1675 throwFail(t, AssertIs(nu.Email, u.Email)) // should contain the value in the table, not the one specified above
1676 throwFail(t, AssertIs(nu.Password, u.Password))
1677 throwFail(t, AssertIs(nu.Status, u.Status))
1678 throwFail(t, AssertIs(nu.IsStaff, u.IsStaff))
1679 throwFail(t, AssertIs(nu.IsActive, u.IsActive))
1680
1681 dORM.Delete(u)
1682 }
......
...@@ -23,6 +23,7 @@ type Fielder interface { ...@@ -23,6 +23,7 @@ type Fielder interface {
23 // orm struct 23 // orm struct
24 type Ormer interface { 24 type Ormer interface {
25 Read(interface{}, ...string) error 25 Read(interface{}, ...string) error
26 ReadOrCreate(interface{}, string, ...string) (bool, int64, error)
26 Insert(interface{}) (int64, error) 27 Insert(interface{}) (int64, error)
27 InsertMulti(int, interface{}) (int64, error) 28 InsertMulti(int, interface{}) (int64, error)
28 Update(interface{}, ...string) (int64, error) 29 Update(interface{}, ...string) (int64, error)
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!