github.com/astaxie/beego@v1.12.3/orm/orm_test.go (about)

     1  // Copyright 2014 beego Author. All Rights Reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // +build go1.8
    16  
    17  package orm
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"database/sql"
    23  	"fmt"
    24  	"io/ioutil"
    25  	"math"
    26  	"os"
    27  	"path/filepath"
    28  	"reflect"
    29  	"runtime"
    30  	"strings"
    31  	"testing"
    32  	"time"
    33  )
    34  
    35  var _ = os.PathSeparator
    36  
    37  var (
    38  	testDate     = formatDate + " -0700"
    39  	testDateTime = formatDateTime + " -0700"
    40  	testTime     = formatTime + " -0700"
    41  )
    42  
    43  type argAny []interface{}
    44  
    45  // get interface by index from interface slice
    46  func (a argAny) Get(i int, args ...interface{}) (r interface{}) {
    47  	if i >= 0 && i < len(a) {
    48  		r = a[i]
    49  	}
    50  	if len(args) > 0 {
    51  		r = args[0]
    52  	}
    53  	return
    54  }
    55  
    56  func ValuesCompare(is bool, a interface{}, args ...interface{}) (ok bool, err error) {
    57  	if len(args) == 0 {
    58  		return false, fmt.Errorf("miss args")
    59  	}
    60  	b := args[0]
    61  	arg := argAny(args)
    62  
    63  	switch v := a.(type) {
    64  	case reflect.Kind:
    65  		ok = reflect.ValueOf(b).Kind() == v
    66  	case time.Time:
    67  		if v2, vo := b.(time.Time); vo {
    68  			if arg.Get(1) != nil {
    69  				format := ToStr(arg.Get(1))
    70  				a = v.Format(format)
    71  				b = v2.Format(format)
    72  				ok = a == b
    73  			} else {
    74  				err = fmt.Errorf("compare datetime miss format")
    75  				goto wrongArg
    76  			}
    77  		}
    78  	default:
    79  		ok = ToStr(a) == ToStr(b)
    80  	}
    81  	ok = is && ok || !is && !ok
    82  	if !ok {
    83  		if is {
    84  			err = fmt.Errorf("expected: `%v`, get `%v`", b, a)
    85  		} else {
    86  			err = fmt.Errorf("expected: `%v`, get `%v`", b, a)
    87  		}
    88  	}
    89  
    90  wrongArg:
    91  	if err != nil {
    92  		return false, err
    93  	}
    94  
    95  	return true, nil
    96  }
    97  
    98  func AssertIs(a interface{}, args ...interface{}) error {
    99  	if ok, err := ValuesCompare(true, a, args...); !ok {
   100  		return err
   101  	}
   102  	return nil
   103  }
   104  
   105  func AssertNot(a interface{}, args ...interface{}) error {
   106  	if ok, err := ValuesCompare(false, a, args...); !ok {
   107  		return err
   108  	}
   109  	return nil
   110  }
   111  
   112  func getCaller(skip int) string {
   113  	pc, file, line, _ := runtime.Caller(skip)
   114  	fun := runtime.FuncForPC(pc)
   115  	_, fn := filepath.Split(file)
   116  	data, err := ioutil.ReadFile(file)
   117  	var codes []string
   118  	if err == nil {
   119  		lines := bytes.Split(data, []byte{'\n'})
   120  		n := 10
   121  		for i := 0; i < n; i++ {
   122  			o := line - n
   123  			if o < 0 {
   124  				continue
   125  			}
   126  			cur := o + i + 1
   127  			flag := "  "
   128  			if cur == line {
   129  				flag = ">>"
   130  			}
   131  			code := fmt.Sprintf(" %s %5d:   %s", flag, cur, strings.Replace(string(lines[o+i]), "\t", "    ", -1))
   132  			if code != "" {
   133  				codes = append(codes, code)
   134  			}
   135  		}
   136  	}
   137  	funName := fun.Name()
   138  	if i := strings.LastIndex(funName, "."); i > -1 {
   139  		funName = funName[i+1:]
   140  	}
   141  	return fmt.Sprintf("%s:%s:%d: \n%s", fn, funName, line, strings.Join(codes, "\n"))
   142  }
   143  
   144  func throwFail(t *testing.T, err error, args ...interface{}) {
   145  	if err != nil {
   146  		con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
   147  		if len(args) > 0 {
   148  			parts := make([]string, 0, len(args))
   149  			for _, arg := range args {
   150  				parts = append(parts, fmt.Sprintf("%v", arg))
   151  			}
   152  			con += " " + strings.Join(parts, ", ")
   153  		}
   154  		t.Error(con)
   155  		t.Fail()
   156  	}
   157  }
   158  
   159  func throwFailNow(t *testing.T, err error, args ...interface{}) {
   160  	if err != nil {
   161  		con := fmt.Sprintf("\t\nError: %s\n%s\n", err.Error(), getCaller(2))
   162  		if len(args) > 0 {
   163  			parts := make([]string, 0, len(args))
   164  			for _, arg := range args {
   165  				parts = append(parts, fmt.Sprintf("%v", arg))
   166  			}
   167  			con += " " + strings.Join(parts, ", ")
   168  		}
   169  		t.Error(con)
   170  		t.FailNow()
   171  	}
   172  }
   173  
   174  func TestGetDB(t *testing.T) {
   175  	if db, err := GetDB(); err != nil {
   176  		throwFailNow(t, err)
   177  	} else {
   178  		err = db.Ping()
   179  		throwFailNow(t, err)
   180  	}
   181  }
   182  
   183  func TestSyncDb(t *testing.T) {
   184  	RegisterModel(new(Data), new(DataNull), new(DataCustom))
   185  	RegisterModel(new(User))
   186  	RegisterModel(new(Profile))
   187  	RegisterModel(new(Post))
   188  	RegisterModel(new(Tag))
   189  	RegisterModel(new(Comment))
   190  	RegisterModel(new(UserBig))
   191  	RegisterModel(new(PostTags))
   192  	RegisterModel(new(Group))
   193  	RegisterModel(new(Permission))
   194  	RegisterModel(new(GroupPermissions))
   195  	RegisterModel(new(InLine))
   196  	RegisterModel(new(InLineOneToOne))
   197  	RegisterModel(new(IntegerPk))
   198  	RegisterModel(new(UintPk))
   199  	RegisterModel(new(PtrPk))
   200  
   201  	err := RunSyncdb("default", true, Debug)
   202  	throwFail(t, err)
   203  
   204  	modelCache.clean()
   205  }
   206  
   207  func TestRegisterModels(t *testing.T) {
   208  	RegisterModel(new(Data), new(DataNull), new(DataCustom))
   209  	RegisterModel(new(User))
   210  	RegisterModel(new(Profile))
   211  	RegisterModel(new(Post))
   212  	RegisterModel(new(Tag))
   213  	RegisterModel(new(Comment))
   214  	RegisterModel(new(UserBig))
   215  	RegisterModel(new(PostTags))
   216  	RegisterModel(new(Group))
   217  	RegisterModel(new(Permission))
   218  	RegisterModel(new(GroupPermissions))
   219  	RegisterModel(new(InLine))
   220  	RegisterModel(new(InLineOneToOne))
   221  	RegisterModel(new(IntegerPk))
   222  	RegisterModel(new(UintPk))
   223  	RegisterModel(new(PtrPk))
   224  
   225  	BootStrap()
   226  
   227  	dORM = NewOrm()
   228  	dDbBaser = getDbAlias("default").DbBaser
   229  }
   230  
   231  func TestModelSyntax(t *testing.T) {
   232  	user := &User{}
   233  	ind := reflect.ValueOf(user).Elem()
   234  	fn := getFullName(ind.Type())
   235  	mi, ok := modelCache.getByFullName(fn)
   236  	throwFail(t, AssertIs(ok, true))
   237  
   238  	mi, ok = modelCache.get("user")
   239  	throwFail(t, AssertIs(ok, true))
   240  	if ok {
   241  		throwFail(t, AssertIs(mi.fields.GetByName("ShouldSkip") == nil, true))
   242  	}
   243  }
   244  
   245  var DataValues = map[string]interface{}{
   246  	"Boolean":  true,
   247  	"Char":     "char",
   248  	"Text":     "text",
   249  	"JSON":     `{"name":"json"}`,
   250  	"Jsonb":    `{"name": "jsonb"}`,
   251  	"Time":     time.Now(),
   252  	"Date":     time.Now(),
   253  	"DateTime": time.Now(),
   254  	"Byte":     byte(1<<8 - 1),
   255  	"Rune":     rune(1<<31 - 1),
   256  	"Int":      int(1<<31 - 1),
   257  	"Int8":     int8(1<<7 - 1),
   258  	"Int16":    int16(1<<15 - 1),
   259  	"Int32":    int32(1<<31 - 1),
   260  	"Int64":    int64(1<<63 - 1),
   261  	"Uint":     uint(1<<32 - 1),
   262  	"Uint8":    uint8(1<<8 - 1),
   263  	"Uint16":   uint16(1<<16 - 1),
   264  	"Uint32":   uint32(1<<32 - 1),
   265  	"Uint64":   uint64(1<<63 - 1), // uint64 values with high bit set are not supported
   266  	"Float32":  float32(100.1234),
   267  	"Float64":  float64(100.1234),
   268  	"Decimal":  float64(100.1234),
   269  }
   270  
   271  func TestDataTypes(t *testing.T) {
   272  	d := Data{}
   273  	ind := reflect.Indirect(reflect.ValueOf(&d))
   274  
   275  	for name, value := range DataValues {
   276  		if name == "JSON" {
   277  			continue
   278  		}
   279  		e := ind.FieldByName(name)
   280  		e.Set(reflect.ValueOf(value))
   281  	}
   282  	id, err := dORM.Insert(&d)
   283  	throwFail(t, err)
   284  	throwFail(t, AssertIs(id, 1))
   285  
   286  	d = Data{ID: 1}
   287  	err = dORM.Read(&d)
   288  	throwFail(t, err)
   289  
   290  	ind = reflect.Indirect(reflect.ValueOf(&d))
   291  
   292  	for name, value := range DataValues {
   293  		e := ind.FieldByName(name)
   294  		vu := e.Interface()
   295  		switch name {
   296  		case "Date":
   297  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
   298  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
   299  		case "DateTime":
   300  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
   301  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
   302  		case "Time":
   303  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
   304  			value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
   305  		}
   306  		throwFail(t, AssertIs(vu == value, true), value, vu)
   307  	}
   308  }
   309  
   310  func TestNullDataTypes(t *testing.T) {
   311  	d := DataNull{}
   312  
   313  	if IsPostgres {
   314  		// can removed when this fixed
   315  		// https://github.com/lib/pq/pull/125
   316  		d.DateTime = time.Now()
   317  	}
   318  
   319  	id, err := dORM.Insert(&d)
   320  	throwFail(t, err)
   321  	throwFail(t, AssertIs(id, 1))
   322  
   323  	data := `{"ok":1,"data":{"arr":[1,2],"msg":"gopher"}}`
   324  	d = DataNull{ID: 1, JSON: data}
   325  	num, err := dORM.Update(&d)
   326  	throwFail(t, err)
   327  	throwFail(t, AssertIs(num, 1))
   328  
   329  	d = DataNull{ID: 1}
   330  	err = dORM.Read(&d)
   331  	throwFail(t, err)
   332  
   333  	throwFail(t, AssertIs(d.JSON, data))
   334  
   335  	throwFail(t, AssertIs(d.NullBool.Valid, false))
   336  	throwFail(t, AssertIs(d.NullString.Valid, false))
   337  	throwFail(t, AssertIs(d.NullInt64.Valid, false))
   338  	throwFail(t, AssertIs(d.NullFloat64.Valid, false))
   339  
   340  	throwFail(t, AssertIs(d.BooleanPtr, nil))
   341  	throwFail(t, AssertIs(d.CharPtr, nil))
   342  	throwFail(t, AssertIs(d.TextPtr, nil))
   343  	throwFail(t, AssertIs(d.BytePtr, nil))
   344  	throwFail(t, AssertIs(d.RunePtr, nil))
   345  	throwFail(t, AssertIs(d.IntPtr, nil))
   346  	throwFail(t, AssertIs(d.Int8Ptr, nil))
   347  	throwFail(t, AssertIs(d.Int16Ptr, nil))
   348  	throwFail(t, AssertIs(d.Int32Ptr, nil))
   349  	throwFail(t, AssertIs(d.Int64Ptr, nil))
   350  	throwFail(t, AssertIs(d.UintPtr, nil))
   351  	throwFail(t, AssertIs(d.Uint8Ptr, nil))
   352  	throwFail(t, AssertIs(d.Uint16Ptr, nil))
   353  	throwFail(t, AssertIs(d.Uint32Ptr, nil))
   354  	throwFail(t, AssertIs(d.Uint64Ptr, nil))
   355  	throwFail(t, AssertIs(d.Float32Ptr, nil))
   356  	throwFail(t, AssertIs(d.Float64Ptr, nil))
   357  	throwFail(t, AssertIs(d.DecimalPtr, nil))
   358  	throwFail(t, AssertIs(d.TimePtr, nil))
   359  	throwFail(t, AssertIs(d.DatePtr, nil))
   360  	throwFail(t, AssertIs(d.DateTimePtr, nil))
   361  
   362  	_, err = dORM.Raw(`INSERT INTO data_null (boolean) VALUES (?)`, nil).Exec()
   363  	throwFail(t, err)
   364  
   365  	d = DataNull{ID: 2}
   366  	err = dORM.Read(&d)
   367  	throwFail(t, err)
   368  
   369  	booleanPtr := true
   370  	charPtr := string("test")
   371  	textPtr := string("test")
   372  	bytePtr := byte('t')
   373  	runePtr := rune('t')
   374  	intPtr := int(42)
   375  	int8Ptr := int8(42)
   376  	int16Ptr := int16(42)
   377  	int32Ptr := int32(42)
   378  	int64Ptr := int64(42)
   379  	uintPtr := uint(42)
   380  	uint8Ptr := uint8(42)
   381  	uint16Ptr := uint16(42)
   382  	uint32Ptr := uint32(42)
   383  	uint64Ptr := uint64(42)
   384  	float32Ptr := float32(42.0)
   385  	float64Ptr := float64(42.0)
   386  	decimalPtr := float64(42.0)
   387  	timePtr := time.Now()
   388  	datePtr := time.Now()
   389  	dateTimePtr := time.Now()
   390  
   391  	d = DataNull{
   392  		DateTime:    time.Now(),
   393  		NullString:  sql.NullString{String: "test", Valid: true},
   394  		NullBool:    sql.NullBool{Bool: true, Valid: true},
   395  		NullInt64:   sql.NullInt64{Int64: 42, Valid: true},
   396  		NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true},
   397  		BooleanPtr:  &booleanPtr,
   398  		CharPtr:     &charPtr,
   399  		TextPtr:     &textPtr,
   400  		BytePtr:     &bytePtr,
   401  		RunePtr:     &runePtr,
   402  		IntPtr:      &intPtr,
   403  		Int8Ptr:     &int8Ptr,
   404  		Int16Ptr:    &int16Ptr,
   405  		Int32Ptr:    &int32Ptr,
   406  		Int64Ptr:    &int64Ptr,
   407  		UintPtr:     &uintPtr,
   408  		Uint8Ptr:    &uint8Ptr,
   409  		Uint16Ptr:   &uint16Ptr,
   410  		Uint32Ptr:   &uint32Ptr,
   411  		Uint64Ptr:   &uint64Ptr,
   412  		Float32Ptr:  &float32Ptr,
   413  		Float64Ptr:  &float64Ptr,
   414  		DecimalPtr:  &decimalPtr,
   415  		TimePtr:     &timePtr,
   416  		DatePtr:     &datePtr,
   417  		DateTimePtr: &dateTimePtr,
   418  	}
   419  
   420  	id, err = dORM.Insert(&d)
   421  	throwFail(t, err)
   422  	throwFail(t, AssertIs(id, 3))
   423  
   424  	d = DataNull{ID: 3}
   425  	err = dORM.Read(&d)
   426  	throwFail(t, err)
   427  
   428  	throwFail(t, AssertIs(d.NullBool.Valid, true))
   429  	throwFail(t, AssertIs(d.NullBool.Bool, true))
   430  
   431  	throwFail(t, AssertIs(d.NullString.Valid, true))
   432  	throwFail(t, AssertIs(d.NullString.String, "test"))
   433  
   434  	throwFail(t, AssertIs(d.NullInt64.Valid, true))
   435  	throwFail(t, AssertIs(d.NullInt64.Int64, 42))
   436  
   437  	throwFail(t, AssertIs(d.NullFloat64.Valid, true))
   438  	throwFail(t, AssertIs(d.NullFloat64.Float64, 42.42))
   439  
   440  	throwFail(t, AssertIs(*d.BooleanPtr, booleanPtr))
   441  	throwFail(t, AssertIs(*d.CharPtr, charPtr))
   442  	throwFail(t, AssertIs(*d.TextPtr, textPtr))
   443  	throwFail(t, AssertIs(*d.BytePtr, bytePtr))
   444  	throwFail(t, AssertIs(*d.RunePtr, runePtr))
   445  	throwFail(t, AssertIs(*d.IntPtr, intPtr))
   446  	throwFail(t, AssertIs(*d.Int8Ptr, int8Ptr))
   447  	throwFail(t, AssertIs(*d.Int16Ptr, int16Ptr))
   448  	throwFail(t, AssertIs(*d.Int32Ptr, int32Ptr))
   449  	throwFail(t, AssertIs(*d.Int64Ptr, int64Ptr))
   450  	throwFail(t, AssertIs(*d.UintPtr, uintPtr))
   451  	throwFail(t, AssertIs(*d.Uint8Ptr, uint8Ptr))
   452  	throwFail(t, AssertIs(*d.Uint16Ptr, uint16Ptr))
   453  	throwFail(t, AssertIs(*d.Uint32Ptr, uint32Ptr))
   454  	throwFail(t, AssertIs(*d.Uint64Ptr, uint64Ptr))
   455  	throwFail(t, AssertIs(*d.Float32Ptr, float32Ptr))
   456  	throwFail(t, AssertIs(*d.Float64Ptr, float64Ptr))
   457  	throwFail(t, AssertIs(*d.DecimalPtr, decimalPtr))
   458  	throwFail(t, AssertIs((*d.TimePtr).UTC().Format(testTime), timePtr.UTC().Format(testTime)))
   459  	throwFail(t, AssertIs((*d.DatePtr).UTC().Format(testDate), datePtr.UTC().Format(testDate)))
   460  	throwFail(t, AssertIs((*d.DateTimePtr).UTC().Format(testDateTime), dateTimePtr.UTC().Format(testDateTime)))
   461  
   462  	// test support for pointer fields using RawSeter.QueryRows()
   463  	var dnList []*DataNull
   464  	Q := dDbBaser.TableQuote()
   465  	num, err = dORM.Raw(fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q), 3).QueryRows(&dnList)
   466  	throwFailNow(t, err)
   467  	throwFailNow(t, AssertIs(num, 1))
   468  	equal := reflect.DeepEqual(*dnList[0], d)
   469  	throwFailNow(t, AssertIs(equal, true))
   470  }
   471  
   472  func TestDataCustomTypes(t *testing.T) {
   473  	d := DataCustom{}
   474  	ind := reflect.Indirect(reflect.ValueOf(&d))
   475  
   476  	for name, value := range DataValues {
   477  		e := ind.FieldByName(name)
   478  		if !e.IsValid() {
   479  			continue
   480  		}
   481  		e.Set(reflect.ValueOf(value).Convert(e.Type()))
   482  	}
   483  
   484  	id, err := dORM.Insert(&d)
   485  	throwFail(t, err)
   486  	throwFail(t, AssertIs(id, 1))
   487  
   488  	d = DataCustom{ID: 1}
   489  	err = dORM.Read(&d)
   490  	throwFail(t, err)
   491  
   492  	ind = reflect.Indirect(reflect.ValueOf(&d))
   493  
   494  	for name, value := range DataValues {
   495  		e := ind.FieldByName(name)
   496  		if !e.IsValid() {
   497  			continue
   498  		}
   499  		vu := e.Interface()
   500  		value = reflect.ValueOf(value).Convert(e.Type()).Interface()
   501  		throwFail(t, AssertIs(vu == value, true), value, vu)
   502  	}
   503  }
   504  
   505  func TestCRUD(t *testing.T) {
   506  	profile := NewProfile()
   507  	profile.Age = 30
   508  	profile.Money = 1234.12
   509  	id, err := dORM.Insert(profile)
   510  	throwFail(t, err)
   511  	throwFail(t, AssertIs(id, 1))
   512  
   513  	user := NewUser()
   514  	user.UserName = "slene"
   515  	user.Email = "vslene@gmail.com"
   516  	user.Password = "pass"
   517  	user.Status = 3
   518  	user.IsStaff = true
   519  	user.IsActive = true
   520  
   521  	id, err = dORM.Insert(user)
   522  	throwFail(t, err)
   523  	throwFail(t, AssertIs(id, 1))
   524  
   525  	u := &User{ID: user.ID}
   526  	err = dORM.Read(u)
   527  	throwFail(t, err)
   528  
   529  	throwFail(t, AssertIs(u.UserName, "slene"))
   530  	throwFail(t, AssertIs(u.Email, "vslene@gmail.com"))
   531  	throwFail(t, AssertIs(u.Password, "pass"))
   532  	throwFail(t, AssertIs(u.Status, 3))
   533  	throwFail(t, AssertIs(u.IsStaff, true))
   534  	throwFail(t, AssertIs(u.IsActive, true))
   535  	throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), user.Created.In(DefaultTimeLoc), testDate))
   536  	throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), user.Updated.In(DefaultTimeLoc), testDateTime))
   537  
   538  	user.UserName = "astaxie"
   539  	user.Profile = profile
   540  	num, err := dORM.Update(user)
   541  	throwFail(t, err)
   542  	throwFail(t, AssertIs(num, 1))
   543  
   544  	u = &User{ID: user.ID}
   545  	err = dORM.Read(u)
   546  	throwFailNow(t, err)
   547  	throwFail(t, AssertIs(u.UserName, "astaxie"))
   548  	throwFail(t, AssertIs(u.Profile.ID, profile.ID))
   549  
   550  	u = &User{UserName: "astaxie", Password: "pass"}
   551  	err = dORM.Read(u, "UserName")
   552  	throwFailNow(t, err)
   553  	throwFailNow(t, AssertIs(id, 1))
   554  
   555  	u.UserName = "QQ"
   556  	u.Password = "111"
   557  	num, err = dORM.Update(u, "UserName")
   558  	throwFail(t, err)
   559  	throwFail(t, AssertIs(num, 1))
   560  
   561  	u = &User{ID: user.ID}
   562  	err = dORM.Read(u)
   563  	throwFailNow(t, err)
   564  	throwFail(t, AssertIs(u.UserName, "QQ"))
   565  	throwFail(t, AssertIs(u.Password, "pass"))
   566  
   567  	num, err = dORM.Delete(profile)
   568  	throwFail(t, err)
   569  	throwFail(t, AssertIs(num, 1))
   570  
   571  	u = &User{ID: user.ID}
   572  	err = dORM.Read(u)
   573  	throwFail(t, err)
   574  	throwFail(t, AssertIs(true, u.Profile == nil))
   575  
   576  	num, err = dORM.Delete(user)
   577  	throwFail(t, err)
   578  	throwFail(t, AssertIs(num, 1))
   579  
   580  	u = &User{ID: 100}
   581  	err = dORM.Read(u)
   582  	throwFail(t, AssertIs(err, ErrNoRows))
   583  
   584  	ub := UserBig{}
   585  	ub.Name = "name"
   586  	id, err = dORM.Insert(&ub)
   587  	throwFail(t, err)
   588  	throwFail(t, AssertIs(id, 1))
   589  
   590  	ub = UserBig{ID: 1}
   591  	err = dORM.Read(&ub)
   592  	throwFail(t, err)
   593  	throwFail(t, AssertIs(ub.Name, "name"))
   594  
   595  	num, err = dORM.Delete(&ub, "name")
   596  	throwFail(t, err)
   597  	throwFail(t, AssertIs(num, 1))
   598  }
   599  
   600  func TestInsertTestData(t *testing.T) {
   601  	var users []*User
   602  
   603  	profile := NewProfile()
   604  	profile.Age = 28
   605  	profile.Money = 1234.12
   606  
   607  	id, err := dORM.Insert(profile)
   608  	throwFail(t, err)
   609  	throwFail(t, AssertIs(id, 2))
   610  
   611  	user := NewUser()
   612  	user.UserName = "slene"
   613  	user.Email = "vslene@gmail.com"
   614  	user.Password = "pass"
   615  	user.Status = 1
   616  	user.IsStaff = false
   617  	user.IsActive = true
   618  	user.Profile = profile
   619  
   620  	users = append(users, user)
   621  
   622  	id, err = dORM.Insert(user)
   623  	throwFail(t, err)
   624  	throwFail(t, AssertIs(id, 2))
   625  
   626  	profile = NewProfile()
   627  	profile.Age = 30
   628  	profile.Money = 4321.09
   629  
   630  	id, err = dORM.Insert(profile)
   631  	throwFail(t, err)
   632  	throwFail(t, AssertIs(id, 3))
   633  
   634  	user = NewUser()
   635  	user.UserName = "astaxie"
   636  	user.Email = "astaxie@gmail.com"
   637  	user.Password = "password"
   638  	user.Status = 2
   639  	user.IsStaff = true
   640  	user.IsActive = false
   641  	user.Profile = profile
   642  
   643  	users = append(users, user)
   644  
   645  	id, err = dORM.Insert(user)
   646  	throwFail(t, err)
   647  	throwFail(t, AssertIs(id, 3))
   648  
   649  	user = NewUser()
   650  	user.UserName = "nobody"
   651  	user.Email = "nobody@gmail.com"
   652  	user.Password = "nobody"
   653  	user.Status = 3
   654  	user.IsStaff = false
   655  	user.IsActive = false
   656  
   657  	users = append(users, user)
   658  
   659  	id, err = dORM.Insert(user)
   660  	throwFail(t, err)
   661  	throwFail(t, AssertIs(id, 4))
   662  
   663  	tags := []*Tag{
   664  		{Name: "golang", BestPost: &Post{ID: 2}},
   665  		{Name: "example"},
   666  		{Name: "format"},
   667  		{Name: "c++"},
   668  	}
   669  
   670  	posts := []*Post{
   671  		{User: users[0], Tags: []*Tag{tags[0]}, Title: "Introduction", Content: `Go is a new language. Although it borrows ideas from existing languages, it has unusual properties that make effective Go programs different in character from programs written in its relatives. A straightforward translation of a C++ or Java program into Go is unlikely to produce a satisfactory result—Java programs are written in Java, not Go. On the other hand, thinking about the problem from a Go perspective could produce a successful but quite different program. In other words, to write Go well, it's important to understand its properties and idioms. It's also important to know the established conventions for programming in Go, such as naming, formatting, program construction, and so on, so that programs you write will be easy for other Go programmers to understand.
   672  This document gives tips for writing clear, idiomatic Go code. It augments the language specification, the Tour of Go, and How to Write Go Code, all of which you should read first.`},
   673  		{User: users[1], Tags: []*Tag{tags[0], tags[1]}, Title: "Examples", Content: `The Go package sources are intended to serve not only as the core library but also as examples of how to use the language. Moreover, many of the packages contain working, self-contained executable examples you can run directly from the golang.org web site, such as this one (click on the word "Example" to open it up). If you have a question about how to approach a problem or how something might be implemented, the documentation, code and examples in the library can provide answers, ideas and background.`},
   674  		{User: users[1], Tags: []*Tag{tags[0], tags[2]}, Title: "Formatting", Content: `Formatting issues are the most contentious but the least consequential. People can adapt to different formatting styles but it's better if they don't have to, and less time is devoted to the topic if everyone adheres to the same style. The problem is how to approach this Utopia without a long prescriptive style guide.
   675  With Go we take an unusual approach and let the machine take care of most formatting issues. The gofmt program (also available as go fmt, which operates at the package level rather than source file level) reads a Go program and emits the source in a standard style of indentation and vertical alignment, retaining and if necessary reformatting comments. If you want to know how to handle some new layout situation, run gofmt; if the answer doesn't seem right, rearrange your program (or file a bug about gofmt), don't work around it.`},
   676  		{User: users[2], Tags: []*Tag{tags[3]}, Title: "Commentary", Content: `Go provides C-style /* */ block comments and C++-style // line comments. Line comments are the norm; block comments appear mostly as package comments, but are useful within an expression or to disable large swaths of code.
   677  The program—and web server—godoc processes Go source files to extract documentation about the contents of the package. Comments that appear before top-level declarations, with no intervening newlines, are extracted along with the declaration to serve as explanatory text for the item. The nature and style of these comments determines the quality of the documentation godoc produces.`},
   678  	}
   679  
   680  	comments := []*Comment{
   681  		{Post: posts[0], Content: "a comment"},
   682  		{Post: posts[1], Content: "yes"},
   683  		{Post: posts[1]},
   684  		{Post: posts[1]},
   685  		{Post: posts[2]},
   686  		{Post: posts[2]},
   687  	}
   688  
   689  	for _, tag := range tags {
   690  		id, err := dORM.Insert(tag)
   691  		throwFail(t, err)
   692  		throwFail(t, AssertIs(id > 0, true))
   693  	}
   694  
   695  	for _, post := range posts {
   696  		id, err := dORM.Insert(post)
   697  		throwFail(t, err)
   698  		throwFail(t, AssertIs(id > 0, true))
   699  
   700  		num := len(post.Tags)
   701  		if num > 0 {
   702  			nums, err := dORM.QueryM2M(post, "tags").Add(post.Tags)
   703  			throwFailNow(t, err)
   704  			throwFailNow(t, AssertIs(nums, num))
   705  		}
   706  	}
   707  
   708  	for _, comment := range comments {
   709  		id, err := dORM.Insert(comment)
   710  		throwFail(t, err)
   711  		throwFail(t, AssertIs(id > 0, true))
   712  	}
   713  
   714  	permissions := []*Permission{
   715  		{Name: "writePosts"},
   716  		{Name: "readComments"},
   717  		{Name: "readPosts"},
   718  	}
   719  
   720  	groups := []*Group{
   721  		{
   722  			Name:        "admins",
   723  			Permissions: []*Permission{permissions[0], permissions[1], permissions[2]},
   724  		},
   725  		{
   726  			Name:        "users",
   727  			Permissions: []*Permission{permissions[1], permissions[2]},
   728  		},
   729  	}
   730  
   731  	for _, permission := range permissions {
   732  		id, err := dORM.Insert(permission)
   733  		throwFail(t, err)
   734  		throwFail(t, AssertIs(id > 0, true))
   735  	}
   736  
   737  	for _, group := range groups {
   738  		_, err := dORM.Insert(group)
   739  		throwFail(t, err)
   740  		throwFail(t, AssertIs(id > 0, true))
   741  
   742  		num := len(group.Permissions)
   743  		if num > 0 {
   744  			nums, err := dORM.QueryM2M(group, "permissions").Add(group.Permissions)
   745  			throwFailNow(t, err)
   746  			throwFailNow(t, AssertIs(nums, num))
   747  		}
   748  	}
   749  
   750  }
   751  
   752  func TestCustomField(t *testing.T) {
   753  	user := User{ID: 2}
   754  	err := dORM.Read(&user)
   755  	throwFailNow(t, err)
   756  
   757  	user.Langs = append(user.Langs, "zh-CN", "en-US")
   758  	user.Extra.Name = "beego"
   759  	user.Extra.Data = "orm"
   760  	_, err = dORM.Update(&user, "Langs", "Extra")
   761  	throwFailNow(t, err)
   762  
   763  	user = User{ID: 2}
   764  	err = dORM.Read(&user)
   765  	throwFailNow(t, err)
   766  	throwFailNow(t, AssertIs(len(user.Langs), 2))
   767  	throwFailNow(t, AssertIs(user.Langs[0], "zh-CN"))
   768  	throwFailNow(t, AssertIs(user.Langs[1], "en-US"))
   769  
   770  	throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
   771  	throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
   772  
   773  	var users []User
   774  	Q := dDbBaser.TableQuote()
   775  	n, err := dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRows(&users)
   776  	throwFailNow(t, err)
   777  	throwFailNow(t, AssertIs(n, 1))
   778  	throwFailNow(t, AssertIs(users[0].Extra.Name, "beego"))
   779  	throwFailNow(t, AssertIs(users[0].Extra.Data, "orm"))
   780  
   781  	user = User{}
   782  	err = dORM.Raw(fmt.Sprintf("SELECT * FROM %suser%s where id=?", Q, Q), 2).QueryRow(&user)
   783  	throwFailNow(t, err)
   784  	throwFailNow(t, AssertIs(user.Extra.Name, "beego"))
   785  	throwFailNow(t, AssertIs(user.Extra.Data, "orm"))
   786  }
   787  
   788  func TestExpr(t *testing.T) {
   789  	user := &User{}
   790  	qs := dORM.QueryTable(user)
   791  	qs = dORM.QueryTable((*User)(nil))
   792  	qs = dORM.QueryTable("User")
   793  	qs = dORM.QueryTable("user")
   794  	num, err := qs.Filter("UserName", "slene").Filter("user_name", "slene").Filter("profile__Age", 28).Count()
   795  	throwFail(t, err)
   796  	throwFail(t, AssertIs(num, 1))
   797  
   798  	num, err = qs.Filter("created", time.Now()).Count()
   799  	throwFail(t, err)
   800  	throwFail(t, AssertIs(num, 3))
   801  
   802  	// num, err = qs.Filter("created", time.Now().Format(format_Date)).Count()
   803  	// throwFail(t, err)
   804  	// throwFail(t, AssertIs(num, 3))
   805  }
   806  
   807  func TestOperators(t *testing.T) {
   808  	qs := dORM.QueryTable("user")
   809  	num, err := qs.Filter("user_name", "slene").Count()
   810  	throwFail(t, err)
   811  	throwFail(t, AssertIs(num, 1))
   812  
   813  	num, err = qs.Filter("user_name__exact", String("slene")).Count()
   814  	throwFail(t, err)
   815  	throwFail(t, AssertIs(num, 1))
   816  
   817  	num, err = qs.Filter("user_name__exact", "slene").Count()
   818  	throwFail(t, err)
   819  	throwFail(t, AssertIs(num, 1))
   820  
   821  	num, err = qs.Filter("user_name__iexact", "Slene").Count()
   822  	throwFail(t, err)
   823  	throwFail(t, AssertIs(num, 1))
   824  
   825  	if IsMysql {
   826  		// Now only mysql support `strictexact`
   827  		num, err = qs.Filter("user_name__strictexact", "Slene").Count()
   828  		throwFail(t, err)
   829  		throwFail(t, AssertIs(num, 0))
   830  
   831  		num, err = qs.Filter("user_name__strictexact", "slene").Count()
   832  		throwFail(t, err)
   833  		throwFail(t, AssertIs(num, 1))
   834  	}
   835  
   836  	num, err = qs.Filter("user_name__contains", "e").Count()
   837  	throwFail(t, err)
   838  	throwFail(t, AssertIs(num, 2))
   839  
   840  	var shouldNum int
   841  
   842  	if IsSqlite || IsTidb {
   843  		shouldNum = 2
   844  	} else {
   845  		shouldNum = 0
   846  	}
   847  
   848  	num, err = qs.Filter("user_name__contains", "E").Count()
   849  	throwFail(t, err)
   850  	throwFail(t, AssertIs(num, shouldNum))
   851  
   852  	num, err = qs.Filter("user_name__icontains", "E").Count()
   853  	throwFail(t, err)
   854  	throwFail(t, AssertIs(num, 2))
   855  
   856  	num, err = qs.Filter("user_name__icontains", "E").Count()
   857  	throwFail(t, err)
   858  	throwFail(t, AssertIs(num, 2))
   859  
   860  	num, err = qs.Filter("status__gt", 1).Count()
   861  	throwFail(t, err)
   862  	throwFail(t, AssertIs(num, 2))
   863  
   864  	num, err = qs.Filter("status__gte", 1).Count()
   865  	throwFail(t, err)
   866  	throwFail(t, AssertIs(num, 3))
   867  
   868  	num, err = qs.Filter("status__lt", Uint(3)).Count()
   869  	throwFail(t, err)
   870  	throwFail(t, AssertIs(num, 2))
   871  
   872  	num, err = qs.Filter("status__lte", Int(3)).Count()
   873  	throwFail(t, err)
   874  	throwFail(t, AssertIs(num, 3))
   875  
   876  	num, err = qs.Filter("user_name__startswith", "s").Count()
   877  	throwFail(t, err)
   878  	throwFail(t, AssertIs(num, 1))
   879  
   880  	if IsSqlite || IsTidb {
   881  		shouldNum = 1
   882  	} else {
   883  		shouldNum = 0
   884  	}
   885  
   886  	num, err = qs.Filter("user_name__startswith", "S").Count()
   887  	throwFail(t, err)
   888  	throwFail(t, AssertIs(num, shouldNum))
   889  
   890  	num, err = qs.Filter("user_name__istartswith", "S").Count()
   891  	throwFail(t, err)
   892  	throwFail(t, AssertIs(num, 1))
   893  
   894  	num, err = qs.Filter("user_name__endswith", "e").Count()
   895  	throwFail(t, err)
   896  	throwFail(t, AssertIs(num, 2))
   897  
   898  	if IsSqlite || IsTidb {
   899  		shouldNum = 2
   900  	} else {
   901  		shouldNum = 0
   902  	}
   903  
   904  	num, err = qs.Filter("user_name__endswith", "E").Count()
   905  	throwFail(t, err)
   906  	throwFail(t, AssertIs(num, shouldNum))
   907  
   908  	num, err = qs.Filter("user_name__iendswith", "E").Count()
   909  	throwFail(t, err)
   910  	throwFail(t, AssertIs(num, 2))
   911  
   912  	num, err = qs.Filter("profile__isnull", true).Count()
   913  	throwFail(t, err)
   914  	throwFail(t, AssertIs(num, 1))
   915  
   916  	num, err = qs.Filter("status__in", 1, 2).Count()
   917  	throwFail(t, err)
   918  	throwFail(t, AssertIs(num, 2))
   919  
   920  	num, err = qs.Filter("status__in", []int{1, 2}).Count()
   921  	throwFail(t, err)
   922  	throwFail(t, AssertIs(num, 2))
   923  
   924  	n1, n2 := 1, 2
   925  	num, err = qs.Filter("status__in", []*int{&n1}, &n2).Count()
   926  	throwFail(t, err)
   927  	throwFail(t, AssertIs(num, 2))
   928  
   929  	num, err = qs.Filter("id__between", 2, 3).Count()
   930  	throwFail(t, err)
   931  	throwFail(t, AssertIs(num, 2))
   932  
   933  	num, err = qs.Filter("id__between", []int{2, 3}).Count()
   934  	throwFail(t, err)
   935  	throwFail(t, AssertIs(num, 2))
   936  
   937  	num, err = qs.FilterRaw("user_name", "= 'slene'").Count()
   938  	throwFail(t, err)
   939  	throwFail(t, AssertIs(num, 1))
   940  
   941  	num, err = qs.FilterRaw("status", "IN (1, 2)").Count()
   942  	throwFail(t, err)
   943  	throwFail(t, AssertIs(num, 2))
   944  
   945  	num, err = qs.FilterRaw("profile_id", "IN (SELECT id FROM user_profile WHERE age=30)").Count()
   946  	throwFail(t, err)
   947  	throwFail(t, AssertIs(num, 1))
   948  }
   949  
   950  func TestSetCond(t *testing.T) {
   951  	cond := NewCondition()
   952  	cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000)
   953  
   954  	qs := dORM.QueryTable("user")
   955  	num, err := qs.SetCond(cond1).Count()
   956  	throwFail(t, err)
   957  	throwFail(t, AssertIs(num, 1))
   958  
   959  	cond2 := cond.AndCond(cond1).OrCond(cond.And("user_name", "slene"))
   960  	num, err = qs.SetCond(cond2).Count()
   961  	throwFail(t, err)
   962  	throwFail(t, AssertIs(num, 2))
   963  
   964  	cond3 := cond.AndNotCond(cond.And("status__in", 1))
   965  	num, err = qs.SetCond(cond3).Count()
   966  	throwFail(t, err)
   967  	throwFail(t, AssertIs(num, 2))
   968  
   969  	cond4 := cond.And("user_name", "slene").OrNotCond(cond.And("user_name", "slene"))
   970  	num, err = qs.SetCond(cond4).Count()
   971  	throwFail(t, err)
   972  	throwFail(t, AssertIs(num, 3))
   973  
   974  	cond5 := cond.Raw("user_name", "= 'slene'").OrNotCond(cond.And("user_name", "slene"))
   975  	num, err = qs.SetCond(cond5).Count()
   976  	throwFail(t, err)
   977  	throwFail(t, AssertIs(num, 3))
   978  }
   979  
   980  func TestLimit(t *testing.T) {
   981  	var posts []*Post
   982  	qs := dORM.QueryTable("post")
   983  	num, err := qs.Limit(1).All(&posts)
   984  	throwFail(t, err)
   985  	throwFail(t, AssertIs(num, 1))
   986  
   987  	num, err = qs.Limit(-1).All(&posts)
   988  	throwFail(t, err)
   989  	throwFail(t, AssertIs(num, 4))
   990  
   991  	num, err = qs.Limit(-1, 2).All(&posts)
   992  	throwFail(t, err)
   993  	throwFail(t, AssertIs(num, 2))
   994  
   995  	num, err = qs.Limit(0, 2).All(&posts)
   996  	throwFail(t, err)
   997  	throwFail(t, AssertIs(num, 2))
   998  }
   999  
  1000  func TestOffset(t *testing.T) {
  1001  	var posts []*Post
  1002  	qs := dORM.QueryTable("post")
  1003  	num, err := qs.Limit(1).Offset(2).All(&posts)
  1004  	throwFail(t, err)
  1005  	throwFail(t, AssertIs(num, 1))
  1006  
  1007  	num, err = qs.Offset(2).All(&posts)
  1008  	throwFail(t, err)
  1009  	throwFail(t, AssertIs(num, 2))
  1010  }
  1011  
  1012  func TestOrderBy(t *testing.T) {
  1013  	qs := dORM.QueryTable("user")
  1014  	num, err := qs.OrderBy("-status").Filter("user_name", "nobody").Count()
  1015  	throwFail(t, err)
  1016  	throwFail(t, AssertIs(num, 1))
  1017  
  1018  	num, err = qs.OrderBy("status").Filter("user_name", "slene").Count()
  1019  	throwFail(t, err)
  1020  	throwFail(t, AssertIs(num, 1))
  1021  
  1022  	num, err = qs.OrderBy("-profile__age").Filter("user_name", "astaxie").Count()
  1023  	throwFail(t, err)
  1024  	throwFail(t, AssertIs(num, 1))
  1025  }
  1026  
  1027  func TestAll(t *testing.T) {
  1028  	var users []*User
  1029  	qs := dORM.QueryTable("user")
  1030  	num, err := qs.OrderBy("Id").All(&users)
  1031  	throwFail(t, err)
  1032  	throwFailNow(t, AssertIs(num, 3))
  1033  
  1034  	throwFail(t, AssertIs(users[0].UserName, "slene"))
  1035  	throwFail(t, AssertIs(users[1].UserName, "astaxie"))
  1036  	throwFail(t, AssertIs(users[2].UserName, "nobody"))
  1037  
  1038  	var users2 []User
  1039  	qs = dORM.QueryTable("user")
  1040  	num, err = qs.OrderBy("Id").All(&users2)
  1041  	throwFail(t, err)
  1042  	throwFailNow(t, AssertIs(num, 3))
  1043  
  1044  	throwFailNow(t, AssertIs(users2[0].UserName, "slene"))
  1045  	throwFailNow(t, AssertIs(users2[1].UserName, "astaxie"))
  1046  	throwFailNow(t, AssertIs(users2[2].UserName, "nobody"))
  1047  
  1048  	qs = dORM.QueryTable("user")
  1049  	num, err = qs.OrderBy("Id").RelatedSel().All(&users2, "UserName")
  1050  	throwFail(t, err)
  1051  	throwFailNow(t, AssertIs(num, 3))
  1052  	throwFailNow(t, AssertIs(len(users2), 3))
  1053  	throwFailNow(t, AssertIs(users2[0].UserName, "slene"))
  1054  	throwFailNow(t, AssertIs(users2[1].UserName, "astaxie"))
  1055  	throwFailNow(t, AssertIs(users2[2].UserName, "nobody"))
  1056  	throwFailNow(t, AssertIs(users2[0].ID, 0))
  1057  	throwFailNow(t, AssertIs(users2[1].ID, 0))
  1058  	throwFailNow(t, AssertIs(users2[2].ID, 0))
  1059  	throwFailNow(t, AssertIs(users2[0].Profile == nil, false))
  1060  	throwFailNow(t, AssertIs(users2[1].Profile == nil, false))
  1061  	throwFailNow(t, AssertIs(users2[2].Profile == nil, true))
  1062  
  1063  	qs = dORM.QueryTable("user")
  1064  	num, err = qs.Filter("user_name", "nothing").All(&users)
  1065  	throwFailNow(t, err)
  1066  	throwFailNow(t, AssertIs(num, 0))
  1067  
  1068  	var users3 []*User
  1069  	qs = dORM.QueryTable("user")
  1070  	num, err = qs.Filter("user_name", "nothing").All(&users3)
  1071  	throwFailNow(t, err)
  1072  	throwFailNow(t, AssertIs(num, 0))
  1073  	throwFailNow(t, AssertIs(users3 == nil, false))
  1074  }
  1075  
  1076  func TestOne(t *testing.T) {
  1077  	var user User
  1078  	qs := dORM.QueryTable("user")
  1079  	err := qs.One(&user)
  1080  	throwFail(t, err)
  1081  
  1082  	user = User{}
  1083  	err = qs.OrderBy("Id").Limit(1).One(&user)
  1084  	throwFailNow(t, err)
  1085  	throwFail(t, AssertIs(user.UserName, "slene"))
  1086  	throwFail(t, AssertNot(err, ErrMultiRows))
  1087  
  1088  	user = User{}
  1089  	err = qs.OrderBy("-Id").Limit(100).One(&user)
  1090  	throwFailNow(t, err)
  1091  	throwFail(t, AssertIs(user.UserName, "nobody"))
  1092  	throwFail(t, AssertNot(err, ErrMultiRows))
  1093  
  1094  	err = qs.Filter("user_name", "nothing").One(&user)
  1095  	throwFail(t, AssertIs(err, ErrNoRows))
  1096  
  1097  }
  1098  
  1099  func TestValues(t *testing.T) {
  1100  	var maps []Params
  1101  	qs := dORM.QueryTable("user")
  1102  
  1103  	num, err := qs.OrderBy("Id").Values(&maps)
  1104  	throwFail(t, err)
  1105  	throwFail(t, AssertIs(num, 3))
  1106  	if num == 3 {
  1107  		throwFail(t, AssertIs(maps[0]["UserName"], "slene"))
  1108  		throwFail(t, AssertIs(maps[2]["Profile"], nil))
  1109  	}
  1110  
  1111  	num, err = qs.OrderBy("Id").Values(&maps, "UserName", "Profile__Age")
  1112  	throwFail(t, err)
  1113  	throwFail(t, AssertIs(num, 3))
  1114  	if num == 3 {
  1115  		throwFail(t, AssertIs(maps[0]["UserName"], "slene"))
  1116  		throwFail(t, AssertIs(maps[0]["Profile__Age"], 28))
  1117  		throwFail(t, AssertIs(maps[2]["Profile__Age"], nil))
  1118  	}
  1119  
  1120  	num, err = qs.Filter("UserName", "slene").Values(&maps)
  1121  	throwFail(t, err)
  1122  	throwFail(t, AssertIs(num, 1))
  1123  }
  1124  
  1125  func TestValuesList(t *testing.T) {
  1126  	var list []ParamsList
  1127  	qs := dORM.QueryTable("user")
  1128  
  1129  	num, err := qs.OrderBy("Id").ValuesList(&list)
  1130  	throwFail(t, err)
  1131  	throwFail(t, AssertIs(num, 3))
  1132  	if num == 3 {
  1133  		throwFail(t, AssertIs(list[0][1], "slene"))
  1134  		throwFail(t, AssertIs(list[2][9], nil))
  1135  	}
  1136  
  1137  	num, err = qs.OrderBy("Id").ValuesList(&list, "UserName", "Profile__Age")
  1138  	throwFail(t, err)
  1139  	throwFail(t, AssertIs(num, 3))
  1140  	if num == 3 {
  1141  		throwFail(t, AssertIs(list[0][0], "slene"))
  1142  		throwFail(t, AssertIs(list[0][1], 28))
  1143  		throwFail(t, AssertIs(list[2][1], nil))
  1144  	}
  1145  }
  1146  
  1147  func TestValuesFlat(t *testing.T) {
  1148  	var list ParamsList
  1149  	qs := dORM.QueryTable("user")
  1150  
  1151  	num, err := qs.OrderBy("id").ValuesFlat(&list, "UserName")
  1152  	throwFail(t, err)
  1153  	throwFail(t, AssertIs(num, 3))
  1154  	if num == 3 {
  1155  		throwFail(t, AssertIs(list[0], "slene"))
  1156  		throwFail(t, AssertIs(list[1], "astaxie"))
  1157  		throwFail(t, AssertIs(list[2], "nobody"))
  1158  	}
  1159  }
  1160  
  1161  func TestRelatedSel(t *testing.T) {
  1162  	if IsTidb {
  1163  		// Skip it. TiDB does not support relation now.
  1164  		return
  1165  	}
  1166  	qs := dORM.QueryTable("user")
  1167  	num, err := qs.Filter("profile__age", 28).Count()
  1168  	throwFail(t, err)
  1169  	throwFail(t, AssertIs(num, 1))
  1170  
  1171  	num, err = qs.Filter("profile__age__gt", 28).Count()
  1172  	throwFail(t, err)
  1173  	throwFail(t, AssertIs(num, 1))
  1174  
  1175  	num, err = qs.Filter("profile__user__profile__age__gt", 28).Count()
  1176  	throwFail(t, err)
  1177  	throwFail(t, AssertIs(num, 1))
  1178  
  1179  	var user User
  1180  	err = qs.Filter("user_name", "slene").RelatedSel("profile").One(&user)
  1181  	throwFail(t, err)
  1182  	throwFail(t, AssertIs(num, 1))
  1183  	throwFail(t, AssertNot(user.Profile, nil))
  1184  	if user.Profile != nil {
  1185  		throwFail(t, AssertIs(user.Profile.Age, 28))
  1186  	}
  1187  
  1188  	err = qs.Filter("user_name", "slene").RelatedSel().One(&user)
  1189  	throwFail(t, err)
  1190  	throwFail(t, AssertIs(num, 1))
  1191  	throwFail(t, AssertNot(user.Profile, nil))
  1192  	if user.Profile != nil {
  1193  		throwFail(t, AssertIs(user.Profile.Age, 28))
  1194  	}
  1195  
  1196  	err = qs.Filter("user_name", "nobody").RelatedSel("profile").One(&user)
  1197  	throwFail(t, err)
  1198  	throwFail(t, AssertIs(num, 1))
  1199  	throwFail(t, AssertIs(user.Profile, nil))
  1200  
  1201  	qs = dORM.QueryTable("user_profile")
  1202  	num, err = qs.Filter("user__username", "slene").Count()
  1203  	throwFail(t, err)
  1204  	throwFail(t, AssertIs(num, 1))
  1205  
  1206  	var posts []*Post
  1207  	qs = dORM.QueryTable("post")
  1208  	num, err = qs.RelatedSel().All(&posts)
  1209  	throwFail(t, err)
  1210  	throwFailNow(t, AssertIs(num, 4))
  1211  
  1212  	throwFailNow(t, AssertIs(posts[0].User.UserName, "slene"))
  1213  	throwFailNow(t, AssertIs(posts[1].User.UserName, "astaxie"))
  1214  	throwFailNow(t, AssertIs(posts[2].User.UserName, "astaxie"))
  1215  	throwFailNow(t, AssertIs(posts[3].User.UserName, "nobody"))
  1216  }
  1217  
  1218  func TestReverseQuery(t *testing.T) {
  1219  	var profile Profile
  1220  	err := dORM.QueryTable("user_profile").Filter("User", 3).One(&profile)
  1221  	throwFailNow(t, err)
  1222  	throwFailNow(t, AssertIs(profile.Age, 30))
  1223  
  1224  	profile = Profile{}
  1225  	err = dORM.QueryTable("user_profile").Filter("User__UserName", "astaxie").One(&profile)
  1226  	throwFailNow(t, err)
  1227  	throwFailNow(t, AssertIs(profile.Age, 30))
  1228  
  1229  	var user User
  1230  	err = dORM.QueryTable("user").Filter("Posts__Title", "Examples").One(&user)
  1231  	throwFailNow(t, err)
  1232  	throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  1233  
  1234  	user = User{}
  1235  	err = dORM.QueryTable("user").Filter("Posts__User__UserName", "astaxie").Limit(1).One(&user)
  1236  	throwFailNow(t, err)
  1237  	throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  1238  
  1239  	user = User{}
  1240  	err = dORM.QueryTable("user").Filter("Posts__User__UserName", "astaxie").RelatedSel().Limit(1).One(&user)
  1241  	throwFailNow(t, err)
  1242  	throwFailNow(t, AssertIs(user.UserName, "astaxie"))
  1243  	throwFailNow(t, AssertIs(user.Profile == nil, false))
  1244  	throwFailNow(t, AssertIs(user.Profile.Age, 30))
  1245  
  1246  	var posts []*Post
  1247  	num, err := dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").All(&posts)
  1248  	throwFailNow(t, err)
  1249  	throwFailNow(t, AssertIs(num, 3))
  1250  	throwFailNow(t, AssertIs(posts[0].Title, "Introduction"))
  1251  
  1252  	posts = []*Post{}
  1253  	num, err = dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").Filter("User__UserName", "slene").All(&posts)
  1254  	throwFailNow(t, err)
  1255  	throwFailNow(t, AssertIs(num, 1))
  1256  	throwFailNow(t, AssertIs(posts[0].Title, "Introduction"))
  1257  
  1258  	posts = []*Post{}
  1259  	num, err = dORM.QueryTable("post").Filter("Tags__Tag__Name", "golang").
  1260  		Filter("User__UserName", "slene").RelatedSel().All(&posts)
  1261  	throwFailNow(t, err)
  1262  	throwFailNow(t, AssertIs(num, 1))
  1263  	throwFailNow(t, AssertIs(posts[0].User == nil, false))
  1264  	throwFailNow(t, AssertIs(posts[0].User.UserName, "slene"))
  1265  
  1266  	var tags []*Tag
  1267  	num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").All(&tags)
  1268  	throwFailNow(t, err)
  1269  	throwFailNow(t, AssertIs(num, 1))
  1270  	throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  1271  
  1272  	tags = []*Tag{}
  1273  	num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").
  1274  		Filter("BestPost__User__UserName", "astaxie").All(&tags)
  1275  	throwFailNow(t, err)
  1276  	throwFailNow(t, AssertIs(num, 1))
  1277  	throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  1278  
  1279  	tags = []*Tag{}
  1280  	num, err = dORM.QueryTable("tag").Filter("Posts__Post__Title", "Introduction").
  1281  		Filter("BestPost__User__UserName", "astaxie").RelatedSel().All(&tags)
  1282  	throwFailNow(t, err)
  1283  	throwFailNow(t, AssertIs(num, 1))
  1284  	throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  1285  	throwFailNow(t, AssertIs(tags[0].BestPost == nil, false))
  1286  	throwFailNow(t, AssertIs(tags[0].BestPost.Title, "Examples"))
  1287  	throwFailNow(t, AssertIs(tags[0].BestPost.User == nil, false))
  1288  	throwFailNow(t, AssertIs(tags[0].BestPost.User.UserName, "astaxie"))
  1289  }
  1290  
  1291  func TestLoadRelated(t *testing.T) {
  1292  	// load reverse foreign key
  1293  	user := User{ID: 3}
  1294  
  1295  	err := dORM.Read(&user)
  1296  	throwFailNow(t, err)
  1297  
  1298  	num, err := dORM.LoadRelated(&user, "Posts")
  1299  	throwFailNow(t, err)
  1300  	throwFailNow(t, AssertIs(num, 2))
  1301  	throwFailNow(t, AssertIs(len(user.Posts), 2))
  1302  	throwFailNow(t, AssertIs(user.Posts[0].User.ID, 3))
  1303  
  1304  	num, err = dORM.LoadRelated(&user, "Posts", true)
  1305  	throwFailNow(t, err)
  1306  	throwFailNow(t, AssertIs(num, 2))
  1307  	throwFailNow(t, AssertIs(len(user.Posts), 2))
  1308  	throwFailNow(t, AssertIs(user.Posts[0].User.UserName, "astaxie"))
  1309  
  1310  	num, err = dORM.LoadRelated(&user, "Posts", true, 1)
  1311  	throwFailNow(t, err)
  1312  	throwFailNow(t, AssertIs(num, 1))
  1313  	throwFailNow(t, AssertIs(len(user.Posts), 1))
  1314  
  1315  	num, err = dORM.LoadRelated(&user, "Posts", true, 0, 0, "-Id")
  1316  	throwFailNow(t, err)
  1317  	throwFailNow(t, AssertIs(num, 2))
  1318  	throwFailNow(t, AssertIs(len(user.Posts), 2))
  1319  	throwFailNow(t, AssertIs(user.Posts[0].Title, "Formatting"))
  1320  
  1321  	num, err = dORM.LoadRelated(&user, "Posts", true, 1, 1, "Id")
  1322  	throwFailNow(t, err)
  1323  	throwFailNow(t, AssertIs(num, 1))
  1324  	throwFailNow(t, AssertIs(len(user.Posts), 1))
  1325  	throwFailNow(t, AssertIs(user.Posts[0].Title, "Formatting"))
  1326  
  1327  	// load reverse one to one
  1328  	profile := Profile{ID: 3}
  1329  	profile.BestPost = &Post{ID: 2}
  1330  	num, err = dORM.Update(&profile, "BestPost")
  1331  	throwFailNow(t, err)
  1332  	throwFailNow(t, AssertIs(num, 1))
  1333  
  1334  	err = dORM.Read(&profile)
  1335  	throwFailNow(t, err)
  1336  
  1337  	num, err = dORM.LoadRelated(&profile, "User")
  1338  	throwFailNow(t, err)
  1339  	throwFailNow(t, AssertIs(num, 1))
  1340  	throwFailNow(t, AssertIs(profile.User == nil, false))
  1341  	throwFailNow(t, AssertIs(profile.User.UserName, "astaxie"))
  1342  
  1343  	num, err = dORM.LoadRelated(&profile, "User", true)
  1344  	throwFailNow(t, err)
  1345  	throwFailNow(t, AssertIs(num, 1))
  1346  	throwFailNow(t, AssertIs(profile.User == nil, false))
  1347  	throwFailNow(t, AssertIs(profile.User.UserName, "astaxie"))
  1348  	throwFailNow(t, AssertIs(profile.User.Profile.Age, profile.Age))
  1349  
  1350  	// load rel one to one
  1351  	err = dORM.Read(&user)
  1352  	throwFailNow(t, err)
  1353  
  1354  	num, err = dORM.LoadRelated(&user, "Profile")
  1355  	throwFailNow(t, err)
  1356  	throwFailNow(t, AssertIs(num, 1))
  1357  	throwFailNow(t, AssertIs(user.Profile == nil, false))
  1358  	throwFailNow(t, AssertIs(user.Profile.Age, 30))
  1359  
  1360  	num, err = dORM.LoadRelated(&user, "Profile", true)
  1361  	throwFailNow(t, err)
  1362  	throwFailNow(t, AssertIs(num, 1))
  1363  	throwFailNow(t, AssertIs(user.Profile == nil, false))
  1364  	throwFailNow(t, AssertIs(user.Profile.Age, 30))
  1365  	throwFailNow(t, AssertIs(user.Profile.BestPost == nil, false))
  1366  	throwFailNow(t, AssertIs(user.Profile.BestPost.Title, "Examples"))
  1367  
  1368  	post := Post{ID: 2}
  1369  
  1370  	// load rel foreign key
  1371  	err = dORM.Read(&post)
  1372  	throwFailNow(t, err)
  1373  
  1374  	num, err = dORM.LoadRelated(&post, "User")
  1375  	throwFailNow(t, err)
  1376  	throwFailNow(t, AssertIs(num, 1))
  1377  	throwFailNow(t, AssertIs(post.User == nil, false))
  1378  	throwFailNow(t, AssertIs(post.User.UserName, "astaxie"))
  1379  
  1380  	num, err = dORM.LoadRelated(&post, "User", true)
  1381  	throwFailNow(t, err)
  1382  	throwFailNow(t, AssertIs(num, 1))
  1383  	throwFailNow(t, AssertIs(post.User == nil, false))
  1384  	throwFailNow(t, AssertIs(post.User.UserName, "astaxie"))
  1385  	throwFailNow(t, AssertIs(post.User.Profile == nil, false))
  1386  	throwFailNow(t, AssertIs(post.User.Profile.Age, 30))
  1387  
  1388  	// load rel m2m
  1389  	post = Post{ID: 2}
  1390  
  1391  	err = dORM.Read(&post)
  1392  	throwFailNow(t, err)
  1393  
  1394  	num, err = dORM.LoadRelated(&post, "Tags")
  1395  	throwFailNow(t, err)
  1396  	throwFailNow(t, AssertIs(num, 2))
  1397  	throwFailNow(t, AssertIs(len(post.Tags), 2))
  1398  	throwFailNow(t, AssertIs(post.Tags[0].Name, "golang"))
  1399  
  1400  	num, err = dORM.LoadRelated(&post, "Tags", true)
  1401  	throwFailNow(t, err)
  1402  	throwFailNow(t, AssertIs(num, 2))
  1403  	throwFailNow(t, AssertIs(len(post.Tags), 2))
  1404  	throwFailNow(t, AssertIs(post.Tags[0].Name, "golang"))
  1405  	throwFailNow(t, AssertIs(post.Tags[0].BestPost == nil, false))
  1406  	throwFailNow(t, AssertIs(post.Tags[0].BestPost.User.UserName, "astaxie"))
  1407  
  1408  	// load reverse m2m
  1409  	tag := Tag{ID: 1}
  1410  
  1411  	err = dORM.Read(&tag)
  1412  	throwFailNow(t, err)
  1413  
  1414  	num, err = dORM.LoadRelated(&tag, "Posts")
  1415  	throwFailNow(t, err)
  1416  	throwFailNow(t, AssertIs(num, 3))
  1417  	throwFailNow(t, AssertIs(tag.Posts[0].Title, "Introduction"))
  1418  	throwFailNow(t, AssertIs(tag.Posts[0].User.ID, 2))
  1419  	throwFailNow(t, AssertIs(tag.Posts[0].User.Profile == nil, true))
  1420  
  1421  	num, err = dORM.LoadRelated(&tag, "Posts", true)
  1422  	throwFailNow(t, err)
  1423  	throwFailNow(t, AssertIs(num, 3))
  1424  	throwFailNow(t, AssertIs(tag.Posts[0].Title, "Introduction"))
  1425  	throwFailNow(t, AssertIs(tag.Posts[0].User.ID, 2))
  1426  	throwFailNow(t, AssertIs(tag.Posts[0].User.UserName, "slene"))
  1427  }
  1428  
  1429  func TestQueryM2M(t *testing.T) {
  1430  	post := Post{ID: 4}
  1431  	m2m := dORM.QueryM2M(&post, "Tags")
  1432  
  1433  	tag1 := []*Tag{{Name: "TestTag1"}, {Name: "TestTag2"}}
  1434  	tag2 := &Tag{Name: "TestTag3"}
  1435  	tag3 := []interface{}{&Tag{Name: "TestTag4"}}
  1436  
  1437  	tags := []interface{}{tag1[0], tag1[1], tag2, tag3[0]}
  1438  
  1439  	for _, tag := range tags {
  1440  		_, err := dORM.Insert(tag)
  1441  		throwFailNow(t, err)
  1442  	}
  1443  
  1444  	num, err := m2m.Add(tag1)
  1445  	throwFailNow(t, err)
  1446  	throwFailNow(t, AssertIs(num, 2))
  1447  
  1448  	num, err = m2m.Add(tag2)
  1449  	throwFailNow(t, err)
  1450  	throwFailNow(t, AssertIs(num, 1))
  1451  
  1452  	num, err = m2m.Add(tag3)
  1453  	throwFailNow(t, err)
  1454  	throwFailNow(t, AssertIs(num, 1))
  1455  
  1456  	num, err = m2m.Count()
  1457  	throwFailNow(t, err)
  1458  	throwFailNow(t, AssertIs(num, 5))
  1459  
  1460  	num, err = m2m.Remove(tag3)
  1461  	throwFailNow(t, err)
  1462  	throwFailNow(t, AssertIs(num, 1))
  1463  
  1464  	num, err = m2m.Count()
  1465  	throwFailNow(t, err)
  1466  	throwFailNow(t, AssertIs(num, 4))
  1467  
  1468  	exist := m2m.Exist(tag2)
  1469  	throwFailNow(t, AssertIs(exist, true))
  1470  
  1471  	num, err = m2m.Remove(tag2)
  1472  	throwFailNow(t, err)
  1473  	throwFailNow(t, AssertIs(num, 1))
  1474  
  1475  	exist = m2m.Exist(tag2)
  1476  	throwFailNow(t, AssertIs(exist, false))
  1477  
  1478  	num, err = m2m.Count()
  1479  	throwFailNow(t, err)
  1480  	throwFailNow(t, AssertIs(num, 3))
  1481  
  1482  	num, err = m2m.Clear()
  1483  	throwFailNow(t, err)
  1484  	throwFailNow(t, AssertIs(num, 3))
  1485  
  1486  	num, err = m2m.Count()
  1487  	throwFailNow(t, err)
  1488  	throwFailNow(t, AssertIs(num, 0))
  1489  
  1490  	tag := Tag{Name: "test"}
  1491  	_, err = dORM.Insert(&tag)
  1492  	throwFailNow(t, err)
  1493  
  1494  	m2m = dORM.QueryM2M(&tag, "Posts")
  1495  
  1496  	post1 := []*Post{{Title: "TestPost1"}, {Title: "TestPost2"}}
  1497  	post2 := &Post{Title: "TestPost3"}
  1498  	post3 := []interface{}{&Post{Title: "TestPost4"}}
  1499  
  1500  	posts := []interface{}{post1[0], post1[1], post2, post3[0]}
  1501  
  1502  	for _, post := range posts {
  1503  		p := post.(*Post)
  1504  		p.User = &User{ID: 1}
  1505  		_, err := dORM.Insert(post)
  1506  		throwFailNow(t, err)
  1507  	}
  1508  
  1509  	num, err = m2m.Add(post1)
  1510  	throwFailNow(t, err)
  1511  	throwFailNow(t, AssertIs(num, 2))
  1512  
  1513  	num, err = m2m.Add(post2)
  1514  	throwFailNow(t, err)
  1515  	throwFailNow(t, AssertIs(num, 1))
  1516  
  1517  	num, err = m2m.Add(post3)
  1518  	throwFailNow(t, err)
  1519  	throwFailNow(t, AssertIs(num, 1))
  1520  
  1521  	num, err = m2m.Count()
  1522  	throwFailNow(t, err)
  1523  	throwFailNow(t, AssertIs(num, 4))
  1524  
  1525  	num, err = m2m.Remove(post3)
  1526  	throwFailNow(t, err)
  1527  	throwFailNow(t, AssertIs(num, 1))
  1528  
  1529  	num, err = m2m.Count()
  1530  	throwFailNow(t, err)
  1531  	throwFailNow(t, AssertIs(num, 3))
  1532  
  1533  	exist = m2m.Exist(post2)
  1534  	throwFailNow(t, AssertIs(exist, true))
  1535  
  1536  	num, err = m2m.Remove(post2)
  1537  	throwFailNow(t, err)
  1538  	throwFailNow(t, AssertIs(num, 1))
  1539  
  1540  	exist = m2m.Exist(post2)
  1541  	throwFailNow(t, AssertIs(exist, false))
  1542  
  1543  	num, err = m2m.Count()
  1544  	throwFailNow(t, err)
  1545  	throwFailNow(t, AssertIs(num, 2))
  1546  
  1547  	num, err = m2m.Clear()
  1548  	throwFailNow(t, err)
  1549  	throwFailNow(t, AssertIs(num, 2))
  1550  
  1551  	num, err = m2m.Count()
  1552  	throwFailNow(t, err)
  1553  	throwFailNow(t, AssertIs(num, 0))
  1554  
  1555  	num, err = dORM.Delete(&tag)
  1556  	throwFailNow(t, err)
  1557  	throwFailNow(t, AssertIs(num, 1))
  1558  }
  1559  
  1560  func TestQueryRelate(t *testing.T) {
  1561  	// post := &Post{Id: 2}
  1562  
  1563  	// qs := dORM.QueryRelate(post, "Tags")
  1564  	// num, err := qs.Count()
  1565  	// throwFailNow(t, err)
  1566  	// throwFailNow(t, AssertIs(num, 2))
  1567  
  1568  	// var tags []*Tag
  1569  	// num, err = qs.All(&tags)
  1570  	// throwFailNow(t, err)
  1571  	// throwFailNow(t, AssertIs(num, 2))
  1572  	// throwFailNow(t, AssertIs(tags[0].Name, "golang"))
  1573  
  1574  	// num, err = dORM.QueryTable("Tag").Filter("Posts__Post", 2).Count()
  1575  	// throwFailNow(t, err)
  1576  	// throwFailNow(t, AssertIs(num, 2))
  1577  }
  1578  
  1579  func TestPkManyRelated(t *testing.T) {
  1580  	permission := &Permission{Name: "readPosts"}
  1581  	err := dORM.Read(permission, "Name")
  1582  	throwFailNow(t, err)
  1583  
  1584  	var groups []*Group
  1585  	qs := dORM.QueryTable("Group")
  1586  	num, err := qs.Filter("Permissions__Permission", permission.ID).All(&groups)
  1587  	throwFailNow(t, err)
  1588  	throwFailNow(t, AssertIs(num, 2))
  1589  }
  1590  
  1591  func TestPrepareInsert(t *testing.T) {
  1592  	qs := dORM.QueryTable("user")
  1593  	i, err := qs.PrepareInsert()
  1594  	throwFailNow(t, err)
  1595  
  1596  	var user User
  1597  	user.UserName = "testing1"
  1598  	num, err := i.Insert(&user)
  1599  	throwFail(t, err)
  1600  	throwFail(t, AssertIs(num > 0, true))
  1601  
  1602  	user.UserName = "testing2"
  1603  	num, err = i.Insert(&user)
  1604  	throwFail(t, err)
  1605  	throwFail(t, AssertIs(num > 0, true))
  1606  
  1607  	num, err = qs.Filter("user_name__in", "testing1", "testing2").Delete()
  1608  	throwFail(t, err)
  1609  	throwFail(t, AssertIs(num, 2))
  1610  
  1611  	err = i.Close()
  1612  	throwFail(t, err)
  1613  	err = i.Close()
  1614  	throwFail(t, AssertIs(err, ErrStmtClosed))
  1615  }
  1616  
  1617  func TestRawExec(t *testing.T) {
  1618  	Q := dDbBaser.TableQuote()
  1619  
  1620  	query := fmt.Sprintf("UPDATE %suser%s SET %suser_name%s = ? WHERE %suser_name%s = ?", Q, Q, Q, Q, Q, Q)
  1621  	res, err := dORM.Raw(query, "testing", "slene").Exec()
  1622  	throwFail(t, err)
  1623  	num, err := res.RowsAffected()
  1624  	throwFail(t, AssertIs(num, 1), err)
  1625  
  1626  	res, err = dORM.Raw(query, "slene", "testing").Exec()
  1627  	throwFail(t, err)
  1628  	num, err = res.RowsAffected()
  1629  	throwFail(t, AssertIs(num, 1), err)
  1630  }
  1631  
  1632  func TestRawQueryRow(t *testing.T) {
  1633  	var (
  1634  		Boolean  bool
  1635  		Char     string
  1636  		Text     string
  1637  		Time     time.Time
  1638  		Date     time.Time
  1639  		DateTime time.Time
  1640  		Byte     byte
  1641  		Rune     rune
  1642  		Int      int
  1643  		Int8     int
  1644  		Int16    int16
  1645  		Int32    int32
  1646  		Int64    int64
  1647  		Uint     uint
  1648  		Uint8    uint8
  1649  		Uint16   uint16
  1650  		Uint32   uint32
  1651  		Uint64   uint64
  1652  		Float32  float32
  1653  		Float64  float64
  1654  		Decimal  float64
  1655  	)
  1656  
  1657  	dataValues := make(map[string]interface{}, len(DataValues))
  1658  
  1659  	for k, v := range DataValues {
  1660  		dataValues[strings.ToLower(k)] = v
  1661  	}
  1662  
  1663  	Q := dDbBaser.TableQuote()
  1664  
  1665  	cols := []string{
  1666  		"id", "boolean", "char", "text", "time", "date", "datetime", "byte", "rune", "int", "int8", "int16", "int32",
  1667  		"int64", "uint", "uint8", "uint16", "uint32", "uint64", "float32", "float64", "decimal",
  1668  	}
  1669  	sep := fmt.Sprintf("%s, %s", Q, Q)
  1670  	query := fmt.Sprintf("SELECT %s%s%s FROM data WHERE id = ?", Q, strings.Join(cols, sep), Q)
  1671  	var id int
  1672  	values := []interface{}{
  1673  		&id, &Boolean, &Char, &Text, &Time, &Date, &DateTime, &Byte, &Rune, &Int, &Int8, &Int16, &Int32,
  1674  		&Int64, &Uint, &Uint8, &Uint16, &Uint32, &Uint64, &Float32, &Float64, &Decimal,
  1675  	}
  1676  	err := dORM.Raw(query, 1).QueryRow(values...)
  1677  	throwFailNow(t, err)
  1678  	for i, col := range cols {
  1679  		vu := values[i]
  1680  		v := reflect.ValueOf(vu).Elem().Interface()
  1681  		switch col {
  1682  		case "id":
  1683  			throwFail(t, AssertIs(id, 1))
  1684  		case "time":
  1685  			v = v.(time.Time).In(DefaultTimeLoc)
  1686  			value := dataValues[col].(time.Time).In(DefaultTimeLoc)
  1687  			throwFail(t, AssertIs(v, value, testTime))
  1688  		case "date":
  1689  			v = v.(time.Time).In(DefaultTimeLoc)
  1690  			value := dataValues[col].(time.Time).In(DefaultTimeLoc)
  1691  			throwFail(t, AssertIs(v, value, testDate))
  1692  		case "datetime":
  1693  			v = v.(time.Time).In(DefaultTimeLoc)
  1694  			value := dataValues[col].(time.Time).In(DefaultTimeLoc)
  1695  			throwFail(t, AssertIs(v, value, testDateTime))
  1696  		default:
  1697  			throwFail(t, AssertIs(v, dataValues[col]))
  1698  		}
  1699  	}
  1700  
  1701  	var (
  1702  		uid    int
  1703  		status *int
  1704  		pid    *int
  1705  	)
  1706  
  1707  	cols = []string{
  1708  		"id", "Status", "profile_id",
  1709  	}
  1710  	query = fmt.Sprintf("SELECT %s%s%s FROM %suser%s WHERE id = ?", Q, strings.Join(cols, sep), Q, Q, Q)
  1711  	err = dORM.Raw(query, 4).QueryRow(&uid, &status, &pid)
  1712  	throwFail(t, err)
  1713  	throwFail(t, AssertIs(uid, 4))
  1714  	throwFail(t, AssertIs(*status, 3))
  1715  	throwFail(t, AssertIs(pid, nil))
  1716  
  1717  	// test for sql.Null* fields
  1718  	nData := &DataNull{
  1719  		NullString:  sql.NullString{String: "test sql.null", Valid: true},
  1720  		NullBool:    sql.NullBool{Bool: true, Valid: true},
  1721  		NullInt64:   sql.NullInt64{Int64: 42, Valid: true},
  1722  		NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true},
  1723  	}
  1724  	newId, err := dORM.Insert(nData)
  1725  	throwFailNow(t, err)
  1726  
  1727  	var nd *DataNull
  1728  	query = fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q)
  1729  	err = dORM.Raw(query, newId).QueryRow(&nd)
  1730  	throwFailNow(t, err)
  1731  
  1732  	throwFailNow(t, AssertNot(nd, nil))
  1733  	throwFail(t, AssertIs(nd.NullBool.Valid, true))
  1734  	throwFail(t, AssertIs(nd.NullBool.Bool, true))
  1735  	throwFail(t, AssertIs(nd.NullString.Valid, true))
  1736  	throwFail(t, AssertIs(nd.NullString.String, "test sql.null"))
  1737  	throwFail(t, AssertIs(nd.NullInt64.Valid, true))
  1738  	throwFail(t, AssertIs(nd.NullInt64.Int64, 42))
  1739  	throwFail(t, AssertIs(nd.NullFloat64.Valid, true))
  1740  	throwFail(t, AssertIs(nd.NullFloat64.Float64, 42.42))
  1741  }
  1742  
  1743  // user_profile table
  1744  type userProfile struct {
  1745  	User
  1746  	Age   int
  1747  	Money float64
  1748  }
  1749  
  1750  func TestQueryRows(t *testing.T) {
  1751  	Q := dDbBaser.TableQuote()
  1752  
  1753  	var datas []*Data
  1754  
  1755  	query := fmt.Sprintf("SELECT * FROM %sdata%s", Q, Q)
  1756  	num, err := dORM.Raw(query).QueryRows(&datas)
  1757  	throwFailNow(t, err)
  1758  	throwFailNow(t, AssertIs(num, 1))
  1759  	throwFailNow(t, AssertIs(len(datas), 1))
  1760  
  1761  	ind := reflect.Indirect(reflect.ValueOf(datas[0]))
  1762  
  1763  	for name, value := range DataValues {
  1764  		e := ind.FieldByName(name)
  1765  		vu := e.Interface()
  1766  		switch name {
  1767  		case "Time":
  1768  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
  1769  			value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
  1770  		case "Date":
  1771  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
  1772  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
  1773  		case "DateTime":
  1774  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
  1775  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
  1776  		}
  1777  		throwFail(t, AssertIs(vu == value, true), value, vu)
  1778  	}
  1779  
  1780  	var datas2 []Data
  1781  
  1782  	query = fmt.Sprintf("SELECT * FROM %sdata%s", Q, Q)
  1783  	num, err = dORM.Raw(query).QueryRows(&datas2)
  1784  	throwFailNow(t, err)
  1785  	throwFailNow(t, AssertIs(num, 1))
  1786  	throwFailNow(t, AssertIs(len(datas2), 1))
  1787  
  1788  	ind = reflect.Indirect(reflect.ValueOf(datas2[0]))
  1789  
  1790  	for name, value := range DataValues {
  1791  		e := ind.FieldByName(name)
  1792  		vu := e.Interface()
  1793  		switch name {
  1794  		case "Time":
  1795  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testTime)
  1796  			value = value.(time.Time).In(DefaultTimeLoc).Format(testTime)
  1797  		case "Date":
  1798  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDate)
  1799  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDate)
  1800  		case "DateTime":
  1801  			vu = vu.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
  1802  			value = value.(time.Time).In(DefaultTimeLoc).Format(testDateTime)
  1803  		}
  1804  		throwFail(t, AssertIs(vu == value, true), value, vu)
  1805  	}
  1806  
  1807  	var ids []int
  1808  	var usernames []string
  1809  	query = fmt.Sprintf("SELECT %sid%s, %suser_name%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q, Q, Q)
  1810  	num, err = dORM.Raw(query).QueryRows(&ids, &usernames)
  1811  	throwFailNow(t, err)
  1812  	throwFailNow(t, AssertIs(num, 3))
  1813  	throwFailNow(t, AssertIs(len(ids), 3))
  1814  	throwFailNow(t, AssertIs(ids[0], 2))
  1815  	throwFailNow(t, AssertIs(usernames[0], "slene"))
  1816  	throwFailNow(t, AssertIs(ids[1], 3))
  1817  	throwFailNow(t, AssertIs(usernames[1], "astaxie"))
  1818  	throwFailNow(t, AssertIs(ids[2], 4))
  1819  	throwFailNow(t, AssertIs(usernames[2], "nobody"))
  1820  
  1821  	//test query rows by nested struct
  1822  	var l []userProfile
  1823  	query = fmt.Sprintf("SELECT * FROM %suser_profile%s LEFT JOIN %suser%s ON %suser_profile%s.%sid%s = %suser%s.%sid%s", Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q, Q)
  1824  	num, err = dORM.Raw(query).QueryRows(&l)
  1825  	throwFailNow(t, err)
  1826  	throwFailNow(t, AssertIs(num, 2))
  1827  	throwFailNow(t, AssertIs(len(l), 2))
  1828  	throwFailNow(t, AssertIs(l[0].UserName, "slene"))
  1829  	throwFailNow(t, AssertIs(l[0].Age, 28))
  1830  	throwFailNow(t, AssertIs(l[1].UserName, "astaxie"))
  1831  	throwFailNow(t, AssertIs(l[1].Age, 30))
  1832  
  1833  	// test for sql.Null* fields
  1834  	nData := &DataNull{
  1835  		NullString:  sql.NullString{String: "test sql.null", Valid: true},
  1836  		NullBool:    sql.NullBool{Bool: true, Valid: true},
  1837  		NullInt64:   sql.NullInt64{Int64: 42, Valid: true},
  1838  		NullFloat64: sql.NullFloat64{Float64: 42.42, Valid: true},
  1839  	}
  1840  	newId, err := dORM.Insert(nData)
  1841  	throwFailNow(t, err)
  1842  
  1843  	var nDataList []*DataNull
  1844  	query = fmt.Sprintf("SELECT * FROM %sdata_null%s where id=?", Q, Q)
  1845  	num, err = dORM.Raw(query, newId).QueryRows(&nDataList)
  1846  	throwFailNow(t, err)
  1847  	throwFailNow(t, AssertIs(num, 1))
  1848  
  1849  	nd := nDataList[0]
  1850  	throwFailNow(t, AssertNot(nd, nil))
  1851  	throwFail(t, AssertIs(nd.NullBool.Valid, true))
  1852  	throwFail(t, AssertIs(nd.NullBool.Bool, true))
  1853  	throwFail(t, AssertIs(nd.NullString.Valid, true))
  1854  	throwFail(t, AssertIs(nd.NullString.String, "test sql.null"))
  1855  	throwFail(t, AssertIs(nd.NullInt64.Valid, true))
  1856  	throwFail(t, AssertIs(nd.NullInt64.Int64, 42))
  1857  	throwFail(t, AssertIs(nd.NullFloat64.Valid, true))
  1858  	throwFail(t, AssertIs(nd.NullFloat64.Float64, 42.42))
  1859  }
  1860  
  1861  func TestRawValues(t *testing.T) {
  1862  	Q := dDbBaser.TableQuote()
  1863  
  1864  	var maps []Params
  1865  	query := fmt.Sprintf("SELECT %suser_name%s FROM %suser%s WHERE %sStatus%s = ?", Q, Q, Q, Q, Q, Q)
  1866  	num, err := dORM.Raw(query, 1).Values(&maps)
  1867  	throwFail(t, err)
  1868  	throwFail(t, AssertIs(num, 1))
  1869  	if num == 1 {
  1870  		throwFail(t, AssertIs(maps[0]["user_name"], "slene"))
  1871  	}
  1872  
  1873  	var lists []ParamsList
  1874  	num, err = dORM.Raw(query, 1).ValuesList(&lists)
  1875  	throwFail(t, err)
  1876  	throwFail(t, AssertIs(num, 1))
  1877  	if num == 1 {
  1878  		throwFail(t, AssertIs(lists[0][0], "slene"))
  1879  	}
  1880  
  1881  	query = fmt.Sprintf("SELECT %sprofile_id%s FROM %suser%s ORDER BY %sid%s ASC", Q, Q, Q, Q, Q, Q)
  1882  	var list ParamsList
  1883  	num, err = dORM.Raw(query).ValuesFlat(&list)
  1884  	throwFail(t, err)
  1885  	throwFail(t, AssertIs(num, 3))
  1886  	if num == 3 {
  1887  		throwFail(t, AssertIs(list[0], "2"))
  1888  		throwFail(t, AssertIs(list[1], "3"))
  1889  		throwFail(t, AssertIs(list[2], nil))
  1890  	}
  1891  }
  1892  
  1893  func TestRawPrepare(t *testing.T) {
  1894  	switch {
  1895  	case IsMysql || IsSqlite:
  1896  
  1897  		pre, err := dORM.Raw("INSERT INTO tag (name) VALUES (?)").Prepare()
  1898  		throwFail(t, err)
  1899  		if pre != nil {
  1900  			r, err := pre.Exec("name1")
  1901  			throwFail(t, err)
  1902  
  1903  			tid, err := r.LastInsertId()
  1904  			throwFail(t, err)
  1905  			throwFail(t, AssertIs(tid > 0, true))
  1906  
  1907  			r, err = pre.Exec("name2")
  1908  			throwFail(t, err)
  1909  
  1910  			id, err := r.LastInsertId()
  1911  			throwFail(t, err)
  1912  			throwFail(t, AssertIs(id, tid+1))
  1913  
  1914  			r, err = pre.Exec("name3")
  1915  			throwFail(t, err)
  1916  
  1917  			id, err = r.LastInsertId()
  1918  			throwFail(t, err)
  1919  			throwFail(t, AssertIs(id, tid+2))
  1920  
  1921  			err = pre.Close()
  1922  			throwFail(t, err)
  1923  
  1924  			res, err := dORM.Raw("DELETE FROM tag WHERE name IN (?, ?, ?)", []string{"name1", "name2", "name3"}).Exec()
  1925  			throwFail(t, err)
  1926  
  1927  			num, err := res.RowsAffected()
  1928  			throwFail(t, err)
  1929  			throwFail(t, AssertIs(num, 3))
  1930  		}
  1931  
  1932  	case IsPostgres:
  1933  
  1934  		pre, err := dORM.Raw(`INSERT INTO "tag" ("name") VALUES (?) RETURNING "id"`).Prepare()
  1935  		throwFail(t, err)
  1936  		if pre != nil {
  1937  			_, err := pre.Exec("name1")
  1938  			throwFail(t, err)
  1939  
  1940  			_, err = pre.Exec("name2")
  1941  			throwFail(t, err)
  1942  
  1943  			_, err = pre.Exec("name3")
  1944  			throwFail(t, err)
  1945  
  1946  			err = pre.Close()
  1947  			throwFail(t, err)
  1948  
  1949  			res, err := dORM.Raw(`DELETE FROM "tag" WHERE "name" IN (?, ?, ?)`, []string{"name1", "name2", "name3"}).Exec()
  1950  			throwFail(t, err)
  1951  
  1952  			if err == nil {
  1953  				num, err := res.RowsAffected()
  1954  				throwFail(t, err)
  1955  				throwFail(t, AssertIs(num, 3))
  1956  			}
  1957  		}
  1958  	}
  1959  }
  1960  
  1961  func TestUpdate(t *testing.T) {
  1962  	qs := dORM.QueryTable("user")
  1963  	num, err := qs.Filter("user_name", "slene").Filter("is_staff", false).Update(Params{
  1964  		"is_staff":  true,
  1965  		"is_active": true,
  1966  	})
  1967  	throwFail(t, err)
  1968  	throwFail(t, AssertIs(num, 1))
  1969  
  1970  	// with join
  1971  	num, err = qs.Filter("user_name", "slene").Filter("profile__age", 28).Filter("is_staff", true).Update(Params{
  1972  		"is_staff": false,
  1973  	})
  1974  	throwFail(t, err)
  1975  	throwFail(t, AssertIs(num, 1))
  1976  
  1977  	num, err = qs.Filter("user_name", "slene").Update(Params{
  1978  		"Nums": ColValue(ColAdd, 100),
  1979  	})
  1980  	throwFail(t, err)
  1981  	throwFail(t, AssertIs(num, 1))
  1982  
  1983  	num, err = qs.Filter("user_name", "slene").Update(Params{
  1984  		"Nums": ColValue(ColMinus, 50),
  1985  	})
  1986  	throwFail(t, err)
  1987  	throwFail(t, AssertIs(num, 1))
  1988  
  1989  	num, err = qs.Filter("user_name", "slene").Update(Params{
  1990  		"Nums": ColValue(ColMultiply, 3),
  1991  	})
  1992  	throwFail(t, err)
  1993  	throwFail(t, AssertIs(num, 1))
  1994  
  1995  	num, err = qs.Filter("user_name", "slene").Update(Params{
  1996  		"Nums": ColValue(ColExcept, 5),
  1997  	})
  1998  	throwFail(t, err)
  1999  	throwFail(t, AssertIs(num, 1))
  2000  
  2001  	user := User{UserName: "slene"}
  2002  	err = dORM.Read(&user, "UserName")
  2003  	throwFail(t, err)
  2004  	throwFail(t, AssertIs(user.Nums, 30))
  2005  }
  2006  
  2007  func TestDelete(t *testing.T) {
  2008  	qs := dORM.QueryTable("user_profile")
  2009  	num, err := qs.Filter("user__user_name", "slene").Delete()
  2010  	throwFail(t, err)
  2011  	throwFail(t, AssertIs(num, 1))
  2012  
  2013  	qs = dORM.QueryTable("user")
  2014  	num, err = qs.Filter("user_name", "slene").Filter("profile__isnull", true).Count()
  2015  	throwFail(t, err)
  2016  	throwFail(t, AssertIs(num, 1))
  2017  
  2018  	qs = dORM.QueryTable("comment")
  2019  	num, err = qs.Count()
  2020  	throwFail(t, err)
  2021  	throwFail(t, AssertIs(num, 6))
  2022  
  2023  	qs = dORM.QueryTable("post")
  2024  	num, err = qs.Filter("Id", 3).Delete()
  2025  	throwFail(t, err)
  2026  	throwFail(t, AssertIs(num, 1))
  2027  
  2028  	qs = dORM.QueryTable("comment")
  2029  	num, err = qs.Count()
  2030  	throwFail(t, err)
  2031  	throwFail(t, AssertIs(num, 4))
  2032  
  2033  	qs = dORM.QueryTable("comment")
  2034  	num, err = qs.Filter("Post__User", 3).Delete()
  2035  	throwFail(t, err)
  2036  	throwFail(t, AssertIs(num, 3))
  2037  
  2038  	qs = dORM.QueryTable("comment")
  2039  	num, err = qs.Count()
  2040  	throwFail(t, err)
  2041  	throwFail(t, AssertIs(num, 1))
  2042  }
  2043  
  2044  func TestTransaction(t *testing.T) {
  2045  	// this test worked when database support transaction
  2046  
  2047  	o := NewOrm()
  2048  	err := o.Begin()
  2049  	throwFail(t, err)
  2050  
  2051  	var names = []string{"1", "2", "3"}
  2052  
  2053  	var tag Tag
  2054  	tag.Name = names[0]
  2055  	id, err := o.Insert(&tag)
  2056  	throwFail(t, err)
  2057  	throwFail(t, AssertIs(id > 0, true))
  2058  
  2059  	num, err := o.QueryTable("tag").Filter("name", "golang").Update(Params{"name": names[1]})
  2060  	throwFail(t, err)
  2061  	throwFail(t, AssertIs(num, 1))
  2062  
  2063  	switch {
  2064  	case IsMysql || IsSqlite:
  2065  		res, err := o.Raw("INSERT INTO tag (name) VALUES (?)", names[2]).Exec()
  2066  		throwFail(t, err)
  2067  		if err == nil {
  2068  			id, err = res.LastInsertId()
  2069  			throwFail(t, err)
  2070  			throwFail(t, AssertIs(id > 0, true))
  2071  		}
  2072  	}
  2073  
  2074  	err = o.Rollback()
  2075  	throwFail(t, err)
  2076  
  2077  	num, err = o.QueryTable("tag").Filter("name__in", names).Count()
  2078  	throwFail(t, err)
  2079  	throwFail(t, AssertIs(num, 0))
  2080  
  2081  	err = o.Begin()
  2082  	throwFail(t, err)
  2083  
  2084  	tag.Name = "commit"
  2085  	id, err = o.Insert(&tag)
  2086  	throwFail(t, err)
  2087  	throwFail(t, AssertIs(id > 0, true))
  2088  
  2089  	o.Commit()
  2090  	throwFail(t, err)
  2091  
  2092  	num, err = o.QueryTable("tag").Filter("name", "commit").Delete()
  2093  	throwFail(t, err)
  2094  	throwFail(t, AssertIs(num, 1))
  2095  
  2096  }
  2097  
  2098  func TestTransactionIsolationLevel(t *testing.T) {
  2099  	// this test worked when database support transaction isolation level
  2100  	if IsSqlite {
  2101  		return
  2102  	}
  2103  
  2104  	o1 := NewOrm()
  2105  	o2 := NewOrm()
  2106  
  2107  	// start two transaction with isolation level repeatable read
  2108  	err := o1.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
  2109  	throwFail(t, err)
  2110  	err = o2.BeginTx(context.Background(), &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
  2111  	throwFail(t, err)
  2112  
  2113  	// o1 insert tag
  2114  	var tag Tag
  2115  	tag.Name = "test-transaction"
  2116  	id, err := o1.Insert(&tag)
  2117  	throwFail(t, err)
  2118  	throwFail(t, AssertIs(id > 0, true))
  2119  
  2120  	// o2 query tag table, no result
  2121  	num, err := o2.QueryTable("tag").Filter("name", "test-transaction").Count()
  2122  	throwFail(t, err)
  2123  	throwFail(t, AssertIs(num, 0))
  2124  
  2125  	// o1 commit
  2126  	o1.Commit()
  2127  
  2128  	// o2 query tag table, still no result
  2129  	num, err = o2.QueryTable("tag").Filter("name", "test-transaction").Count()
  2130  	throwFail(t, err)
  2131  	throwFail(t, AssertIs(num, 0))
  2132  
  2133  	// o2 commit and query tag table, get the result
  2134  	o2.Commit()
  2135  	num, err = o2.QueryTable("tag").Filter("name", "test-transaction").Count()
  2136  	throwFail(t, err)
  2137  	throwFail(t, AssertIs(num, 1))
  2138  
  2139  	num, err = o1.QueryTable("tag").Filter("name", "test-transaction").Delete()
  2140  	throwFail(t, err)
  2141  	throwFail(t, AssertIs(num, 1))
  2142  }
  2143  
  2144  func TestBeginTxWithContextCanceled(t *testing.T) {
  2145  	o := NewOrm()
  2146  	ctx, cancel := context.WithCancel(context.Background())
  2147  	o.BeginTx(ctx, nil)
  2148  	id, err := o.Insert(&Tag{Name: "test-context"})
  2149  	throwFail(t, err)
  2150  	throwFail(t, AssertIs(id > 0, true))
  2151  
  2152  	// cancel the context before commit to make it error
  2153  	cancel()
  2154  	err = o.Commit()
  2155  	throwFail(t, AssertIs(err, context.Canceled))
  2156  }
  2157  
  2158  func TestReadOrCreate(t *testing.T) {
  2159  	u := &User{
  2160  		UserName: "Kyle",
  2161  		Email:    "kylemcc@gmail.com",
  2162  		Password: "other_pass",
  2163  		Status:   7,
  2164  		IsStaff:  false,
  2165  		IsActive: true,
  2166  	}
  2167  
  2168  	created, pk, err := dORM.ReadOrCreate(u, "UserName")
  2169  	throwFail(t, err)
  2170  	throwFail(t, AssertIs(created, true))
  2171  	throwFail(t, AssertIs(u.ID, pk))
  2172  	throwFail(t, AssertIs(u.UserName, "Kyle"))
  2173  	throwFail(t, AssertIs(u.Email, "kylemcc@gmail.com"))
  2174  	throwFail(t, AssertIs(u.Password, "other_pass"))
  2175  	throwFail(t, AssertIs(u.Status, 7))
  2176  	throwFail(t, AssertIs(u.IsStaff, false))
  2177  	throwFail(t, AssertIs(u.IsActive, true))
  2178  	throwFail(t, AssertIs(u.Created.In(DefaultTimeLoc), u.Created.In(DefaultTimeLoc), testDate))
  2179  	throwFail(t, AssertIs(u.Updated.In(DefaultTimeLoc), u.Updated.In(DefaultTimeLoc), testDateTime))
  2180  
  2181  	nu := &User{UserName: u.UserName, Email: "someotheremail@gmail.com"}
  2182  	created, pk, err = dORM.ReadOrCreate(nu, "UserName")
  2183  	throwFail(t, err)
  2184  	throwFail(t, AssertIs(created, false))
  2185  	throwFail(t, AssertIs(nu.ID, u.ID))
  2186  	throwFail(t, AssertIs(pk, u.ID))
  2187  	throwFail(t, AssertIs(nu.UserName, u.UserName))
  2188  	throwFail(t, AssertIs(nu.Email, u.Email)) // should contain the value in the table, not the one specified above
  2189  	throwFail(t, AssertIs(nu.Password, u.Password))
  2190  	throwFail(t, AssertIs(nu.Status, u.Status))
  2191  	throwFail(t, AssertIs(nu.IsStaff, u.IsStaff))
  2192  	throwFail(t, AssertIs(nu.IsActive, u.IsActive))
  2193  
  2194  	dORM.Delete(u)
  2195  }
  2196  
  2197  func TestInLine(t *testing.T) {
  2198  	name := "inline"
  2199  	email := "hello@go.com"
  2200  	inline := NewInLine()
  2201  	inline.Name = name
  2202  	inline.Email = email
  2203  
  2204  	id, err := dORM.Insert(inline)
  2205  	throwFail(t, err)
  2206  	throwFail(t, AssertIs(id, 1))
  2207  
  2208  	il := NewInLine()
  2209  	il.ID = 1
  2210  	err = dORM.Read(il)
  2211  	throwFail(t, err)
  2212  
  2213  	throwFail(t, AssertIs(il.Name, name))
  2214  	throwFail(t, AssertIs(il.Email, email))
  2215  	throwFail(t, AssertIs(il.Created.In(DefaultTimeLoc), inline.Created.In(DefaultTimeLoc), testDate))
  2216  	throwFail(t, AssertIs(il.Updated.In(DefaultTimeLoc), inline.Updated.In(DefaultTimeLoc), testDateTime))
  2217  }
  2218  
  2219  func TestInLineOneToOne(t *testing.T) {
  2220  	name := "121"
  2221  	email := "121@go.com"
  2222  	inline := NewInLine()
  2223  	inline.Name = name
  2224  	inline.Email = email
  2225  
  2226  	id, err := dORM.Insert(inline)
  2227  	throwFail(t, err)
  2228  	throwFail(t, AssertIs(id, 2))
  2229  
  2230  	note := "one2one"
  2231  	il121 := NewInLineOneToOne()
  2232  	il121.Note = note
  2233  	il121.InLine = inline
  2234  	_, err = dORM.Insert(il121)
  2235  	throwFail(t, err)
  2236  	throwFail(t, AssertIs(il121.ID, 1))
  2237  
  2238  	il := NewInLineOneToOne()
  2239  	err = dORM.QueryTable(il).Filter("Id", 1).RelatedSel().One(il)
  2240  
  2241  	throwFail(t, err)
  2242  	throwFail(t, AssertIs(il.Note, note))
  2243  	throwFail(t, AssertIs(il.InLine.ID, id))
  2244  	throwFail(t, AssertIs(il.InLine.Name, name))
  2245  	throwFail(t, AssertIs(il.InLine.Email, email))
  2246  
  2247  	rinline := NewInLine()
  2248  	err = dORM.QueryTable(rinline).Filter("InLineOneToOne__Id", 1).One(rinline)
  2249  
  2250  	throwFail(t, err)
  2251  	throwFail(t, AssertIs(rinline.ID, id))
  2252  	throwFail(t, AssertIs(rinline.Name, name))
  2253  	throwFail(t, AssertIs(rinline.Email, email))
  2254  }
  2255  
  2256  func TestIntegerPk(t *testing.T) {
  2257  	its := []IntegerPk{
  2258  		{ID: math.MinInt64, Value: "-"},
  2259  		{ID: 0, Value: "0"},
  2260  		{ID: math.MaxInt64, Value: "+"},
  2261  	}
  2262  
  2263  	num, err := dORM.InsertMulti(len(its), its)
  2264  	throwFail(t, err)
  2265  	throwFail(t, AssertIs(num, len(its)))
  2266  
  2267  	for _, intPk := range its {
  2268  		out := IntegerPk{ID: intPk.ID}
  2269  		err = dORM.Read(&out)
  2270  		throwFail(t, err)
  2271  		throwFail(t, AssertIs(out.Value, intPk.Value))
  2272  	}
  2273  
  2274  	num, err = dORM.InsertMulti(1, []*IntegerPk{{
  2275  		ID: 1, Value: "ok",
  2276  	}})
  2277  	throwFail(t, err)
  2278  	throwFail(t, AssertIs(num, 1))
  2279  }
  2280  
  2281  func TestInsertAuto(t *testing.T) {
  2282  	u := &User{
  2283  		UserName: "autoPre",
  2284  		Email:    "autoPre@gmail.com",
  2285  	}
  2286  
  2287  	id, err := dORM.Insert(u)
  2288  	throwFail(t, err)
  2289  
  2290  	id += 100
  2291  	su := &User{
  2292  		ID:       int(id),
  2293  		UserName: "auto",
  2294  		Email:    "auto@gmail.com",
  2295  	}
  2296  
  2297  	nid, err := dORM.Insert(su)
  2298  	throwFail(t, err)
  2299  	throwFail(t, AssertIs(nid, id))
  2300  
  2301  	users := []User{
  2302  		{ID: int(id + 100), UserName: "auto_100"},
  2303  		{ID: int(id + 110), UserName: "auto_110"},
  2304  		{ID: int(id + 120), UserName: "auto_120"},
  2305  	}
  2306  	num, err := dORM.InsertMulti(100, users)
  2307  	throwFail(t, err)
  2308  	throwFail(t, AssertIs(num, 3))
  2309  
  2310  	u = &User{
  2311  		UserName: "auto_121",
  2312  	}
  2313  
  2314  	nid, err = dORM.Insert(u)
  2315  	throwFail(t, err)
  2316  	throwFail(t, AssertIs(nid, id+120+1))
  2317  }
  2318  
  2319  func TestUintPk(t *testing.T) {
  2320  	name := "go"
  2321  	u := &UintPk{
  2322  		ID:   8,
  2323  		Name: name,
  2324  	}
  2325  
  2326  	created, _, err := dORM.ReadOrCreate(u, "ID")
  2327  	throwFail(t, err)
  2328  	throwFail(t, AssertIs(created, true))
  2329  	throwFail(t, AssertIs(u.Name, name))
  2330  
  2331  	nu := &UintPk{ID: 8}
  2332  	created, pk, err := dORM.ReadOrCreate(nu, "ID")
  2333  	throwFail(t, err)
  2334  	throwFail(t, AssertIs(created, false))
  2335  	throwFail(t, AssertIs(nu.ID, u.ID))
  2336  	throwFail(t, AssertIs(pk, u.ID))
  2337  	throwFail(t, AssertIs(nu.Name, name))
  2338  
  2339  	dORM.Delete(u)
  2340  }
  2341  
  2342  func TestPtrPk(t *testing.T) {
  2343  	parent := &IntegerPk{ID: 10, Value: "10"}
  2344  
  2345  	id, _ := dORM.Insert(parent)
  2346  	if !IsMysql {
  2347  		// MySql does not support last_insert_id in this case: see #2382
  2348  		throwFail(t, AssertIs(id, 10))
  2349  	}
  2350  
  2351  	ptr := PtrPk{ID: parent, Positive: true}
  2352  	num, err := dORM.InsertMulti(2, []PtrPk{ptr})
  2353  	throwFail(t, err)
  2354  	throwFail(t, AssertIs(num, 1))
  2355  	throwFail(t, AssertIs(ptr.ID, parent))
  2356  
  2357  	nptr := &PtrPk{ID: parent}
  2358  	created, pk, err := dORM.ReadOrCreate(nptr, "ID")
  2359  	throwFail(t, err)
  2360  	throwFail(t, AssertIs(created, false))
  2361  	throwFail(t, AssertIs(pk, 10))
  2362  	throwFail(t, AssertIs(nptr.ID, parent))
  2363  	throwFail(t, AssertIs(nptr.Positive, true))
  2364  
  2365  	nptr = &PtrPk{Positive: true}
  2366  	created, pk, err = dORM.ReadOrCreate(nptr, "Positive")
  2367  	throwFail(t, err)
  2368  	throwFail(t, AssertIs(created, false))
  2369  	throwFail(t, AssertIs(pk, 10))
  2370  	throwFail(t, AssertIs(nptr.ID, parent))
  2371  
  2372  	nptr.Positive = false
  2373  	num, err = dORM.Update(nptr)
  2374  	throwFail(t, err)
  2375  	throwFail(t, AssertIs(num, 1))
  2376  	throwFail(t, AssertIs(nptr.ID, parent))
  2377  	throwFail(t, AssertIs(nptr.Positive, false))
  2378  
  2379  	num, err = dORM.Delete(nptr)
  2380  	throwFail(t, err)
  2381  	throwFail(t, AssertIs(num, 1))
  2382  }
  2383  
  2384  func TestSnake(t *testing.T) {
  2385  	cases := map[string]string{
  2386  		"i":           "i",
  2387  		"I":           "i",
  2388  		"iD":          "i_d",
  2389  		"ID":          "i_d",
  2390  		"NO":          "n_o",
  2391  		"NOO":         "n_o_o",
  2392  		"NOOooOOoo":   "n_o_ooo_o_ooo",
  2393  		"OrderNO":     "order_n_o",
  2394  		"tagName":     "tag_name",
  2395  		"tag_Name":    "tag__name",
  2396  		"tag_name":    "tag_name",
  2397  		"_tag_name":   "_tag_name",
  2398  		"tag_666name": "tag_666name",
  2399  		"tag_666Name": "tag_666_name",
  2400  	}
  2401  	for name, want := range cases {
  2402  		got := snakeString(name)
  2403  		throwFail(t, AssertIs(got, want))
  2404  	}
  2405  }
  2406  
  2407  func TestIgnoreCaseTag(t *testing.T) {
  2408  	type testTagModel struct {
  2409  		ID     int    `orm:"pk"`
  2410  		NOO    string `orm:"column(n)"`
  2411  		Name01 string `orm:"NULL"`
  2412  		Name02 string `orm:"COLUMN(Name)"`
  2413  		Name03 string `orm:"Column(name)"`
  2414  	}
  2415  	modelCache.clean()
  2416  	RegisterModel(&testTagModel{})
  2417  	info, ok := modelCache.get("test_tag_model")
  2418  	throwFail(t, AssertIs(ok, true))
  2419  	throwFail(t, AssertNot(info, nil))
  2420  	if t == nil {
  2421  		return
  2422  	}
  2423  	throwFail(t, AssertIs(info.fields.GetByName("NOO").column, "n"))
  2424  	throwFail(t, AssertIs(info.fields.GetByName("Name01").null, true))
  2425  	throwFail(t, AssertIs(info.fields.GetByName("Name02").column, "Name"))
  2426  	throwFail(t, AssertIs(info.fields.GetByName("Name03").column, "name"))
  2427  }
  2428  
  2429  func TestInsertOrUpdate(t *testing.T) {
  2430  	RegisterModel(new(User))
  2431  	user := User{UserName: "unique_username133", Status: 1, Password: "o"}
  2432  	user1 := User{UserName: "unique_username133", Status: 2, Password: "o"}
  2433  	user2 := User{UserName: "unique_username133", Status: 3, Password: "oo"}
  2434  	dORM.Insert(&user)
  2435  	test := User{UserName: "unique_username133"}
  2436  	fmt.Println(dORM.Driver().Name())
  2437  	if dORM.Driver().Name() == "sqlite3" {
  2438  		fmt.Println("sqlite3 is nonsupport")
  2439  		return
  2440  	}
  2441  	//test1
  2442  	_, err := dORM.InsertOrUpdate(&user1, "user_name")
  2443  	if err != nil {
  2444  		fmt.Println(err)
  2445  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2446  		} else {
  2447  			throwFailNow(t, err)
  2448  		}
  2449  	} else {
  2450  		dORM.Read(&test, "user_name")
  2451  		throwFailNow(t, AssertIs(user1.Status, test.Status))
  2452  	}
  2453  	//test2
  2454  	_, err = dORM.InsertOrUpdate(&user2, "user_name")
  2455  	if err != nil {
  2456  		fmt.Println(err)
  2457  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2458  		} else {
  2459  			throwFailNow(t, err)
  2460  		}
  2461  	} else {
  2462  		dORM.Read(&test, "user_name")
  2463  		throwFailNow(t, AssertIs(user2.Status, test.Status))
  2464  		throwFailNow(t, AssertIs(user2.Password, strings.TrimSpace(test.Password)))
  2465  	}
  2466  
  2467  	//postgres ON CONFLICT DO UPDATE SET can`t use colu=colu+values
  2468  	if IsPostgres {
  2469  		return
  2470  	}
  2471  	//test3 +
  2472  	_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status+1")
  2473  	if err != nil {
  2474  		fmt.Println(err)
  2475  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2476  		} else {
  2477  			throwFailNow(t, err)
  2478  		}
  2479  	} else {
  2480  		dORM.Read(&test, "user_name")
  2481  		throwFailNow(t, AssertIs(user2.Status+1, test.Status))
  2482  	}
  2483  	//test4 -
  2484  	_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status-1")
  2485  	if err != nil {
  2486  		fmt.Println(err)
  2487  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2488  		} else {
  2489  			throwFailNow(t, err)
  2490  		}
  2491  	} else {
  2492  		dORM.Read(&test, "user_name")
  2493  		throwFailNow(t, AssertIs((user2.Status+1)-1, test.Status))
  2494  	}
  2495  	//test5 *
  2496  	_, err = dORM.InsertOrUpdate(&user2, "user_name", "status=status*3")
  2497  	if err != nil {
  2498  		fmt.Println(err)
  2499  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2500  		} else {
  2501  			throwFailNow(t, err)
  2502  		}
  2503  	} else {
  2504  		dORM.Read(&test, "user_name")
  2505  		throwFailNow(t, AssertIs(((user2.Status+1)-1)*3, test.Status))
  2506  	}
  2507  	//test6 /
  2508  	_, err = dORM.InsertOrUpdate(&user2, "user_name", "Status=Status/3")
  2509  	if err != nil {
  2510  		fmt.Println(err)
  2511  		if err.Error() == "postgres version must 9.5 or higher" || err.Error() == "`sqlite3` nonsupport InsertOrUpdate in beego" {
  2512  		} else {
  2513  			throwFailNow(t, err)
  2514  		}
  2515  	} else {
  2516  		dORM.Read(&test, "user_name")
  2517  		throwFailNow(t, AssertIs((((user2.Status+1)-1)*3)/3, test.Status))
  2518  	}
  2519  }