github.com/ravendb/ravendb-go-client@v0.0.0-20240229102137-4474ee7aa0fa/tests/first_class_patch_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	ravendb "github.com/ravendb/ravendb-go-client"
     8  	"github.com/stretchr/testify/assert"
     9  )
    10  
    11  // User2 describes a user
    12  // Note: conflicts with User in user_test.go
    13  type User2 struct {
    14  	Stuff     []*Stuff     `json:"stuff"`
    15  	LastLogin ravendb.Time `json:"lastLogin"`
    16  	Numbers   []int        `json:"numbers"`
    17  }
    18  
    19  // Stuff describes stuff
    20  type Stuff struct {
    21  	Key    int               `json:"key"`
    22  	Phone  *string           `json:"phone"`
    23  	Pet    *Pet              `json:"pet"`
    24  	Friend *Friend           `json:"friend"`
    25  	Dic    map[string]string `json:"dic"`
    26  }
    27  
    28  // Friend describes a friend
    29  type Friend struct {
    30  	Name string `json:"name"`
    31  	Age  int    `json:"age"`
    32  	Pet  *Pet   `json:"pet"`
    33  }
    34  
    35  // Pet describes a pet
    36  type Pet struct {
    37  	Name string `json:"name"`
    38  	Kind string `json:"kind"`
    39  }
    40  
    41  const (
    42  	_docId = "user2s/1-A"
    43  )
    44  
    45  func firstClassPatchCanPatch(t *testing.T, driver *RavenTestDriver) {
    46  	stuff := []*Stuff{nil, nil, nil}
    47  	stuff[0] = &Stuff{}
    48  	stuff[0].Key = 6
    49  
    50  	user := &User2{}
    51  	user.Numbers = []int{66}
    52  	user.Stuff = stuff
    53  
    54  	var err error
    55  	store := driver.getDocumentStoreMust(t)
    56  	defer store.Close()
    57  
    58  	{
    59  		session := openSessionMust(t, store)
    60  		err = session.Store(user)
    61  		assert.NoError(t, err)
    62  		err = session.SaveChanges()
    63  		assert.NoError(t, err)
    64  
    65  		session.Close()
    66  	}
    67  
    68  	now := ravendb.Time(time.Now().UTC())
    69  	{
    70  		session := openSessionMust(t, store)
    71  
    72  		err = session.Advanced().PatchByID(_docId, "numbers[0]", 31)
    73  		assert.NoError(t, err)
    74  		err = session.Advanced().PatchByID(_docId, "lastLogin", now)
    75  		assert.NoError(t, err)
    76  		err = session.SaveChanges()
    77  		assert.NoError(t, err)
    78  
    79  		session.Close()
    80  	}
    81  
    82  	{
    83  		session := openSessionMust(t, store)
    84  
    85  		var loaded *User2
    86  		err = session.Load(&loaded, _docId)
    87  		assert.NoError(t, err)
    88  		assert.Equal(t, loaded.Numbers[0], 31)
    89  
    90  		// Note: round-tripping can loose time precision so
    91  		nowRounded := ravendb.RoundToServerTime(time.Time(now))
    92  		assert.Equal(t, loaded.LastLogin, ravendb.Time(nowRounded))
    93  
    94  		err = session.Advanced().Patch(loaded, "stuff[0].phone", "123456")
    95  		assert.NoError(t, err)
    96  		err = session.SaveChanges()
    97  		assert.NoError(t, err)
    98  
    99  		session.Close()
   100  	}
   101  
   102  	{
   103  		session := openSessionMust(t, store)
   104  		var loaded *User2
   105  		err = session.Load(&loaded, _docId)
   106  		assert.NoError(t, err)
   107  
   108  		assert.Equal(t, *loaded.Stuff[0].Phone, "123456")
   109  
   110  		session.Close()
   111  	}
   112  }
   113  
   114  func firstClassPatchCanPatchAndModify(t *testing.T, driver *RavenTestDriver) {
   115  	user := &User2{}
   116  	user.Numbers = []int{66}
   117  
   118  	var err error
   119  	store := driver.getDocumentStoreMust(t)
   120  	defer store.Close()
   121  
   122  	{
   123  		session := openSessionMust(t, store)
   124  
   125  		err = session.Store(user)
   126  		assert.NoError(t, err)
   127  		err = session.SaveChanges()
   128  		assert.NoError(t, err)
   129  
   130  		session.Close()
   131  	}
   132  
   133  	{
   134  		session := openSessionMust(t, store)
   135  		var loaded *User2
   136  		err = session.Load(&loaded, _docId)
   137  		assert.NoError(t, err)
   138  		loaded.Numbers[0] = 1
   139  
   140  		err = session.Advanced().Patch(loaded, "numbers[0]", 2)
   141  		assert.NoError(t, err)
   142  		err = session.SaveChanges()
   143  		_ = err.(*ravendb.IllegalStateError)
   144  
   145  		session.Close()
   146  	}
   147  }
   148  
   149  func firstClassPatchCanPatchComplex(t *testing.T, driver *RavenTestDriver) {
   150  	stuff := []*Stuff{nil, nil, nil}
   151  	stuff[0] = &Stuff{
   152  		Key: 6,
   153  	}
   154  
   155  	user := &User2{
   156  		Stuff: stuff,
   157  	}
   158  
   159  	var err error
   160  	store := driver.getDocumentStoreMust(t)
   161  	defer store.Close()
   162  
   163  	{
   164  		session := openSessionMust(t, store)
   165  
   166  		err = session.Store(user)
   167  		assert.NoError(t, err)
   168  		err = session.SaveChanges()
   169  		assert.NoError(t, err)
   170  
   171  		session.Close()
   172  	}
   173  
   174  	{
   175  		session := openSessionMust(t, store)
   176  
   177  		phone := "9255864406"
   178  		newStuff := &Stuff{
   179  			Key:    4,
   180  			Phone:  &phone,
   181  			Friend: &Friend{},
   182  		}
   183  		err = session.Advanced().PatchByID(_docId, "stuff[1]", newStuff)
   184  		assert.NoError(t, err)
   185  		err = session.SaveChanges()
   186  		assert.NoError(t, err)
   187  
   188  		session.Close()
   189  	}
   190  
   191  	{
   192  		session := openSessionMust(t, store)
   193  
   194  		var loaded *User2
   195  		err = session.Load(&loaded, _docId)
   196  		assert.NoError(t, err)
   197  		assert.Equal(t, *loaded.Stuff[1].Phone, "9255864406")
   198  
   199  		assert.Equal(t, loaded.Stuff[1].Key, 4)
   200  		assert.NotNil(t, loaded.Stuff[1].Friend)
   201  
   202  		pet1 := &Pet{
   203  			Kind: "Dog",
   204  			Name: "Hanan",
   205  		}
   206  
   207  		friendsPet := &Pet{
   208  			Name: "Miriam",
   209  			Kind: "Cat",
   210  		}
   211  
   212  		friend := &Friend{
   213  			Name: "Gonras",
   214  			Age:  28,
   215  			Pet:  friendsPet,
   216  		}
   217  
   218  		phone := "9255864406"
   219  		secondStuff := &Stuff{
   220  			Key:    4,
   221  			Phone:  &phone,
   222  			Pet:    pet1,
   223  			Friend: friend,
   224  		}
   225  
   226  		m := map[string]string{
   227  			"Ohio":       "Columbus",
   228  			"Utah":       "Salt Lake City",
   229  			"Texas":      "Austin",
   230  			"California": "Sacramento",
   231  		}
   232  
   233  		secondStuff.Dic = m
   234  
   235  		err = session.Advanced().Patch(loaded, "stuff[2]", secondStuff)
   236  		assert.NoError(t, err)
   237  		err = session.SaveChanges()
   238  		assert.NoError(t, err)
   239  
   240  		session.Close()
   241  	}
   242  
   243  	{
   244  		session := openSessionMust(t, store)
   245  
   246  		var loaded *User2
   247  		err = session.Load(&loaded, _docId)
   248  		assert.NoError(t, err)
   249  
   250  		assert.Equal(t, loaded.Stuff[2].Pet.Name, "Hanan")
   251  		assert.Equal(t, loaded.Stuff[2].Friend.Name, "Gonras")
   252  		assert.Equal(t, loaded.Stuff[2].Friend.Pet.Name, "Miriam")
   253  		assert.Equal(t, len(loaded.Stuff[2].Dic), 4)
   254  		assert.Equal(t, loaded.Stuff[2].Dic["Utah"], "Salt Lake City")
   255  
   256  		session.Close()
   257  	}
   258  }
   259  
   260  func firstClassPatchCanAddToArray(t *testing.T, driver *RavenTestDriver) {
   261  	stuff := []*Stuff{nil}
   262  
   263  	stuff[0] = &Stuff{}
   264  	stuff[0].Key = 6
   265  
   266  	user := &User2{
   267  		Stuff:   stuff,
   268  		Numbers: []int{1, 2},
   269  	}
   270  
   271  	var err error
   272  	store := driver.getDocumentStoreMust(t)
   273  	defer store.Close()
   274  
   275  	{
   276  		session := openSessionMust(t, store)
   277  
   278  		err = session.Store(user)
   279  		assert.NoError(t, err)
   280  		err = session.SaveChanges()
   281  		assert.NoError(t, err)
   282  
   283  		session.Close()
   284  	}
   285  
   286  	{
   287  		session := openSessionMust(t, store)
   288  		//push
   289  		adder := func(roles *ravendb.JavaScriptArray) {
   290  			roles.Add(3)
   291  		}
   292  		err = session.Advanced().PatchArrayByID(_docId, "numbers", adder)
   293  		assert.NoError(t, err)
   294  
   295  		adder = func(roles *ravendb.JavaScriptArray) {
   296  			stuff1 := &Stuff{
   297  				Key: 75,
   298  			}
   299  			roles.Add(stuff1)
   300  		}
   301  		err = session.Advanced().PatchArrayByID(_docId, "stuff", adder)
   302  		assert.NoError(t, err)
   303  
   304  		err = session.SaveChanges()
   305  		assert.NoError(t, err)
   306  
   307  		session.Close()
   308  	}
   309  
   310  	{
   311  		session := openSessionMust(t, store)
   312  
   313  		var loaded *User2
   314  		err = session.Load(&loaded, _docId)
   315  		assert.NoError(t, err)
   316  
   317  		assert.Equal(t, loaded.Numbers[2], 3)
   318  		assert.Equal(t, loaded.Stuff[1].Key, 75)
   319  
   320  		adder := func(roles *ravendb.JavaScriptArray) {
   321  			roles.Add(101, 102, 103)
   322  		}
   323  		err = session.Advanced().PatchArray(loaded, "numbers", adder)
   324  		assert.NoError(t, err)
   325  		adder = func(roles *ravendb.JavaScriptArray) {
   326  			s1 := &Stuff{
   327  				Key: 102,
   328  			}
   329  
   330  			phone := "123456"
   331  			s2 := &Stuff{
   332  				Phone: &phone,
   333  			}
   334  
   335  			roles.Add(s1).Add(s2)
   336  		}
   337  		err = session.Advanced().PatchArray(loaded, "stuff", adder)
   338  		assert.NoError(t, err)
   339  		err = session.SaveChanges()
   340  		assert.NoError(t, err)
   341  
   342  		session.Close()
   343  	}
   344  
   345  	{
   346  		session := openSessionMust(t, store)
   347  
   348  		var loaded *User2
   349  		err = session.Load(&loaded, _docId)
   350  		assert.NoError(t, err)
   351  		assert.Equal(t, len(loaded.Numbers), 6)
   352  
   353  		assert.Equal(t, loaded.Numbers[5], 103)
   354  
   355  		assert.Equal(t, loaded.Stuff[2].Key, 102)
   356  
   357  		assert.Equal(t, *loaded.Stuff[3].Phone, "123456")
   358  
   359  		adder := func(roles *ravendb.JavaScriptArray) {
   360  			roles.Add(201, 202, 203)
   361  		}
   362  
   363  		err = session.Advanced().PatchArray(loaded, "numbers", adder)
   364  		assert.NoError(t, err)
   365  
   366  		err = session.SaveChanges()
   367  		assert.NoError(t, err)
   368  
   369  		session.Close()
   370  	}
   371  
   372  	{
   373  		session := openSessionMust(t, store)
   374  
   375  		var loaded *User2
   376  		err = session.Load(&loaded, _docId)
   377  		assert.NoError(t, err)
   378  
   379  		assert.Equal(t, len(loaded.Numbers), 9)
   380  		assert.Equal(t, loaded.Numbers[7], 202)
   381  
   382  		session.Close()
   383  	}
   384  }
   385  
   386  func firstClassPatchCanRemoveFromArray(t *testing.T, driver *RavenTestDriver) {
   387  	stuff := []*Stuff{nil, nil}
   388  	stuff[0] = &Stuff{
   389  		Key: 6,
   390  	}
   391  
   392  	phone := "123456"
   393  	stuff[1] = &Stuff{
   394  		Phone: &phone,
   395  	}
   396  
   397  	user := &User2{
   398  		Stuff:   stuff,
   399  		Numbers: []int{1, 2, 3},
   400  	}
   401  
   402  	var err error
   403  	store := driver.getDocumentStoreMust(t)
   404  	defer store.Close()
   405  
   406  	{
   407  		session := openSessionMust(t, store)
   408  
   409  		err = session.Store(user)
   410  		assert.NoError(t, err)
   411  		err = session.SaveChanges()
   412  		assert.NoError(t, err)
   413  
   414  		session.Close()
   415  	}
   416  
   417  	{
   418  		session := openSessionMust(t, store)
   419  
   420  		adder := func(roles *ravendb.JavaScriptArray) {
   421  			roles.RemoveAt(1)
   422  		}
   423  		err = session.Advanced().PatchArrayByID(_docId, "numbers", adder)
   424  		assert.NoError(t, err)
   425  		adder = func(roles *ravendb.JavaScriptArray) {
   426  			roles.RemoveAt(0)
   427  		}
   428  		err = session.Advanced().PatchArrayByID(_docId, "stuff", adder)
   429  		assert.NoError(t, err)
   430  		err = session.SaveChanges()
   431  		assert.NoError(t, err)
   432  
   433  		session.Close()
   434  	}
   435  
   436  	{
   437  		session := openSessionMust(t, store)
   438  
   439  		var loaded *User2
   440  		err = session.Load(&loaded, _docId)
   441  		assert.NoError(t, err)
   442  		assert.Equal(t, len(loaded.Numbers), 2)
   443  		assert.Equal(t, loaded.Numbers[1], 3)
   444  
   445  		assert.Equal(t, len(loaded.Stuff), 1)
   446  		assert.Equal(t, *loaded.Stuff[0].Phone, "123456")
   447  
   448  		session.Close()
   449  	}
   450  }
   451  
   452  func firstClassPatchCanIncrement(t *testing.T, driver *RavenTestDriver) {
   453  	s := []*Stuff{nil, nil, nil}
   454  	s[0] = &Stuff{
   455  		Key: 6,
   456  	}
   457  
   458  	user := &User2{
   459  		Numbers: []int{66},
   460  		Stuff:   s,
   461  	}
   462  
   463  	var err error
   464  	store := driver.getDocumentStoreMust(t)
   465  	defer store.Close()
   466  
   467  	{
   468  		session := openSessionMust(t, store)
   469  
   470  		err = session.Store(user)
   471  		assert.NoError(t, err)
   472  		err = session.SaveChanges()
   473  		assert.NoError(t, err)
   474  
   475  		session.Close()
   476  	}
   477  
   478  	{
   479  		session := openSessionMust(t, store)
   480  
   481  		err = session.Advanced().IncrementByID(_docId, "numbers[0]", 1)
   482  		assert.NoError(t, err)
   483  		err = session.SaveChanges()
   484  		assert.NoError(t, err)
   485  
   486  		session.Close()
   487  	}
   488  
   489  	{
   490  		session := openSessionMust(t, store)
   491  		var loaded *User2
   492  		err = session.Load(&loaded, _docId)
   493  		assert.NoError(t, err)
   494  		assert.Equal(t, loaded.Numbers[0], 67)
   495  
   496  		err = session.Advanced().Increment(loaded, "stuff[0].key", -3)
   497  		assert.NoError(t, err)
   498  		err = session.SaveChanges()
   499  		assert.NoError(t, err)
   500  
   501  		session.Close()
   502  	}
   503  
   504  	{
   505  		session := openSessionMust(t, store)
   506  		var loaded *User2
   507  		err = session.Load(&loaded, _docId)
   508  		assert.NoError(t, err)
   509  
   510  		assert.Equal(t, loaded.Stuff[0].Key, 3)
   511  		session.Close()
   512  	}
   513  }
   514  
   515  func firstClassPatchShouldMergePatchCalls(t *testing.T, driver *RavenTestDriver) {
   516  	stuff := []*Stuff{nil, nil, nil}
   517  	stuff[0] = &Stuff{
   518  		Key: 6,
   519  	}
   520  
   521  	user := &User2{
   522  		Stuff:   stuff,
   523  		Numbers: []int{66},
   524  	}
   525  
   526  	user2 := &User2{
   527  		Numbers: []int{1, 2, 3},
   528  		Stuff:   stuff,
   529  	}
   530  
   531  	docID2 := "user2s/2-A"
   532  
   533  	var err error
   534  	store := driver.getDocumentStoreMust(t)
   535  	defer store.Close()
   536  
   537  	{
   538  		session := openSessionMust(t, store)
   539  
   540  		err = session.Store(user)
   541  		assert.NoError(t, err)
   542  		err = session.StoreWithID(user2, docID2)
   543  		assert.NoError(t, err)
   544  		err = session.SaveChanges()
   545  		assert.NoError(t, err)
   546  
   547  		session.Close()
   548  	}
   549  
   550  	now := time.Now()
   551  
   552  	{
   553  		session := openSessionMust(t, store)
   554  
   555  		err = session.Advanced().PatchByID(_docId, "numbers[0]", 31)
   556  		assert.NoError(t, err)
   557  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   558  
   559  		err = session.Advanced().PatchByID(_docId, "lastLogin", now)
   560  		assert.NoError(t, err)
   561  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   562  
   563  		err = session.Advanced().PatchByID(docID2, "numbers[0]", 123)
   564  		assert.NoError(t, err)
   565  		assert.Equal(t, session.GetDeferredCommandsCount(), 2)
   566  
   567  		err = session.Advanced().PatchByID(docID2, "lastLogin", now)
   568  		assert.NoError(t, err)
   569  		assert.Equal(t, session.GetDeferredCommandsCount(), 2)
   570  
   571  		err = session.SaveChanges()
   572  		assert.NoError(t, err)
   573  
   574  		session.Close()
   575  	}
   576  
   577  	{
   578  		session := openSessionMust(t, store)
   579  
   580  		err = session.Advanced().IncrementByID(_docId, "numbers[0]", 1)
   581  		assert.NoError(t, err)
   582  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   583  
   584  		adder := func(r *ravendb.JavaScriptArray) {
   585  			r.Add(77)
   586  		}
   587  		err = session.Advanced().PatchArrayByID(_docId, "numbers", adder)
   588  		assert.NoError(t, err)
   589  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   590  
   591  		adder = func(r *ravendb.JavaScriptArray) {
   592  			r.Add(88)
   593  		}
   594  		err = session.Advanced().PatchArrayByID(_docId, "numbers", adder)
   595  		assert.NoError(t, err)
   596  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   597  
   598  		adder = func(r *ravendb.JavaScriptArray) {
   599  			r.RemoveAt(1)
   600  		}
   601  		err = session.Advanced().PatchArrayByID(_docId, "numbers", adder)
   602  		assert.NoError(t, err)
   603  		assert.Equal(t, session.GetDeferredCommandsCount(), 1)
   604  
   605  		err = session.SaveChanges()
   606  		assert.NoError(t, err)
   607  
   608  		session.Close()
   609  	}
   610  }
   611  
   612  func TestFirstClassPatch(t *testing.T) {
   613  	driver := createTestDriver(t)
   614  	destroy := func() { destroyDriver(t, driver) }
   615  	defer recoverTest(t, destroy)
   616  
   617  	// matches order of Java tests
   618  	firstClassPatchCanIncrement(t, driver)
   619  	firstClassPatchCanAddToArray(t, driver)
   620  	firstClassPatchCanRemoveFromArray(t, driver)
   621  	firstClassPatchShouldMergePatchCalls(t, driver)
   622  	firstClassPatchCanPatch(t, driver)
   623  	firstClassPatchCanPatchAndModify(t, driver)
   624  	firstClassPatchCanPatchComplex(t, driver)
   625  }