diff --git a/processors_test.go b/processors_test.go index e370d7a0..6c22af0a 100644 --- a/processors_test.go +++ b/processors_test.go @@ -5,6 +5,8 @@ package xorm import ( + "errors" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -66,3 +68,899 @@ func TestBefore_Find(t *testing.T) { assert.Equal(t, "val", be[1].Val) assert.Equal(t, "test2", be[1].Name) } + +type ProcessorsStruct struct { + Id int64 + + B4InsertFlag int + AfterInsertedFlag int + B4UpdateFlag int + AfterUpdatedFlag int + B4DeleteFlag int `xorm:"-"` + AfterDeletedFlag int `xorm:"-"` + BeforeSetFlag int `xorm:"-"` + + B4InsertViaExt int + AfterInsertedViaExt int + B4UpdateViaExt int + AfterUpdatedViaExt int + B4DeleteViaExt int `xorm:"-"` + AfterDeletedViaExt int `xorm:"-"` + AfterSetFlag int `xorm:"-"` +} + +func (p *ProcessorsStruct) BeforeInsert() { + p.B4InsertFlag = 1 +} + +func (p *ProcessorsStruct) BeforeUpdate() { + p.B4UpdateFlag = 1 +} + +func (p *ProcessorsStruct) BeforeDelete() { + p.B4DeleteFlag = 1 +} + +func (p *ProcessorsStruct) BeforeSet(col string, cell Cell) { + p.BeforeSetFlag = p.BeforeSetFlag + 1 +} + +func (p *ProcessorsStruct) AfterInsert() { + p.AfterInsertedFlag = 1 +} + +func (p *ProcessorsStruct) AfterUpdate() { + p.AfterUpdatedFlag = 1 +} + +func (p *ProcessorsStruct) AfterDelete() { + p.AfterDeletedFlag = 1 +} + +func (p *ProcessorsStruct) AfterSet(col string, cell Cell) { + p.AfterSetFlag = p.AfterSetFlag + 1 +} + +func TestProcessors(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.DropTables(&ProcessorsStruct{}) + if err != nil { + t.Error(err) + panic(err) + } + p := &ProcessorsStruct{} + + err = testEngine.CreateTables(&ProcessorsStruct{}) + if err != nil { + t.Error(err) + panic(err) + } + + b4InsertFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4InsertViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterInsertFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterInsertedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + _, err = testEngine.Before(b4InsertFunc).After(afterInsertFunc).Insert(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedViaExt == 0 { + t.Error(errors.New("AfterInsertedViaExt not set")) + } + } + + p2 := &ProcessorsStruct{} + _, err = testEngine.Id(p.Id).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p2.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p2.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p2.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + if p2.BeforeSetFlag != 9 { + t.Error(fmt.Errorf("BeforeSetFlag is %d not 9", p2.BeforeSetFlag)) + } + if p2.AfterSetFlag != 9 { + t.Error(fmt.Errorf("AfterSetFlag is %d not 9", p2.BeforeSetFlag)) + } + } + // -- + + // test find processors + var p2Find []*ProcessorsStruct + err = testEngine.Find(&p2Find) + if err != nil { + t.Error(err) + panic(err) + } else { + if len(p2Find) != 1 { + err = errors.New("Should get 1") + t.Error(err) + } + p21 := p2Find[0] + if p21.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p21.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p21.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p21.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + if p21.BeforeSetFlag != 9 { + t.Error(fmt.Errorf("BeforeSetFlag is %d not 9", p21.BeforeSetFlag)) + } + if p21.AfterSetFlag != 9 { + t.Error(fmt.Errorf("AfterSetFlag is %d not 9", p21.BeforeSetFlag)) + } + } + // -- + + // test find map processors + var p2FindMap = make(map[int64]*ProcessorsStruct) + err = testEngine.Find(&p2FindMap) + if err != nil { + t.Error(err) + panic(err) + } else { + if len(p2FindMap) != 1 { + err = errors.New("Should get 1") + t.Error(err) + } + var p22 *ProcessorsStruct + for _, v := range p2FindMap { + p22 = v + } + + if p22.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p22.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p22.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p22.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + if p22.BeforeSetFlag != 9 { + t.Error(fmt.Errorf("BeforeSetFlag is %d not 9", p22.BeforeSetFlag)) + } + if p22.AfterSetFlag != 9 { + t.Error(fmt.Errorf("AfterSetFlag is %d not 9", p22.BeforeSetFlag)) + } + } + // -- + + // test update processors + b4UpdateFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4UpdateViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterUpdateFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterUpdatedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + p = p2 // reset + + _, err = testEngine.Before(b4UpdateFunc).After(afterUpdateFunc).Update(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag == 0 { + t.Error(errors.New("AfterUpdatedFlag not set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt == 0 { + t.Error(errors.New("AfterUpdatedViaExt not set")) + } + } + + p2 = &ProcessorsStruct{} + _, err = testEngine.Id(p.Id).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p2.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set: " + string(p.AfterUpdatedFlag))) + } + if p2.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p2.AfterUpdatedViaExt != 0 { + t.Error(errors.New("AfterUpdatedViaExt is set: " + string(p.AfterUpdatedViaExt))) + } + if p2.BeforeSetFlag != 9 { + t.Error(fmt.Errorf("BeforeSetFlag is %d not 9", p2.BeforeSetFlag)) + } + if p2.AfterSetFlag != 9 { + t.Error(fmt.Errorf("AfterSetFlag is %d not 9", p2.BeforeSetFlag)) + } + } + // -- + + // test delete processors + b4DeleteFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4DeleteViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterDeleteFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterDeletedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + p = p2 // reset + _, err = testEngine.Before(b4DeleteFunc).After(afterDeleteFunc).Delete(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag == 0 { + t.Error(errors.New("AfterDeletedFlag not set")) + } + if p.B4DeleteViaExt == 0 { + t.Error(errors.New("B4DeleteViaExt not set")) + } + if p.AfterDeletedViaExt == 0 { + t.Error(errors.New("AfterDeletedViaExt not set")) + } + } + // -- + + // test insert multi + pslice := make([]*ProcessorsStruct, 0) + pslice = append(pslice, &ProcessorsStruct{}) + pslice = append(pslice, &ProcessorsStruct{}) + cnt, err := testEngine.Before(b4InsertFunc).After(afterInsertFunc).Insert(&pslice) + if err != nil { + t.Error(err) + panic(err) + } else { + if cnt != 2 { + t.Error(errors.New("incorrect insert count")) + } + for _, elem := range pslice { + if elem.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if elem.AfterInsertedFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if elem.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if elem.AfterInsertedViaExt == 0 { + t.Error(errors.New("AfterInsertedViaExt not set")) + } + } + } + + for _, elem := range pslice { + p = &ProcessorsStruct{} + _, err = testEngine.Id(elem.Id).Get(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p2.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p2.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p2.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + if p2.BeforeSetFlag != 9 { + t.Error(fmt.Errorf("BeforeSetFlag is %d not 9", p2.BeforeSetFlag)) + } + if p2.AfterSetFlag != 9 { + t.Error(fmt.Errorf("AfterSetFlag is %d not 9", p2.BeforeSetFlag)) + } + } + } + // -- +} + +func TestProcessorsTx(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.DropTables(&ProcessorsStruct{}) + if err != nil { + t.Error(err) + panic(err) + } + + err = testEngine.CreateTables(&ProcessorsStruct{}) + if err != nil { + t.Error(err) + panic(err) + } + + // test insert processors with tx rollback + session := testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p := &ProcessorsStruct{} + b4InsertFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4InsertViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterInsertFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterInsertedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + _, err = session.Before(b4InsertFunc).After(afterInsertFunc).Insert(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedFlag != 0 { + t.Error(errors.New("B4InsertFlag is set")) + } + if p.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + } + + err = session.Rollback() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedFlag != 0 { + t.Error(errors.New("B4InsertFlag is set")) + } + if p.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + } + session.Close() + p2 := &ProcessorsStruct{} + _, err = testEngine.Id(p.Id).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.Id > 0 { + err = errors.New("tx got committed upon insert!?") + t.Error(err) + panic(err) + } + } + // -- + + // test insert processors with tx commit + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p = &ProcessorsStruct{} + _, err = session.Before(b4InsertFunc).After(afterInsertFunc).Insert(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + } + + err = session.Commit() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p.AfterInsertedFlag == 0 { + t.Error(errors.New("AfterInsertedFlag not set")) + } + if p.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p.AfterInsertedViaExt == 0 { + t.Error(errors.New("AfterInsertedViaExt not set")) + } + } + session.Close() + p2 = &ProcessorsStruct{} + _, err = testEngine.Id(p.Id).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4InsertFlag == 0 { + t.Error(errors.New("B4InsertFlag not set")) + } + if p2.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag is set")) + } + if p2.B4InsertViaExt == 0 { + t.Error(errors.New("B4InsertViaExt not set")) + } + if p2.AfterInsertedViaExt != 0 { + t.Error(errors.New("AfterInsertedViaExt is set")) + } + } + insertedId := p2.Id + // -- + + // test update processors with tx rollback + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + b4UpdateFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4UpdateViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterUpdateFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterUpdatedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + p = p2 // reset + + _, err = session.Id(insertedId).Before(b4UpdateFunc).After(afterUpdateFunc).Update(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt != 0 { + t.Error(errors.New("AfterUpdatedViaExt is set")) + } + } + err = session.Rollback() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt != 0 { + t.Error(errors.New("AfterUpdatedViaExt is set")) + } + } + + session.Close() + + p2 = &ProcessorsStruct{} + _, err = testEngine.Id(insertedId).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4UpdateFlag != 0 { + t.Error(errors.New("B4UpdateFlag is set")) + } + if p2.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set")) + } + if p2.B4UpdateViaExt != 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p2.AfterUpdatedViaExt != 0 { + t.Error(errors.New("AfterUpdatedViaExt is set")) + } + } + // -- + + // test update processors with tx rollback + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p = &ProcessorsStruct{Id: insertedId} + + _, err = session.Update(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set")) + } + } + err = session.Commit() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag == 0 { + t.Error(errors.New("AfterUpdatedFlag not set")) + } + if p.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag set")) + } + if p.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag set")) + } + } + + session.Close() + + // test update processors with tx commit + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p = &ProcessorsStruct{} + + _, err = session.Id(insertedId).Before(b4UpdateFunc).After(afterUpdateFunc).Update(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag is set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt != 0 { + t.Error(errors.New("AfterUpdatedViaExt is set")) + } + } + err = session.Commit() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag == 0 { + t.Error(errors.New("AfterUpdatedFlag not set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt == 0 { + t.Error(errors.New("AfterUpdatedViaExt not set")) + } + } + session.Close() + p2 = &ProcessorsStruct{} + _, err = testEngine.Id(insertedId).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4UpdateFlag == 0 { + t.Error(errors.New("B4UpdateFlag not set")) + } + if p.AfterUpdatedFlag == 0 { + t.Error(errors.New("AfterUpdatedFlag not set")) + } + if p.B4UpdateViaExt == 0 { + t.Error(errors.New("B4UpdateViaExt not set")) + } + if p.AfterUpdatedViaExt == 0 { + t.Error(errors.New("AfterUpdatedViaExt not set")) + } + } + // -- + + // test delete processors with tx rollback + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + b4DeleteFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.B4DeleteViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + afterDeleteFunc := func(bean interface{}) { + if v, ok := (bean).(*ProcessorsStruct); ok { + v.AfterDeletedViaExt = 1 + } else { + t.Error(errors.New("cast to ProcessorsStruct failed, how can this be!?")) + } + } + + p = &ProcessorsStruct{} // reset + + _, err = session.Id(insertedId).Before(b4DeleteFunc).After(afterDeleteFunc).Delete(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag is set")) + } + if p.B4DeleteViaExt == 0 { + t.Error(errors.New("B4DeleteViaExt not set")) + } + if p.AfterDeletedViaExt != 0 { + t.Error(errors.New("AfterDeletedViaExt is set")) + } + } + err = session.Rollback() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag is set")) + } + if p.B4DeleteViaExt == 0 { + t.Error(errors.New("B4DeleteViaExt not set")) + } + if p.AfterDeletedViaExt != 0 { + t.Error(errors.New("AfterDeletedViaExt is set")) + } + } + session.Close() + + p2 = &ProcessorsStruct{} + _, err = testEngine.Id(insertedId).Get(p2) + if err != nil { + t.Error(err) + panic(err) + } else { + if p2.B4DeleteFlag != 0 { + t.Error(errors.New("B4DeleteFlag is set")) + } + if p2.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag is set")) + } + if p2.B4DeleteViaExt != 0 { + t.Error(errors.New("B4DeleteViaExt is set")) + } + if p2.AfterDeletedViaExt != 0 { + t.Error(errors.New("AfterDeletedViaExt is set")) + } + } + // -- + + // test delete processors with tx commit + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p = &ProcessorsStruct{} + + _, err = session.Id(insertedId).Before(b4DeleteFunc).After(afterDeleteFunc).Delete(p) + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag is set")) + } + if p.B4DeleteViaExt == 0 { + t.Error(errors.New("B4DeleteViaExt not set")) + } + if p.AfterDeletedViaExt != 0 { + t.Error(errors.New("AfterDeletedViaExt is set")) + } + } + err = session.Commit() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag == 0 { + t.Error(errors.New("AfterDeletedFlag not set")) + } + if p.B4DeleteViaExt == 0 { + t.Error(errors.New("B4DeleteViaExt not set")) + } + if p.AfterDeletedViaExt == 0 { + t.Error(errors.New("AfterDeletedViaExt not set")) + } + } + session.Close() + + // test delete processors with tx commit + session = testEngine.NewSession() + err = session.Begin() + if err != nil { + t.Error(err) + panic(err) + } + + p = &ProcessorsStruct{Id: insertedId} + fmt.Println("delete") + _, err = session.Delete(p) + + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag != 0 { + t.Error(errors.New("AfterDeletedFlag is set")) + } + } + err = session.Commit() + if err != nil { + t.Error(err) + panic(err) + } else { + if p.B4DeleteFlag == 0 { + t.Error(errors.New("B4DeleteFlag not set")) + } + if p.AfterDeletedFlag == 0 { + t.Error(errors.New("AfterDeletedFlag not set")) + } + if p.AfterInsertedFlag != 0 { + t.Error(errors.New("AfterInsertedFlag set")) + } + if p.AfterUpdatedFlag != 0 { + t.Error(errors.New("AfterUpdatedFlag set")) + } + } + session.Close() + // -- +} diff --git a/tag_version_test.go b/tag_version_test.go new file mode 100644 index 00000000..1aeabcaa --- /dev/null +++ b/tag_version_test.go @@ -0,0 +1,128 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "errors" + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +type VersionS struct { + Id int64 + Name string + Ver int `xorm:"version"` + Created time.Time `xorm:"created"` +} + +func TestVersion1(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.DropTables(new(VersionS)) + if err != nil { + t.Error(err) + panic(err) + } + + err = testEngine.CreateTables(new(VersionS)) + if err != nil { + t.Error(err) + panic(err) + } + + ver := &VersionS{Name: "sfsfdsfds"} + _, err = testEngine.Insert(ver) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(ver) + if ver.Ver != 1 { + err = errors.New("insert error") + t.Error(err) + panic(err) + } + + newVer := new(VersionS) + has, err := testEngine.Id(ver.Id).Get(newVer) + if err != nil { + t.Error(err) + panic(err) + } + + if !has { + t.Error(errors.New(fmt.Sprintf("no version id is %v", ver.Id))) + panic(err) + } + fmt.Println(newVer) + if newVer.Ver != 1 { + err = errors.New("insert error") + t.Error(err) + panic(err) + } + + newVer.Name = "-------" + _, err = testEngine.Id(ver.Id).Update(newVer) + if err != nil { + t.Error(err) + panic(err) + } + if newVer.Ver != 2 { + err = errors.New("update should set version back to struct") + t.Error(err) + } + + newVer = new(VersionS) + has, err = testEngine.Id(ver.Id).Get(newVer) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(newVer) + if newVer.Ver != 2 { + err = errors.New("insert error") + t.Error(err) + panic(err) + } +} + +func TestVersion2(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.DropTables(new(VersionS)) + if err != nil { + t.Error(err) + panic(err) + } + + err = testEngine.CreateTables(new(VersionS)) + if err != nil { + t.Error(err) + panic(err) + } + + var vers = []VersionS{ + {Name: "sfsfdsfds"}, + {Name: "xxxxx"}, + } + _, err = testEngine.Insert(vers) + if err != nil { + t.Error(err) + panic(err) + } + + fmt.Println(vers) + + for _, v := range vers { + if v.Ver != 1 { + err := errors.New("version should be 1") + t.Error(err) + panic(err) + } + } +} diff --git a/types_null_test.go b/types_null_test.go new file mode 100644 index 00000000..776b2e6e --- /dev/null +++ b/types_null_test.go @@ -0,0 +1,404 @@ +// Copyright 2017 The Xorm Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package xorm + +import ( + "database/sql" + "database/sql/driver" + "errors" + "fmt" + "strconv" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +type NullType struct { + Id int `xorm:"pk autoincr"` + Name sql.NullString + Age sql.NullInt64 + Height sql.NullFloat64 + IsMan sql.NullBool `xorm:"null"` + CustomStruct CustomStruct `xorm:"valchar(64) null"` +} + +type CustomStruct struct { + Year int + Month int + Day int +} + +func (CustomStruct) String() string { + return "CustomStruct" +} + +func (m *CustomStruct) Scan(value interface{}) error { + if value == nil { + m.Year, m.Month, m.Day = 0, 0, 0 + return nil + } + + if s, ok := value.([]byte); ok { + seps := strings.Split(string(s), "/") + m.Year, _ = strconv.Atoi(seps[0]) + m.Month, _ = strconv.Atoi(seps[1]) + m.Day, _ = strconv.Atoi(seps[2]) + return nil + } + + return errors.New("scan data not fit []byte") +} + +func (m CustomStruct) Value() (driver.Value, error) { + return fmt.Sprintf("%d/%d/%d", m.Year, m.Month, m.Day), nil +} + +func TestCreateNullStructTable(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.CreateTables(new(NullType)) + if err != nil { + t.Error(err) + panic(err) + } +} + +func TestDropNullStructTable(t *testing.T) { + assert.NoError(t, prepareEngine()) + + err := testEngine.DropTables(new(NullType)) + if err != nil { + t.Error(err) + panic(err) + } +} + +func TestNullStructInsert(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + if true { + item := new(NullType) + _, err := testEngine.Insert(item) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(item) + if item.Id != 1 { + err = errors.New("insert error") + t.Error(err) + panic(err) + } + } + + if true { + item := NullType{ + Name: sql.NullString{"haolei", true}, + Age: sql.NullInt64{34, true}, + Height: sql.NullFloat64{1.72, true}, + IsMan: sql.NullBool{true, true}, + } + _, err := testEngine.Insert(&item) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(item) + if item.Id != 2 { + err = errors.New("insert error") + t.Error(err) + panic(err) + } + } + + if true { + items := []NullType{} + + for i := 0; i < 5; i++ { + item := NullType{ + Name: sql.NullString{"haolei_" + fmt.Sprint(i+1), true}, + Age: sql.NullInt64{30 + int64(i), true}, + Height: sql.NullFloat64{1.5 + 1.1*float64(i), true}, + IsMan: sql.NullBool{true, true}, + CustomStruct: CustomStruct{i, i + 1, i + 2}, + } + + items = append(items, item) + } + + _, err := testEngine.Insert(&items) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(items) + } +} + +func TestNullStructUpdate(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + _, err := testEngine.Insert([]NullType{ + { + Name: sql.NullString{ + String: "name1", + Valid: true, + }, + }, + { + Name: sql.NullString{ + String: "name2", + Valid: true, + }, + }, + { + Name: sql.NullString{ + String: "name3", + Valid: true, + }, + }, + { + Name: sql.NullString{ + String: "name4", + Valid: true, + }, + }, + }) + assert.NoError(t, err) + + if true { // 测试可插入NULL + item := new(NullType) + item.Age = sql.NullInt64{23, true} + item.Height = sql.NullFloat64{0, false} // update to NULL + + affected, err := testEngine.Id(2).Cols("age", "height", "is_man").Update(item) + if err != nil { + t.Error(err) + panic(err) + } + if affected != 1 { + err := errors.New("update failed") + t.Error(err) + panic(err) + } + } + + if true { // 测试In update + item := new(NullType) + item.Age = sql.NullInt64{23, true} + affected, err := testEngine.In("id", 3, 4).Cols("age", "height", "is_man").Update(item) + if err != nil { + t.Error(err) + panic(err) + } + if affected != 2 { + err := errors.New("update failed") + t.Error(err) + panic(err) + } + } + + if true { // 测试where + item := new(NullType) + item.Name = sql.NullString{"nullname", true} + item.IsMan = sql.NullBool{true, true} + item.Age = sql.NullInt64{34, true} + + _, err := testEngine.Where("age > ?", 34).Update(item) + if err != nil { + t.Error(err) + panic(err) + } + } + + if true { // 修改全部时,插入空值 + item := &NullType{ + Name: sql.NullString{"winxxp", true}, + Age: sql.NullInt64{30, true}, + Height: sql.NullFloat64{1.72, true}, + // IsMan: sql.NullBool{true, true}, + } + + _, err := testEngine.AllCols().Id(6).Update(item) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(item) + } + +} + +func TestNullStructFind(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + _, err := testEngine.Insert([]NullType{ + { + Name: sql.NullString{ + String: "name1", + Valid: false, + }, + }, + { + Name: sql.NullString{ + String: "name2", + Valid: true, + }, + }, + { + Name: sql.NullString{ + String: "name3", + Valid: true, + }, + }, + { + Name: sql.NullString{ + String: "name4", + Valid: true, + }, + }, + }) + assert.NoError(t, err) + + if true { + item := new(NullType) + has, err := testEngine.Id(1).Get(item) + if err != nil { + t.Error(err) + panic(err) + } + if !has { + t.Error(errors.New("no find id 1")) + panic(err) + } + fmt.Println(item) + if item.Id != 1 || item.Name.Valid || item.Age.Valid || item.Height.Valid || + item.IsMan.Valid { + err = errors.New("insert error") + t.Error(err) + panic(err) + } + } + + if true { + item := new(NullType) + item.Id = 2 + + has, err := testEngine.Get(item) + if err != nil { + t.Error(err) + panic(err) + } + if !has { + t.Error(errors.New("no find id 2")) + panic(err) + } + fmt.Println(item) + } + + if true { + item := make([]NullType, 0) + + err := testEngine.Id(2).Find(&item) + if err != nil { + t.Error(err) + panic(err) + } + + fmt.Println(item) + } + + if true { + item := make([]NullType, 0) + + err := testEngine.Asc("age").Find(&item) + if err != nil { + t.Error(err) + panic(err) + } + + for k, v := range item { + fmt.Println(k, v) + } + } +} + +func TestNullStructIterate(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + if true { + err := testEngine.Where("age IS NOT NULL").OrderBy("age").Iterate(new(NullType), + func(i int, bean interface{}) error { + nultype := bean.(*NullType) + fmt.Println(i, nultype) + return nil + }) + if err != nil { + t.Error(err) + panic(err) + } + } +} + +func TestNullStructCount(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + if true { + item := new(NullType) + total, err := testEngine.Where("age IS NOT NULL").Count(item) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(total) + } +} + +func TestNullStructRows(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + item := new(NullType) + rows, err := testEngine.Where("id > ?", 1).Rows(item) + if err != nil { + t.Error(err) + panic(err) + } + defer rows.Close() + + for rows.Next() { + err = rows.Scan(item) + if err != nil { + t.Error(err) + panic(err) + } + fmt.Println(item) + } +} + +func TestNullStructDelete(t *testing.T) { + assert.NoError(t, prepareEngine()) + assertSync(t, new(NullType)) + + item := new(NullType) + + _, err := testEngine.Id(1).Delete(item) + if err != nil { + t.Error(err) + panic(err) + } + + _, err = testEngine.Where("id > ?", 1).Delete(item) + if err != nil { + t.Error(err) + panic(err) + } +}