couchbase 3.8.0 → 3.8.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/ext/cache/extconf_include.rb +4 -4
  4. data/ext/cache/mozilla-ca-bundle.crt +96 -675
  5. data/ext/cache/mozilla-ca-bundle.sha256 +1 -1
  6. data/ext/couchbase/CMakeLists.txt +3 -1
  7. data/ext/couchbase/core/error_context/base_error_context.hxx +32 -0
  8. data/ext/couchbase/core/error_context/key_value.cxx +1 -0
  9. data/ext/couchbase/core/error_context/key_value.hxx +23 -0
  10. data/ext/couchbase/core/error_context/key_value_error_context.hxx +35 -0
  11. data/ext/couchbase/core/error_context/subdocument_error_context.hxx +41 -0
  12. data/ext/couchbase/core/impl/binary_collection.cxx +123 -88
  13. data/ext/couchbase/core/impl/collection.cxx +416 -189
  14. data/ext/couchbase/core/impl/error.cxx +29 -4
  15. data/ext/couchbase/core/impl/invoke_with_node_id.hxx +44 -0
  16. data/ext/couchbase/core/impl/node_id.cxx +110 -0
  17. data/ext/couchbase/core/impl/node_id.hxx +40 -0
  18. data/ext/couchbase/core/impl/public_cluster.cxx +118 -5
  19. data/ext/couchbase/core/io/configuration_belongs_to_session.hxx +67 -0
  20. data/ext/couchbase/core/io/http_session_manager.hxx +97 -57
  21. data/ext/couchbase/core/io/mcbp_session.cxx +7 -16
  22. data/ext/couchbase/core/io/streams.cxx +143 -12
  23. data/ext/couchbase/core/io/streams.hxx +6 -0
  24. data/ext/couchbase/core/operations/document_get_all_replicas.hxx +14 -4
  25. data/ext/couchbase/core/operations/document_get_projected.cxx +3 -4
  26. data/ext/couchbase/core/operations/document_lookup_in_all_replicas.hxx +4 -0
  27. data/ext/couchbase/core/operations/document_query.cxx +12 -12
  28. data/ext/couchbase/core/operations/management/bucket_create.cxx +37 -38
  29. data/ext/couchbase/core/operations/management/bucket_update.cxx +26 -28
  30. data/ext/couchbase/core/operations/management/collection_create.cxx +11 -11
  31. data/ext/couchbase/core/operations/management/collection_drop.cxx +11 -11
  32. data/ext/couchbase/core/operations/management/collection_update.cxx +11 -11
  33. data/ext/couchbase/core/operations/management/error_utils.cxx +9 -6
  34. data/ext/couchbase/core/operations/management/query_index_create.cxx +5 -4
  35. data/ext/couchbase/core/operations/management/query_index_drop.cxx +7 -6
  36. data/ext/couchbase/core/operations/management/scope_create.cxx +12 -13
  37. data/ext/couchbase/core/operations/management/scope_drop.cxx +8 -9
  38. data/ext/couchbase/core/topology/configuration.cxx +21 -0
  39. data/ext/couchbase/core/topology/configuration.hxx +28 -0
  40. data/ext/couchbase/core/transactions/attempt_context_impl.cxx +254 -178
  41. data/ext/couchbase/core/transactions/attempt_context_impl.hxx +5 -1
  42. data/ext/couchbase/core/transactions/transactions_cleanup.cxx +42 -7
  43. data/ext/couchbase/core/transactions/waitable_op_list.hxx +13 -2
  44. data/ext/couchbase/core/utils/contains_string.cxx +61 -0
  45. data/ext/couchbase/core/utils/contains_string.hxx +26 -0
  46. data/ext/couchbase/couchbase/cluster.hxx +33 -0
  47. data/ext/couchbase/couchbase/collection.hxx +73 -0
  48. data/ext/couchbase/couchbase/error.hxx +16 -0
  49. data/ext/couchbase/couchbase/node_id.hxx +123 -0
  50. data/ext/couchbase/couchbase/node_id_for_options.hxx +61 -0
  51. data/ext/couchbase/couchbase/node_ids_options.hxx +62 -0
  52. data/ext/couchbase/couchbase/result.hxx +42 -0
  53. data/ext/rcb_crud.cxx +2 -0
  54. data/ext/rcb_logger.cxx +15 -17
  55. data/lib/couchbase/cluster.rb +16 -14
  56. data/lib/couchbase/datastructures/couchbase_list.rb +1 -0
  57. data/lib/couchbase/datastructures/couchbase_map.rb +1 -0
  58. data/lib/couchbase/datastructures/couchbase_queue.rb +1 -0
  59. data/lib/couchbase/datastructures/couchbase_set.rb +1 -0
  60. data/lib/couchbase/errors.rb +1 -1
  61. data/lib/couchbase/json_transcoder.rb +1 -1
  62. data/lib/couchbase/options.rb +9 -4
  63. data/lib/couchbase/protostellar/client.rb +0 -2
  64. data/lib/couchbase/protostellar/cluster.rb +4 -0
  65. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_pb.rb +54 -0
  66. data/lib/couchbase/protostellar/generated/admin/analytics/v1/analytics_services_pb.rb +51 -0
  67. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_pb.rb +5 -24
  68. data/lib/couchbase/protostellar/generated/admin/bucket/v1/bucket_services_pb.rb +16 -0
  69. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_pb.rb +5 -24
  70. data/lib/couchbase/protostellar/generated/admin/collection/v1/collection_services_pb.rb +16 -0
  71. data/lib/couchbase/protostellar/generated/admin/query/v1/query_pb.rb +5 -24
  72. data/lib/couchbase/protostellar/generated/admin/query/v1/query_services_pb.rb +18 -0
  73. data/lib/couchbase/protostellar/generated/admin/search/v1/search_pb.rb +2 -23
  74. data/lib/couchbase/protostellar/generated/admin/search/v1/search_services_pb.rb +23 -0
  75. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_pb.rb +4 -25
  76. data/lib/couchbase/protostellar/generated/analytics/v1/analytics_services_pb.rb +10 -0
  77. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_pb.rb +6 -25
  78. data/lib/couchbase/protostellar/generated/internal/hooks/v1/hooks_services_pb.rb +18 -0
  79. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_pb.rb +46 -0
  80. data/lib/couchbase/protostellar/generated/internal/xdcr/v1/xdcr_services_pb.rb +56 -0
  81. data/lib/couchbase/protostellar/generated/kv/v1/kv_pb.rb +3 -26
  82. data/lib/couchbase/protostellar/generated/kv/v1/kv_services_pb.rb +47 -0
  83. data/lib/couchbase/protostellar/generated/query/v1/query_pb.rb +4 -26
  84. data/lib/couchbase/protostellar/generated/query/v1/query_services_pb.rb +10 -0
  85. data/lib/couchbase/protostellar/generated/routing/v2/routing_pb.rb +26 -0
  86. data/lib/couchbase/protostellar/generated/routing/v2/routing_services_pb.rb +43 -0
  87. data/lib/couchbase/protostellar/generated/search/v1/search_pb.rb +5 -26
  88. data/lib/couchbase/protostellar/generated/search/v1/search_services_pb.rb +11 -0
  89. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_pb.rb +2 -23
  90. data/lib/couchbase/protostellar/generated/transactions/v1/transactions_services_pb.rb +30 -0
  91. data/lib/couchbase/protostellar/generated/view/v1/view_pb.rb +2 -23
  92. data/lib/couchbase/protostellar/generated/view/v1/view_services_pb.rb +9 -0
  93. data/lib/couchbase/protostellar/request_generator/admin/collection.rb +4 -2
  94. data/lib/couchbase/protostellar/request_generator/admin/query.rb +2 -0
  95. data/lib/couchbase/protostellar/request_generator/kv.rb +1 -1
  96. data/lib/couchbase/protostellar/scope.rb +4 -0
  97. data/lib/couchbase/utils/observability.rb +10 -4
  98. data/lib/couchbase/version.rb +1 -1
  99. metadata +20 -7
  100. data/lib/couchbase/protostellar/generated/routing/v1/routing_pb.rb +0 -52
  101. data/lib/couchbase/protostellar/generated/routing/v1/routing_services_pb.rb +0 -30
@@ -30,104 +30,101 @@ namespace couchbase::core::operations::management
30
30
  {
31
31
 
32
32
  auto
33
- bucket_create_request::encode_to(encoded_request_type& encoded,
34
- http_context& /* context */) const -> std::error_code
33
+ bucket_create_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
34
+ -> std::error_code
35
35
  {
36
36
  encoded.method = "POST";
37
37
  encoded.path = "/pools/default/buckets";
38
38
 
39
39
  encoded.headers["content-type"] = "application/x-www-form-urlencoded";
40
- encoded.body.append(fmt::format("name={}", utils::string_codec::form_encode(bucket.name)));
40
+
41
+ std::map<std::string, std::string> values{};
42
+ values["name"] = bucket.name;
41
43
  switch (bucket.bucket_type) {
42
44
  case couchbase::core::management::cluster::bucket_type::couchbase:
43
- encoded.body.append("&bucketType=couchbase");
45
+ values["bucketType"] = "couchbase";
44
46
  break;
45
47
  case couchbase::core::management::cluster::bucket_type::memcached:
46
- encoded.body.append("&bucketType=memcached");
48
+ values["bucketType"] = "memcached";
47
49
  break;
48
50
  case couchbase::core::management::cluster::bucket_type::ephemeral:
49
- encoded.body.append("&bucketType=ephemeral");
51
+ values["bucketType"] = "ephemeral";
50
52
  break;
51
53
  case couchbase::core::management::cluster::bucket_type::unknown:
52
54
  break;
53
55
  }
54
56
  if (bucket.ram_quota_mb == 0) {
55
- encoded.body.append(fmt::format(
56
- "&ramQuotaMB={}", 100)); // If not explicitly set, set to prior default value of 100
57
+ values["ramQuotaMB"] = "100"; // If not explicitly set, set to prior default value of 100
57
58
  } else {
58
- encoded.body.append(fmt::format("&ramQuotaMB={}", bucket.ram_quota_mb));
59
+ values["ramQuotaMB"] = std::to_string(bucket.ram_quota_mb);
59
60
  }
60
61
 
61
62
  if (bucket.bucket_type != couchbase::core::management::cluster::bucket_type::memcached &&
62
63
  bucket.num_replicas.has_value()) {
63
- encoded.body.append(fmt::format("&replicaNumber={}", bucket.num_replicas.value()));
64
+ values["replicaNumber"] = std::to_string(bucket.num_replicas.value());
64
65
  }
65
66
  if (bucket.max_expiry.has_value()) {
66
- encoded.body.append(fmt::format("&maxTTL={}", bucket.max_expiry.value()));
67
+ values["maxTTL"] = std::to_string(bucket.max_expiry.value());
67
68
  }
68
69
  if (bucket.bucket_type != couchbase::core::management::cluster::bucket_type::ephemeral &&
69
70
  bucket.replica_indexes.has_value()) {
70
- encoded.body.append(
71
- fmt::format("&replicaIndex={}", bucket.replica_indexes.value() ? "1" : "0"));
71
+ values["replicaIndex"] = bucket.replica_indexes.value() ? "1" : "0";
72
72
  }
73
73
  if (bucket.history_retention_collection_default.has_value()) {
74
- encoded.body.append(
75
- fmt::format("&historyRetentionCollectionDefault={}",
76
- bucket.history_retention_collection_default.value() ? "true" : "false"));
74
+ values["historyRetentionCollectionDefault"] =
75
+ bucket.history_retention_collection_default.value() ? "true" : "false";
77
76
  }
78
77
  if (bucket.history_retention_bytes.has_value()) {
79
- encoded.body.append(
80
- fmt::format("&historyRetentionBytes={}", bucket.history_retention_bytes.value()));
78
+ values["historyRetentionBytes"] = std::to_string(bucket.history_retention_bytes.value());
81
79
  }
82
80
  if (bucket.history_retention_duration.has_value()) {
83
- encoded.body.append(
84
- fmt::format("&historyRetentionSeconds={}", bucket.history_retention_duration.value()));
81
+ values["historyRetentionSeconds"] = std::to_string(bucket.history_retention_duration.value());
85
82
  }
86
83
  if (bucket.flush_enabled.has_value()) {
87
- encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
84
+ values["flushEnabled"] = bucket.flush_enabled.value() ? "1" : "0";
88
85
  }
89
86
  if (bucket.num_vbuckets.has_value()) {
90
- encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
87
+ values["numVBuckets"] = std::to_string(bucket.num_vbuckets.value());
91
88
  }
92
89
 
93
90
  switch (bucket.eviction_policy) {
94
91
  case couchbase::core::management::cluster::bucket_eviction_policy::full:
95
- encoded.body.append("&evictionPolicy=fullEviction");
92
+ values["evictionPolicy"] = "fullEviction";
96
93
  break;
97
94
  case couchbase::core::management::cluster::bucket_eviction_policy::value_only:
98
- encoded.body.append("&evictionPolicy=valueOnly");
95
+ values["evictionPolicy"] = "valueOnly";
99
96
  break;
100
97
  case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction:
101
- encoded.body.append("&evictionPolicy=noEviction");
98
+ values["evictionPolicy"] = "noEviction";
102
99
  break;
103
100
  case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used:
104
- encoded.body.append("&evictionPolicy=nruEviction");
101
+ values["evictionPolicy"] = "nruEviction";
105
102
  break;
106
103
  case couchbase::core::management::cluster::bucket_eviction_policy::unknown:
107
104
  break;
108
105
  }
109
106
  switch (bucket.compression_mode) {
110
107
  case couchbase::core::management::cluster::bucket_compression::off:
111
- encoded.body.append("&compressionMode=off");
108
+ values["compressionMode"] = "off";
112
109
  break;
113
110
  case couchbase::core::management::cluster::bucket_compression::active:
114
- encoded.body.append("&compressionMode=active");
111
+ values["compressionMode"] = "active";
115
112
  break;
116
113
  case couchbase::core::management::cluster::bucket_compression::passive:
117
- encoded.body.append("&compressionMode=passive");
114
+ values["compressionMode"] = "passive";
118
115
  break;
119
116
  case couchbase::core::management::cluster::bucket_compression::unknown:
120
117
  break;
121
118
  }
122
119
  switch (bucket.conflict_resolution_type) {
123
120
  case couchbase::core::management::cluster::bucket_conflict_resolution::timestamp:
124
- encoded.body.append("&conflictResolutionType=lww");
121
+ values["conflictResolutionType"] = "lww";
125
122
  break;
126
123
  case couchbase::core::management::cluster::bucket_conflict_resolution::sequence_number:
127
- encoded.body.append("&conflictResolutionType=seqno");
124
+ values["conflictResolutionType"] = "seqno";
128
125
  break;
129
126
  case couchbase::core::management::cluster::bucket_conflict_resolution::custom:
130
- encoded.body.append("&conflictResolutionType=custom");
127
+ values["conflictResolutionType"] = "custom";
131
128
  break;
132
129
  case couchbase::core::management::cluster::bucket_conflict_resolution::unknown:
133
130
  break;
@@ -135,16 +132,16 @@ bucket_create_request::encode_to(encoded_request_type& encoded,
135
132
  if (bucket.minimum_durability_level.has_value()) {
136
133
  switch (bucket.minimum_durability_level.value()) {
137
134
  case durability_level::none:
138
- encoded.body.append("&durabilityMinLevel=none");
135
+ values["durabilityMinLevel"] = "none";
139
136
  break;
140
137
  case durability_level::majority:
141
- encoded.body.append("&durabilityMinLevel=majority");
138
+ values["durabilityMinLevel"] = "majority";
142
139
  break;
143
140
  case durability_level::majority_and_persist_to_active:
144
- encoded.body.append("&durabilityMinLevel=majorityAndPersistActive");
141
+ values["durabilityMinLevel"] = "majorityAndPersistActive";
145
142
  break;
146
143
  case durability_level::persist_to_majority:
147
- encoded.body.append("&durabilityMinLevel=persistToMajority");
144
+ values["durabilityMinLevel"] = "persistToMajority";
148
145
  break;
149
146
  }
150
147
  }
@@ -152,12 +149,14 @@ bucket_create_request::encode_to(encoded_request_type& encoded,
152
149
  case couchbase::core::management::cluster::bucket_storage_backend::unknown:
153
150
  break;
154
151
  case couchbase::core::management::cluster::bucket_storage_backend::couchstore:
155
- encoded.body.append("&storageBackend=couchstore");
152
+ values["storageBackend"] = "couchstore";
156
153
  break;
157
154
  case couchbase::core::management::cluster::bucket_storage_backend::magma:
158
- encoded.body.append("&storageBackend=magma");
155
+ values["storageBackend"] = "magma";
159
156
  break;
160
157
  }
158
+
159
+ encoded.body = utils::string_codec::v2::form_encode(values);
161
160
  return {};
162
161
  }
163
162
  auto
@@ -30,8 +30,8 @@
30
30
  namespace couchbase::core::operations::management
31
31
  {
32
32
  auto
33
- bucket_update_request::encode_to(encoded_request_type& encoded,
34
- http_context& /* context */) const -> std::error_code
33
+ bucket_update_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
34
+ -> std::error_code
35
35
  {
36
36
  encoded.method = "POST";
37
37
  encoded.path =
@@ -39,65 +39,61 @@ bucket_update_request::encode_to(encoded_request_type& encoded,
39
39
 
40
40
  encoded.headers["content-type"] = "application/x-www-form-urlencoded";
41
41
 
42
+ std::map<std::string, std::string> values{};
42
43
  if (bucket.ram_quota_mb > 0) {
43
- encoded.body.append(fmt::format("&ramQuotaMB={}", bucket.ram_quota_mb));
44
+ values["ramQuotaMB"] = std::to_string(bucket.ram_quota_mb);
44
45
  }
45
46
  if (bucket.num_replicas.has_value()) {
46
- encoded.body.append(fmt::format("&replicaNumber={}", bucket.num_replicas.value()));
47
+ values["replicaNumber"] = std::to_string(bucket.num_replicas.value());
47
48
  }
48
-
49
49
  if (bucket.max_expiry.has_value()) {
50
- encoded.body.append(fmt::format("&maxTTL={}", bucket.max_expiry.value()));
50
+ values["maxTTL"] = std::to_string(bucket.max_expiry.value());
51
51
  }
52
52
  if (bucket.history_retention_collection_default.has_value()) {
53
- encoded.body.append(
54
- fmt::format("&historyRetentionCollectionDefault={}",
55
- bucket.history_retention_collection_default.value() ? "true" : "false"));
53
+ values["historyRetentionCollectionDefault"] =
54
+ bucket.history_retention_collection_default.value() ? "true" : "false";
56
55
  }
57
56
  if (bucket.history_retention_bytes.has_value()) {
58
- encoded.body.append(
59
- fmt::format("&historyRetentionBytes={}", bucket.history_retention_bytes.value()));
57
+ values["historyRetentionBytes"] = std::to_string(bucket.history_retention_bytes.value());
60
58
  }
61
59
  if (bucket.history_retention_duration.has_value()) {
62
- encoded.body.append(
63
- fmt::format("&historyRetentionSeconds={}", bucket.history_retention_duration.value()));
60
+ values["historyRetentionSeconds"] = std::to_string(bucket.history_retention_duration.value());
64
61
  }
65
62
  if (bucket.replica_indexes.has_value()) {
66
- encoded.body.append(
67
- fmt::format("&replicaIndex={}", bucket.replica_indexes.value() ? "1" : "0"));
63
+ values["replicaIndex"] = bucket.replica_indexes.value() ? "1" : "0";
68
64
  }
69
65
  if (bucket.flush_enabled.has_value()) {
70
- encoded.body.append(fmt::format("&flushEnabled={}", bucket.flush_enabled.value() ? "1" : "0"));
66
+ values["flushEnabled"] = bucket.flush_enabled.value() ? "1" : "0";
71
67
  }
72
68
  if (bucket.num_vbuckets.has_value()) {
73
- encoded.body.append(fmt::format("&numVBuckets={}", bucket.num_vbuckets.value()));
69
+ values["numVBuckets"] = std::to_string(bucket.num_vbuckets.value());
74
70
  }
75
71
 
76
72
  switch (bucket.eviction_policy) {
77
73
  case couchbase::core::management::cluster::bucket_eviction_policy::full:
78
- encoded.body.append("&evictionPolicy=fullEviction");
74
+ values["evictionPolicy"] = "fullEviction";
79
75
  break;
80
76
  case couchbase::core::management::cluster::bucket_eviction_policy::value_only:
81
- encoded.body.append("&evictionPolicy=valueOnly");
77
+ values["evictionPolicy"] = "valueOnly";
82
78
  break;
83
79
  case couchbase::core::management::cluster::bucket_eviction_policy::no_eviction:
84
- encoded.body.append("&evictionPolicy=noEviction");
80
+ values["evictionPolicy"] = "noEviction";
85
81
  break;
86
82
  case couchbase::core::management::cluster::bucket_eviction_policy::not_recently_used:
87
- encoded.body.append("&evictionPolicy=nruEviction");
83
+ values["evictionPolicy"] = "nruEviction";
88
84
  break;
89
85
  case couchbase::core::management::cluster::bucket_eviction_policy::unknown:
90
86
  break;
91
87
  }
92
88
  switch (bucket.compression_mode) {
93
89
  case couchbase::core::management::cluster::bucket_compression::off:
94
- encoded.body.append("&compressionMode=off");
90
+ values["compressionMode"] = "off";
95
91
  break;
96
92
  case couchbase::core::management::cluster::bucket_compression::active:
97
- encoded.body.append("&compressionMode=active");
93
+ values["compressionMode"] = "active";
98
94
  break;
99
95
  case couchbase::core::management::cluster::bucket_compression::passive:
100
- encoded.body.append("&compressionMode=passive");
96
+ values["compressionMode"] = "passive";
101
97
  break;
102
98
  case couchbase::core::management::cluster::bucket_compression::unknown:
103
99
  break;
@@ -105,19 +101,21 @@ bucket_update_request::encode_to(encoded_request_type& encoded,
105
101
  if (bucket.minimum_durability_level) {
106
102
  switch (bucket.minimum_durability_level.value()) {
107
103
  case durability_level::none:
108
- encoded.body.append("&durabilityMinLevel=none");
104
+ values["durabilityMinLevel"] = "none";
109
105
  break;
110
106
  case durability_level::majority:
111
- encoded.body.append("&durabilityMinLevel=majority");
107
+ values["durabilityMinLevel"] = "majority";
112
108
  break;
113
109
  case durability_level::majority_and_persist_to_active:
114
- encoded.body.append("&durabilityMinLevel=majorityAndPersistActive");
110
+ values["durabilityMinLevel"] = "majorityAndPersistActive";
115
111
  break;
116
112
  case durability_level::persist_to_majority:
117
- encoded.body.append("&durabilityMinLevel=persistToMajority");
113
+ values["durabilityMinLevel"] = "persistToMajority";
118
114
  break;
119
115
  }
120
116
  }
117
+
118
+ encoded.body = utils::string_codec::v2::form_encode(values);
121
119
  return {};
122
120
  }
123
121
 
@@ -24,13 +24,11 @@
24
24
  #include <spdlog/fmt/bundled/core.h>
25
25
  #include <tao/json/value.hpp>
26
26
 
27
- #include <regex>
28
-
29
27
  namespace couchbase::core::operations::management
30
28
  {
31
29
  auto
32
- collection_create_request::encode_to(encoded_request_type& encoded,
33
- http_context& /*context*/) const -> std::error_code
30
+ collection_create_request::encode_to(encoded_request_type& encoded, http_context& /*context*/) const
31
+ -> std::error_code
34
32
  {
35
33
  encoded.method = "POST";
36
34
  encoded.path = fmt::format("/pools/default/buckets/{}/scopes/{}/collections",
@@ -58,18 +56,20 @@ collection_create_request::make_response(error_context::http&& ctx,
58
56
  {
59
57
  collection_create_response response{ std::move(ctx) };
60
58
  if (!response.ctx.ec) {
61
- switch (encoded.status_code) {
59
+ switch (const auto& body = encoded.body.data(); encoded.status_code) {
62
60
  case 400: {
63
- const std::regex collection_exists("Collection with name .+ already exists");
64
- if (std::regex_search(encoded.body.data(), collection_exists)) {
61
+ const auto prefix_pos = body.find("Collection with name ");
62
+ if (prefix_pos != std::string_view::npos &&
63
+ body.find(" already exists", prefix_pos) != std::string_view::npos) {
65
64
  response.ctx.ec = errc::management::collection_exists;
66
65
  } else {
67
66
  response.ctx.ec = errc::common::invalid_argument;
68
67
  }
69
68
  } break;
70
69
  case 404: {
71
- const std::regex scope_not_found("Scope with name .+ is not found");
72
- if (std::regex_search(encoded.body.data(), scope_not_found)) {
70
+ const auto prefix_pos = body.find("Scope with name ");
71
+ if (prefix_pos != std::string_view::npos &&
72
+ body.find(" is not found", prefix_pos) != std::string_view::npos) {
73
73
  response.ctx.ec = errc::common::scope_not_found;
74
74
  } else {
75
75
  response.ctx.ec = errc::common::bucket_not_found;
@@ -78,7 +78,7 @@ collection_create_request::make_response(error_context::http&& ctx,
78
78
  case 200: {
79
79
  tao::json::value payload{};
80
80
  try {
81
- payload = utils::json::parse(encoded.body.data());
81
+ payload = utils::json::parse(body);
82
82
  } catch (const tao::pegtl::parse_error&) {
83
83
  response.ctx.ec = errc::common::parsing_failure;
84
84
  return response;
@@ -86,7 +86,7 @@ collection_create_request::make_response(error_context::http&& ctx,
86
86
  response.uid = std::stoull(payload.at("uid").get_string(), nullptr, 16);
87
87
  } break;
88
88
  default:
89
- response.ctx.ec = extract_common_error_code(encoded.status_code, encoded.body.data());
89
+ response.ctx.ec = extract_common_error_code(encoded.status_code, body);
90
90
  break;
91
91
  }
92
92
  }
@@ -24,13 +24,11 @@
24
24
  #include <spdlog/fmt/bundled/core.h>
25
25
  #include <tao/json/value.hpp>
26
26
 
27
- #include <regex>
28
-
29
27
  namespace couchbase::core::operations::management
30
28
  {
31
29
  auto
32
- collection_drop_request::encode_to(encoded_request_type& encoded,
33
- http_context& /* context */) const -> std::error_code
30
+ collection_drop_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
31
+ -> std::error_code
34
32
  {
35
33
  encoded.method = "DELETE";
36
34
  encoded.path = fmt::format("/pools/default/buckets/{}/scopes/{}/collections/{}",
@@ -47,16 +45,18 @@ collection_drop_request::make_response(error_context::http&& ctx,
47
45
  {
48
46
  collection_drop_response response{ std::move(ctx) };
49
47
  if (!response.ctx.ec) {
50
- switch (encoded.status_code) {
48
+ switch (const auto& body = encoded.body.data(); encoded.status_code) {
51
49
  case 400:
52
50
  response.ctx.ec = errc::common::unsupported_operation;
53
51
  break;
54
52
  case 404: {
55
- const std::regex scope_not_found("Scope with name .+ is not found");
56
- const std::regex collection_not_found("Collection with name .+ is not found");
57
- if (std::regex_search(encoded.body.data(), collection_not_found)) {
53
+ const auto collection_prefix_pos = body.find("Collection with name ");
54
+ const auto scope_prefix_pos = body.find("Scope with name ");
55
+ if (collection_prefix_pos != std::string_view::npos &&
56
+ body.find(" is not found", collection_prefix_pos) != std::string_view::npos) {
58
57
  response.ctx.ec = errc::common::collection_not_found;
59
- } else if (std::regex_search(encoded.body.data(), scope_not_found)) {
58
+ } else if (scope_prefix_pos != std::string_view::npos &&
59
+ body.find(" is not found", scope_prefix_pos) != std::string_view::npos) {
60
60
  response.ctx.ec = errc::common::scope_not_found;
61
61
  } else {
62
62
  response.ctx.ec = errc::common::bucket_not_found;
@@ -65,7 +65,7 @@ collection_drop_request::make_response(error_context::http&& ctx,
65
65
  case 200: {
66
66
  tao::json::value payload{};
67
67
  try {
68
- payload = utils::json::parse(encoded.body.data());
68
+ payload = utils::json::parse(body);
69
69
  } catch (const tao::pegtl::parse_error&) {
70
70
  response.ctx.ec = errc::common::parsing_failure;
71
71
  return response;
@@ -73,7 +73,7 @@ collection_drop_request::make_response(error_context::http&& ctx,
73
73
  response.uid = std::stoull(payload.at("uid").get_string(), nullptr, 16);
74
74
  } break;
75
75
  default:
76
- response.ctx.ec = extract_common_error_code(encoded.status_code, encoded.body.data());
76
+ response.ctx.ec = extract_common_error_code(encoded.status_code, body);
77
77
  break;
78
78
  }
79
79
  }
@@ -24,13 +24,11 @@
24
24
  #include <spdlog/fmt/bundled/core.h>
25
25
  #include <tao/json/value.hpp>
26
26
 
27
- #include <regex>
28
-
29
27
  namespace couchbase::core::operations::management
30
28
  {
31
29
  auto
32
- collection_update_request::encode_to(encoded_request_type& encoded,
33
- http_context& /*context*/) const -> std::error_code
30
+ collection_update_request::encode_to(encoded_request_type& encoded, http_context& /*context*/) const
31
+ -> std::error_code
34
32
  {
35
33
  encoded.method = "PATCH";
36
34
  encoded.path = fmt::format("/pools/default/buckets/{}/scopes/{}/collections/{}",
@@ -60,16 +58,18 @@ collection_update_request::make_response(error_context::http&& ctx,
60
58
  {
61
59
  collection_update_response response{ std::move(ctx) };
62
60
  if (!response.ctx.ec) {
63
- switch (encoded.status_code) {
61
+ switch (const auto& body = encoded.body.data(); encoded.status_code) {
64
62
  case 400: {
65
63
  response.ctx.ec = errc::common::invalid_argument;
66
64
  } break;
67
65
  case 404: {
68
- const std::regex scope_not_found("Scope with name .+ is not found");
69
- const std::regex collection_not_found("Collection with name .+ is not found");
70
- if (std::regex_search(encoded.body.data(), collection_not_found)) {
66
+ const auto collection_prefix_pos = body.find("Collection with name ");
67
+ const auto scope_prefix_pos = body.find("Scope with name ");
68
+ if (collection_prefix_pos != std::string_view::npos &&
69
+ body.find(" is not found", collection_prefix_pos) != std::string_view::npos) {
71
70
  response.ctx.ec = errc::common::collection_not_found;
72
- } else if (std::regex_search(encoded.body.data(), scope_not_found)) {
71
+ } else if (scope_prefix_pos != std::string_view::npos &&
72
+ body.find(" is not found", scope_prefix_pos) != std::string_view::npos) {
73
73
  response.ctx.ec = errc::common::scope_not_found;
74
74
  } else {
75
75
  response.ctx.ec = errc::common::bucket_not_found;
@@ -78,7 +78,7 @@ collection_update_request::make_response(error_context::http&& ctx,
78
78
  case 200: {
79
79
  tao::json::value payload{};
80
80
  try {
81
- payload = utils::json::parse(encoded.body.data());
81
+ payload = utils::json::parse(body);
82
82
  } catch (const tao::pegtl::parse_error&) {
83
83
  response.ctx.ec = errc::common::parsing_failure;
84
84
  return response;
@@ -86,7 +86,7 @@ collection_update_request::make_response(error_context::http&& ctx,
86
86
  response.uid = std::stoull(payload.at("uid").get_string(), nullptr, 16);
87
87
  } break;
88
88
  default:
89
- response.ctx.ec = extract_common_error_code(encoded.status_code, encoded.body.data());
89
+ response.ctx.ec = extract_common_error_code(encoded.status_code, body);
90
90
  break;
91
91
  }
92
92
  }
@@ -16,12 +16,11 @@
16
16
  */
17
17
 
18
18
  #include "error_utils.hxx"
19
+ #include "core/utils/contains_string.hxx"
19
20
  #include "core/utils/json.hxx"
20
21
 
21
22
  #include <tao/json/value.hpp>
22
23
 
23
- #include <regex>
24
-
25
24
  namespace couchbase::core::operations::management
26
25
  {
27
26
 
@@ -143,12 +142,16 @@ translate_query_error_code(std::uint64_t error, const std::string& message, std:
143
142
  {
144
143
  switch (error) {
145
144
  case 5000: /* IKey: "Internal Error" */
146
- if (std::regex_search(message, std::regex{ ".*[iI]ndex .*already exist.*" })) {
145
+ if (utils::contains_string(message, "index", true) &&
146
+ utils::contains_string(message, "already exist", true)) {
147
147
  return errc::common::index_exists;
148
- } else if (message.find("Index does not exist") != std::string::npos ||
149
- std::regex_search(message, std::regex{ ".*[iI]ndex .*[nN]ot [fF]ound.*" })) {
148
+ }
149
+ if (utils::contains_string(message, "Index does not exist") ||
150
+ (utils::contains_string(message, "index", true) &&
151
+ utils::contains_string(message, "not found", true))) {
150
152
  return errc::common::index_not_found;
151
- } else if (message.find("Bucket Not Found") != std::string::npos) {
153
+ }
154
+ if (message.find("Bucket Not Found") != std::string::npos) {
152
155
  return errc::common::bucket_not_found;
153
156
  }
154
157
  break;
@@ -17,6 +17,7 @@
17
17
 
18
18
  #include "query_index_create.hxx"
19
19
 
20
+ #include "core/utils/contains_string.hxx"
20
21
  #include "core/utils/json.hxx"
21
22
  #include "core/utils/keyspace.hxx"
22
23
  #include "error_utils.hxx"
@@ -24,8 +25,6 @@
24
25
  #include <spdlog/fmt/bundled/core.h>
25
26
  #include <tao/json/value.hpp>
26
27
 
27
- #include <regex>
28
-
29
28
  namespace couchbase::core::operations::management
30
29
  {
31
30
  auto
@@ -118,13 +117,15 @@ query_index_create_request::make_response(error_context::http&& ctx,
118
117
  error.message = entry.at("msg").get_string();
119
118
  switch (error.code) {
120
119
  case 5000: /* IKey: "Internal Error" */
121
- if (std::regex_search(error.message, std::regex{ ".*[iI]ndex .*already exist.*" })) {
120
+ {
121
+ if (utils::contains_string(error.message, "index", true) &&
122
+ utils::contains_string(error.message, "already exist", true)) {
122
123
  index_already_exists = true;
123
124
  }
124
125
  if (error.message.find("Bucket Not Found") != std::string::npos) {
125
126
  bucket_not_found = true;
126
127
  }
127
- break;
128
+ } break;
128
129
 
129
130
  case 12003: /* IKey: "datastore.couchbase.keyspace_not_found" */
130
131
  if (error.message.find("missing_collection") != std::string::npos) {
@@ -17,6 +17,7 @@
17
17
 
18
18
  #include "query_index_drop.hxx"
19
19
 
20
+ #include "core/utils/contains_string.hxx"
20
21
  #include "core/utils/json.hxx"
21
22
  #include "core/utils/keyspace.hxx"
22
23
  #include "error_utils.hxx"
@@ -24,13 +25,11 @@
24
25
  #include <spdlog/fmt/bundled/core.h>
25
26
  #include <tao/json/value.hpp>
26
27
 
27
- #include <regex>
28
-
29
28
  namespace couchbase::core::operations::management
30
29
  {
31
30
  auto
32
- query_index_drop_request::encode_to(encoded_request_type& encoded,
33
- http_context& /*context*/) const -> std::error_code
31
+ query_index_drop_request::encode_to(encoded_request_type& encoded, http_context& /*context*/) const
32
+ -> std::error_code
34
33
  {
35
34
  if (!utils::check_query_management_request(*this)) {
36
35
  return errc::common::invalid_argument;
@@ -87,10 +86,12 @@ query_index_drop_request::make_response(error_context::http&& ctx,
87
86
  error.message = entry.at("msg").get_string();
88
87
  switch (error.code) {
89
88
  case 5000: /* IKey: "Internal Error" */
90
- if (std::regex_search(error.message, std::regex{ ".*[iI]ndex .*[nN]ot [fF]ound.*" })) {
89
+ {
90
+ if (utils::contains_string(error.message, "index", true) &&
91
+ utils::contains_string(error.message, "not found", true)) {
91
92
  index_not_found = true;
92
93
  }
93
- break;
94
+ } break;
94
95
 
95
96
  case 12003: /* IKey: "datastore.couchbase.keyspace_not_found" */
96
97
  if (error.message.find("missing_collection") != std::string::npos) {
@@ -24,13 +24,11 @@
24
24
  #include <spdlog/fmt/bundled/core.h>
25
25
  #include <tao/json/value.hpp>
26
26
 
27
- #include <regex>
28
-
29
27
  namespace couchbase::core::operations::management
30
28
  {
31
29
  auto
32
- scope_create_request::encode_to(encoded_request_type& encoded,
33
- http_context& /* context */) const -> std::error_code
30
+ scope_create_request::encode_to(encoded_request_type& encoded, http_context& /* context */) const
31
+ -> std::error_code
34
32
  {
35
33
  encoded.method = "POST";
36
34
  encoded.path = fmt::format("/pools/default/buckets/{}/scopes",
@@ -41,18 +39,19 @@ scope_create_request::encode_to(encoded_request_type& encoded,
41
39
  }
42
40
 
43
41
  auto
44
- scope_create_request::make_response(error_context::http&& ctx, const encoded_response_type& encoded)
45
- const -> scope_create_response
42
+ scope_create_request::make_response(error_context::http&& ctx,
43
+ const encoded_response_type& encoded) const
44
+ -> scope_create_response
46
45
  {
47
46
  scope_create_response response{ std::move(ctx) };
48
47
  if (!response.ctx.ec) {
49
- switch (encoded.status_code) {
48
+ switch (const auto& body = encoded.body.data(); encoded.status_code) {
50
49
  case 400: {
51
- const std::regex scope_exists("Scope with name .+ already exists");
52
- if (std::regex_search(encoded.body.data(), scope_exists)) {
50
+ const auto prefix_pos = body.find("Scope with name ");
51
+ if (prefix_pos != std::string_view::npos &&
52
+ body.find(" already exists", prefix_pos) != std::string_view::npos) {
53
53
  response.ctx.ec = errc::management::scope_exists;
54
- } else if (encoded.body.data().find("Not allowed on this version of cluster") !=
55
- std::string::npos) {
54
+ } else if (body.find("Not allowed on this version of cluster") != std::string::npos) {
56
55
  response.ctx.ec = errc::common::feature_not_available;
57
56
  } else {
58
57
  response.ctx.ec = errc::common::invalid_argument;
@@ -64,7 +63,7 @@ scope_create_request::make_response(error_context::http&& ctx, const encoded_res
64
63
  case 200: {
65
64
  tao::json::value payload{};
66
65
  try {
67
- payload = utils::json::parse(encoded.body.data());
66
+ payload = utils::json::parse(body);
68
67
  } catch (const tao::pegtl::parse_error&) {
69
68
  response.ctx.ec = errc::common::parsing_failure;
70
69
  return response;
@@ -72,7 +71,7 @@ scope_create_request::make_response(error_context::http&& ctx, const encoded_res
72
71
  response.uid = std::stoull(payload.at("uid").get_string(), nullptr, 16);
73
72
  } break;
74
73
  default:
75
- response.ctx.ec = extract_common_error_code(encoded.status_code, encoded.body.data());
74
+ response.ctx.ec = extract_common_error_code(encoded.status_code, body);
76
75
  break;
77
76
  }
78
77
  }