github.com/paweljw/pop/v5@v5.4.6/executors_test.go (about)

     1  package pop
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/gobuffalo/nulls"
     8  	"github.com/gofrs/uuid"
     9  	"github.com/stretchr/testify/require"
    10  )
    11  
    12  func Test_IsZeroOfUnderlyingType(t *testing.T) {
    13  	if PDB == nil {
    14  		t.Skip("skipping integration tests")
    15  	}
    16  	r := require.New(t)
    17  	transaction(func(tx *Connection) {
    18  		car := &ValidatableCar{Name: "VW"}
    19  		r.True(IsZeroOfUnderlyingType(car.ID))
    20  		err := tx.Save(car)
    21  		r.NoError(err)
    22  		r.NotZero(car.ID)
    23  		r.NotZero(car.CreatedAt)
    24  
    25  		r.False(IsZeroOfUnderlyingType(car.ID))
    26  
    27  		var i int
    28  		r.True(IsZeroOfUnderlyingType(i))
    29  		i = 32
    30  		r.False(IsZeroOfUnderlyingType(i))
    31  
    32  		var s string
    33  		r.True(IsZeroOfUnderlyingType(s))
    34  		s = "42"
    35  		r.False(IsZeroOfUnderlyingType(s))
    36  
    37  		var u uuid.UUID
    38  		r.True(IsZeroOfUnderlyingType(u))
    39  		u, err = uuid.NewV1()
    40  		r.NoError(err)
    41  		r.False(IsZeroOfUnderlyingType(u))
    42  	})
    43  }
    44  
    45  func Test_ValidateAndSave(t *testing.T) {
    46  	if PDB == nil {
    47  		t.Skip("skipping integration tests")
    48  	}
    49  	r := require.New(t)
    50  	validationLogs = []string{}
    51  	transaction(func(tx *Connection) {
    52  		car := &ValidatableCar{Name: "VW"}
    53  		verrs, err := tx.ValidateAndSave(car)
    54  		r.NoError(err)
    55  		r.False(verrs.HasAny())
    56  		r.Len(validationLogs, 2)
    57  		r.Equal([]string{"Validate", "ValidateSave"}, validationLogs)
    58  		r.NotZero(car.ID)
    59  		r.NotZero(car.CreatedAt)
    60  
    61  		validationLogs = []string{}
    62  		car = &ValidatableCar{Name: ""}
    63  		verrs, err = tx.ValidateAndSave(car)
    64  		r.NoError(err)
    65  		r.True(verrs.HasAny())
    66  		r.Len(validationLogs, 2)
    67  		errs := verrs.Get("name")
    68  		r.Len(errs, 1)
    69  
    70  		validationLogs = []string{}
    71  		ncar := &NotValidatableCar{Name: ""}
    72  		verrs, err = tx.ValidateAndSave(ncar)
    73  		r.NoError(err)
    74  		r.False(verrs.HasAny())
    75  		r.Len(validationLogs, 0)
    76  	})
    77  }
    78  
    79  func Test_ValidateAndSave_With_Slice(t *testing.T) {
    80  	if PDB == nil {
    81  		t.Skip("skipping integration tests")
    82  	}
    83  	r := require.New(t)
    84  	validationLogs = []string{}
    85  	transaction(func(tx *Connection) {
    86  		car := []ValidatableCar{
    87  			{Name: "VW"},
    88  			{Name: "AU"},
    89  		}
    90  		verrs, err := tx.ValidateAndSave(&car)
    91  		r.NoError(err)
    92  		r.False(verrs.HasAny())
    93  		r.Len(validationLogs, 4)
    94  		r.Equal([]string{"Validate", "ValidateSave", "Validate", "ValidateSave"}, validationLogs)
    95  
    96  		r.NotZero(car[0].ID)
    97  		r.NotZero(car[0].CreatedAt)
    98  		r.NotZero(car[1].ID)
    99  		r.NotZero(car[1].CreatedAt)
   100  
   101  		validationLogs = []string{}
   102  		car = []ValidatableCar{
   103  			{Name: ""},
   104  			{Name: "AU"},
   105  		}
   106  		verrs, err = tx.ValidateAndSave(&car)
   107  		r.NoError(err)
   108  		r.True(verrs.HasAny())
   109  		r.Len(validationLogs, 2)
   110  		errs := verrs.Get("name")
   111  		r.Len(errs, 1)
   112  
   113  		validationLogs = []string{}
   114  		ncar := []NotValidatableCar{
   115  			{Name: ""},
   116  			{Name: "AU"},
   117  		}
   118  		verrs, err = tx.ValidateAndSave(&ncar)
   119  		r.NoError(err)
   120  		r.False(verrs.HasAny())
   121  		r.Len(validationLogs, 0)
   122  	})
   123  }
   124  
   125  func Test_ValidateAndCreate(t *testing.T) {
   126  	if PDB == nil {
   127  		t.Skip("skipping integration tests")
   128  	}
   129  	r := require.New(t)
   130  	validationLogs = []string{}
   131  	transaction(func(tx *Connection) {
   132  		car := &ValidatableCar{Name: "VW"}
   133  		verrs, err := tx.ValidateAndCreate(car)
   134  		r.NoError(err)
   135  		r.False(verrs.HasAny())
   136  		r.Len(validationLogs, 2)
   137  		r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs)
   138  		r.NotZero(car.ID)
   139  		r.NotZero(car.CreatedAt)
   140  
   141  		validationLogs = []string{}
   142  		car = &ValidatableCar{Name: ""}
   143  		verrs, err = tx.ValidateAndSave(car)
   144  		r.NoError(err)
   145  		r.True(verrs.HasAny())
   146  		r.Len(validationLogs, 2)
   147  		errs := verrs.Get("name")
   148  		r.Len(errs, 1)
   149  
   150  		validationLogs = []string{}
   151  		ncar := &NotValidatableCar{Name: ""}
   152  		verrs, err = tx.ValidateAndCreate(ncar)
   153  		r.NoError(err)
   154  		r.False(verrs.HasAny())
   155  		r.Len(validationLogs, 0)
   156  	})
   157  }
   158  
   159  func Test_Create_Single_Incremental_ID(t *testing.T) {
   160  	if PDB == nil {
   161  		t.Skip("skipping integration tests")
   162  	}
   163  	r := require.New(t)
   164  	validationLogs = []string{}
   165  	transaction(func(tx *Connection) {
   166  		singleID := &SingleID{}
   167  		err := tx.Create(singleID)
   168  		r.NoError(err)
   169  		r.NotZero(singleID.ID)
   170  	})
   171  }
   172  
   173  func Test_ValidateAndCreate_With_Slice(t *testing.T) {
   174  	if PDB == nil {
   175  		t.Skip("skipping integration tests")
   176  	}
   177  	r := require.New(t)
   178  	validationLogs = []string{}
   179  	transaction(func(tx *Connection) {
   180  		car := []ValidatableCar{
   181  			{Name: "VW"},
   182  			{Name: "AU"},
   183  		}
   184  		verrs, err := tx.ValidateAndCreate(&car)
   185  		r.NoError(err)
   186  		r.False(verrs.HasAny())
   187  		r.Len(validationLogs, 4)
   188  		r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs)
   189  		r.NotZero(car[0].ID)
   190  		r.NotZero(car[0].CreatedAt)
   191  		r.NotZero(car[1].ID)
   192  		r.NotZero(car[1].CreatedAt)
   193  
   194  		validationLogs = []string{}
   195  		car = []ValidatableCar{
   196  			{Name: ""},
   197  			{Name: "AU"},
   198  		}
   199  		verrs, err = tx.ValidateAndSave(&car)
   200  		r.NoError(err)
   201  		r.True(verrs.HasAny())
   202  		r.Len(validationLogs, 2)
   203  		errs := verrs.Get("name")
   204  		r.Len(errs, 1)
   205  
   206  		validationLogs = []string{}
   207  		ncar := []NotValidatableCar{
   208  			{Name: ""},
   209  			{Name: "AU"},
   210  		}
   211  		verrs, err = tx.ValidateAndCreate(ncar)
   212  		r.NoError(err)
   213  		r.False(verrs.HasAny())
   214  		r.Len(validationLogs, 0)
   215  	})
   216  }
   217  
   218  func Test_ValidateAndUpdate(t *testing.T) {
   219  	if PDB == nil {
   220  		t.Skip("skipping integration tests")
   221  	}
   222  	r := require.New(t)
   223  	validationLogs = []string{}
   224  	transaction(func(tx *Connection) {
   225  		car := &ValidatableCar{Name: "VW"}
   226  		verrs, err := tx.ValidateAndCreate(car)
   227  		r.NoError(err)
   228  		r.False(verrs.HasAny())
   229  		r.Len(validationLogs, 2)
   230  		r.Equal([]string{"Validate", "ValidateCreate"}, validationLogs)
   231  		r.NotZero(car.ID)
   232  		r.NotZero(car.CreatedAt)
   233  
   234  		validationLogs = []string{}
   235  		car.Name = ""
   236  		verrs, err = tx.ValidateAndUpdate(car)
   237  		r.NoError(err)
   238  		r.True(verrs.HasAny())
   239  		r.Len(validationLogs, 2)
   240  		errs := verrs.Get("name")
   241  		r.Len(errs, 1)
   242  
   243  		validationLogs = []string{}
   244  		ncar := &NotValidatableCar{Name: ""}
   245  		verrs, err = tx.ValidateAndCreate(ncar)
   246  		r.NoError(err)
   247  		r.False(verrs.HasAny())
   248  		r.Len(validationLogs, 0)
   249  
   250  		validationLogs = []string{}
   251  		ncar.Name = ""
   252  		verrs, err = tx.ValidateAndUpdate(ncar)
   253  		r.NoError(err)
   254  		r.False(verrs.HasAny())
   255  		r.Len(validationLogs, 0)
   256  	})
   257  }
   258  
   259  func Test_ValidateAndUpdate_With_Slice(t *testing.T) {
   260  	if PDB == nil {
   261  		t.Skip("skipping integration tests")
   262  	}
   263  	r := require.New(t)
   264  	validationLogs = []string{}
   265  	transaction(func(tx *Connection) {
   266  		car := []ValidatableCar{
   267  			{Name: "VW"},
   268  			{Name: "AU"},
   269  		}
   270  		verrs, err := tx.ValidateAndCreate(&car)
   271  		r.NoError(err)
   272  		r.False(verrs.HasAny())
   273  		r.Len(validationLogs, 4)
   274  		r.Equal([]string{"Validate", "ValidateCreate", "Validate", "ValidateCreate"}, validationLogs)
   275  		r.NotZero(car[0].ID)
   276  		r.NotZero(car[0].CreatedAt)
   277  		r.NotZero(car[1].ID)
   278  		r.NotZero(car[1].CreatedAt)
   279  
   280  		validationLogs = []string{}
   281  		car[0].Name = ""
   282  		verrs, err = tx.ValidateAndUpdate(&car)
   283  		r.NoError(err)
   284  		r.True(verrs.HasAny())
   285  		r.Len(validationLogs, 2)
   286  		errs := verrs.Get("name")
   287  		r.Len(errs, 1)
   288  
   289  		validationLogs = []string{}
   290  		ncar := []NotValidatableCar{
   291  			{Name: ""},
   292  			{Name: "AU"},
   293  		}
   294  		verrs, err = tx.ValidateAndCreate(&ncar)
   295  		r.NoError(err)
   296  		r.False(verrs.HasAny())
   297  		r.Len(validationLogs, 0)
   298  
   299  		validationLogs = []string{}
   300  		ncar[1].Name = ""
   301  		verrs, err = tx.ValidateAndUpdate(&ncar)
   302  		r.NoError(err)
   303  		r.False(verrs.HasAny())
   304  		r.Len(validationLogs, 0)
   305  	})
   306  }
   307  
   308  func Test_Exec(t *testing.T) {
   309  	if PDB == nil {
   310  		t.Skip("skipping integration tests")
   311  	}
   312  	transaction(func(tx *Connection) {
   313  		r := require.New(t)
   314  
   315  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   316  		tx.Create(&user)
   317  
   318  		ctx, _ := tx.Count(user)
   319  		r.Equal(1, ctx)
   320  
   321  		q := tx.RawQuery("delete from users where id = ?", user.ID)
   322  		err := q.Exec()
   323  		r.NoError(err)
   324  
   325  		ctx, _ = tx.Count(user)
   326  		r.Equal(0, ctx)
   327  	})
   328  }
   329  
   330  func Test_ExecCount(t *testing.T) {
   331  	if PDB == nil {
   332  		t.Skip("skipping integration tests")
   333  	}
   334  	transaction(func(tx *Connection) {
   335  		r := require.New(t)
   336  
   337  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   338  		tx.Create(&user)
   339  
   340  		ctx, _ := tx.Count(user)
   341  		r.Equal(1, ctx)
   342  
   343  		q := tx.RawQuery("delete from users where id = ?", user.ID)
   344  		count, err := q.ExecWithCount()
   345  		r.NoError(err)
   346  
   347  		r.Equal(1, count)
   348  
   349  		ctx, _ = tx.Count(user)
   350  		r.Equal(0, ctx)
   351  	})
   352  }
   353  
   354  func Test_Save(t *testing.T) {
   355  	if PDB == nil {
   356  		t.Skip("skipping integration tests")
   357  	}
   358  	r := require.New(t)
   359  	transaction(func(tx *Connection) {
   360  		u := &User{Name: nulls.NewString("Mark")}
   361  		r.Zero(u.ID)
   362  		r.NoError(tx.Save(u))
   363  		r.NotZero(u.ID)
   364  
   365  		uat := u.UpdatedAt.UnixNano()
   366  
   367  		r.NoError(tx.Save(u))
   368  		time.Sleep(1 * time.Second)
   369  		r.NotEqual(uat, u.UpdatedAt.UnixNano())
   370  	})
   371  }
   372  
   373  func Test_Save_With_Slice(t *testing.T) {
   374  	if PDB == nil {
   375  		t.Skip("skipping integration tests")
   376  	}
   377  	r := require.New(t)
   378  	transaction(func(tx *Connection) {
   379  		u := Users{
   380  			{Name: nulls.NewString("Mark")},
   381  			{Name: nulls.NewString("Larry")},
   382  		}
   383  		r.Zero(u[0].ID)
   384  		r.Zero(u[1].ID)
   385  
   386  		r.NoError(tx.Save(&u))
   387  		r.NotZero(u[0].ID)
   388  		r.NotZero(u[1].ID)
   389  
   390  		uat := u[0].UpdatedAt.UnixNano()
   391  
   392  		r.NoError(tx.Save(u))
   393  		r.NotEqual(uat, u[0].UpdatedAt.UnixNano())
   394  	})
   395  }
   396  
   397  func Test_Create(t *testing.T) {
   398  	if PDB == nil {
   399  		t.Skip("skipping integration tests")
   400  	}
   401  	transaction(func(tx *Connection) {
   402  		r := require.New(t)
   403  
   404  		count, _ := tx.Count(&User{})
   405  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
   406  		err := tx.Create(&user)
   407  		r.NoError(err)
   408  		r.NotEqual(0, user.ID)
   409  
   410  		ctx, _ := tx.Count(&User{})
   411  		r.Equal(count+1, ctx)
   412  
   413  		u := User{}
   414  		q := tx.Where("name = ?", "Mark 'Awesome' Bates")
   415  		err = q.First(&u)
   416  		r.NoError(err)
   417  		r.Equal("Mark 'Awesome' Bates", user.Name.String)
   418  	})
   419  }
   420  
   421  func Test_Create_stringID(t *testing.T) {
   422  	if PDB == nil {
   423  		t.Skip("skipping integration tests")
   424  	}
   425  	transaction(func(tx *Connection) {
   426  		r := require.New(t)
   427  
   428  		count, err := tx.Count(&Label{})
   429  		r.NoError(err)
   430  		label := Label{ID: "red"}
   431  		err = tx.Create(&label)
   432  		r.NoError(err)
   433  		r.Equal("red", label.ID)
   434  
   435  		ctx, err := tx.Count(&Label{})
   436  		r.NoError(err)
   437  		r.Equal(count+1, ctx)
   438  
   439  		l := Label{}
   440  		err = tx.Find(&l, "red")
   441  		r.NoError(err)
   442  		r.Equal("red", l.ID)
   443  	})
   444  }
   445  
   446  func Test_Create_With_Slice(t *testing.T) {
   447  	if PDB == nil {
   448  		t.Skip("skipping integration tests")
   449  	}
   450  	transaction(func(tx *Connection) {
   451  		r := require.New(t)
   452  
   453  		count, _ := tx.Count(&User{})
   454  		users := Users{
   455  			{Name: nulls.NewString("Mark Bates")},
   456  			{Name: nulls.NewString("Larry M. Jordan")},
   457  			{Name: nulls.NewString("Pop")},
   458  		}
   459  		err := tx.Create(&users)
   460  		r.NoError(err)
   461  
   462  		ctx, _ := tx.Count(&User{})
   463  		r.Equal(count+3, ctx)
   464  	})
   465  }
   466  
   467  func Test_Create_With_Non_ID_PK(t *testing.T) {
   468  	if PDB == nil {
   469  		t.Skip("skipping integration tests")
   470  	}
   471  	transaction(func(tx *Connection) {
   472  		r := require.New(t)
   473  
   474  		count, _ := tx.Count(&CrookedColour{})
   475  		djs := []CrookedColour{
   476  			{Name: "Phil Slabber"},
   477  			{Name: "Leon Debaughn"},
   478  			{Name: "Liam Merrett-Park"},
   479  		}
   480  		err := tx.Create(&djs)
   481  		r.NoError(err)
   482  
   483  		ctx, _ := tx.Count(&CrookedColour{})
   484  		r.Equal(count+3, ctx)
   485  		r.NotEqual(djs[0].ID, djs[1].ID)
   486  		r.NotEqual(djs[1].ID, djs[2].ID)
   487  	})
   488  }
   489  
   490  func Test_Create_With_Non_ID_PK_String(t *testing.T) {
   491  	if PDB == nil {
   492  		t.Skip("skipping integration tests")
   493  	}
   494  	transaction(func(tx *Connection) {
   495  		r := require.New(t)
   496  
   497  		count, _ := tx.Count(&CrookedSong{})
   498  		djs := []CrookedSong{
   499  			{ID: "Flow"},
   500  			{ID: "Do It Like You"},
   501  			{ID: "I C Light"},
   502  		}
   503  		err := tx.Create(&djs)
   504  		r.NoError(err)
   505  
   506  		ctx, _ := tx.Count(&CrookedSong{})
   507  		r.Equal(count+3, ctx)
   508  		r.NotEqual(djs[0].ID, djs[1].ID)
   509  		r.NotEqual(djs[1].ID, djs[2].ID)
   510  	})
   511  }
   512  
   513  func Test_Create_Non_PK_ID(t *testing.T) {
   514  	if PDB == nil {
   515  		t.Skip("skipping integration tests")
   516  	}
   517  	transaction(func(tx *Connection) {
   518  		r := require.New(t)
   519  
   520  		r.NoError(tx.Create(&NonStandardID{OutfacingID: "make sure the tested entry does not have pk=0"}))
   521  
   522  		count, err := tx.Count(&NonStandardID{})
   523  		entry := &NonStandardID{
   524  			OutfacingID: "beautiful to the outside ID",
   525  		}
   526  		r.NoError(tx.Create(entry))
   527  
   528  		ctx, err := tx.Count(&NonStandardID{})
   529  		r.NoError(err)
   530  		r.Equal(count+1, ctx)
   531  		r.NotZero(entry.ID)
   532  	})
   533  }
   534  
   535  func Test_Eager_Create_Has_Many(t *testing.T) {
   536  	if PDB == nil {
   537  		t.Skip("skipping integration tests")
   538  	}
   539  	transaction(func(tx *Connection) {
   540  		r := require.New(t)
   541  		count, _ := tx.Count(&User{})
   542  		user := User{
   543  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   544  			Books:        Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   545  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   546  			Houses: Addresses{
   547  				Address{HouseNumber: 86, Street: "Modelo"},
   548  			},
   549  		}
   550  
   551  		err := tx.Eager().Create(&user)
   552  		r.NoError(err)
   553  		r.NotEqual(user.ID, 0)
   554  
   555  		ctx, _ := tx.Count(&User{})
   556  		r.Equal(count+1, ctx)
   557  
   558  		ctx, _ = tx.Count(&Book{})
   559  		r.Equal(count+1, ctx)
   560  
   561  		ctx, _ = tx.Count(&Song{})
   562  		r.Equal(count+1, ctx)
   563  
   564  		ctx, _ = tx.Count(&Address{})
   565  		r.Equal(count+1, ctx)
   566  
   567  		u := User{}
   568  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   569  		err = q.First(&u)
   570  		r.NoError(err)
   571  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   572  		r.Equal(1, len(u.Books))
   573  		r.Equal(u.Books[0].Title, "Pop Book")
   574  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   575  		r.Equal(1, len(u.Houses))
   576  		r.Equal(u.Houses[0].Street, "Modelo")
   577  	})
   578  }
   579  
   580  func Test_Eager_Create_Has_Many_With_Existing(t *testing.T) {
   581  	if PDB == nil {
   582  		t.Skip("skipping integration tests")
   583  	}
   584  	transaction(func(tx *Connection) {
   585  		r := require.New(t)
   586  
   587  		addr := Address{HouseNumber: 42, Street: "Life"}
   588  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   589  		r.NoError(addrErr)
   590  		addrCount, _ := tx.Count(&Address{})
   591  		r.Zero(addrVerrs.Count())
   592  		r.Equal(1, addrCount)
   593  		r.NotZero(addr.ID)
   594  
   595  		count, _ := tx.Count(&User{})
   596  		user := User{
   597  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   598  			Books:        Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   599  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   600  			Houses: Addresses{
   601  				Address{HouseNumber: 86, Street: "Modelo"},
   602  				addr,
   603  			},
   604  		}
   605  
   606  		err := tx.Eager().Create(&user)
   607  		r.NoError(err)
   608  		r.NotEqual(user.ID, 0)
   609  
   610  		ctx, _ := tx.Count(&User{})
   611  		r.Equal(count+1, ctx)
   612  
   613  		ctx, _ = tx.Count(&Book{})
   614  		r.Equal(count+1, ctx)
   615  
   616  		ctx, _ = tx.Count(&Song{})
   617  		r.Equal(count+1, ctx)
   618  
   619  		ctx, _ = tx.Count(&Address{})
   620  		r.Equal(addrCount+1, ctx)
   621  
   622  		u := User{}
   623  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   624  		err = q.First(&u)
   625  		r.NoError(err)
   626  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   627  		r.Equal(1, len(u.Books))
   628  		r.Equal(u.Books[0].Title, "Pop Book")
   629  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   630  		r.Equal(2, len(u.Houses))
   631  		if u.Houses[0].ID == addr.ID {
   632  			r.Equal(u.Houses[0].Street, "Life")
   633  			r.Equal(u.Houses[1].Street, "Modelo")
   634  		} else {
   635  			r.Equal(u.Houses[0].Street, "Modelo")
   636  			r.Equal(u.Houses[1].Street, "Life")
   637  		}
   638  	})
   639  }
   640  
   641  func Test_Eager_Create_Has_Many_Reset_Eager_Mode_Connection(t *testing.T) {
   642  	if PDB == nil {
   643  		t.Skip("skipping integration tests")
   644  	}
   645  	transaction(func(tx *Connection) {
   646  		r := require.New(t)
   647  		count, _ := tx.Count(&User{})
   648  		user1 := User{
   649  			Name:  nulls.NewString("Mark 'Awesome' Bates"),
   650  			Books: Books{{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}},
   651  		}
   652  
   653  		err := tx.Eager("Books").Create(&user1)
   654  		r.NoError(err)
   655  		ctx, _ := tx.Count(&User{})
   656  		r.Equal(count+1, ctx)
   657  		ctx, _ = tx.Count(&Book{})
   658  		r.Equal(count+1, ctx)
   659  
   660  		book := Book{Title: "Pop Book", Description: "Pop Book", Isbn: "PB1"}
   661  
   662  		err = tx.Eager().Create(&book)
   663  		r.NoError(err)
   664  		ctx, _ = tx.Count(&Book{})
   665  		r.Equal(count+2, ctx)
   666  	})
   667  }
   668  
   669  func Test_Eager_Validate_And_Create_Has_Many(t *testing.T) {
   670  	if PDB == nil {
   671  		t.Skip("skipping integration tests")
   672  	}
   673  	r := require.New(t)
   674  	transaction(func(tx *Connection) {
   675  		user := User{
   676  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   677  			Books:        Books{{Title: "Pop Book", Isbn: "PB1"}},
   678  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   679  			Houses: Addresses{
   680  				Address{HouseNumber: 86, Street: "Modelo"},
   681  			},
   682  		}
   683  
   684  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   685  		r.NoError(err)
   686  		ctx, _ := tx.Count(&User{})
   687  		r.Zero(ctx)
   688  		r.Equal(1, verrs.Count()) // Missing Books.Description.
   689  	})
   690  }
   691  
   692  func Test_Eager_Validate_And_Create_Parental(t *testing.T) {
   693  	if PDB == nil {
   694  		t.Skip("skipping integration tests")
   695  	}
   696  	r := require.New(t)
   697  	transaction(func(tx *Connection) {
   698  		user := User{
   699  			Name:         nulls.NewString(""),
   700  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   701  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   702  			Houses: Addresses{
   703  				Address{HouseNumber: 86, Street: "Modelo"},
   704  			},
   705  		}
   706  
   707  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   708  		r.NoError(err)
   709  		ctx, _ := tx.Count(&User{})
   710  		r.Zero(ctx)
   711  		r.Equal(1, verrs.Count()) // Missing Books.Description.
   712  	})
   713  }
   714  
   715  func Test_Eager_Validate_And_Create_Parental_With_Existing(t *testing.T) {
   716  	if PDB == nil {
   717  		t.Skip("skipping integration tests")
   718  	}
   719  	r := require.New(t)
   720  	transaction(func(tx *Connection) {
   721  		addr := Address{HouseNumber: 42, Street: "Life"}
   722  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   723  		r.NoError(addrErr)
   724  		addrCount, _ := tx.Count(&Address{})
   725  		r.Zero(addrVerrs.Count())
   726  		r.Equal(1, addrCount)
   727  		r.NotZero(addr.ID)
   728  
   729  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   730  		r.NoError(m2mErr)
   731  		r.Zero(m2mCount)
   732  
   733  		user := User{
   734  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   735  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   736  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   737  			Houses: Addresses{
   738  				Address{HouseNumber: 86, Street: "Modelo"},
   739  				addr,
   740  			},
   741  		}
   742  		count, _ := tx.Count(&User{})
   743  
   744  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   745  		r.NoError(err)
   746  		r.NotEqual(user.ID, 0)
   747  		r.Equal(0, verrs.Count())
   748  
   749  		ctx, _ := tx.Count(&User{})
   750  		r.Equal(count+1, ctx)
   751  
   752  		ctx, _ = tx.Count(&Address{})
   753  		r.Equal(addrCount+1, ctx)
   754  
   755  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   756  		r.NoError(m2mErr)
   757  		r.Equal(2, m2mCount)
   758  
   759  		u := User{}
   760  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   761  		err = q.First(&u)
   762  		r.NoError(err)
   763  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   764  		r.Equal(1, len(u.Books))
   765  		r.Equal(u.Books[0].Title, "Pop Book")
   766  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   767  		r.Equal(2, len(u.Houses))
   768  		if u.Houses[0].ID == addr.ID {
   769  			r.Equal(u.Houses[0].Street, "Life")
   770  			r.Equal(u.Houses[1].Street, "Modelo")
   771  		} else {
   772  			r.Equal(u.Houses[1].ID, addr.ID)
   773  			r.Equal(u.Houses[0].Street, "Modelo")
   774  			r.Equal(u.Houses[1].Street, "Life")
   775  		}
   776  	})
   777  }
   778  
   779  func Test_Eager_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) {
   780  	if PDB == nil {
   781  		t.Skip("skipping integration tests")
   782  	}
   783  	r := require.New(t)
   784  	transaction(func(tx *Connection) {
   785  		addr := Address{HouseNumber: 42, Street: "Life"}
   786  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   787  		r.NoError(addrErr)
   788  		addrCount, _ := tx.Count(&Address{})
   789  		r.Zero(addrVerrs.Count())
   790  		r.Equal(1, addrCount)
   791  		r.NotZero(addr.ID)
   792  
   793  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   794  		r.NoError(m2mErr)
   795  		r.Zero(m2mCount)
   796  
   797  		user := User{
   798  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   799  			Books:        Books{{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}},
   800  			FavoriteSong: Song{Title: "Hook - Blues Traveler"},
   801  			Houses: Addresses{
   802  				Address{HouseNumber: 86, Street: "Modelo"},
   803  				Address{ID: addr.ID},
   804  			},
   805  		}
   806  		count, _ := tx.Count(&User{})
   807  
   808  		verrs, err := tx.Eager().ValidateAndCreate(&user)
   809  		r.NoError(err)
   810  		r.NotEqual(user.ID, 0)
   811  		r.Equal(0, verrs.Count())
   812  
   813  		ctx, _ := tx.Count(&User{})
   814  		r.Equal(count+1, ctx)
   815  
   816  		ctx, _ = tx.Count(&Address{})
   817  		r.Equal(addrCount+1, ctx)
   818  
   819  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   820  		r.NoError(m2mErr)
   821  		r.Equal(2, m2mCount)
   822  
   823  		u := User{}
   824  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   825  		err = q.First(&u)
   826  		r.NoError(err)
   827  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   828  		r.Equal(1, len(u.Books))
   829  		r.Equal(u.Books[0].Title, "Pop Book")
   830  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   831  		r.Equal(2, len(u.Houses))
   832  		if u.Houses[0].ID == addr.ID {
   833  			r.Equal("Life", u.Houses[0].Street) // Street is blanked out
   834  			r.Equal("Modelo", u.Houses[1].Street)
   835  		} else {
   836  			r.Equal(addr.ID, u.Houses[1].ID)
   837  			r.Equal("Modelo", u.Houses[0].Street)
   838  			r.Equal("Life", u.Houses[1].Street) // Street is blanked out
   839  		}
   840  	})
   841  }
   842  
   843  func Test_Flat_Validate_And_Create_Parental_With_Existing(t *testing.T) {
   844  	if PDB == nil {
   845  		t.Skip("skipping integration tests")
   846  	}
   847  	r := require.New(t)
   848  	transaction(func(tx *Connection) {
   849  		addr := Address{HouseNumber: 42, Street: "Life"}
   850  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   851  		r.NoError(addrErr)
   852  		addrCount, _ := tx.Count(&Address{})
   853  		r.Zero(addrVerrs.Count())
   854  		r.Equal(1, addrCount)
   855  		r.NotZero(addr.ID)
   856  
   857  		book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}
   858  		bookVerrs, bookErr := tx.ValidateAndCreate(&book)
   859  		r.NoError(bookErr)
   860  		r.Zero(bookVerrs.Count())
   861  		r.NotZero(book.ID)
   862  
   863  		book2 := Book{Title: "Pop Book2", Isbn: "PB2", Description: "Awesome Book Also!"}
   864  		bookVerrs, bookErr = tx.ValidateAndCreate(&book2)
   865  		r.NoError(bookErr)
   866  		r.Zero(bookVerrs.Count())
   867  		r.NotZero(book2.ID)
   868  
   869  		bookCount, _ := tx.Count(&Book{})
   870  		r.Equal(2, bookCount)
   871  
   872  		song := Song{Title: "Hook - Blues Traveler"}
   873  		songVerrs, songErr := tx.ValidateAndCreate(&song)
   874  		r.NoError(songErr)
   875  		songCount, _ := tx.Count(&Song{})
   876  		r.Zero(songVerrs.Count())
   877  		r.Equal(1, songCount)
   878  		r.NotZero(song.ID)
   879  
   880  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   881  		r.NoError(m2mErr)
   882  		r.Zero(m2mCount)
   883  
   884  		user := User{
   885  			Name:         nulls.NewString("Mark 'Awesome' Bates"),
   886  			Books:        Books{book, book2},
   887  			FavoriteSong: song,
   888  			Houses: Addresses{
   889  				Address{HouseNumber: 86, Street: "Modelo"},
   890  				addr,
   891  			},
   892  		}
   893  		count, _ := tx.Count(&User{})
   894  
   895  		verrs, err := tx.ValidateAndCreate(&user)
   896  		r.NoError(err)
   897  		r.NotEqual(user.ID, 0)
   898  		r.Equal(0, verrs.Count())
   899  
   900  		ctx, _ := tx.Count(&User{})
   901  		r.Equal(count+1, ctx)
   902  
   903  		ctx, _ = tx.Count(&Address{})
   904  		r.Equal(addrCount, ctx)
   905  
   906  		ctx, _ = tx.Count(&Book{})
   907  		r.Equal(bookCount, ctx)
   908  
   909  		ctx, _ = tx.Count(&Song{})
   910  		r.Equal(songCount, ctx)
   911  
   912  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
   913  		r.NoError(m2mErr)
   914  		r.Equal(1, m2mCount)
   915  
   916  		u := User{}
   917  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
   918  		err = q.First(&u)
   919  		r.NoError(err)
   920  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
   921  		r.Equal(2, len(u.Books))
   922  		if u.Books[0].ID == book.ID {
   923  			r.Equal(u.Books[0].Title, "Pop Book")
   924  			r.Equal(u.Books[1].Title, "Pop Book2")
   925  		} else {
   926  			r.Equal(u.Books[1].Title, "Pop Book")
   927  			r.Equal(u.Books[0].Title, "Pop Book2")
   928  		}
   929  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
   930  		r.Equal(1, len(u.Houses))
   931  		r.Equal(addr.ID, u.Houses[0].ID)
   932  		r.Equal("Life", u.Houses[0].Street)
   933  	})
   934  }
   935  
   936  func Test_Flat_Validate_And_Create_Parental_With_Partial_Existing(t *testing.T) {
   937  	if PDB == nil {
   938  		t.Skip("skipping integration tests")
   939  	}
   940  	r := require.New(t)
   941  	transaction(func(tx *Connection) {
   942  		addr := Address{HouseNumber: 42, Street: "Life"}
   943  		addrVerrs, addrErr := tx.ValidateAndCreate(&addr)
   944  		r.NoError(addrErr)
   945  		addrCount, _ := tx.Count(&Address{})
   946  		r.Zero(addrVerrs.Count())
   947  		r.Equal(1, addrCount)
   948  		r.NotZero(addr.ID)
   949  
   950  		book := Book{Title: "Pop Book", Isbn: "PB1", Description: "Awesome Book!"}
   951  		bookVerrs, bookErr := tx.ValidateAndCreate(&book)
   952  		r.NoError(bookErr)
   953  		bookCount, _ := tx.Count(&Book{})
   954  		r.Zero(bookVerrs.Count())
   955  		r.Equal(1, bookCount)
   956  		r.NotZero(book.ID)
   957  
   958  		song := Song{Title: "Hook - Blues Traveler"}
   959  		songVerrs, songErr := tx.ValidateAndCreate(&song)
   960  		r.NoError(songErr)
   961  		songCount, _ := tx.Count(&Song{})
   962  		r.Zero(songVerrs.Count())
   963  		r.Equal(1, songCount)
   964  		r.NotZero(song.ID)
   965  
   966  		m2mCount, m2mErr := tx.Count(&UsersAddress{})
   967  		r.NoError(m2mErr)
   968  		r.Zero(m2mCount)
   969  
   970  		user := User{
   971  			Name: nulls.NewString("Mark 'Awesome' Bates"),
   972  			//TODO: add another existing here and test for it to make sure this works with multiples (books)
   973  			Books:        Books{Book{ID: book.ID}},
   974  			FavoriteSong: Song{ID: song.ID},
   975  			Houses: Addresses{
   976  				Address{HouseNumber: 86, Street: "Modelo"},
   977  				Address{ID: addr.ID},
   978  			},
   979  		}
   980  		count, _ := tx.Count(&User{})
   981  
   982  		verrs, err := tx.ValidateAndCreate(&user)
   983  		r.NoError(err)
   984  		r.NotEqual(user.ID, 0)
   985  		r.Equal(0, verrs.Count())
   986  
   987  		ctx, _ := tx.Count(&User{})
   988  		r.Equal(count+1, ctx)
   989  
   990  		ctx, _ = tx.Count(&Address{})
   991  		r.Equal(addrCount, ctx)
   992  
   993  		ctx, _ = tx.Where("user_id = ?", user.ID).Count(&Book{})
   994  		r.Equal(bookCount, ctx)
   995  
   996  		ctx, _ = tx.Count(&Song{})
   997  		r.Equal(songCount, ctx)
   998  
   999  		m2mCount, m2mErr = tx.Count(&UsersAddress{})
  1000  		r.NoError(m2mErr)
  1001  		r.Equal(1, m2mCount)
  1002  
  1003  		u := User{}
  1004  		q := tx.Eager().Where("name = ?", "Mark 'Awesome' Bates")
  1005  		err = q.First(&u)
  1006  		r.NoError(err)
  1007  		r.Equal(u.Name.String, "Mark 'Awesome' Bates")
  1008  		r.Equal(1, len(u.Books))
  1009  		r.Equal(u.Books[0].Title, "Pop Book")
  1010  		r.Equal(u.FavoriteSong.Title, "Hook - Blues Traveler")
  1011  		r.Equal(1, len(u.Houses))
  1012  		r.Equal(addr.ID, u.Houses[0].ID)
  1013  		r.Equal("Life", u.Houses[0].Street)
  1014  	})
  1015  }
  1016  
  1017  func Test_Eager_Create_Belongs_To(t *testing.T) {
  1018  	if PDB == nil {
  1019  		t.Skip("skipping integration tests")
  1020  	}
  1021  	transaction(func(tx *Connection) {
  1022  		r := require.New(t)
  1023  		book := Book{
  1024  			Title:       "Pop Book",
  1025  			Description: "Pop Book",
  1026  			Isbn:        "PB1",
  1027  			User: User{
  1028  				Name: nulls.NewString("Larry"),
  1029  			},
  1030  		}
  1031  
  1032  		err := tx.Eager().Create(&book)
  1033  		r.NoError(err)
  1034  
  1035  		ctx, _ := tx.Count(&Book{})
  1036  		r.Equal(1, ctx)
  1037  
  1038  		ctx, _ = tx.Count(&User{})
  1039  		r.Equal(1, ctx)
  1040  
  1041  		car := Taxi{
  1042  			Model: "Fancy car",
  1043  			Driver: &User{
  1044  				Name: nulls.NewString("Larry 2"),
  1045  			},
  1046  		}
  1047  
  1048  		err = tx.Eager().Create(&car)
  1049  		r.NoError(err)
  1050  
  1051  		ctx, _ = tx.Count(&Taxi{})
  1052  		r.Equal(1, ctx)
  1053  
  1054  		err = tx.Eager().Find(&car, car.ID)
  1055  		r.NoError(err)
  1056  
  1057  		r.Equal(nulls.NewString("Larry 2"), car.Driver.Name)
  1058  	})
  1059  }
  1060  
  1061  func Test_Eager_Create_Belongs_To_Pointers(t *testing.T) {
  1062  	if PDB == nil {
  1063  		t.Skip("skipping integration tests")
  1064  	}
  1065  	transaction(func(tx *Connection) {
  1066  		r := require.New(t)
  1067  		// Create a body with a head
  1068  		body := Body{
  1069  			Head: &Head{},
  1070  		}
  1071  
  1072  		err := tx.Eager().Create(&body)
  1073  		r.NoError(err)
  1074  		r.NotZero(body.ID)
  1075  		r.NotZero(body.Head.ID)
  1076  
  1077  		ctx, _ := tx.Count(&Body{})
  1078  		r.Equal(1, ctx)
  1079  
  1080  		ctx, _ = tx.Count(&Head{})
  1081  		r.Equal(1, ctx)
  1082  
  1083  		// Create a body without a head:
  1084  		body = Body{
  1085  			Head: nil,
  1086  		}
  1087  
  1088  		err = tx.Eager().Create(&body)
  1089  		r.NoError(err)
  1090  		r.NotZero(body.ID)
  1091  		r.Nil(body.Head)
  1092  
  1093  		ctx, _ = tx.Count(&Body{})
  1094  		r.Equal(2, ctx)
  1095  
  1096  		ctx, _ = tx.Count(&Head{})
  1097  		r.Equal(1, ctx)
  1098  
  1099  		err = tx.Eager().Create(&Head{
  1100  			BodyID: body.ID,
  1101  			Body:   nil,
  1102  		})
  1103  		r.NoError(err)
  1104  	})
  1105  }
  1106  
  1107  func Test_Create_Belongs_To_Pointers(t *testing.T) {
  1108  	if PDB == nil {
  1109  		t.Skip("skipping integration tests")
  1110  	}
  1111  	transaction(func(tx *Connection) {
  1112  		r := require.New(t)
  1113  		// Create a body without a head:
  1114  		body := Body{
  1115  			Head: nil,
  1116  		}
  1117  
  1118  		err := tx.Create(&body)
  1119  		r.NoError(err)
  1120  		r.NotZero(body.ID)
  1121  		r.Nil(body.Head)
  1122  
  1123  		// Create a head with the associated model set but not the ID
  1124  		created := HeadPtr{
  1125  			Body: &body,
  1126  		}
  1127  		err = tx.Create(&created)
  1128  		r.NoError(err)
  1129  
  1130  		found := HeadPtr{}
  1131  		err = tx.Find(&found, created.ID)
  1132  		r.NoError(err)
  1133  		r.Equal(body.ID, *found.BodyID)
  1134  	})
  1135  }
  1136  
  1137  func Test_Flat_Create_Belongs_To(t *testing.T) {
  1138  	if PDB == nil {
  1139  		t.Skip("skipping integration tests")
  1140  	}
  1141  	transaction(func(tx *Connection) {
  1142  		r := require.New(t)
  1143  		user := User{
  1144  			Name: nulls.NewString("Larry"),
  1145  		}
  1146  
  1147  		err := tx.Create(&user)
  1148  		r.NoError(err)
  1149  		ctx, _ := tx.Count(&User{})
  1150  		r.Equal(1, ctx)
  1151  
  1152  		book := Book{
  1153  			Title:       "Pop Book",
  1154  			Description: "Pop Book",
  1155  			Isbn:        "PB1",
  1156  			User:        user,
  1157  		}
  1158  
  1159  		err = tx.Create(&book)
  1160  		r.NoError(err)
  1161  
  1162  		ctx, _ = tx.Count(&Book{})
  1163  		r.Equal(1, ctx)
  1164  
  1165  		err = tx.Eager().Find(&book, book.ID)
  1166  		r.NoError(err)
  1167  
  1168  		r.Equal(nulls.NewString("Larry"), book.User.Name)
  1169  
  1170  		car := Taxi{
  1171  			Model:  "Fancy car",
  1172  			Driver: &user,
  1173  		}
  1174  
  1175  		err = tx.Create(&car)
  1176  		r.NoError(err)
  1177  
  1178  		ctx, _ = tx.Count(&Taxi{})
  1179  		r.Equal(1, ctx)
  1180  
  1181  		err = tx.Eager().Find(&car, car.ID)
  1182  		r.NoError(err)
  1183  
  1184  		r.Equal(nulls.NewString("Larry"), car.Driver.Name)
  1185  	})
  1186  }
  1187  
  1188  func Test_Eager_Creation_Without_Associations(t *testing.T) {
  1189  	if PDB == nil {
  1190  		t.Skip("skipping integration tests")
  1191  	}
  1192  	transaction(func(tx *Connection) {
  1193  		r := require.New(t)
  1194  		code := CourseCode{
  1195  			Course: Course{},
  1196  		}
  1197  
  1198  		err := tx.Eager().Create(&code)
  1199  		r.NoError(err)
  1200  
  1201  		ctx, _ := tx.Count(&CourseCode{})
  1202  		r.Equal(1, ctx)
  1203  	})
  1204  }
  1205  
  1206  func Test_Create_UUID(t *testing.T) {
  1207  	if PDB == nil {
  1208  		t.Skip("skipping integration tests")
  1209  	}
  1210  	transaction(func(tx *Connection) {
  1211  		r := require.New(t)
  1212  
  1213  		count, _ := tx.Count(&Song{})
  1214  		song := Song{Title: "Automatic Buffalo"}
  1215  		err := tx.Create(&song)
  1216  		r.NoError(err)
  1217  		r.NotZero(song.ID)
  1218  
  1219  		ctx, _ := tx.Count(&Song{})
  1220  		r.Equal(count+1, ctx)
  1221  
  1222  		u := Song{}
  1223  		q := tx.Where("title = ?", "Automatic Buffalo")
  1224  		err = q.First(&u)
  1225  		r.NoError(err)
  1226  	})
  1227  }
  1228  
  1229  func Test_Create_Existing_UUID(t *testing.T) {
  1230  	if PDB == nil {
  1231  		t.Skip("skipping integration tests")
  1232  	}
  1233  	transaction(func(tx *Connection) {
  1234  		r := require.New(t)
  1235  		id, err := uuid.NewV4()
  1236  		r.NoError(err)
  1237  
  1238  		count, _ := tx.Count(&Song{})
  1239  		song := Song{
  1240  			ID:    id,
  1241  			Title: "Automatic Buffalo",
  1242  		}
  1243  
  1244  		err = tx.Create(&song)
  1245  		r.NoError(err)
  1246  		r.NotZero(song.ID)
  1247  		r.Equal(id.String(), song.ID.String())
  1248  
  1249  		ctx, _ := tx.Count(&Song{})
  1250  		r.Equal(count+1, ctx)
  1251  
  1252  	})
  1253  }
  1254  
  1255  func Test_Create_Timestamps(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  		user := User{Name: nulls.NewString("Mark 'Awesome' Bates")}
  1263  		r.Zero(user.CreatedAt)
  1264  		r.Zero(user.UpdatedAt)
  1265  
  1266  		err := tx.Create(&user)
  1267  		r.NoError(err)
  1268  
  1269  		r.NotZero(user.CreatedAt)
  1270  		r.NotZero(user.UpdatedAt)
  1271  
  1272  		friend := Friend{FirstName: "Ross", LastName: "Gellar"}
  1273  		err = tx.Create(&friend)
  1274  		r.NoError(err)
  1275  	})
  1276  }
  1277  
  1278  func Test_Update(t *testing.T) {
  1279  	if PDB == nil {
  1280  		t.Skip("skipping integration tests")
  1281  	}
  1282  	transaction(func(tx *Connection) {
  1283  		r := require.New(t)
  1284  
  1285  		user := User{Name: nulls.NewString("Mark")}
  1286  		tx.Create(&user)
  1287  
  1288  		r.NotZero(user.CreatedAt)
  1289  		r.NotZero(user.UpdatedAt)
  1290  
  1291  		user.Name.String = "Marky"
  1292  		err := tx.Update(&user)
  1293  		r.NoError(err)
  1294  
  1295  		r.NoError(tx.Reload(&user))
  1296  		r.Equal(user.Name.String, "Marky")
  1297  	})
  1298  }
  1299  
  1300  func Test_UpdateColumns(t *testing.T) {
  1301  	if PDB == nil {
  1302  		t.Skip("skipping integration tests")
  1303  	}
  1304  	transaction(func(tx *Connection) {
  1305  		r := require.New(t)
  1306  
  1307  		user := User{Name: nulls.NewString("Mark")}
  1308  		tx.Create(&user)
  1309  
  1310  		r.NotZero(user.CreatedAt)
  1311  		r.NotZero(user.UpdatedAt)
  1312  
  1313  		user.Name.String = "Fulano"
  1314  		user.UserName = "Fulano"
  1315  		err := tx.UpdateColumns(&user, "user_name") // Update UserName field/column only
  1316  		r.NoError(err)
  1317  
  1318  		r.NoError(tx.Reload(&user))
  1319  		r.Equal(user.Name.String, "Mark") // Name column should not be updated
  1320  		r.Equal(user.UserName, "Fulano")
  1321  	})
  1322  }
  1323  
  1324  func Test_UpdateColumns_UpdatedAt(t *testing.T) {
  1325  	if PDB == nil {
  1326  		t.Skip("skipping integration tests")
  1327  	}
  1328  	transaction(func(tx *Connection) {
  1329  		r := require.New(t)
  1330  
  1331  		user := User{Name: nulls.NewString("Foo")}
  1332  		tx.Create(&user)
  1333  
  1334  		r.NotZero(user.CreatedAt)
  1335  		r.NotZero(user.UpdatedAt)
  1336  		updatedAtBefore := user.UpdatedAt
  1337  
  1338  		user.Name.String = "Bar"
  1339  		err := tx.UpdateColumns(&user, "name", "updated_at") // Update name and updated_at
  1340  		r.NoError(err)
  1341  
  1342  		r.NoError(tx.Reload(&user))
  1343  		r.NotEqual(user.UpdatedAt, updatedAtBefore) // UpdatedAt should be updated automatically
  1344  	})
  1345  }
  1346  
  1347  func Test_UpdateColumns_MultipleColumns(t *testing.T) {
  1348  	if PDB == nil {
  1349  		t.Skip("skipping integration tests")
  1350  	}
  1351  	transaction(func(tx *Connection) {
  1352  		r := require.New(t)
  1353  
  1354  		user := User{Name: nulls.NewString("Mark"), UserName: "Sagan", Email: "test@example.com"}
  1355  		tx.Create(&user)
  1356  
  1357  		r.NotZero(user.CreatedAt)
  1358  		r.NotZero(user.UpdatedAt)
  1359  
  1360  		user.Name.String = "Ping"
  1361  		user.UserName = "Pong"
  1362  		user.Email = "fulano@example"
  1363  		err := tx.UpdateColumns(&user, "name", "user_name") // Update multiple columns
  1364  		r.NoError(err)
  1365  
  1366  		r.NoError(tx.Reload(&user))
  1367  		r.Equal(user.Name.String, "Ping")
  1368  		r.Equal(user.UserName, "Pong")
  1369  		r.Equal(user.Email, "test@example.com") // Email should not be updated
  1370  	})
  1371  }
  1372  
  1373  func Test_UpdateColumns_All(t *testing.T) {
  1374  	if PDB == nil {
  1375  		t.Skip("skipping integration tests")
  1376  	}
  1377  	transaction(func(tx *Connection) {
  1378  		r := require.New(t)
  1379  
  1380  		user := User{Name: nulls.NewString("Mark"), UserName: "Sagan"}
  1381  		tx.Create(&user)
  1382  
  1383  		r.NotZero(user.CreatedAt)
  1384  		r.NotZero(user.UpdatedAt)
  1385  
  1386  		user.Name.String = "Ping"
  1387  		user.UserName = "Pong"
  1388  		user.Email = "ping@pong.com"
  1389  		err := tx.UpdateColumns(&user) // Update all columns
  1390  		r.NoError(err)
  1391  
  1392  		r.NoError(tx.Reload(&user))
  1393  		r.Equal(user.Name.String, "Ping")
  1394  		r.Equal(user.UserName, "Pong")
  1395  		r.Equal(user.Email, "ping@pong.com")
  1396  	})
  1397  }
  1398  
  1399  func Test_UpdateColumns_With_Slice(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  		user := Users{
  1407  			{
  1408  				Name:     nulls.NewString("Mark"),
  1409  				UserName: "Ping",
  1410  			},
  1411  			{
  1412  				Name:     nulls.NewString("Larry"),
  1413  				UserName: "Pong",
  1414  			},
  1415  		}
  1416  		tx.Create(&user)
  1417  
  1418  		r.NotZero(user[0].CreatedAt)
  1419  		r.NotZero(user[0].UpdatedAt)
  1420  
  1421  		r.NotZero(user[1].CreatedAt)
  1422  		r.NotZero(user[1].UpdatedAt)
  1423  
  1424  		user[0].Name.String = "Fulano"
  1425  		user[0].UserName = "Thor"
  1426  		user[1].Name.String = "Fulana"
  1427  		user[1].UserName = "Freya"
  1428  
  1429  		err := tx.UpdateColumns(&user, "name") // Update Name field/column only
  1430  		r.NoError(err)
  1431  
  1432  		r.NoError(tx.Reload(&user))
  1433  		r.Equal(user[0].Name.String, "Fulano")
  1434  		r.Equal(user[0].UserName, "Ping") // UserName should not be updated
  1435  		r.Equal(user[1].Name.String, "Fulana")
  1436  		r.Equal(user[1].UserName, "Pong") // UserName should not be updated
  1437  	})
  1438  }
  1439  
  1440  func Test_Update_With_Slice(t *testing.T) {
  1441  	if PDB == nil {
  1442  		t.Skip("skipping integration tests")
  1443  	}
  1444  	transaction(func(tx *Connection) {
  1445  		r := require.New(t)
  1446  
  1447  		user := Users{
  1448  			{Name: nulls.NewString("Mark")},
  1449  			{Name: nulls.NewString("Larry")},
  1450  		}
  1451  		tx.Create(&user)
  1452  
  1453  		r.NotZero(user[0].CreatedAt)
  1454  		r.NotZero(user[0].UpdatedAt)
  1455  
  1456  		r.NotZero(user[1].CreatedAt)
  1457  		r.NotZero(user[1].UpdatedAt)
  1458  
  1459  		user[0].Name.String = "Marky"
  1460  		user[1].Name.String = "Lawrence"
  1461  
  1462  		err := tx.Update(&user)
  1463  		r.NoError(err)
  1464  
  1465  		r.NoError(tx.Reload(&user))
  1466  		r.Equal(user[0].Name.String, "Marky")
  1467  		r.Equal(user[1].Name.String, "Lawrence")
  1468  	})
  1469  }
  1470  
  1471  func Test_Update_UUID(t *testing.T) {
  1472  	if PDB == nil {
  1473  		t.Skip("skipping integration tests")
  1474  	}
  1475  	transaction(func(tx *Connection) {
  1476  		r := require.New(t)
  1477  
  1478  		song := Song{Title: "Automatic Buffalo"}
  1479  		err := tx.Create(&song)
  1480  		r.NoError(err)
  1481  
  1482  		r.NotZero(song.CreatedAt)
  1483  		r.NotZero(song.UpdatedAt)
  1484  
  1485  		song.Title = "Hum"
  1486  		err = tx.Update(&song)
  1487  		r.NoError(err)
  1488  
  1489  		err = tx.Reload(&song)
  1490  		r.NoError(err)
  1491  		r.Equal("Hum", song.Title)
  1492  	})
  1493  }
  1494  
  1495  func Test_Update_With_Non_ID_PK(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  		r.NoError(tx.Create(&CrookedColour{Name: "cc is not the first one"}))
  1503  
  1504  		cc := CrookedColour{
  1505  			Name: "You?",
  1506  		}
  1507  		err := tx.Create(&cc)
  1508  		r.NoError(err)
  1509  		r.NotZero(cc.ID)
  1510  		id := cc.ID
  1511  
  1512  		updatedName := "Me!"
  1513  		cc.Name = updatedName
  1514  		r.NoError(tx.Update(&cc))
  1515  		r.Equal(id, cc.ID)
  1516  
  1517  		r.NoError(tx.Reload(&cc))
  1518  		r.Equal(updatedName, cc.Name)
  1519  		r.Equal(id, cc.ID)
  1520  	})
  1521  }
  1522  
  1523  func Test_Update_Non_PK_ID(t *testing.T) {
  1524  	if PDB == nil {
  1525  		t.Skip("skipping integration tests")
  1526  	}
  1527  	transaction(func(tx *Connection) {
  1528  		r := require.New(t)
  1529  
  1530  		client := &NonStandardID{
  1531  			OutfacingID: "my awesome hydra client",
  1532  		}
  1533  		r.NoError(tx.Create(client))
  1534  
  1535  		updatedID := "your awesome hydra client"
  1536  		client.OutfacingID = updatedID
  1537  		r.NoError(tx.Update(client))
  1538  		r.NoError(tx.Reload(client))
  1539  		r.Equal(updatedID, client.OutfacingID)
  1540  	})
  1541  }
  1542  
  1543  func Test_Destroy(t *testing.T) {
  1544  	if PDB == nil {
  1545  		t.Skip("skipping integration tests")
  1546  	}
  1547  	transaction(func(tx *Connection) {
  1548  		r := require.New(t)
  1549  
  1550  		count, err := tx.Count("users")
  1551  		r.NoError(err)
  1552  		user := User{Name: nulls.NewString("Mark")}
  1553  		err = tx.Create(&user)
  1554  		r.NoError(err)
  1555  		r.NotEqual(user.ID, 0)
  1556  
  1557  		ctx, err := tx.Count("users")
  1558  		r.NoError(err)
  1559  		r.Equal(count+1, ctx)
  1560  
  1561  		err = tx.Destroy(&user)
  1562  		r.NoError(err)
  1563  
  1564  		ctx, _ = tx.Count("users")
  1565  		r.Equal(count, ctx)
  1566  	})
  1567  }
  1568  
  1569  func Test_Destroy_With_Slice(t *testing.T) {
  1570  	if PDB == nil {
  1571  		t.Skip("skipping integration tests")
  1572  	}
  1573  	transaction(func(tx *Connection) {
  1574  		r := require.New(t)
  1575  
  1576  		count, err := tx.Count("users")
  1577  		r.NoError(err)
  1578  		user := Users{
  1579  			{Name: nulls.NewString("Mark")},
  1580  			{Name: nulls.NewString("Larry")},
  1581  		}
  1582  		err = tx.Create(&user)
  1583  		r.NoError(err)
  1584  		r.NotEqual(user[0].ID, 0)
  1585  		r.NotEqual(user[1].ID, 0)
  1586  
  1587  		ctx, err := tx.Count("users")
  1588  		r.NoError(err)
  1589  		r.Equal(count+2, ctx)
  1590  
  1591  		err = tx.Destroy(&user)
  1592  		r.NoError(err)
  1593  
  1594  		ctx, _ = tx.Count("users")
  1595  		r.Equal(count, ctx)
  1596  	})
  1597  }
  1598  
  1599  func Test_Destroy_UUID(t *testing.T) {
  1600  	if PDB == nil {
  1601  		t.Skip("skipping integration tests")
  1602  	}
  1603  	transaction(func(tx *Connection) {
  1604  		r := require.New(t)
  1605  
  1606  		count, err := tx.Count("songs")
  1607  		r.NoError(err)
  1608  		song := Song{Title: "Automatic Buffalo"}
  1609  		err = tx.Create(&song)
  1610  		r.NoError(err)
  1611  		r.NotZero(song.ID)
  1612  
  1613  		ctx, err := tx.Count("songs")
  1614  		r.NoError(err)
  1615  		r.Equal(count+1, ctx)
  1616  
  1617  		err = tx.Destroy(&song)
  1618  		r.NoError(err)
  1619  
  1620  		ctx, _ = tx.Count("songs")
  1621  		r.Equal(count, ctx)
  1622  	})
  1623  }
  1624  
  1625  func Test_TruncateAll(t *testing.T) {
  1626  	if PDB == nil {
  1627  		t.Skip("skipping integration tests")
  1628  	}
  1629  	count := int(0)
  1630  	transaction(func(tx *Connection) {
  1631  		r := require.New(t)
  1632  
  1633  		var err error
  1634  		count, err = tx.Count("users")
  1635  		r.NoError(err)
  1636  		user := User{Name: nulls.NewString("Mark")}
  1637  		err = tx.Create(&user)
  1638  		r.NoError(err)
  1639  		r.NotEqual(user.ID, 0)
  1640  
  1641  		ctx, err := tx.Count("users")
  1642  		r.NoError(err)
  1643  		r.Equal(count+1, ctx)
  1644  
  1645  		err = tx.TruncateAll()
  1646  		r.NoError(err)
  1647  
  1648  		ctx, _ = tx.Count("users")
  1649  		r.Equal(count, ctx)
  1650  	})
  1651  }