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 }