| 476 | } |
| 477 | |
| 478 | PyObject* |
| 479 | Connection::handle_range_scan_op(PyObject* kwargs) |
| 480 | { |
| 481 | try { |
| 482 | PyObject* pyObj_bucket = PyDict_GetItemString(kwargs, "bucket"); |
| 483 | PyObject* pyObj_scope = PyDict_GetItemString(kwargs, "scope"); |
| 484 | PyObject* pyObj_collection = PyDict_GetItemString(kwargs, "collection_name"); |
| 485 | |
| 486 | if (!pyObj_bucket || !pyObj_scope || !pyObj_collection) { |
| 487 | return raise_invalid_argument( |
| 488 | "bucket, scope, and collection are required", __FILE__, __LINE__); |
| 489 | } |
| 490 | |
| 491 | std::string bucket_name = PyUnicode_AsUTF8(pyObj_bucket); |
| 492 | std::string scope_name = PyUnicode_AsUTF8(pyObj_scope); |
| 493 | std::string collection_name = PyUnicode_AsUTF8(pyObj_collection); |
| 494 | |
| 495 | PyObject* pyObj_scan_type = PyDict_GetItemString(kwargs, "scan_type"); |
| 496 | if (!pyObj_scan_type) { |
| 497 | return raise_invalid_argument("scan_type is required", __FILE__, __LINE__); |
| 498 | } |
| 499 | int py_scan_type = PyLong_AsLong(pyObj_scan_type); |
| 500 | |
| 501 | PyObject* pyObj_scan_config = PyDict_GetItemString(kwargs, "scan_config"); |
| 502 | if (!pyObj_scan_config || !PyDict_Check(pyObj_scan_config)) { |
| 503 | return raise_invalid_argument("scan_config must be a dictionary", __FILE__, __LINE__); |
| 504 | } |
| 505 | |
| 506 | PyObject* pyObj_orchestrator_opts = PyDict_GetItemString(kwargs, "orchestrator_options"); |
| 507 | if (nullptr != pyObj_orchestrator_opts && !PyDict_Check(pyObj_orchestrator_opts)) { |
| 508 | return raise_invalid_argument( |
| 509 | "orchestrator_options must be a dictionary", __FILE__, __LINE__); |
| 510 | } |
| 511 | |
| 512 | auto barrier = std::make_shared<std::promise< |
| 513 | std::pair<std::error_code, std::shared_ptr<couchbase::core::topology::configuration>>>>(); |
| 514 | auto f = barrier->get_future(); |
| 515 | cluster_.with_bucket_configuration(bucket_name, |
| 516 | [barrier](std::error_code ec, auto config) mutable { |
| 517 | barrier->set_value({ ec, std::move(config) }); |
| 518 | }); |
| 519 | auto [ec, bucket_config] = f.get(); |
| 520 | |
| 521 | if (ec) { |
| 522 | return build_exception( |
| 523 | ec, __FILE__, __LINE__, "Failed to get bucket configuration for range scan"); |
| 524 | } |
| 525 | if (!bucket_config->capabilities.supports_range_scan()) { |
| 526 | return raise_feature_unavailable( |
| 527 | "The server does not support key-value scan operations.", __FILE__, __LINE__); |
| 528 | } |
| 529 | if (!bucket_config->vbmap || bucket_config->vbmap->empty()) { |
| 530 | return raise_unsuccessful_operation( |
| 531 | "Cannot perform kv range scan operation. Unable to get vbucket map.", __FILE__, __LINE__); |
| 532 | } |
| 533 | |
| 534 | auto agent_group = |
| 535 | couchbase::core::agent_group(io_, couchbase::core::agent_group_config{ { cluster_ } }); |
no test coverage detected