github.com/friesencr/pop/v6@v6.1.6/executors_test.go (about)

     1  package pop
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/gobuffalo/nulls"
     9  	"github.com/gofrs/uuid/v5"
    10  	"github.com/stretchr/testify/require"
    11  )
    12  
    13  func Test_IsZeroOfUnderlyingType(t *testing.T) {
    14  	if PDB == nil {
    15  		t.Skip("skipping integration tests")
    16  	}
    17  	r := require.New(t)
    18  	transaction(func(tx *Connection) {
    19  		car := &ValidatableCar{Name: "VW"}
    20  		r.True(IsZeroOfUnderlyingType(car.ID))
    21  		err := tx.Save(car)
    22  		r.NoError(err)
    23  		r.NotZero(car.ID)
    24  		r.NotZero(car.CreatedAt)
    25  
    26  		r.False(IsZeroOfUnderlyingType(car.ID))
    27  
    28  		var i int
    29  		r.True(IsZeroOfUnderlyingType(i))
    30  		i = 32
    31  		r.False(IsZeroOfUnderlyingType(i))
    32  
    33  		var s string
    34  		r.True(IsZeroOfUnderlyingType(s))
    35  		s = "42"
    36  		r.False(IsZeroOfUnderlyingType(s))
    37  
    38  		var u uuid.UUID
    39  		r.True(IsZeroOfUnderlyingType(u))
    40  		u, err = uuid.NewV1()
    41  		r.NoError(err)
    42  		r.False(IsZeroOfUnderlyingType(u))
    43  	})
    44  }
    45  
    46  func Test_ValidateAndSave(t *testing.T) {
    47  	if PDB == nil {
    48  		t.Skip("skipping integration tests")
    49  	}
    50  	r := require.New(t)
    51  	validationLogs = []string{}
    52  	transaction(func(tx *Connection) {
    53  		car := &ValidatableCar{Name: "VW"}
    54  		verrs, err := tx.ValidateAndSave(car)
    55  		r.NoError(err)
    56  		r.False(verrs.HasAny())
    57  		r.Len(validationLogs, 2)
    58  		r.Equal([]string{"Validate", "ValidateSave"}, validationLogs)
    59  		r.NotZero(car.ID)
    60  		r.NotZero(car.CreatedAt)
    61  
    62  		validationLogs = []string{}
    63  		car = &ValidatableCar{Name: ""}
    64  		verrs, err = tx.ValidateAndSave(car)
    65  		r.NoError(err)
    66  		r.True(verrs.HasAny())
    67  		r.Len(validationLogs, 2)
    68  		errs := verrs.Get("name")
    69  		r.Len(errs, 1)
    70  
    71  		validationLogs = []string{}
    72  		ncar := &NotValidatableCar{Name: ""}
    73  		verrs, err = tx.ValidateAndSave(ncar)
    74  		r.NoError(err)
    75  		r.False(verrs.HasAny())
    76  		r.Len(validationLogs, 0)
    77  	})
    78  }
    79  
    80  func Test_ValidateAndSave_With_Slice(t *testing.T) {
    81  	if PDB == nil {
    82  		t.Skip("skipping integration tests")
    83  	}
    84  	r := require.New(t)
    85  	validationLogs = []string{}
    86  	transaction(func(tx *Connection) {
    87  		car := []ValidatableCar{
    88  			{Name: "VW"},
    89  			{Name: "AU"},
    90  		}
    91  		verrs, err := tx.ValidateAndSave(&car)
    92  		r.NoError(err)
    93  		r.False(verrs.HasAny())
    94  		r.Len(validationLogs, 4)
    95  		r.Equal([]string{"Validate", "ValidateSave", "Validate", "ValidateSave"}, validationLogs)
    96  
    97  		r.NotZero(car[0].ID)
    98  		r.NotZero(car[0].CreatedAt)
    99  		r.NotZero(car[1].ID)
   100  		r.NotZero(car[1].CreatedAt)
   101  
   102  		validationLogs = []string{}
   103  		car = []ValidatableCar{
   104  			{Name: ""},
   105  			{Name: "AU"},
   106  		}
   107  		verrs, err = tx.ValidateAndSave(&car)
   108  		r.NoError(err)
   109  		r.True(verrs.HasAny())
   110  		r.Len(validationLogs, 2)
   111  		errs := verrs.Get("name")
   112  		r.Len(errs, 1)
   113  
   114  		validationLogs = []string{}
   115  		ncar := []NotValidatableCar{
   116  			{Name: ""},
   117  			{Name: "AU"},
   118  		}
   119  		verrs, err = tx.ValidateAndSave(&ncar)
   120  		r.NoError(err)
   121  		r.False(verrs.HasAny())
   122  		r.Len(validationLogs, 0)
   123  	})
   124  }
   125  
   126  func Test_ValidateAndCreate(t *testing.T) {
   127  	if PDB == nil {
   128  		t.Skip("skipping integration tests")
   129  	}
   130  	r := require.New(t)
   131  	validationLogs = []string{}
   132  	transaction(func(tx *Connection) {
   133  		car := &ValidatableCar{Name: "VW"}
   134  		verrs, err := tx.ValidateAndCreate(car)
   135  		r.NoError(err)
   136  		r.False(verrs.HasAny())
   137  		r.Len(validationLogs, 2)
   138  		r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs)
   139  		r.NotZero(car.ID)
   140  		r.NotZero(car.CreatedAt)
   141  
   142  		validationLogs = []string{}
   143  		car = &ValidatableCar{Name: ""}
   144  		verrs, err = tx.ValidateAndSave(car)
   145  		r.NoError(err)
   146  		r.True(verrs.HasAny())
   147  		r.Len(validationLogs, 2)
   148  		errs := verrs.Get("name")
   149  		r.Len(errs, 1)
   150  
   151  		validationLogs = []string{}
   152  		ncar := &NotValidatableCar{Name: ""}
   153  		verrs, err = tx.ValidateAndCreate(ncar)
   154  		r.NoError(err)
   155  		r.False(verrs.HasAny())
   156  		r.Len(validationLogs, 0)
   157  	})
   158  }
   159  
   160  func Test_Create_Single_Incremental_ID(t *testing.T) {
   161  	if PDB == nil {
   162  		t.Skip("skipping integration tests")
   163  	}
   164  	r := require.New(t)
   165  	validationLogs = []string{}
   166  	transaction(func(tx *Connection) {
   167  		singleID := &SingleID{}
   168  		err := tx.Create(singleID)
   169  		r.NoError(err)
   170  		r.NotZero(singleID.ID)
   171  	})
   172  }
   173  
   174  func Test_ValidateAndCreate_With_Slice(t *testing.T) {
   175  	if PDB == nil {
   176  		t.Skip("skipping integration tests")
   177  	}
   178  	r := require.New(t)
   179  	validationLogs = []string{}
   180  	transaction(func(tx *Connection) {
   181  		car := []ValidatableCar{
   182  			{Name: "VW"},
   183  			{Name: "AU"},
   184  		}
   185  		verrs, err := tx.ValidateAndCreate(&car)
   186  		r.NoError(err)
   187  		r.False(verrs.HasAny())
   188  		r.Len(validationLogs, 4)
   189  		r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs)
   190  		r.NotZero(car[0].ID)
   191  		r.NotZero(car[0].CreatedAt)
   192  		r.NotZero(car[1].ID)
   193  		r.NotZero(car[1].CreatedAt)
   194  
   195  		validationLogs = []string{}
   196  		car = []ValidatableCar{
   197  			{Name: ""},
   198  			{Name: "AU"},
   199  		}
   200  		verrs, err = tx.ValidateAndSave(&car)
   201  		r.NoError(err)
   202  		r.True(verrs.HasAny())
   203  		r.Len(validationLogs, 2)
   204  		errs := verrs.Get("name")
   205  		r.Len(errs, 1)
   206  
   207  		validationLogs = []string{}
   208  		ncar := []NotValidatableCar{
   209  			{Name: ""},
   210  			{Name: "AU"},
   211  		}
   212  		verrs, err = tx.ValidateAndCreate(ncar)
   213  		r.NoError(err)
   214  		r.False(verrs.HasAny())
   215  		r.Len(validationLogs, 0)
   216  	})
   217  }
   218  
   219  func Test_ValidateAndUpdate(t *testing.T) {
   220  	if PDB == nil {
   221  		t.Skip("skipping integration tests")
   222  	}
   223  	r := require.New(t)
   224  	validationLogs = []string{}
   225  	transaction(func(tx *Connection) {
   226  		car := &ValidatableCar{Name: "VW"}
   227  		verrs, err := tx.ValidateAndCreate(car)
   228  		r.NoError(err)
   229  		r.False(verrs.HasAny())
   230  		r.Len(validationLogs, 2)
   231  		r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs)
   232  		r.NotZero(car.ID)
   233  		r.NotZero(car.CreatedAt)
   234  
   235  		validationLogs = []string{}
   236  		car.Name = ""
   237  		verrs, err = tx.ValidateAndUpdate(car)
   238  		r.NoError(err)
   239  		r.True(verrs.HasAny())
   240  		r.Len(validationLogs, 2)
   241  		errs := verrs.Get("name")
   242  		r.Len(errs, 1)
   243  
   244  		validationLogs = []string{}
   245  		ncar := &NotValidatableCar{Name: ""}
   246  		verrs, err = tx.ValidateAndCreate(ncar)
   247  		r.NoError(err)
   248  		r.False(verrs.HasAny())
   249  		r.Len(validationLogs, 0)
   250  
   251  		validationLogs = []string{}
   252  		ncar.Name = ""
   253  		verrs, err = tx.ValidateAndUpdate(ncar)
   254  		r.NoError(err)
   255  		r.False(verrs.HasAny())
   256  		r.Len(validationLogs, 0)
   257  	})
   258  }
   259  
   260  func Test_ValidateAndUpdate_With_Slice(t *testing.T) {
   261  	if PDB == nil {
   262  		t.Skip("skipping integration tests")
   263  	}
   264  	r := require.New(t)
   265  	validationLogs = []string{}
   266  	transaction(func(tx *Connection) {
   267  		car := []ValidatableCar{
   268  			{Name: "VW"},
   269  			{Name: "AU"},
   270  		}
   271  		verrs, err := tx.ValidateAndCreate(&car)
   272  		r.NoError(err)
   273  		r.False(verrs.HasAny())
   274  		r.Len(validationLogs, 4)
   275  		r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs)
   276  		r.NotZero(car[0].ID)
   277  		r.NotZero(car[0].CreatedAt)
   278  		r.NotZero(car[1].ID)
   279  		r.NotZero(car[1].CreatedAt)
   280  
   281  		validationLogs = []string{}
   282  		car[0].Name = ""
   283  		verrs, err = tx.ValidateAndUpdate(&car)
   284  		r.NoError(err)
   285  		r.True(verrs.HasAny())
   286  		r.Len(validationLogs, 2)
   287  		errs := verrs.Get("name")
   288  		r.Len(errs, 1)
   289  
   290  		validationLogs = []string{}
   291  		ncar := []NotValidatableCar{
   292  			{Name: ""},
   293  			{Name: "AU"},
   294  		}
   295  		verrs, err = tx.ValidateAndCreate(&ncar)
   296  		r.NoError(err)
   297  		r.False(verrs.HasAny())
   298  		r.Len(validationLogs, 0)
   299  
   300  		validationLogs = []string{}
   301  		ncar[1].Name = ""
   302  		verrs, err = tx.ValidateAndUpdate(&ncar)
   303  		r.NoError(err)
   304  		r.False(verrs.HasAny())
   305  		r.Len(validationLogs, 0)
   306  	})
   307  }
   308  
   309  func Test_Exec(t *testing.T) {
   310  	if PDB == nil {
   311  		t.Skip("skipping integration tests")
   312  	}
   313  	transaction(func(tx *Connection) {
   314  		r := require.New(t)
   315  
   316  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   317  		r.NoError(tx.Create(&user))
   318  
   319  		ctx, _ := tx.Count(user)
   320  		r.Equal(1, ctx)
   321  
   322  		q := tx.RawQuery("delete from users where id = ?", user.ID)
   323  		err := q.Exec()
   324  		r.NoError(err)
   325  
   326  		ctx, _ = tx.Count(user)
   327  		r.Equal(0, ctx)
   328  	})
   329  }
   330  
   331  func Test_ExecCount(t *testing.T) {
   332  	if PDB == nil {
   333  		t.Skip("skipping integration tests")
   334  	}
   335  	transaction(func(tx *Connection) {
   336  		r := require.New(t)
   337  
   338  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   339  		tx.Create(&user)
   340  
   341  		ctx, _ := tx.Count(user)
   342  		r.Equal(1, ctx)
   343  
   344  		q := tx.RawQuery("delete from users where id = ?", user.ID)
   345  		count, err := q.ExecWithCount()
   346  		r.NoError(err)
   347  
   348  		r.Equal(1, count)
   349  
   350  		ctx, _ = tx.Count(user)
   351  		r.Equal(0, ctx)
   352  	})
   353  }
   354  
   355  func Test_Save(t *testing.T) {
   356  	if PDB == nil {
   357  		t.Skip("skipping integration tests")
   358  	}
   359  	r := require.New(t)
   360  	transaction(func(tx *Connection) {
   361  		u := &User{Name: nulls.NewString("Mark")}
   362  		r.Zero(u.ID)
   363  		r.NoError(tx.Save(u))
   364  		r.NotZero(u.ID)
   365  
   366  		uat := u.UpdatedAt.UnixNano()
   367  
   368  		r.NoError(tx.Save(u))
   369  		time.Sleep(1 * time.Second)
   370  		r.NotEqual(uat, u.UpdatedAt.UnixNano())
   371  	})
   372  }
   373  
   374  func Test_Save_With_Slice(t *testing.T) {
   375  	if PDB == nil {
   376  		t.Skip("skipping integration tests")
   377  	}
   378  	r := require.New(t)
   379  	transaction(func(tx *Connection) {
   380  		u := Users{
   381  			{Name: nulls.NewString("Mark")},
   382  			{Name: nulls.NewString("Larry")},
   383  		}
   384  		r.Zero(u[0].ID)
   385  		r.Zero(u[1].ID)
   386  
   387  		r.NoError(tx.Save(&u))
   388  		r.NotZero(u[0].ID)
   389  		r.NotZero(u[1].ID)
   390  
   391  		uat := u[0].UpdatedAt.UnixNano()
   392  
   393  		r.NoError(tx.Save(u))
   394  		r.NotEqual(uat, u[0].UpdatedAt.UnixNano())
   395  	})
   396  }
   397  
   398  func Test_Create(t *testing.T) {
   399  	if PDB == nil {
   400  		t.Skip("skipping integration tests")
   401  	}
   402  	transaction(func(tx *Connection) {
   403  		r := require.New(t)
   404  
   405  		count, _ := tx.Count(&User{})
   406  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   407  		err := tx.Create(&user)
   408  		r.NoError(err)
   409  		r.NotEqual(0, user.ID)
   410  
   411  		ctx, _ := tx.Count(&User{})
   412  		r.Equal(count+1, ctx)
   413  
   414  		u := User{}
   415  		q := tx.Where("name = ?", "Mark 'Awesome' Bates")
   416  		err = q.First(&u)
   417  		r.NoError(err)
   418  		r.Equal("Mark 'Awesome' Bates", user.Name.String)
   419  	})
   420  }
   421  
   422  func Test_Create_stringID(t *testing.T) {
   423  	if PDB == nil {
   424  		t.Skip("skipping integration tests")
   425  	}
   426  	transaction(func(tx *Connection) {
   427  		r := require.New(t)
   428  
   429  		count, err := tx.Count(&Label{})
   430  		r.NoError(err)
   431  		label := Label{ID: "red"}
   432  		err = tx.Create(&label)
   433  		r.NoError(err)
   434  		r.Equal("red", label.ID)
   435  
   436  		ctx, err := tx.Count(&Label{})
   437  		r.NoError(err)
   438  		r.Equal(count+1, ctx)
   439  
   440  		l := Label{}
   441  		err = tx.Find(&l, "red")
   442  		r.NoError(err)
   443  		r.Equal("red", l.ID)
   444  	})
   445  }
   446  
   447  func Test_Create_With_Slice(t *testing.T) {
   448  	if PDB == nil {
   449  		t.Skip("skipping integration tests")
   450  	}
   451  	transaction(func(tx *Connection) {
   452  		r := require.New(t)
   453  
   454  		count, _ := tx.Count(&User{})
   455  		users := Users{
   456  			{Name: nulls.NewString("Mark Bates")},
   457  			{Name: nulls.NewString("Larry M. Jordan")},
   458  			{Name: nulls.NewString("Pop")},
   459  		}
   460  		err := tx.Create(&users)
   461  		r.NoError(err)
   462  
   463  		ctx, _ := tx.Count(&User{})
   464  		r.Equal(count+3, ctx)
   465  	})
   466  }
   467  
   468  func Test_Create_With_Non_ID_PK(t *testing.T) {
   469  	if PDB == nil {
   470  		t.Skip("skipping integration tests")
   471  	}
   472  	transaction(func(tx *Connection) {
   473  		r := require.New(t)
   474  
   475  		count, _ := tx.Count(&CrookedColour{})
   476  		djs := []CrookedColour{
   477  			{Name: "Phil Slabber"},
   478  			{Name: "Leon Debaughn"},
   479  			{Name: "Liam Merrett-Park"},
   480  		}
   481  		err := tx.Create(&djs)
   482  		r.NoError(err)
   483  
   484  		ctx, _ := tx.Count(&CrookedColour{})
   485  		r.Equal(count+3, ctx)
   486  		r.NotEqual(djs[0].ID, djs[1].ID)
   487  		r.NotEqual(djs[1].ID, djs[2].ID)
   488  	})
   489  }
   490  
   491  func Test_Create_With_Non_ID_PK_String(t *testing.T) {
   492  	if PDB == nil {
   493  		t.Skip("skipping integration tests")
   494  	}
   495  	transaction(func(tx *Connection) {
   496  		r := require.New(t)
   497  
   498  		count, _ := tx.Count(&CrookedSong{})
   499  		djs := []CrookedSong{
   500  			{ID: "Flow"},
   501  			{ID: "Do It Like You"},
   502  			{ID: "I C Light"},
   503  		}
   504  		err := tx.Create(&djs)
   505  		r.NoError(err)
   506  
   507  		ctx, _ := tx.Count(&CrookedSong{})
   508  		r.Equal(count+3, ctx)
   509  		r.NotEqual(djs[0].ID, djs[1].ID)
   510  		r.NotEqual(djs[1].ID, djs[2].ID)
   511  	})
   512  }
   513  
   514  func Test_Create_Non_PK_ID(t *testing.T) {
   515  	if PDB == nil {
   516  		t.Skip("skipping integration tests")
   517  	}
   518  	transaction(func(tx *Connection) {
   519  		r := require.New(t)
   520  
   521  		r.NoError(tx.Create(&NonStandardID{OutfacingID: "make sure the tested entry does not have pk=0"}))
   522  
   523  		count, err := tx.Count(&NonStandardID{})
   524  		r.NoError(err)
   525  		entry := &NonStandardID{
   526  			OutfacingID: "beautiful to the outside ID",
   527  		}
   528  		r.NoError(tx.Create(entry))
   529  
   530  		ctx, err := tx.Count(&NonStandardID{})
   531  		r.NoError(err)
   532  		r.Equal(count+1, ctx)
   533  		r.NotZero(entry.ID)
   534  	})
   535  }
   536  
   537  func Test_Create_Parallel(t *testing.T) {
   538  	if PDB == nil {
   539  		t.Skip("skipping integration tests")
   540  	}
   541  	for i := 0; i < 5; i++ {
   542  		i := i
   543  		t.Run(fmt.Sprintf("case=%d", i), func(t *testing.T) {
   544  			t.Parallel()
   545  			require.NoError(t, PDB.Create(&CrookedColour{Name: fmt.Sprintf("Singer %d", i)}))
   546  		})
   547  	}
   548  }
   549  
   550  func Test_Embedded_Struct(t *testing.T) {
   551  	if PDB == nil {
   552  		t.Skip("skipping integration tests")
   553  	}
   554  	transaction(func(tx *Connection) {
   555  		r := require.New(t)
   556  
   557  		entry := &EmbeddingStruct{
   558  			InnerStruct:     InnerStruct{},
   559  			AdditionalField: "I am also important!",
   560  		}
   561  		r.NoError(tx.Create(entry))
   562  
   563  		var actual EmbeddingStruct
   564  		r.NoError(tx.Find(&actual, entry.ID))
   565  		r.Equal(entry.AdditionalField, actual.AdditionalField)
   566  
   567  		entry.AdditionalField = entry.AdditionalField + " updated"
   568  		r.NoError(tx.Update(entry))
   569  
   570  		r.NoError(tx.Find(&actual, entry.ID))
   571  		r.Equal(entry.AdditionalField, actual.AdditionalField)
   572  
   573  		entry.AdditionalField = entry.AdditionalField + "; updated again"
   574  		count, err := tx.Where("id = ?", entry.ID).UpdateQuery(entry, "additional_field")
   575  		r.NoError(err)
   576  		require.Equal(t, int64(1), count)
   577  		r.NoError(tx.Find(&actual, entry.ID))
   578  		r.Equal(entry.AdditionalField, actual.AdditionalField)
   579  
   580  		r.NoError(tx.Destroy(entry))
   581  	})
   582  }
   583  
   584  func Test_Eager_Create_Has_Many(t *testing.T) {
   585  	if PDB == nil {
   586  		t.Skip("skipping integration tests")
   587  	}
   588  	transaction(func(tx *Connection) {
   589  		r := require.New(t)
   590  		count, _ := tx.Count(&User{})
   591  		user := User{
   592  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   593  			Books:        Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   594  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   595  			Houses: Addresses{
   596  				Address{HouseNumber: 86, Street: "Modelo"},
   597  			},
   598  		}
   599  
   600  		err := tx.Eager().Create(&user)
   601  		r.NoError(err)
   602  		r.NotEqual(user.ID, 0)
   603  
   604  		ctx, _ := tx.Count(&User{})
   605  		r.Equal(count+1, ctx)
   606  
   607  		ctx, _ = tx.Count(&Book{})
   608  		r.Equal(count+1, ctx)
   609  
   610  		ctx, _ = tx.Count(&Song{})
   611  		r.Equal(count+1, ctx)
   612  
   613  		ctx, _ = tx.Count(&Address{})
   614  		r.Equal(count+1, ctx)
   615  
   616  		u := User{}
   617  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   618  		err = q.First(&u)
   619  		r.NoError(err)
   620  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   621  		r.Equal(1, len(u.Books))
   622  		r.Equal(u.Books[0].Title, "Pop Book")
   623  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   624  		r.Equal(1, len(u.Houses))
   625  		r.Equal(u.Houses[0].Street, "Modelo")
   626  	})
   627  }
   628  
   629  func Test_Eager_Create_Has_Many_With_Existing(t *testing.T) {
   630  	if PDB == nil {
   631  		t.Skip("skipping integration tests")
   632  	}
   633  	transaction(func(tx *Connection) {
   634  		r := require.New(t)
   635  
   636  		addr := Address{HouseNumber: 42, Street: "Life"}
   637  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   638  		r.NoError(addrErr)
   639  		addrCount, _ := tx.Count(&Address{})
   640  		r.Zero(addrVerrs.Count())
   641  		r.Equal(1, addrCount)
   642  		r.NotZero(addr.ID)
   643  
   644  		count, _ := tx.Count(&User{})
   645  		user := User{
   646  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   647  			Books:        Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   648  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   649  			Houses: Addresses{
   650  				Address{HouseNumber: 86, Street: "Modelo"},
   651  				addr,
   652  			},
   653  		}
   654  
   655  		err := tx.Eager().Create(&user)
   656  		r.NoError(err)
   657  		r.NotEqual(user.ID, 0)
   658  
   659  		ctx, _ := tx.Count(&User{})
   660  		r.Equal(count+1, ctx)
   661  
   662  		ctx, _ = tx.Count(&Book{})
   663  		r.Equal(count+1, ctx)
   664  
   665  		ctx, _ = tx.Count(&Song{})
   666  		r.Equal(count+1, ctx)
   667  
   668  		ctx, _ = tx.Count(&Address{})
   669  		r.Equal(addrCount+1, ctx)
   670  
   671  		u := User{}
   672  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   673  		err = q.First(&u)
   674  		r.NoError(err)
   675  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   676  		r.Equal(1, len(u.Books))
   677  		r.Equal(u.Books[0].Title, "Pop Book")
   678  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   679  		r.Equal(2, len(u.Houses))
   680  		if u.Houses[0].ID == addr.ID {
   681  			r.Equal(u.Houses[0].Street, "Life")
   682  			r.Equal(u.Houses[1].Street, "Modelo")
   683  		} else {
   684  			r.Equal(u.Houses[0].Street, "Modelo")
   685  			r.Equal(u.Houses[1].Street, "Life")
   686  		}
   687  	})
   688  }
   689  
   690  func Test_Eager_Create_Has_Many_Reset_Eager_Mode_Connection(t *testing.T) {
   691  	if PDB == nil {
   692  		t.Skip("skipping integration tests")
   693  	}
   694  	transaction(func(tx *Connection) {
   695  		r := require.New(t)
   696  		count, _ := tx.Count(&User{})
   697  		user1 := User{
   698  			Name:  nulls.NewString("Mark 'Awesome' Bates"),
   699  			Books: Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   700  		}
   701  
   702  		err := tx.Eager("Books").Create(&user1)
   703  		r.NoError(err)
   704  		ctx, _ := tx.Count(&User{})
   705  		r.Equal(count+1, ctx)
   706  		ctx, _ = tx.Count(&Book{})
   707  		r.Equal(count+1, ctx)
   708  
   709  		book := Book{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}
   710  
   711  		err = tx.Eager().Create(&book)
   712  		r.NoError(err)
   713  		ctx, _ = tx.Count(&Book{})
   714  		r.Equal(count+2, ctx)
   715  	})
   716  }
   717  
   718  func Test_Eager_Validate_And_Create_Has_Many(t *testing.T) {
   719  	if PDB == nil {
   720  		t.Skip("skipping integration tests")
   721  	}
   722  	r := require.New(t)
   723  	transaction(func(tx *Connection) {
   724  		user := User{
   725  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   726  			Books:        Books{{Title: "Pop Book", Isbn: "PB1"}},
   727  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   728  			Houses: Addresses{
   729  				Address{HouseNumber: 86, Street: "Modelo"},
   730  			},
   731  		}
   732  
   733  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   734  		r.NoError(err)
   735  		ctx, _ := tx.Count(&User{})
   736  		r.Zero(ctx)
   737  		r.Equal(1, verrs.Count()) // Missing Books.Description.
   738  	})
   739  }
   740  
   741  func Test_Eager_Validate_And_Create_Parental(t *testing.T) {
   742  	if PDB == nil {
   743  		t.Skip("skipping integration tests")
   744  	}
   745  	r := require.New(t)
   746  	transaction(func(tx *Connection) {
   747  		user := User{
   748  			Name:         nulls.NewString(""),
   749  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   750  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   751  			Houses: Addresses{
   752  				Address{HouseNumber: 86, Street: "Modelo"},
   753  			},
   754  		}
   755  
   756  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   757  		r.NoError(err)
   758  		ctx, _ := tx.Count(&User{})
   759  		r.Zero(ctx)
   760  		r.Equal(1, verrs.Count()) // Missing Books.Description.
   761  	})
   762  }
   763  
   764  func Test_Eager_Validate_And_Create_Parental_With_Existing(t *testing.T) {
   765  	if PDB == nil {
   766  		t.Skip("skipping integration tests")
   767  	}
   768  	r := require.New(t)
   769  	transaction(func(tx *Connection) {
   770  		addr := Address{HouseNumber: 42, Street: "Life"}
   771  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   772  		r.NoError(addrErr)
   773  		addrCount, _ := tx.Count(&Address{})
   774  		r.Zero(addrVerrs.Count())
   775  		r.Equal(1, addrCount)
   776  		r.NotZero(addr.ID)
   777  
   778  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   779  		r.NoError(m2mErr)
   780  		r.Zero(m2mCount)
   781  
   782  		user := User{
   783  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   784  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   785  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   786  			Houses: Addresses{
   787  				Address{HouseNumber: 86, Street: "Modelo"},
   788  				addr,
   789  			},
   790  		}
   791  		count, _ := tx.Count(&User{})
   792  
   793  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   794  		r.NoError(err)
   795  		r.NotEqual(user.ID, 0)
   796  		r.Equal(0, verrs.Count())
   797  
   798  		ctx, _ := tx.Count(&User{})
   799  		r.Equal(count+1, ctx)
   800  
   801  		ctx, _ = tx.Count(&Address{})
   802  		r.Equal(addrCount+1, ctx)
   803  
   804  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   805  		r.NoError(m2mErr)
   806  		r.Equal(2, m2mCount)
   807  
   808  		u := User{}
   809  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   810  		err = q.First(&u)
   811  		r.NoError(err)
   812  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   813  		r.Equal(1, len(u.Books))
   814  		r.Equal(u.Books[0].Title, "Pop Book")
   815  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   816  		r.Equal(2, len(u.Houses))
   817  		if u.Houses[0].ID == addr.ID {
   818  			r.Equal(u.Houses[0].Street, "Life")
   819  			r.Equal(u.Houses[1].Street, "Modelo")
   820  		} else {
   821  			r.Equal(u.Houses[1].ID, addr.ID)
   822  			r.Equal(u.Houses[0].Street, "Modelo")
   823  			r.Equal(u.Houses[1].Street, "Life")
   824  		}
   825  	})
   826  }
   827  
   828  func Test_Eager_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) {
   829  	if PDB == nil {
   830  		t.Skip("skipping integration tests")
   831  	}
   832  	r := require.New(t)
   833  	transaction(func(tx *Connection) {
   834  		addr := Address{HouseNumber: 42, Street: "Life"}
   835  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   836  		r.NoError(addrErr)
   837  		addrCount, _ := tx.Count(&Address{})
   838  		r.Zero(addrVerrs.Count())
   839  		r.Equal(1, addrCount)
   840  		r.NotZero(addr.ID)
   841  
   842  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   843  		r.NoError(m2mErr)
   844  		r.Zero(m2mCount)
   845  
   846  		user := User{
   847  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   848  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   849  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   850  			Houses: Addresses{
   851  				Address{HouseNumber: 86, Street: "Modelo"},
   852  				Address{ID: addr.ID},
   853  			},
   854  		}
   855  		count, _ := tx.Count(&User{})
   856  
   857  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   858  		r.NoError(err)
   859  		r.NotEqual(user.ID, 0)
   860  		r.Equal(0, verrs.Count())
   861  
   862  		ctx, _ := tx.Count(&User{})
   863  		r.Equal(count+1, ctx)
   864  
   865  		ctx, _ = tx.Count(&Address{})
   866  		r.Equal(addrCount+1, ctx)
   867  
   868  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   869  		r.NoError(m2mErr)
   870  		r.Equal(2, m2mCount)
   871  
   872  		u := User{}
   873  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   874  		err = q.First(&u)
   875  		r.NoError(err)
   876  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   877  		r.Equal(1, len(u.Books))
   878  		r.Equal(u.Books[0].Title, "Pop Book")
   879  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   880  		r.Equal(2, len(u.Houses))
   881  		if u.Houses[0].ID == addr.ID {
   882  			r.Equal("Life", u.Houses[0].Street) // Street is blanked out
   883  			r.Equal("Modelo", u.Houses[1].Street)
   884  		} else {
   885  			r.Equal(addr.ID, u.Houses[1].ID)
   886  			r.Equal("Modelo", u.Houses[0].Street)
   887  			r.Equal("Life", u.Houses[1].Street) // Street is blanked out
   888  		}
   889  	})
   890  }
   891  
   892  func Test_Flat_Validate_And_Create_Parental_With_Existing(t *testing.T) {
   893  	if PDB == nil {
   894  		t.Skip("skipping integration tests")
   895  	}
   896  	r := require.New(t)
   897  	transaction(func(tx *Connection) {
   898  		addr := Address{HouseNumber: 42, Street: "Life"}
   899  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   900  		r.NoError(addrErr)
   901  		addrCount, _ := tx.Count(&Address{})
   902  		r.Zero(addrVerrs.Count())
   903  		r.Equal(1, addrCount)
   904  		r.NotZero(addr.ID)
   905  
   906  		book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}
   907  		bookVerrs, bookErr := tx.ValidateAndCreate(&book)
   908  		r.NoError(bookErr)
   909  		r.Zero(bookVerrs.Count())
   910  		r.NotZero(book.ID)
   911  
   912  		book2 := Book{Title: "Pop Book2", Isbn: "PB2", Description: "Awesome Book Also!"}
   913  		bookVerrs, bookErr = tx.ValidateAndCreate(&book2)
   914  		r.NoError(bookErr)
   915  		r.Zero(bookVerrs.Count())
   916  		r.NotZero(book2.ID)
   917  
   918  		bookCount, _ := tx.Count(&Book{})
   919  		r.Equal(2, bookCount)
   920  
   921  		song := Song{Title: "Hook - Blues Traveler"}
   922  		songVerrs, songErr := tx.ValidateAndCreate(&song)
   923  		r.NoError(songErr)
   924  		songCount, _ := tx.Count(&Song{})
   925  		r.Zero(songVerrs.Count())
   926  		r.Equal(1, songCount)
   927  		r.NotZero(song.ID)
   928  
   929  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   930  		r.NoError(m2mErr)
   931  		r.Zero(m2mCount)
   932  
   933  		user := User{
   934  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   935  			Books:        Books{book, book2},
   936  			FavoriteSong: song,
   937  			Houses: Addresses{
   938  				Address{HouseNumber: 86, Street: "Modelo"},
   939  				addr,
   940  			},
   941  		}
   942  		count, _ := tx.Count(&User{})
   943  
   944  		verrs, err := tx.ValidateAndCreate(&user)
   945  		r.NoError(err)
   946  		r.NotEqual(user.ID, 0)
   947  		r.Equal(0, verrs.Count())
   948  
   949  		ctx, _ := tx.Count(&User{})
   950  		r.Equal(count+1, ctx)
   951  
   952  		ctx, _ = tx.Count(&Address{})
   953  		r.Equal(addrCount, ctx)
   954  
   955  		ctx, _ = tx.Count(&Book{})
   956  		r.Equal(bookCount, ctx)
   957  
   958  		ctx, _ = tx.Count(&Song{})
   959  		r.Equal(songCount, ctx)
   960  
   961  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   962  		r.NoError(m2mErr)
   963  		r.Equal(1, m2mCount)
   964  
   965  		u := User{}
   966  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   967  		err = q.First(&u)
   968  		r.NoError(err)
   969  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   970  		r.Equal(2, len(u.Books))
   971  		if u.Books[0].ID == book.ID {
   972  			r.Equal(u.Books[0].Title, "Pop Book")
   973  			r.Equal(u.Books[1].Title, "Pop Book2")
   974  		} else {
   975  			r.Equal(u.Books[1].Title, "Pop Book")
   976  			r.Equal(u.Books[0].Title, "Pop Book2")
   977  		}
   978  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   979  		r.Equal(1, len(u.Houses))
   980  		r.Equal(addr.ID, u.Houses[0].ID)
   981  		r.Equal("Life", u.Houses[0].Street)
   982  	})
   983  }
   984  
   985  func Test_Flat_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) {
   986  	if PDB == nil {
   987  		t.Skip("skipping integration tests")
   988  	}
   989  	r := require.New(t)
   990  	transaction(func(tx *Connection) {
   991  		addr := Address{HouseNumber: 42, Street: "Life"}
   992  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   993  		r.NoError(addrErr)
   994  		addrCount, _ := tx.Count(&Address{})
   995  		r.Zero(addrVerrs.Count())
   996  		r.Equal(1, addrCount)
   997  		r.NotZero(addr.ID)
   998  
   999  		book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}
  1000  		bookVerrs, bookErr := tx.ValidateAndCreate(&book)
  1001  		r.NoError(bookErr)
  1002  		bookCount, _ := tx.Count(&Book{})
  1003  		r.Zero(bookVerrs.Count())
  1004  		r.Equal(1, bookCount)
  1005  		r.NotZero(book.ID)
  1006  
  1007  		song := Song{Title: "Hook - Blues Traveler"}
  1008  		songVerrs, songErr := tx.ValidateAndCreate(&song)
  1009  		r.NoError(songErr)
  1010  		songCount, _ := tx.Count(&Song{})
  1011  		r.Zero(songVerrs.Count())
  1012  		r.Equal(1, songCount)
  1013  		r.NotZero(song.ID)
  1014  
  1015  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
  1016  		r.NoError(m2mErr)
  1017  		r.Zero(m2mCount)
  1018  
  1019  		user := User{
  1020  			Name: nulls.NewString("Mark 'Awesome' Bates"),
  1021  			//TODO: add another existing here and test for it to make sure this works with multiples (books)
  1022  			Books:        Books{Book{ID: book.ID}},
  1023  			FavoriteSong: Song{ID: song.ID},
  1024  			Houses: Addresses{
  1025  				Address{HouseNumber: 86, Street: "Modelo"},
  1026  				Address{ID: addr.ID},
  1027  			},
  1028  		}
  1029  		count, _ := tx.Count(&User{})
  1030  
  1031  		verrs, err := tx.ValidateAndCreate(&user)
  1032  		r.NoError(err)
  1033  		r.NotEqual(user.ID, 0)
  1034  		r.Equal(0, verrs.Count())
  1035  
  1036  		ctx, _ := tx.Count(&User{})
  1037  		r.Equal(count+1, ctx)
  1038  
  1039  		ctx, _ = tx.Count(&Address{})
  1040  		r.Equal(addrCount, ctx)
  1041  
  1042  		ctx, _ = tx.Where("user_id = ?", user.ID).Count(&Book{})
  1043  		r.Equal(bookCount, ctx)
  1044  
  1045  		ctx, _ = tx.Count(&Song{})
  1046  		r.Equal(songCount, ctx)
  1047  
  1048  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
  1049  		r.NoError(m2mErr)
  1050  		r.Equal(1, m2mCount)
  1051  
  1052  		u := User{}
  1053  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
  1054  		err = q.First(&u)
  1055  		r.NoError(err)
  1056  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
  1057  		r.Equal(1, len(u.Books))
  1058  		r.Equal(u.Books[0].Title, "Pop Book")
  1059  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
  1060  		r.Equal(1, len(u.Houses))
  1061  		r.Equal(addr.ID, u.Houses[0].ID)
  1062  		r.Equal("Life", u.Houses[0].Street)
  1063  	})
  1064  }
  1065  
  1066  func Test_Eager_Create_Belongs_To(t *testing.T) {
  1067  	if PDB == nil {
  1068  		t.Skip("skipping integration tests")
  1069  	}
  1070  	transaction(func(tx *Connection) {
  1071  		r := require.New(t)
  1072  		book := Book{
  1073  			Title:       "Pop Book",
  1074  			Description: "Pop Book",
  1075  			Isbn:        "PB1",
  1076  			User: User{
  1077  				Name: nulls.NewString("Larry"),
  1078  			},
  1079  		}
  1080  
  1081  		err := tx.Eager().Create(&book)
  1082  		r.NoError(err)
  1083  
  1084  		ctx, _ := tx.Count(&Book{})
  1085  		r.Equal(1, ctx)
  1086  
  1087  		ctx, _ = tx.Count(&User{})
  1088  		r.Equal(1, ctx)
  1089  
  1090  		car := Taxi{
  1091  			Model: "Fancy car",
  1092  			Driver: &User{
  1093  				Name: nulls.NewString("Larry 2"),
  1094  			},
  1095  		}
  1096  
  1097  		err = tx.Eager().Create(&car)
  1098  		r.NoError(err)
  1099  
  1100  		ctx, _ = tx.Count(&Taxi{})
  1101  		r.Equal(1, ctx)
  1102  
  1103  		err = tx.Eager().Find(&car, car.ID)
  1104  		r.NoError(err)
  1105  
  1106  		r.Equal(nulls.NewString("Larry 2"), car.Driver.Name)
  1107  	})
  1108  }
  1109  
  1110  func Test_Eager_Create_Belongs_To_Pointers(t *testing.T) {
  1111  	if PDB == nil {
  1112  		t.Skip("skipping integration tests")
  1113  	}
  1114  	transaction(func(tx *Connection) {
  1115  		r := require.New(t)
  1116  		// Create a body with a head
  1117  		body := Body{
  1118  			Head: &Head{},
  1119  		}
  1120  
  1121  		err := tx.Eager().Create(&body)
  1122  		r.NoError(err)
  1123  		r.NotZero(body.ID)
  1124  		r.NotZero(body.Head.ID)
  1125  
  1126  		ctx, _ := tx.Count(&Body{})
  1127  		r.Equal(1, ctx)
  1128  
  1129  		ctx, _ = tx.Count(&Head{})
  1130  		r.Equal(1, ctx)
  1131  
  1132  		// Create a body without a head:
  1133  		body = Body{
  1134  			Head: nil,
  1135  		}
  1136  
  1137  		err = tx.Eager().Create(&body)
  1138  		r.NoError(err)
  1139  		r.NotZero(body.ID)
  1140  		r.Nil(body.Head)
  1141  
  1142  		ctx, _ = tx.Count(&Body{})
  1143  		r.Equal(2, ctx)
  1144  
  1145  		ctx, _ = tx.Count(&Head{})
  1146  		r.Equal(1, ctx)
  1147  
  1148  		err = tx.Eager().Create(&Head{
  1149  			BodyID: body.ID,
  1150  			Body:   nil,
  1151  		})
  1152  		r.NoError(err)
  1153  	})
  1154  }
  1155  
  1156  func Test_Create_Belongs_To_Pointers(t *testing.T) {
  1157  	if PDB == nil {
  1158  		t.Skip("skipping integration tests")
  1159  	}
  1160  	transaction(func(tx *Connection) {
  1161  		r := require.New(t)
  1162  		// Create a body without a head:
  1163  		body := Body{
  1164  			Head: nil,
  1165  		}
  1166  
  1167  		err := tx.Create(&body)
  1168  		r.NoError(err)
  1169  		r.NotZero(body.ID)
  1170  		r.Nil(body.Head)
  1171  
  1172  		// Create a head with the associated model set but not the ID
  1173  		created := HeadPtr{
  1174  			Body: &body,
  1175  		}
  1176  		err = tx.Create(&created)
  1177  		r.NoError(err)
  1178  
  1179  		found := HeadPtr{}
  1180  		err = tx.Find(&found, created.ID)
  1181  		r.NoError(err)
  1182  		r.Equal(body.ID, *found.BodyID)
  1183  	})
  1184  }
  1185  
  1186  func Test_Flat_Create_Belongs_To(t *testing.T) {
  1187  	if PDB == nil {
  1188  		t.Skip("skipping integration tests")
  1189  	}
  1190  	transaction(func(tx *Connection) {
  1191  		r := require.New(t)
  1192  		user := User{
  1193  			Name: nulls.NewString("Larry"),
  1194  		}
  1195  
  1196  		err := tx.Create(&user)
  1197  		r.NoError(err)
  1198  		ctx, _ := tx.Count(&User{})
  1199  		r.Equal(1, ctx)
  1200  
  1201  		book := Book{
  1202  			Title:       "Pop Book",
  1203  			Description: "Pop Book",
  1204  			Isbn:        "PB1",
  1205  			User:        user,
  1206  		}
  1207  
  1208  		err = tx.Create(&book)
  1209  		r.NoError(err)
  1210  
  1211  		ctx, _ = tx.Count(&Book{})
  1212  		r.Equal(1, ctx)
  1213  
  1214  		err = tx.Eager().Find(&book, book.ID)
  1215  		r.NoError(err)
  1216  
  1217  		r.Equal(nulls.NewString("Larry"), book.User.Name)
  1218  
  1219  		car := Taxi{
  1220  			Model:  "Fancy car",
  1221  			Driver: &user,
  1222  		}
  1223  
  1224  		err = tx.Create(&car)
  1225  		r.NoError(err)
  1226  
  1227  		ctx, _ = tx.Count(&Taxi{})
  1228  		r.Equal(1, ctx)
  1229  
  1230  		err = tx.Eager().Find(&car, car.ID)
  1231  		r.NoError(err)
  1232  
  1233  		r.Equal(nulls.NewString("Larry"), car.Driver.Name)
  1234  	})
  1235  }
  1236  
  1237  func Test_Eager_Creation_Without_Associations(t *testing.T) {
  1238  	if PDB == nil {
  1239  		t.Skip("skipping integration tests")
  1240  	}
  1241  	transaction(func(tx *Connection) {
  1242  		r := require.New(t)
  1243  		code := CourseCode{
  1244  			Course: Course{},
  1245  		}
  1246  
  1247  		err := tx.Eager().Create(&code)
  1248  		r.NoError(err)
  1249  
  1250  		ctx, _ := tx.Count(&CourseCode{})
  1251  		r.Equal(1, ctx)
  1252  	})
  1253  }
  1254  
  1255  func Test_Eager_Embedded_Struct(t *testing.T) {
  1256  	if PDB == nil {
  1257  		t.Skip("skipping integration tests")
  1258  	}
  1259  	transaction(func(tx *Connection) {
  1260  		r := require.New(t)
  1261  
  1262  		type AssocFields struct {
  1263  			Books        Books     `has_many:"books" order_by:"title asc"`
  1264  			FavoriteSong Song      `has_one:"song" fk_id:"u_id"`
  1265  			Houses       Addresses `many_to_many:"users_addresses"`
  1266  		}
  1267  
  1268  		type User struct {
  1269  			ID        int           `db:"id"`
  1270  			UserName  string        `db:"user_name"`
  1271  			Email     string        `db:"email"`
  1272  			Name      nulls.String  `db:"name"`
  1273  			Alive     nulls.Bool    `db:"alive"`
  1274  			CreatedAt time.Time     `db:"created_at"`
  1275  			UpdatedAt time.Time     `db:"updated_at"`
  1276  			BirthDate nulls.Time    `db:"birth_date"`
  1277  			Bio       nulls.String  `db:"bio"`
  1278  			Price     nulls.Float64 `db:"price"`
  1279  			FullName  nulls.String  `db:"full_name" select:"name as full_name"`
  1280  
  1281  			AssocFields
  1282  		}
  1283  
  1284  		count, _ := tx.Count(&User{})
  1285  		user := User{
  1286  			UserName: "dumb-dumb",
  1287  			Name:     nulls.NewString("Arthur Dent"),
  1288  			AssocFields: AssocFields{
  1289  				Books:        Books{{Title: "The Hitchhiker's Guide to the Galaxy", Description: "Comedy Science Fiction somewhere in Space", Isbn: "PB42"}},
  1290  				FavoriteSong: Song{Title: "Wish You Were Here", ComposedBy: Composer{Name: "Pink Floyd"}},
  1291  				Houses: Addresses{
  1292  					Address{HouseNumber: 155, Street: "Country Lane"},
  1293  				},
  1294  			},
  1295  		}
  1296  
  1297  		err := tx.Eager().Create(&user)
  1298  		r.NoError(err)
  1299  		r.NotZero(user.ID)
  1300  
  1301  		ctx, _ := tx.Count(&User{})
  1302  		r.Equal(count+1, ctx)
  1303  
  1304  		ctx, _ = tx.Count(&Book{})
  1305  		r.Equal(count+1, ctx)
  1306  
  1307  		ctx, _ = tx.Count(&Song{})
  1308  		r.Equal(count+1, ctx)
  1309  
  1310  		ctx, _ = tx.Count(&Address{})
  1311  		r.Equal(count+1, ctx)
  1312  
  1313  		u := User{}
  1314  		q := tx.Eager().Where("name = ?", user.Name.String)
  1315  		err = q.First(&u)
  1316  		r.NoError(err)
  1317  
  1318  		r.Equal(user.Name.String, u.Name.String)
  1319  		r.Len(u.Books, 1)
  1320  		r.Equal(user.Books[0].Title, u.Books[0].Title)
  1321  		r.Equal(user.FavoriteSong.Title, u.FavoriteSong.Title)
  1322  		r.Len(u.Houses, 1)
  1323  		r.Equal(user.Houses[0].Street, u.Houses[0].Street)
  1324  	})
  1325  }
  1326  
  1327  func Test_Eager_Embedded_Ptr_Struct(t *testing.T) {
  1328  	if PDB == nil {
  1329  		t.Skip("skipping integration tests")
  1330  	}
  1331  	transaction(func(tx *Connection) {
  1332  		r := require.New(t)
  1333  
  1334  		type AssocFields struct {
  1335  			Books        Books     `has_many:"books" order_by:"title asc"`
  1336  			FavoriteSong Song      `has_one:"song" fk_id:"u_id"`
  1337  			Houses       Addresses `many_to_many:"users_addresses"`
  1338  		}
  1339  
  1340  		type User struct {
  1341  			ID        int           `db:"id"`
  1342  			UserName  string        `db:"user_name"`
  1343  			Email     string        `db:"email"`
  1344  			Name      nulls.String  `db:"name"`
  1345  			Alive     nulls.Bool    `db:"alive"`
  1346  			CreatedAt time.Time     `db:"created_at"`
  1347  			UpdatedAt time.Time     `db:"updated_at"`
  1348  			BirthDate nulls.Time    `db:"birth_date"`
  1349  			Bio       nulls.String  `db:"bio"`
  1350  			Price     nulls.Float64 `db:"price"`
  1351  			FullName  nulls.String  `db:"full_name" select:"name as full_name"`
  1352  
  1353  			*AssocFields
  1354  		}
  1355  
  1356  		count, _ := tx.Count(&User{})
  1357  		user := User{
  1358  			UserName: "dumb-dumb",
  1359  			Name:     nulls.NewString("Arthur Dent"),
  1360  			AssocFields: &AssocFields{
  1361  				Books:        Books{{Title: "The Hitchhiker's Guide to the Galaxy", Description: "Comedy Science Fiction somewhere in Space", Isbn: "PB42"}},
  1362  				FavoriteSong: Song{Title: "Wish You Were Here", ComposedBy: Composer{Name: "Pink Floyd"}},
  1363  				Houses: Addresses{
  1364  					Address{HouseNumber: 155, Street: "Country Lane"},
  1365  				},
  1366  			},
  1367  		}
  1368  
  1369  		err := tx.Eager().Create(&user)
  1370  		r.NoError(err)
  1371  		r.NotZero(user.ID)
  1372  
  1373  		ctx, _ := tx.Count(&User{})
  1374  		r.Equal(count+1, ctx)
  1375  
  1376  		ctx, _ = tx.Count(&Book{})
  1377  		r.Equal(count+1, ctx)
  1378  
  1379  		ctx, _ = tx.Count(&Song{})
  1380  		r.Equal(count+1, ctx)
  1381  
  1382  		ctx, _ = tx.Count(&Address{})
  1383  		r.Equal(count+1, ctx)
  1384  
  1385  		u := User{}
  1386  		q := tx.Eager().Where("name = ?", user.Name.String)
  1387  		err = q.First(&u)
  1388  		r.NoError(err)
  1389  
  1390  		r.Equal(user.Name.String, u.Name.String)
  1391  		r.Len(u.Books, 1)
  1392  		r.Equal(user.Books[0].Title, u.Books[0].Title)
  1393  		r.Equal(user.FavoriteSong.Title, u.FavoriteSong.Title)
  1394  		r.Len(u.Houses, 1)
  1395  		r.Equal(user.Houses[0].Street, u.Houses[0].Street)
  1396  	})
  1397  }
  1398  
  1399  func Test_Create_UUID(t *testing.T) {
  1400  	if PDB == nil {
  1401  		t.Skip("skipping integration tests")
  1402  	}
  1403  	transaction(func(tx *Connection) {
  1404  		r := require.New(t)
  1405  
  1406  		count, _ := tx.Count(&Song{})
  1407  		song := Song{Title: "Automatic Buffalo"}
  1408  		r.Equal(uuid.Nil, song.ID)
  1409  		err := tx.Create(&song)
  1410  		r.NoError(err)
  1411  		r.NotZero(song.ID)
  1412  		r.NotEqual(uuid.Nil, song.ID)
  1413  
  1414  		ctx, _ := tx.Count(&Song{})
  1415  		r.Equal(count+1, ctx)
  1416  
  1417  		u := Song{}
  1418  		q := tx.Where("title = ?", "Automatic Buffalo")
  1419  		err = q.First(&u)
  1420  		r.NoError(err)
  1421  	})
  1422  }
  1423  
  1424  func Test_Create_Existing_UUID(t *testing.T) {
  1425  	if PDB == nil {
  1426  		t.Skip("skipping integration tests")
  1427  	}
  1428  	transaction(func(tx *Connection) {
  1429  		r := require.New(t)
  1430  		id, err := uuid.NewV4()
  1431  		r.NoError(err)
  1432  
  1433  		count, _ := tx.Count(&Song{})
  1434  		song := Song{
  1435  			ID:    id,
  1436  			Title: "Automatic Buffalo",
  1437  		}
  1438  
  1439  		err = tx.Create(&song)
  1440  		r.NoError(err)
  1441  		r.NotZero(song.ID)
  1442  		r.Equal(id.String(), song.ID.String())
  1443  
  1444  		ctx, _ := tx.Count(&Song{})
  1445  		r.Equal(count+1, ctx)
  1446  
  1447  	})
  1448  }
  1449  
  1450  func Test_Create_Timestamps(t *testing.T) {
  1451  	if PDB == nil {
  1452  		t.Skip("skipping integration tests")
  1453  	}
  1454  	transaction(func(tx *Connection) {
  1455  		r := require.New(t)
  1456  
  1457  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
  1458  		r.Zero(user.CreatedAt)
  1459  		r.Zero(user.UpdatedAt)
  1460  
  1461  		err := tx.Create(&user)
  1462  		r.NoError(err)
  1463  
  1464  		r.NotZero(user.CreatedAt)
  1465  		r.NotZero(user.UpdatedAt)
  1466  
  1467  		friend := Friend{FirstName: "Ross", LastName: "Gellar"}
  1468  		err = tx.Create(&friend)
  1469  		r.NoError(err)
  1470  	})
  1471  }
  1472  
  1473  func Test_Update(t *testing.T) {
  1474  	if PDB == nil {
  1475  		t.Skip("skipping integration tests")
  1476  	}
  1477  	transaction(func(tx *Connection) {
  1478  		r := require.New(t)
  1479  
  1480  		user := User{Name: nulls.NewString("Mark")}
  1481  		tx.Create(&user)
  1482  
  1483  		r.NotZero(user.CreatedAt)
  1484  		r.NotZero(user.UpdatedAt)
  1485  
  1486  		user.Name.String = "Marky"
  1487  		err := tx.Update(&user)
  1488  		r.NoError(err)
  1489  
  1490  		r.NoError(tx.Reload(&user))
  1491  		r.Equal(user.Name.String, "Marky")
  1492  	})
  1493  }
  1494  
  1495  func Test_UpdateColumns(t *testing.T) {
  1496  	if PDB == nil {
  1497  		t.Skip("skipping integration tests")
  1498  	}
  1499  	transaction(func(tx *Connection) {
  1500  		r := require.New(t)
  1501  
  1502  		user := User{Name: nulls.NewString("Mark")}
  1503  		tx.Create(&user)
  1504  
  1505  		r.NotZero(user.CreatedAt)
  1506  		r.NotZero(user.UpdatedAt)
  1507  
  1508  		user.Name.String = "Fulano"
  1509  		user.UserName = "Fulano"
  1510  		err := tx.UpdateColumns(&user, "user_name") // Update UserName field/column only
  1511  		r.NoError(err)
  1512  
  1513  		r.NoError(tx.Reload(&user))
  1514  		r.Equal(user.Name.String, "Mark") // Name column should not be updated
  1515  		r.Equal(user.UserName, "Fulano")
  1516  	})
  1517  }
  1518  
  1519  func Test_UpdateQuery_NoUpdatedAt(t *testing.T) {
  1520  	if PDB == nil {
  1521  		t.Skip("skipping integration tests")
  1522  	}
  1523  	transaction(func(tx *Connection) {
  1524  		r := require.New(t)
  1525  		existing, err := PDB.Count(&NonStandardID{}) // from previous test runs
  1526  		r.NoError(err)
  1527  		r.GreaterOrEqual(existing, 0)
  1528  		r.NoError(PDB.Create(&NonStandardID{OutfacingID: "must-change"}))
  1529  		count, err := PDB.Where("true").UpdateQuery(&NonStandardID{OutfacingID: "has-changed"}, "id")
  1530  		r.NoError(err)
  1531  		r.Equal(int64(existing+1), count)
  1532  		entity := NonStandardID{}
  1533  		r.NoError(PDB.First(&entity))
  1534  		r.Equal("has-changed", entity.OutfacingID)
  1535  	})
  1536  }
  1537  
  1538  func Test_UpdateQuery_NoTransaction(t *testing.T) {
  1539  	if PDB == nil {
  1540  		t.Skip("skipping integration tests")
  1541  	}
  1542  
  1543  	r := require.New(t)
  1544  	u1 := User{Name: nulls.NewString("Foo"), Bio: nulls.NewString("must-not-change-1")}
  1545  	r.NoError(PDB.Create(&u1))
  1546  	r.NoError(PDB.Reload(&u1))
  1547  	count, err := PDB.Where("name = ?", "Nemo").UpdateQuery(&User{Bio: nulls.NewString("did-change")}, "bio")
  1548  	r.NoError(err)
  1549  	require.Equal(t, int64(0), count)
  1550  
  1551  	count, err = PDB.Where("name = ?", "Foo").UpdateQuery(&User{Name: nulls.NewString("Bar")}, "name")
  1552  	r.NoError(err)
  1553  	r.Equal(int64(1), count)
  1554  
  1555  	require.NoError(t, PDB.Destroy(&u1))
  1556  }
  1557  
  1558  func Test_UpdateQuery(t *testing.T) {
  1559  	if PDB == nil {
  1560  		t.Skip("skipping integration tests")
  1561  	}
  1562  	transaction(func(tx *Connection) {
  1563  		r := require.New(t)
  1564  
  1565  		u1 := User{Name: nulls.NewString("Foo"), Bio: nulls.NewString("must-not-change-1")}
  1566  		u2 := User{Name: nulls.NewString("Foo"), Bio: nulls.NewString("must-not-change-2")}
  1567  		u3 := User{Name: nulls.NewString("Baz"), Bio: nulls.NewString("must-not-change-3")}
  1568  		tx.Create(&u1)
  1569  		tx.Create(&u2)
  1570  		tx.Create(&u3)
  1571  		r.NoError(tx.Reload(&u1))
  1572  		r.NoError(tx.Reload(&u2))
  1573  		r.NoError(tx.Reload(&u3))
  1574  		time.Sleep(time.Millisecond * 1)
  1575  
  1576  		// No affected rows
  1577  		count, err := tx.Where("name = ?", "Nemo").UpdateQuery(&User{Bio: nulls.NewString("did-change")}, "bio")
  1578  		r.NoError(err)
  1579  		require.Equal(t, int64(0), count)
  1580  		mustUnchanged := &User{}
  1581  		r.NoError(tx.Find(mustUnchanged, u1.ID))
  1582  		r.Equal(u1.Bio, mustUnchanged.Bio)
  1583  		r.Equal(u1.UpdatedAt, mustUnchanged.UpdatedAt)
  1584  
  1585  		// Correct rows are updated, including updated_at
  1586  		count, err = tx.Where("name = ?", "Foo").UpdateQuery(&User{Name: nulls.NewString("Bar")}, "name")
  1587  		r.NoError(err)
  1588  		r.Equal(int64(2), count)
  1589  
  1590  		u1b, u2b, u3b := &User{}, &User{}, &User{}
  1591  		r.NoError(tx.Find(u1b, u1.ID))
  1592  		r.NoError(tx.Find(u2b, u2.ID))
  1593  		r.NoError(tx.Find(u3b, u3.ID))
  1594  		r.Equal(u1b.Name.String, "Bar")
  1595  		r.Equal(u2b.Name.String, "Bar")
  1596  		r.Equal(u3b.Name.String, "Baz")
  1597  		r.Equal(u1b.Bio.String, "must-not-change-1")
  1598  		r.Equal(u2b.Bio.String, "must-not-change-2")
  1599  		r.Equal(u3b.Bio.String, "must-not-change-3")
  1600  		if tx.Dialect.Name() != nameMySQL { // MySQL timestamps are in seconds
  1601  			r.NotEqual(u1.UpdatedAt, u1b.UpdatedAt)
  1602  			r.NotEqual(u2.UpdatedAt, u2b.UpdatedAt)
  1603  		}
  1604  		r.Equal(u3.UpdatedAt, u3b.UpdatedAt)
  1605  
  1606  		// ID is ignored
  1607  		count, err = tx.Where("true").UpdateQuery(&User{ID: 123, Name: nulls.NewString("Bar")}, "id", "name")
  1608  		r.NoError(tx.Find(u1b, u1.ID))
  1609  		r.NoError(tx.Find(u2b, u2.ID))
  1610  		r.NoError(tx.Find(u3b, u3.ID))
  1611  		r.Equal(u1b.Name.String, "Bar")
  1612  		r.Equal(u2b.Name.String, "Bar")
  1613  		r.Equal(u3b.Name.String, "Bar")
  1614  
  1615  		// Invalid column yields an error
  1616  		count, err = tx.Where("name = ?", "Foo").UpdateQuery(&User{Name: nulls.NewString("Bar")}, "mistake")
  1617  		r.Contains(err.Error(), "could not find name mistake")
  1618  
  1619  		tx.Where("true").Delete(&User{})
  1620  	})
  1621  }
  1622  
  1623  func Test_UpdateColumns_UpdatedAt(t *testing.T) {
  1624  	if PDB == nil {
  1625  		t.Skip("skipping integration tests")
  1626  	}
  1627  	transaction(func(tx *Connection) {
  1628  		r := require.New(t)
  1629  
  1630  		user := User{Name: nulls.NewString("Foo")}
  1631  		tx.Create(&user)
  1632  
  1633  		r.NotZero(user.CreatedAt)
  1634  		r.NotZero(user.UpdatedAt)
  1635  		updatedAtBefore := user.UpdatedAt
  1636  
  1637  		user.Name.String = "Bar"
  1638  		err := tx.UpdateColumns(&user, "name", "updated_at") // Update name and updated_at
  1639  		r.NoError(err)
  1640  
  1641  		r.NoError(tx.Reload(&user))
  1642  		r.NotEqual(user.UpdatedAt, updatedAtBefore) // UpdatedAt should be updated automatically
  1643  	})
  1644  }
  1645  
  1646  func Test_UpdateColumns_MultipleColumns(t *testing.T) {
  1647  	if PDB == nil {
  1648  		t.Skip("skipping integration tests")
  1649  	}
  1650  	transaction(func(tx *Connection) {
  1651  		r := require.New(t)
  1652  
  1653  		user := User{Name: nulls.NewString("Mark"), UserName: "Sagan", Email: "test@example.com"}
  1654  		tx.Create(&user)
  1655  
  1656  		r.NotZero(user.CreatedAt)
  1657  		r.NotZero(user.UpdatedAt)
  1658  
  1659  		user.Name.String = "Ping"
  1660  		user.UserName = "Pong"
  1661  		user.Email = "fulano@example"
  1662  		err := tx.UpdateColumns(&user, "name", "user_name") // Update multiple columns
  1663  		r.NoError(err)
  1664  
  1665  		r.NoError(tx.Reload(&user))
  1666  		r.Equal(user.Name.String, "Ping")
  1667  		r.Equal(user.UserName, "Pong")
  1668  		r.Equal(user.Email, "test@example.com") // Email should not be updated
  1669  	})
  1670  }
  1671  
  1672  func Test_UpdateColumns_All(t *testing.T) {
  1673  	if PDB == nil {
  1674  		t.Skip("skipping integration tests")
  1675  	}
  1676  	transaction(func(tx *Connection) {
  1677  		r := require.New(t)
  1678  
  1679  		user := User{Name: nulls.NewString("Mark"), UserName: "Sagan"}
  1680  		tx.Create(&user)
  1681  
  1682  		r.NotZero(user.CreatedAt)
  1683  		r.NotZero(user.UpdatedAt)
  1684  
  1685  		user.Name.String = "Ping"
  1686  		user.UserName = "Pong"
  1687  		user.Email = "ping@pong.com"
  1688  		err := tx.UpdateColumns(&user) // Update all columns
  1689  		r.NoError(err)
  1690  
  1691  		r.NoError(tx.Reload(&user))
  1692  		r.Equal(user.Name.String, "Ping")
  1693  		r.Equal(user.UserName, "Pong")
  1694  		r.Equal(user.Email, "ping@pong.com")
  1695  	})
  1696  }
  1697  
  1698  func Test_UpdateColumns_With_Slice(t *testing.T) {
  1699  	if PDB == nil {
  1700  		t.Skip("skipping integration tests")
  1701  	}
  1702  	transaction(func(tx *Connection) {
  1703  		r := require.New(t)
  1704  
  1705  		user := Users{
  1706  			{
  1707  				Name:     nulls.NewString("Mark"),
  1708  				UserName: "Ping",
  1709  			},
  1710  			{
  1711  				Name:     nulls.NewString("Larry"),
  1712  				UserName: "Pong",
  1713  			},
  1714  		}
  1715  		tx.Create(&user)
  1716  
  1717  		r.NotZero(user[0].CreatedAt)
  1718  		r.NotZero(user[0].UpdatedAt)
  1719  
  1720  		r.NotZero(user[1].CreatedAt)
  1721  		r.NotZero(user[1].UpdatedAt)
  1722  
  1723  		user[0].Name.String = "Fulano"
  1724  		user[0].UserName = "Thor"
  1725  		user[1].Name.String = "Fulana"
  1726  		user[1].UserName = "Freya"
  1727  
  1728  		err := tx.UpdateColumns(&user, "name") // Update Name field/column only
  1729  		r.NoError(err)
  1730  
  1731  		r.NoError(tx.Reload(&user))
  1732  		r.Equal(user[0].Name.String, "Fulano")
  1733  		r.Equal(user[0].UserName, "Ping") // UserName should not be updated
  1734  		r.Equal(user[1].Name.String, "Fulana")
  1735  		r.Equal(user[1].UserName, "Pong") // UserName should not be updated
  1736  	})
  1737  }
  1738  
  1739  func Test_Update_With_Slice(t *testing.T) {
  1740  	if PDB == nil {
  1741  		t.Skip("skipping integration tests")
  1742  	}
  1743  	transaction(func(tx *Connection) {
  1744  		r := require.New(t)
  1745  
  1746  		user := Users{
  1747  			{Name: nulls.NewString("Mark")},
  1748  			{Name: nulls.NewString("Larry")},
  1749  		}
  1750  		tx.Create(&user)
  1751  
  1752  		r.NotZero(user[0].CreatedAt)
  1753  		r.NotZero(user[0].UpdatedAt)
  1754  
  1755  		r.NotZero(user[1].CreatedAt)
  1756  		r.NotZero(user[1].UpdatedAt)
  1757  
  1758  		user[0].Name.String = "Marky"
  1759  		user[1].Name.String = "Lawrence"
  1760  
  1761  		err := tx.Update(&user)
  1762  		r.NoError(err)
  1763  
  1764  		r.NoError(tx.Reload(&user))
  1765  		r.Equal(user[0].Name.String, "Marky")
  1766  		r.Equal(user[1].Name.String, "Lawrence")
  1767  	})
  1768  }
  1769  
  1770  func Test_Update_UUID(t *testing.T) {
  1771  	if PDB == nil {
  1772  		t.Skip("skipping integration tests")
  1773  	}
  1774  	transaction(func(tx *Connection) {
  1775  		r := require.New(t)
  1776  
  1777  		song := Song{Title: "Automatic Buffalo"}
  1778  		err := tx.Create(&song)
  1779  		r.NoError(err)
  1780  
  1781  		r.NotZero(song.CreatedAt)
  1782  		r.NotZero(song.UpdatedAt)
  1783  
  1784  		song.Title = "Hum"
  1785  		err = tx.Update(&song)
  1786  		r.NoError(err)
  1787  
  1788  		err = tx.Reload(&song)
  1789  		r.NoError(err)
  1790  		r.Equal("Hum", song.Title)
  1791  	})
  1792  }
  1793  
  1794  func Test_Update_With_Non_ID_PK(t *testing.T) {
  1795  	if PDB == nil {
  1796  		t.Skip("skipping integration tests")
  1797  	}
  1798  	transaction(func(tx *Connection) {
  1799  		r := require.New(t)
  1800  
  1801  		r.NoError(tx.Create(&CrookedColour{Name: "cc is not the first one"}))
  1802  
  1803  		cc := CrookedColour{
  1804  			Name: "You?",
  1805  		}
  1806  		err := tx.Create(&cc)
  1807  		r.NoError(err)
  1808  		r.NotZero(cc.ID)
  1809  		id := cc.ID
  1810  
  1811  		updatedName := "Me!"
  1812  		cc.Name = updatedName
  1813  		r.NoError(tx.Update(&cc))
  1814  		r.Equal(id, cc.ID)
  1815  
  1816  		r.NoError(tx.Reload(&cc))
  1817  		r.Equal(updatedName, cc.Name)
  1818  		r.Equal(id, cc.ID)
  1819  	})
  1820  }
  1821  
  1822  func Test_Update_Non_PK_ID(t *testing.T) {
  1823  	if PDB == nil {
  1824  		t.Skip("skipping integration tests")
  1825  	}
  1826  	transaction(func(tx *Connection) {
  1827  		r := require.New(t)
  1828  
  1829  		client := &NonStandardID{
  1830  			OutfacingID: "my awesome hydra client",
  1831  		}
  1832  		r.NoError(tx.Create(client))
  1833  
  1834  		updatedID := "your awesome hydra client"
  1835  		client.OutfacingID = updatedID
  1836  		r.NoError(tx.Update(client))
  1837  		r.NoError(tx.Reload(client))
  1838  		r.Equal(updatedID, client.OutfacingID)
  1839  	})
  1840  }
  1841  
  1842  func Test_Destroy(t *testing.T) {
  1843  	if PDB == nil {
  1844  		t.Skip("skipping integration tests")
  1845  	}
  1846  	transaction(func(tx *Connection) {
  1847  		r := require.New(t)
  1848  
  1849  		count, err := tx.Count("users")
  1850  		r.NoError(err)
  1851  		user := User{Name: nulls.NewString("Mark")}
  1852  		err = tx.Create(&user)
  1853  		r.NoError(err)
  1854  		r.NotEqual(user.ID, 0)
  1855  
  1856  		ctx, err := tx.Count("users")
  1857  		r.NoError(err)
  1858  		r.Equal(count+1, ctx)
  1859  
  1860  		err = tx.Destroy(&user)
  1861  		r.NoError(err)
  1862  
  1863  		ctx, _ = tx.Count("users")
  1864  		r.Equal(count, ctx)
  1865  	})
  1866  }
  1867  
  1868  func Test_Destroy_With_Slice(t *testing.T) {
  1869  	if PDB == nil {
  1870  		t.Skip("skipping integration tests")
  1871  	}
  1872  	transaction(func(tx *Connection) {
  1873  		r := require.New(t)
  1874  
  1875  		count, err := tx.Count("users")
  1876  		r.NoError(err)
  1877  		user := Users{
  1878  			{Name: nulls.NewString("Mark")},
  1879  			{Name: nulls.NewString("Larry")},
  1880  		}
  1881  		err = tx.Create(&user)
  1882  		r.NoError(err)
  1883  		r.NotEqual(user[0].ID, 0)
  1884  		r.NotEqual(user[1].ID, 0)
  1885  
  1886  		ctx, err := tx.Count("users")
  1887  		r.NoError(err)
  1888  		r.Equal(count+2, ctx)
  1889  
  1890  		err = tx.Destroy(&user)
  1891  		r.NoError(err)
  1892  
  1893  		ctx, _ = tx.Count("users")
  1894  		r.Equal(count, ctx)
  1895  	})
  1896  }
  1897  
  1898  func Test_Destroy_UUID(t *testing.T) {
  1899  	if PDB == nil {
  1900  		t.Skip("skipping integration tests")
  1901  	}
  1902  	transaction(func(tx *Connection) {
  1903  		r := require.New(t)
  1904  
  1905  		count, err := tx.Count("songs")
  1906  		r.NoError(err)
  1907  		song := Song{Title: "Automatic Buffalo"}
  1908  		err = tx.Create(&song)
  1909  		r.NoError(err)
  1910  		r.NotZero(song.ID)
  1911  
  1912  		ctx, err := tx.Count("songs")
  1913  		r.NoError(err)
  1914  		r.Equal(count+1, ctx)
  1915  
  1916  		err = tx.Destroy(&song)
  1917  		r.NoError(err)
  1918  
  1919  		ctx, _ = tx.Count("songs")
  1920  		r.Equal(count, ctx)
  1921  	})
  1922  }
  1923  
  1924  func Test_TruncateAll(t *testing.T) {
  1925  	if PDB == nil {
  1926  		t.Skip("skipping integration tests")
  1927  	}
  1928  	count := int(0)
  1929  	transaction(func(tx *Connection) {
  1930  		r := require.New(t)
  1931  
  1932  		var err error
  1933  		count, err = tx.Count("users")
  1934  		r.NoError(err)
  1935  		user := User{Name: nulls.NewString("Mark")}
  1936  		err = tx.Create(&user)
  1937  		r.NoError(err)
  1938  		r.NotEqual(user.ID, 0)
  1939  
  1940  		ctx, err := tx.Count("users")
  1941  		r.NoError(err)
  1942  		r.Equal(count+1, ctx)
  1943  
  1944  		err = tx.TruncateAll()
  1945  		r.NoError(err)
  1946  
  1947  		ctx, _ = tx.Count("users")
  1948  		r.Equal(count, ctx)
  1949  	})
  1950  }
  1951  
  1952  func Test_Delete(t *testing.T) {
  1953  	if PDB == nil {
  1954  		t.Skip("skipping integration tests")
  1955  	}
  1956  
  1957  	transaction(func(tx *Connection) {
  1958  		r := require.New(t)
  1959  
  1960  		songTitles := []string{"Yoshimi Battles the Pink Robots, Pt. 1", "Face Down In The Gutter Of Your Love"}
  1961  		user := User{Name: nulls.NewString("Patrik")}
  1962  
  1963  		r.NoError(tx.Create(&user))
  1964  		r.NotZero(user.ID)
  1965  
  1966  		count, err := tx.Count("songs")
  1967  		r.NoError(err)
  1968  
  1969  		for _, title := range songTitles {
  1970  			err = tx.Create(&Song{Title: title, UserID: user.ID})
  1971  			r.NoError(err)
  1972  		}
  1973  
  1974  		ctx, err := tx.Count("songs")
  1975  		r.NoError(err)
  1976  		r.Equal(count+len(songTitles), ctx)
  1977  
  1978  		err = tx.Where("u_id = ?", user.ID).Delete("songs")
  1979  		r.NoError(err)
  1980  
  1981  		ctx, err = tx.Count("songs")
  1982  		r.NoError(err)
  1983  		r.Equal(count, ctx)
  1984  	})
  1985  }
  1986  
  1987  func Test_Create_Timestamps_With_NowFunc(t *testing.T) {
  1988  	if PDB == nil {
  1989  		t.Skip("skipping integration tests")
  1990  	}
  1991  	transaction(func(tx *Connection) {
  1992  		r := require.New(t)
  1993  
  1994  		originalNowFunc := nowFunc
  1995  		// ensure the original function is restored
  1996  		defer func() {
  1997  			nowFunc = originalNowFunc
  1998  		}()
  1999  
  2000  		fakeNow, _ := time.Parse(time.RFC3339, "2019-07-14T00:00:00Z")
  2001  		SetNowFunc(func() time.Time { return fakeNow })
  2002  
  2003  		friend := Friend{FirstName: "Yester", LastName: "Day"}
  2004  		err := tx.Create(&friend)
  2005  		r.NoError(err)
  2006  
  2007  		r.Equal(fakeNow, friend.CreatedAt)
  2008  		r.Equal(fakeNow, friend.UpdatedAt)
  2009  	})
  2010  }