go.mercari.io/datastore@v1.8.2/testsuite/transaction.go (about)

     1  package testsuite
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"testing"
     7  
     8  	"go.mercari.io/datastore"
     9  )
    10  
    11  func transactionCommit(ctx context.Context, t *testing.T, client datastore.Client) {
    12  	defer func() {
    13  		err := client.Close()
    14  		if err != nil {
    15  			t.Fatal(err)
    16  		}
    17  	}()
    18  
    19  	type Data struct {
    20  		Str string
    21  	}
    22  
    23  	var key datastore.Key
    24  	{ // Put
    25  		tx, err := client.NewTransaction(ctx)
    26  		if err != nil {
    27  			t.Fatal(err)
    28  		}
    29  
    30  		key = client.IncompleteKey("Data", nil)
    31  		pK, err := tx.Put(key, &Data{"Hi!"})
    32  		if err != nil {
    33  			t.Fatal(err)
    34  		}
    35  
    36  		c, err := tx.Commit()
    37  		if err != nil {
    38  			t.Fatal(err)
    39  		}
    40  
    41  		key = c.Key(pK)
    42  		if v := key.ID(); v == 0 {
    43  			t.Errorf("unexpected: %v", v)
    44  		}
    45  	}
    46  	{ // Get
    47  		tx, err := client.NewTransaction(ctx)
    48  		if err != nil {
    49  			t.Fatal(err)
    50  		}
    51  
    52  		obj := &Data{}
    53  		err = tx.Get(key, obj)
    54  		if err != nil {
    55  			t.Fatal(err)
    56  		}
    57  
    58  		_, err = tx.Commit()
    59  		if err != nil {
    60  			t.Fatal(err)
    61  		}
    62  	}
    63  	{ // Delete
    64  		tx, err := client.NewTransaction(ctx)
    65  		if err != nil {
    66  			t.Fatal(err)
    67  		}
    68  
    69  		err = tx.Delete(key)
    70  		if err != nil {
    71  			t.Fatal(err)
    72  		}
    73  
    74  		_, err = tx.Commit()
    75  		if err != nil {
    76  			t.Fatal(err)
    77  		}
    78  
    79  		err = client.Get(ctx, key, &Data{})
    80  		if err != datastore.ErrNoSuchEntity {
    81  			t.Errorf("unexpected: %v", err)
    82  		}
    83  	}
    84  }
    85  
    86  func transactionRollback(ctx context.Context, t *testing.T, client datastore.Client) {
    87  	defer func() {
    88  		err := client.Close()
    89  		if err != nil {
    90  			t.Fatal(err)
    91  		}
    92  	}()
    93  
    94  	type Data struct {
    95  		Str string
    96  	}
    97  
    98  	key := client.NameKey("Data", "test", nil)
    99  
   100  	{ // Put
   101  		tx, err := client.NewTransaction(ctx)
   102  		if err != nil {
   103  			t.Fatal(err)
   104  		}
   105  
   106  		_, err = tx.Put(key, &Data{"Hi!"})
   107  		if err != nil {
   108  			t.Fatal(err)
   109  		}
   110  
   111  		err = tx.Rollback()
   112  		if err != nil {
   113  			t.Fatal(err)
   114  		}
   115  
   116  		err = client.Get(ctx, key, &Data{})
   117  		if err != datastore.ErrNoSuchEntity {
   118  			t.Errorf("unexpected: %v", err)
   119  		}
   120  	}
   121  	{ // Delete
   122  		_, err := client.Put(ctx, key, &Data{"Hi!"})
   123  		if err != nil {
   124  			t.Fatal(err)
   125  		}
   126  
   127  		tx, err := client.NewTransaction(ctx)
   128  		if err != nil {
   129  			t.Fatal(err)
   130  		}
   131  
   132  		err = tx.Delete(key)
   133  		if err != nil {
   134  			t.Fatal(err)
   135  		}
   136  
   137  		err = tx.Rollback()
   138  		if err != nil {
   139  			t.Fatal(err)
   140  		}
   141  
   142  		err = client.Get(ctx, key, &Data{})
   143  		if err != nil {
   144  			t.Errorf("unexpected: %v", err)
   145  		}
   146  	}
   147  }
   148  
   149  func transactionJoinAncesterQuery(ctx context.Context, t *testing.T, client datastore.Client) {
   150  	defer func() {
   151  		err := client.Close()
   152  		if err != nil {
   153  			t.Fatal(err)
   154  		}
   155  	}()
   156  
   157  	type Data struct {
   158  		Str string
   159  	}
   160  
   161  	parentKey := client.NameKey("Parent", "p", nil)
   162  	key := client.NameKey("Data", "d", parentKey)
   163  
   164  	_, err := client.Put(ctx, key, &Data{Str: "Test"})
   165  	if err != nil {
   166  		t.Fatal(err)
   167  	}
   168  
   169  	tx1, err := client.NewTransaction(ctx)
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  	tx2, err := client.NewTransaction(ctx)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	q := client.NewQuery("Data").Transaction(tx1).Ancestor(parentKey)
   179  	var list1 []*Data
   180  	_, err = client.GetAll(ctx, q, &list1)
   181  	if err != nil {
   182  		t.Fatal(err)
   183  	}
   184  	if v := len(list1); v != 1 {
   185  		t.Fatalf("unexpected: %v", err)
   186  	}
   187  	obj1 := list1[0]
   188  
   189  	obj2 := &Data{}
   190  	err = tx2.Get(key, obj2)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  
   195  	obj1.Str = "Test1"
   196  	obj2.Str = "Test2"
   197  
   198  	_, err = tx1.Put(key, obj1)
   199  	if err != nil {
   200  		t.Fatal(err)
   201  	}
   202  	_, err = tx2.Put(key, obj2)
   203  	if err != nil {
   204  		t.Fatal(err)
   205  	}
   206  
   207  	_, err = tx2.Commit()
   208  	if err != nil {
   209  		t.Fatal(err)
   210  	}
   211  
   212  	_, err = tx1.Commit()
   213  	if err != datastore.ErrConcurrentTransaction {
   214  		t.Fatal(err)
   215  	}
   216  }
   217  
   218  func transactionCommitAndRollback(ctx context.Context, t *testing.T, client datastore.Client) {
   219  	defer func() {
   220  		err := client.Close()
   221  		if err != nil {
   222  			t.Fatal(err)
   223  		}
   224  	}()
   225  
   226  	tx, err := client.NewTransaction(ctx)
   227  	if err != nil {
   228  		t.Fatal(err)
   229  	}
   230  
   231  	_, err = tx.Commit()
   232  	if err != nil {
   233  		t.Fatal(err)
   234  	}
   235  
   236  	err = tx.Rollback()
   237  	if err == nil || err.Error() != "datastore: transaction expired" {
   238  		t.Fatal(err)
   239  	}
   240  
   241  	_, err = tx.Commit()
   242  	if err == nil || err.Error() != "datastore: transaction expired" {
   243  		t.Fatal(err)
   244  	}
   245  }
   246  
   247  func runInTransactionCommit(ctx context.Context, t *testing.T, client datastore.Client) {
   248  	defer func() {
   249  		err := client.Close()
   250  		if err != nil {
   251  			t.Fatal(err)
   252  		}
   253  	}()
   254  
   255  	type Data struct {
   256  		Str string
   257  	}
   258  
   259  	var pK datastore.PendingKey
   260  	c, err := client.RunInTransaction(ctx, func(tx datastore.Transaction) error {
   261  		key := client.IncompleteKey("Data", nil)
   262  		var err error
   263  		pK, err = tx.Put(key, &Data{"Hi!"})
   264  		if err != nil {
   265  			t.Fatal(err)
   266  		}
   267  
   268  		return nil
   269  	})
   270  	if err != nil {
   271  		t.Fatal(err)
   272  	}
   273  
   274  	key := c.Key(pK)
   275  	if v := key.ID(); v == 0 {
   276  		t.Errorf("unexpected: %v", v)
   277  	}
   278  }
   279  
   280  func runInTransactionRollback(ctx context.Context, t *testing.T, client datastore.Client) {
   281  	defer func() {
   282  		err := client.Close()
   283  		if err != nil {
   284  			t.Fatal(err)
   285  		}
   286  	}()
   287  
   288  	type Data struct {
   289  		Str string
   290  	}
   291  
   292  	_, err := client.RunInTransaction(ctx, func(tx datastore.Transaction) error {
   293  		key := client.IncompleteKey("Data", nil)
   294  		_, err := tx.Put(key, &Data{"Hi!"})
   295  		if err != nil {
   296  			t.Fatal(err)
   297  		}
   298  
   299  		return errors.New("this tx should failure")
   300  	})
   301  	if err == nil {
   302  		t.Fatal(err)
   303  	}
   304  }