gopkg.in/rethinkdb/rethinkdb-go.v6@v6.2.2/internal/integration/tests/cursor_test.go (about)

     1  package tests
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	test "gopkg.in/check.v1"
     8  	r "gopkg.in/rethinkdb/rethinkdb-go.v6"
     9  )
    10  
    11  type object struct {
    12  	ID    int64  `rethinkdb:"id,omitempty"`
    13  	Name  string `rethinkdb:"name"`
    14  	Attrs []attr
    15  }
    16  
    17  type attr struct {
    18  	Name  string
    19  	Value interface{}
    20  }
    21  
    22  func (s *RethinkSuite) TestCursorLiteral(c *test.C) {
    23  	res, err := r.Expr(5).Run(session)
    24  	c.Assert(err, test.IsNil)
    25  	c.Assert(res.Type(), test.Equals, "Cursor")
    26  
    27  	var response interface{}
    28  	err = res.One(&response)
    29  	c.Assert(err, test.IsNil)
    30  	c.Assert(response, JsonEquals, 5)
    31  }
    32  
    33  func (s *RethinkSuite) TestCursorSlice(c *test.C) {
    34  	res, err := r.Expr([]interface{}{1, 2, 3, 4, 5}).Run(session)
    35  	c.Assert(err, test.IsNil)
    36  	c.Assert(res.Type(), test.Equals, "Cursor")
    37  
    38  	var response []interface{}
    39  	err = res.All(&response)
    40  	c.Assert(err, test.IsNil)
    41  	c.Assert(response, JsonEquals, []interface{}{1, 2, 3, 4, 5})
    42  }
    43  
    44  func (s *RethinkSuite) TestCursorPartiallyNilSlice(c *test.C) {
    45  	res, err := r.Expr(map[string]interface{}{
    46  		"item": []interface{}{
    47  			map[string]interface{}{"num": 1},
    48  			nil,
    49  		},
    50  	}).Run(session)
    51  	c.Assert(err, test.IsNil)
    52  	c.Assert(res.Type(), test.Equals, "Cursor")
    53  
    54  	var response map[string]interface{}
    55  	err = res.One(&response)
    56  	c.Assert(err, test.IsNil)
    57  	c.Assert(response, JsonEquals, map[string]interface{}{
    58  		"item": []interface{}{
    59  			map[string]interface{}{"num": 1},
    60  			nil,
    61  		},
    62  	})
    63  }
    64  
    65  func (s *RethinkSuite) TestCursorMap(c *test.C) {
    66  	res, err := r.Expr(map[string]interface{}{
    67  		"id":   2,
    68  		"name": "Object 1",
    69  	}).Run(session)
    70  	c.Assert(err, test.IsNil)
    71  	c.Assert(res.Type(), test.Equals, "Cursor")
    72  
    73  	var response map[string]interface{}
    74  	err = res.One(&response)
    75  	c.Assert(err, test.IsNil)
    76  	c.Assert(response, JsonEquals, map[string]interface{}{
    77  		"id":   2,
    78  		"name": "Object 1",
    79  	})
    80  }
    81  
    82  func (s *RethinkSuite) TestCursorMapIntoInterface(c *test.C) {
    83  	res, err := r.Expr(map[string]interface{}{
    84  		"id":   2,
    85  		"name": "Object 1",
    86  	}).Run(session)
    87  	c.Assert(err, test.IsNil)
    88  	c.Assert(res.Type(), test.Equals, "Cursor")
    89  
    90  	var response interface{}
    91  	err = res.One(&response)
    92  	c.Assert(err, test.IsNil)
    93  	c.Assert(response, JsonEquals, map[string]interface{}{
    94  		"id":   2,
    95  		"name": "Object 1",
    96  	})
    97  }
    98  
    99  func (s *RethinkSuite) TestCursorMapNested(c *test.C) {
   100  	res, err := r.Expr(map[string]interface{}{
   101  		"id":   2,
   102  		"name": "Object 1",
   103  		"attr": []interface{}{map[string]interface{}{
   104  			"name":  "attr 1",
   105  			"value": "value 1",
   106  		}},
   107  	}).Run(session)
   108  	c.Assert(err, test.IsNil)
   109  	c.Assert(res.Type(), test.Equals, "Cursor")
   110  
   111  	var response interface{}
   112  	err = res.One(&response)
   113  	c.Assert(err, test.IsNil)
   114  	c.Assert(response, JsonEquals, map[string]interface{}{
   115  		"id":   2,
   116  		"name": "Object 1",
   117  		"attr": []interface{}{map[string]interface{}{
   118  			"name":  "attr 1",
   119  			"value": "value 1",
   120  		}},
   121  	})
   122  }
   123  
   124  func (s *RethinkSuite) TestCursorStruct(c *test.C) {
   125  	res, err := r.Expr(map[string]interface{}{
   126  		"id":   2,
   127  		"name": "Object 1",
   128  		"Attrs": []interface{}{map[string]interface{}{
   129  			"Name":  "attr 1",
   130  			"Value": "value 1",
   131  		}},
   132  	}).Run(session)
   133  	c.Assert(err, test.IsNil)
   134  	c.Assert(res.Type(), test.Equals, "Cursor")
   135  
   136  	var response object
   137  	err = res.One(&response)
   138  	c.Assert(err, test.IsNil)
   139  	c.Assert(response, test.DeepEquals, object{
   140  		ID:   2,
   141  		Name: "Object 1",
   142  		Attrs: []attr{attr{
   143  			Name:  "attr 1",
   144  			Value: "value 1",
   145  		}},
   146  	})
   147  }
   148  
   149  func (s *RethinkSuite) TestCursorStructPseudoTypes(c *test.C) {
   150  	var zeroTime time.Time
   151  	t := time.Now()
   152  
   153  	res, err := r.Expr(map[string]interface{}{
   154  		"T": time.Unix(t.Unix(), 0).In(time.UTC),
   155  		"Z": zeroTime,
   156  		"B": []byte("hello"),
   157  	}).Run(session)
   158  	c.Assert(err, test.IsNil)
   159  
   160  	var response PseudoTypes
   161  	err = res.One(&response)
   162  	c.Assert(err, test.IsNil)
   163  	c.Assert(res.Type(), test.Equals, "Cursor")
   164  
   165  	c.Assert(response.T.Equal(time.Unix(t.Unix(), 0)), test.Equals, true)
   166  	c.Assert(response.Z.Equal(zeroTime), test.Equals, true)
   167  	c.Assert(response.B, JsonEquals, []byte("hello"))
   168  }
   169  
   170  func (s *RethinkSuite) TestCursorAtomString(c *test.C) {
   171  	res, err := r.Expr("a").Run(session)
   172  	c.Assert(err, test.IsNil)
   173  	c.Assert(res.Type(), test.Equals, "Cursor")
   174  
   175  	var response string
   176  	err = res.One(&response)
   177  	c.Assert(err, test.IsNil)
   178  	c.Assert(response, test.Equals, "a")
   179  }
   180  
   181  func (s *RethinkSuite) TestCursorAtomArray(c *test.C) {
   182  	res, err := r.Expr([]interface{}{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}).Run(session)
   183  	c.Assert(err, test.IsNil)
   184  	c.Assert(res.Type(), test.Equals, "Cursor")
   185  
   186  	var response []int
   187  	err = res.All(&response)
   188  	c.Assert(err, test.IsNil)
   189  	c.Assert(response, test.DeepEquals, []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0})
   190  }
   191  
   192  func (s *RethinkSuite) TestEmptyResults(c *test.C) {
   193  	r.DBCreate("test_empty_res").Exec(session)
   194  	r.DB("test_empty_res").TableCreate("test_empty_res").Exec(session)
   195  	res, err := r.DB("test_empty_res").Table("test_empty_res").Get("missing value").Run(session)
   196  	c.Assert(err, test.IsNil)
   197  	c.Assert(res.IsNil(), test.Equals, true)
   198  
   199  	res, err = r.DB("test_empty_res").Table("test_empty_res").Get("missing value").Run(session)
   200  	c.Assert(err, test.IsNil)
   201  	var response interface{}
   202  	err = res.One(&response)
   203  	c.Assert(err, test.Equals, r.ErrEmptyResult)
   204  	c.Assert(res.IsNil(), test.Equals, true)
   205  
   206  	res, err = r.Expr(nil).Run(session)
   207  	c.Assert(err, test.IsNil)
   208  	c.Assert(res.IsNil(), test.Equals, true)
   209  
   210  	res, err = r.DB("test_empty_res").Table("test_empty_res").Get("missing value").Run(session)
   211  	c.Assert(err, test.IsNil)
   212  	c.Assert(res.IsNil(), test.Equals, true)
   213  
   214  	res, err = r.DB("test_empty_res").Table("test_empty_res").GetAll("missing value", "another missing value").Run(session)
   215  	c.Assert(err, test.IsNil)
   216  	c.Assert(res.Next(&response), test.Equals, false)
   217  
   218  	var obj object
   219  	obj.Name = "missing value"
   220  	res, err = r.DB("test_empty_res").Table("test_empty_res").Filter(obj).Run(session)
   221  	c.Assert(err, test.IsNil)
   222  	c.Assert(res.IsNil(), test.Equals, true)
   223  
   224  	var objP *object
   225  
   226  	res, err = r.DB("test_empty_res").Table("test_empty_res").Get("missing value").Run(session)
   227  	res.Next(&objP)
   228  	c.Assert(err, test.IsNil)
   229  	c.Assert(objP, test.IsNil)
   230  }
   231  
   232  func (s *RethinkSuite) TestCursorAll(c *test.C) {
   233  	// Ensure table + database exist
   234  	r.DBCreate("test_cur_all").Exec(session)
   235  	r.DB("test_cur_all").TableDrop("Table3All").Exec(session)
   236  	r.DB("test_cur_all").TableCreate("Table3All").Exec(session)
   237  	r.DB("test_cur_all").Table("Table3All").IndexCreate("num").Exec(session)
   238  	r.DB("test_cur_all").Table("Table3All").IndexWait().Exec(session)
   239  
   240  	// Insert rows
   241  	r.DB("test_cur_all").Table("Table3All").Insert([]interface{}{
   242  		map[string]interface{}{
   243  			"id":   2,
   244  			"name": "Object 1",
   245  			"Attrs": []interface{}{map[string]interface{}{
   246  				"Name":  "attr 1",
   247  				"Value": "value 1",
   248  			}},
   249  		},
   250  		map[string]interface{}{
   251  			"id":   3,
   252  			"name": "Object 2",
   253  			"Attrs": []interface{}{map[string]interface{}{
   254  				"Name":  "attr 1",
   255  				"Value": "value 1",
   256  			}},
   257  		},
   258  	}).Exec(session)
   259  
   260  	// Test query
   261  	query := r.DB("test_cur_all").Table("Table3All").OrderBy("id")
   262  	res, err := query.Run(session)
   263  	c.Assert(err, test.IsNil)
   264  
   265  	var response []object
   266  	err = res.All(&response)
   267  	c.Assert(err, test.IsNil)
   268  	c.Assert(response, test.HasLen, 2)
   269  	c.Assert(response, test.DeepEquals, []object{
   270  		object{
   271  			ID:   2,
   272  			Name: "Object 1",
   273  			Attrs: []attr{attr{
   274  				Name:  "attr 1",
   275  				Value: "value 1",
   276  			}},
   277  		},
   278  		object{
   279  			ID:   3,
   280  			Name: "Object 2",
   281  			Attrs: []attr{attr{
   282  				Name:  "attr 1",
   283  				Value: "value 1",
   284  			}},
   285  		},
   286  	})
   287  }
   288  
   289  func (s *RethinkSuite) TestCursorListen(c *test.C) {
   290  	// Ensure table + database exist
   291  	r.DBCreate("test_cur_lis").Exec(session)
   292  	r.DB("test_cur_lis").TableDrop("Table3Listen").Exec(session)
   293  	r.DB("test_cur_lis").TableCreate("Table3Listen").Exec(session)
   294  	r.DB("test_cur_lis").Table("Table3Listen").Wait().Exec(session)
   295  	r.DB("test_cur_lis").Table("Table3Listen").IndexCreate("num").Exec(session)
   296  	r.DB("test_cur_lis").Table("Table3Listen").IndexWait().Exec(session)
   297  
   298  	// Insert rows
   299  	r.DB("test_cur_lis").Table("Table3Listen").Insert([]interface{}{
   300  		map[string]interface{}{
   301  			"id":   2,
   302  			"name": "Object 1",
   303  			"Attrs": []interface{}{map[string]interface{}{
   304  				"Name":  "attr 1",
   305  				"Value": "value 1",
   306  			}},
   307  		},
   308  		map[string]interface{}{
   309  			"id":   3,
   310  			"name": "Object 2",
   311  			"Attrs": []interface{}{map[string]interface{}{
   312  				"Name":  "attr 1",
   313  				"Value": "value 1",
   314  			}},
   315  		},
   316  	}).Exec(session)
   317  
   318  	// Test query
   319  	query := r.DB("test_cur_lis").Table("Table3Listen").OrderBy("id")
   320  	res, err := query.Run(session)
   321  	c.Assert(err, test.IsNil)
   322  
   323  	ch := make(chan object)
   324  	res.Listen(ch)
   325  	var response []object
   326  	for v := range ch {
   327  		response = append(response, v)
   328  	}
   329  
   330  	c.Assert(response, test.HasLen, 2)
   331  	c.Assert(response, test.DeepEquals, []object{
   332  		object{
   333  			ID:   2,
   334  			Name: "Object 1",
   335  			Attrs: []attr{attr{
   336  				Name:  "attr 1",
   337  				Value: "value 1",
   338  			}},
   339  		},
   340  		object{
   341  			ID:   3,
   342  			Name: "Object 2",
   343  			Attrs: []attr{attr{
   344  				Name:  "attr 1",
   345  				Value: "value 1",
   346  			}},
   347  		},
   348  	})
   349  }
   350  
   351  func (s *RethinkSuite) TestCursorChangesClose(c *test.C) {
   352  	// Ensure table + database exist
   353  	r.DBCreate("test_cur_change").Exec(session)
   354  	r.DB("test_cur_change").TableDrop("Table3Close").Exec(session)
   355  	r.DB("test_cur_change").TableCreate("Table3Close").Exec(session)
   356  
   357  	// Test query
   358  	// res, err := DB("test").Table("Table3").Changes().Run(session)
   359  	res, err := r.DB("test_cur_change").Table("Table3Close").Changes().Run(session)
   360  	c.Assert(err, test.IsNil)
   361  	c.Assert(res, test.NotNil)
   362  
   363  	// Ensure that the cursor can be closed
   364  	err = res.Close()
   365  	c.Assert(err, test.IsNil)
   366  }
   367  
   368  func (s *RethinkSuite) TestCursorReuseResult(c *test.C) {
   369  	// Test query
   370  	query := r.Expr([]interface{}{
   371  		map[string]interface{}{
   372  			"A": "a",
   373  		},
   374  		map[string]interface{}{
   375  			"B": 1,
   376  		},
   377  		map[string]interface{}{
   378  			"A": "a",
   379  		},
   380  		map[string]interface{}{
   381  			"B": 1,
   382  		},
   383  		map[string]interface{}{
   384  			"A": "a",
   385  			"B": 1,
   386  		},
   387  	})
   388  	res, err := query.Run(session)
   389  	c.Assert(err, test.IsNil)
   390  
   391  	var i int
   392  	var result SimpleT
   393  	for res.Next(&result) {
   394  		switch i {
   395  		case 0:
   396  			c.Assert(result, test.DeepEquals, SimpleT{
   397  				A: "a",
   398  				B: 0,
   399  			})
   400  		case 1:
   401  			c.Assert(result, test.DeepEquals, SimpleT{
   402  				A: "",
   403  				B: 1,
   404  			})
   405  		case 2:
   406  			c.Assert(result, test.DeepEquals, SimpleT{
   407  				A: "a",
   408  				B: 0,
   409  			})
   410  		case 3:
   411  			c.Assert(result, test.DeepEquals, SimpleT{
   412  				A: "",
   413  				B: 1,
   414  			})
   415  		case 4:
   416  			c.Assert(result, test.DeepEquals, SimpleT{
   417  				A: "a",
   418  				B: 1,
   419  			})
   420  		default:
   421  			c.Fatalf("Unexpected number of results")
   422  		}
   423  
   424  		i++
   425  	}
   426  	c.Assert(res.Err(), test.IsNil)
   427  }
   428  
   429  func (s *RethinkSuite) TestCursorNextResponse(c *test.C) {
   430  	res, err := r.Expr(5).Run(session)
   431  	c.Assert(err, test.IsNil)
   432  	c.Assert(res.Type(), test.Equals, "Cursor")
   433  
   434  	b, ok := res.NextResponse()
   435  	c.Assert(ok, test.Equals, true)
   436  	c.Assert(b, JsonEquals, []byte(`5`))
   437  }
   438  
   439  func (s *RethinkSuite) TestCursorNextResponse_object(c *test.C) {
   440  	res, err := r.Expr(map[string]string{"foo": "bar"}).Run(session)
   441  	c.Assert(err, test.IsNil)
   442  	c.Assert(res.Type(), test.Equals, "Cursor")
   443  
   444  	b, ok := res.NextResponse()
   445  	c.Assert(ok, test.Equals, true)
   446  	c.Assert(b, JsonEquals, []byte(`{"foo":"bar"}`))
   447  }
   448  
   449  func (s *RethinkSuite) TestCursorPeek_idempotency(c *test.C) {
   450  	res, err := r.Expr([]int{1, 2, 3}).Run(session)
   451  	c.Assert(err, test.IsNil)
   452  
   453  	var result int
   454  
   455  	// Test idempotency
   456  	for i := 0; i < 2; i++ {
   457  		hasMore, err := res.Peek(&result)
   458  		c.Assert(err, test.IsNil)
   459  		c.Assert(result, test.Equals, 1)
   460  		c.Assert(hasMore, test.Equals, true)
   461  	}
   462  
   463  }
   464  
   465  func (s *RethinkSuite) TestCursorPeek_wrong_type(c *test.C) {
   466  	res, err := r.Expr([]int{1, 2, 3}).Run(session)
   467  	c.Assert(err, test.IsNil)
   468  
   469  	// Test that wrongType doesn't break the cursor
   470  	wrongType := struct {
   471  		Name string
   472  		Age  int
   473  	}{}
   474  
   475  	hasMore, err := res.Peek(&wrongType)
   476  	c.Assert(err, test.NotNil)
   477  	c.Assert(hasMore, test.Equals, false)
   478  	c.Assert(res.Err(), test.IsNil)
   479  }
   480  
   481  func (s *RethinkSuite) TestCursorPeek_usage(c *test.C) {
   482  	res, err := r.Expr([]int{1, 2, 3}).Run(session)
   483  	c.Assert(err, test.IsNil)
   484  
   485  	var result int
   486  
   487  	// Test that Skip progresses our cursor
   488  	res.Skip()
   489  	hasMore, err := res.Peek(&result)
   490  	c.Assert(err, test.IsNil)
   491  	c.Assert(result, test.Equals, 2)
   492  	c.Assert(hasMore, test.Equals, true)
   493  
   494  	// Test that we can use Next afterwards and we get the same result
   495  	hasMore = res.Next(&result)
   496  	c.Assert(result, test.Equals, 2)
   497  	c.Assert(hasMore, test.Equals, true)
   498  }
   499  
   500  func (s *RethinkSuite) TestCursorSkip(c *test.C) {
   501  	res, err := r.Expr([]int{1, 2, 3}).Run(session)
   502  	c.Assert(err, test.IsNil)
   503  
   504  	res.Skip()
   505  
   506  	var result int
   507  	hasMore := res.Next(&result)
   508  	c.Assert(result, test.Equals, 2)
   509  	c.Assert(hasMore, test.Equals, true)
   510  }
   511  
   512  func ExampleCursor_Peek() {
   513  	res, err := r.Expr([]int{1, 2, 3}).Run(session)
   514  	if err != nil {
   515  		fmt.Print(err)
   516  		return
   517  	}
   518  
   519  	var result, altResult int
   520  	wasRead, err := res.Peek(&result) // Result is now 1
   521  	if err != nil {
   522  		fmt.Print(err)
   523  		return
   524  	} else if !wasRead {
   525  		fmt.Print("No data to read!")
   526  	}
   527  
   528  	res.Next(&altResult) // altResult is also 1, peek didn't progress the cursor
   529  
   530  	res.Skip()        // progress the cursor, skipping 2
   531  	res.Peek(&result) // result is now 3
   532  }