couchbase 3.0.0.alpha.3 → 3.0.0.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/tests-6.0.3.yml +4 -1
  3. data/.github/workflows/tests-dev-preview.yml +4 -1
  4. data/.github/workflows/tests.yml +4 -1
  5. data/README.md +1 -1
  6. data/bin/check-cluster +31 -0
  7. data/bin/init-cluster +16 -4
  8. data/examples/analytics.rb +221 -0
  9. data/examples/managing_analytics_indexes.rb +72 -0
  10. data/examples/managing_view_indexes.rb +54 -0
  11. data/examples/search_with_consistency.rb +84 -0
  12. data/examples/view.rb +50 -0
  13. data/ext/.clang-tidy +1 -0
  14. data/ext/build_version.hxx.in +1 -1
  15. data/ext/couchbase/bucket.hxx +0 -1
  16. data/ext/couchbase/couchbase.cxx +1421 -55
  17. data/ext/couchbase/io/dns_client.hxx +215 -0
  18. data/ext/couchbase/io/dns_codec.hxx +207 -0
  19. data/ext/couchbase/io/dns_config.hxx +116 -0
  20. data/ext/couchbase/io/dns_message.hxx +558 -0
  21. data/ext/couchbase/io/http_session.hxx +16 -4
  22. data/ext/couchbase/io/mcbp_session.hxx +2 -1
  23. data/ext/couchbase/mutation_token.hxx +1 -1
  24. data/ext/couchbase/operations.hxx +19 -0
  25. data/ext/couchbase/operations/analytics_dataset_create.hxx +117 -0
  26. data/ext/couchbase/operations/analytics_dataset_drop.hxx +103 -0
  27. data/ext/couchbase/operations/analytics_dataset_get_all.hxx +107 -0
  28. data/ext/couchbase/operations/analytics_dataverse_create.hxx +104 -0
  29. data/ext/couchbase/operations/analytics_dataverse_drop.hxx +104 -0
  30. data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +91 -0
  31. data/ext/couchbase/operations/analytics_index_create.hxx +128 -0
  32. data/ext/couchbase/operations/analytics_index_drop.hxx +110 -0
  33. data/ext/couchbase/operations/analytics_index_get_all.hxx +106 -0
  34. data/ext/couchbase/operations/analytics_link_connect.hxx +102 -0
  35. data/ext/couchbase/operations/analytics_link_disconnect.hxx +101 -0
  36. data/ext/couchbase/operations/design_document.hxx +59 -0
  37. data/ext/couchbase/operations/document_analytics.hxx +293 -0
  38. data/ext/couchbase/operations/document_query.hxx +2 -2
  39. data/ext/couchbase/operations/document_search.hxx +19 -1
  40. data/ext/couchbase/operations/document_view.hxx +227 -0
  41. data/ext/couchbase/operations/search_index.hxx +17 -0
  42. data/ext/couchbase/operations/search_index_control_ingest.hxx +3 -1
  43. data/ext/couchbase/operations/view_index_drop.hxx +67 -0
  44. data/ext/couchbase/operations/view_index_get.hxx +90 -0
  45. data/ext/couchbase/operations/view_index_get_all.hxx +125 -0
  46. data/ext/couchbase/operations/view_index_upsert.hxx +87 -0
  47. data/ext/couchbase/service_type.hxx +38 -1
  48. data/ext/couchbase/timeout_defaults.hxx +3 -1
  49. data/ext/couchbase/utils/connection_string.hxx +231 -0
  50. data/ext/couchbase/version.hxx +1 -1
  51. data/ext/test/main.cxx +3 -12
  52. data/lib/couchbase/analytics_options.rb +165 -0
  53. data/lib/couchbase/bucket.rb +49 -0
  54. data/lib/couchbase/cluster.rb +46 -207
  55. data/lib/couchbase/management/analytics_index_manager.rb +138 -24
  56. data/lib/couchbase/management/view_index_manager.rb +63 -10
  57. data/lib/couchbase/query_options.rb +219 -0
  58. data/lib/couchbase/search_options.rb +6 -6
  59. data/lib/couchbase/version.rb +1 -1
  60. data/lib/couchbase/view_options.rb +155 -0
  61. metadata +34 -2
@@ -0,0 +1,558 @@
1
+ /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2
+ /*
3
+ * Copyright 2020 Couchbase, Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ #pragma once
19
+
20
+ #include <cstdint>
21
+ #include <vector>
22
+ #include <string>
23
+
24
+ namespace couchbase::io::dns
25
+ {
26
+ /**
27
+ * 3.2.2. TYPE values
28
+ * ==================
29
+ *
30
+ * TYPE fields are used in resource records. Note that these types are a subset of QTYPEs.
31
+ */
32
+ enum class resource_type : std::uint16_t {
33
+ /**
34
+ * a host address
35
+ */
36
+ a = 1,
37
+
38
+ /**
39
+ * an authoritative name server
40
+ */
41
+ ns = 2,
42
+
43
+ /**
44
+ * a mail destination (Obsolete - use MX)
45
+ */
46
+ md = 3,
47
+
48
+ /**
49
+ * a mail forwarder (Obsolete - use MX)
50
+ */
51
+ mf = 4,
52
+
53
+ /**
54
+ * the canonical name for an alias
55
+ */
56
+ cname = 5,
57
+
58
+ /**
59
+ * marks the start of a zone of authority
60
+ */
61
+ soa = 6,
62
+
63
+ /**
64
+ * a mailbox domain name (EXPERIMENTAL)
65
+ */
66
+ mb = 7,
67
+
68
+ /**
69
+ * a mail group member (EXPERIMENTAL)
70
+ */
71
+ mg = 8,
72
+
73
+ /**
74
+ * a mail rename domain name (EXPERIMENTAL)
75
+ */
76
+ mr = 9,
77
+
78
+ /**
79
+ * a null RR (EXPERIMENTAL)
80
+ */
81
+ null = 10,
82
+
83
+ /**
84
+ * a well known service description
85
+ */
86
+ wks = 11,
87
+
88
+ /**
89
+ * a domain name pointer
90
+ */
91
+ ptr = 12,
92
+
93
+ /**
94
+ * host information
95
+ */
96
+ hinfo = 13,
97
+
98
+ /**
99
+ * mailbox or mail list information
100
+ */
101
+ minfo = 14,
102
+
103
+ /**
104
+ * mail exchange
105
+ */
106
+ mx = 15,
107
+
108
+ /**
109
+ * text strings
110
+ */
111
+ txt = 16,
112
+
113
+ /**
114
+ * location services (RFC2782)
115
+ */
116
+ srv = 33,
117
+ };
118
+
119
+ /**
120
+ * 3.2.4. CLASS values
121
+ * ===================
122
+ *
123
+ * CLASS fields appear in resource records. The following CLASS mnemonics and values are defined:
124
+ *
125
+ *
126
+ * 3.2.5. QCLASS values
127
+ * ====================
128
+ *
129
+ * QCLASS fields appear in the question section of a query. QCLASS values are a superset of CLASS values; every CLASS is a valid QCLASS. In
130
+ * addition to CLASS values, the following QCLASSes are defined:
131
+ */
132
+ enum class resource_class : std::uint16_t {
133
+ /**
134
+ * the Internet
135
+ */
136
+ in = 1,
137
+
138
+ /**
139
+ * the CSNET class (Obsolete - used only for examples in some obsolete RFCs)
140
+ */
141
+ cs = 2,
142
+
143
+ /**
144
+ * the CHAOS class
145
+ */
146
+ ch = 3,
147
+
148
+ /**
149
+ * Hesiod [Dyer 87]
150
+ */
151
+ hs = 4,
152
+
153
+ /**
154
+ * any class
155
+ */
156
+ any = 255,
157
+ };
158
+
159
+ /**
160
+ * [OPCODE]
161
+ *
162
+ * A four bit field that specifies kind of query in this message. This value is set by the originator of a query and copied into the
163
+ * response. The values are:
164
+ *
165
+ * 3-15 reserved for future use
166
+ */
167
+ enum class opcode : std::uint8_t {
168
+ /**
169
+ * a standard query (QUERY)
170
+ */
171
+ standard_query = 0,
172
+
173
+ /**
174
+ * an inverse query (IQUERY)
175
+ */
176
+ inverse_query = 1,
177
+
178
+ /**
179
+ * a server status request (STATUS)
180
+ */
181
+ status = 2,
182
+ };
183
+
184
+ /**
185
+ * [QR]
186
+ *
187
+ * A one bit field that specifies whether this message is a query (0), or a response (1).
188
+ */
189
+ enum class message_type : std::uint8_t {
190
+ query = 0,
191
+ response = 1,
192
+ };
193
+
194
+ /**
195
+ * [AA]
196
+ *
197
+ * Authoritative Answer - this bit is valid in responses, and specifies that the responding name server is an authority for the domain name
198
+ * in question section.
199
+ *
200
+ * Note that the contents of the answer section may have multiple owner names because of aliases. The AA bit corresponds to the name which
201
+ * matches the query name, or the first owner name in the answer section.
202
+ */
203
+ enum class authoritative_answer : std::uint8_t {
204
+ no = 0,
205
+ yes = 1,
206
+ };
207
+
208
+ /**
209
+ * [TC]
210
+ *
211
+ * TrunCation - specifies that this message was truncated due to length greater than that permitted on the transmission channel.
212
+ */
213
+ enum class truncation : std::uint8_t {
214
+ no = 0,
215
+ yes = 1,
216
+ };
217
+
218
+ /**
219
+ * [RD]
220
+ *
221
+ * Recursion Desired - this bit may be set in a query and is copied into the response. If RD is set, it directs the name server to pursue
222
+ * the query recursively. Recursive query support is optional.
223
+ */
224
+ enum class recursion_desired : std::uint8_t {
225
+ no = 0,
226
+ yes = 1,
227
+ };
228
+
229
+ /**
230
+ * [RA]
231
+ *
232
+ * Recursion Available - this be is set or cleared in a response, and denotes whether recursive query support is available in the name
233
+ * server.
234
+ */
235
+ enum class recursion_available : std::uint8_t {
236
+ no = 0,
237
+ yes = 1,
238
+ };
239
+
240
+ /**
241
+ * [RCODE]
242
+ *
243
+ * Response code - this 4 bit field is set as part of responses. The values have the following interpretation:
244
+ *
245
+ * 6-15 Reserved for future use.
246
+ */
247
+ enum class response_code : std::uint8_t {
248
+ /**
249
+ * No error condition
250
+ */
251
+ no_error = 0,
252
+
253
+ /**
254
+ * The name server was unable to interpret the query.
255
+ */
256
+ format_error = 1,
257
+
258
+ /**
259
+ * The name server was unable to process this query due to a problem with the name server.
260
+ */
261
+ server_failure = 2,
262
+
263
+ /**
264
+ * Meaningful only for responses from an authoritative name server, this code signifies that the domain name referenced in the query
265
+ * does not exist.
266
+ */
267
+ name_error = 3,
268
+
269
+ /**
270
+ * The name server does not support the requested kind of query.
271
+ */
272
+ not_implemented = 4,
273
+
274
+ /**
275
+ * The name server refuses to perform the specified operation for policy reasons. For example, a name server may not wish to provide
276
+ * the information to the particular requester, or a name server may not wish to perform a particular operation (e.g., zone transfer)
277
+ * for particular data.
278
+ */
279
+ refused = 5,
280
+ };
281
+
282
+ /**
283
+ * 4.1.1. Header section format
284
+ * ============================
285
+ *
286
+ * The header contains the following fields:
287
+ *
288
+ * 1 1 1 1 1 1
289
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
290
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
291
+ * | ID |
292
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
293
+ * |QR| OPCODE |AA|TC|RD|RA| <zero> | RCODE |
294
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
295
+ * | QDCOUNT |
296
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
297
+ * | ANCOUNT |
298
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
299
+ * | NSCOUNT |
300
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
301
+ * | ARCOUNT |
302
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
303
+ */
304
+ struct dns_header {
305
+ struct dns_flags {
306
+ message_type qr{ message_type::query };
307
+ dns::opcode opcode{ dns::opcode::standard_query };
308
+ authoritative_answer aa{ authoritative_answer::no };
309
+ truncation tc{ truncation::no };
310
+ recursion_desired rd{ recursion_desired::yes };
311
+ recursion_available ra{ recursion_available::no };
312
+ response_code rcode{ response_code::no_error };
313
+
314
+ [[nodiscard]] std::uint16_t encode() const
315
+ {
316
+ return std::uint16_t((static_cast<std::uint32_t>(qr) & 1U) << 15U |
317
+ (static_cast<std::uint32_t>(opcode) & 15U) << 11U |
318
+ (static_cast<std::uint32_t>(aa) & 1U) << 10U |
319
+ (static_cast<std::uint32_t>(tc) & 1U) << 9U |
320
+ (static_cast<std::uint32_t>(rd) & 1U) << 8U |
321
+ (static_cast<std::uint32_t>(ra) & 1U) << 7U |
322
+ (static_cast<std::uint32_t>(rcode) & 15U));
323
+ }
324
+
325
+ void decode(std::uint16_t blob)
326
+ {
327
+ qr = static_cast<message_type>((static_cast<std::uint32_t>(blob) >> 15U) & 1U);
328
+ opcode = static_cast<dns::opcode>((static_cast<std::uint32_t>(blob) >> 11U) & 15U);
329
+
330
+ aa = ((static_cast<std::uint32_t>(blob) >> 10U) & 1U) != 0U ? authoritative_answer::yes : authoritative_answer::no;
331
+ tc = ((static_cast<std::uint32_t>(blob) >> 9U) & 1U) != 0U ? truncation::yes : truncation::no;
332
+ rd = ((static_cast<std::uint32_t>(blob) >> 8U) & 1U) != 0U ? recursion_desired::yes : recursion_desired::no;
333
+ ra = ((static_cast<std::uint32_t>(blob) >> 7U) & 1U) != 0U ? recursion_available::yes : recursion_available::no;
334
+
335
+ rcode = static_cast<response_code>(blob & 15U);
336
+ }
337
+ };
338
+
339
+ /**
340
+ * [ID]
341
+ *
342
+ * A 16 bit identifier assigned by the program that generates any kind of query. This identifier is copied the corresponding reply and
343
+ * can be used by the requester to match up replies to outstanding queries.
344
+ */
345
+ std::uint16_t id;
346
+
347
+ dns_flags flags;
348
+
349
+ /**
350
+ * [QDCOUNT]
351
+ *
352
+ * an unsigned 16 bit integer specifying the number of entries in the question section.
353
+ */
354
+ std::uint16_t question_records;
355
+
356
+ /**
357
+ * [ANCOUNT]
358
+ *
359
+ * an unsigned 16 bit integer specifying the number of resource records in the answer section.
360
+ */
361
+ std::uint16_t answer_records;
362
+
363
+ /**
364
+ * [NSCOUNT]
365
+ *
366
+ * an unsigned 16 bit integer specifying the number of name server resource records in the authority records section.
367
+ */
368
+ std::uint16_t authority_records;
369
+
370
+ /**
371
+ * [ARCOUNT]
372
+ *
373
+ * an unsigned 16 bit integer specifying the number of resource records in the additional records section.
374
+ */
375
+ std::uint16_t additional_records;
376
+ };
377
+
378
+ struct resource_name {
379
+ std::vector<std::string> labels{};
380
+ };
381
+
382
+ /**
383
+ * 4.1.2. Question section format
384
+ * ==============================
385
+ *
386
+ * The question section is used to carry the "question" in most queries, i.e., the parameters that define what is being asked. The section
387
+ * contains QDCOUNT (usually 1) entries, each of the following format:
388
+ *
389
+ * 1 1 1 1 1 1
390
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
391
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
392
+ * | |
393
+ * / QNAME /
394
+ * / /
395
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
396
+ * | QTYPE |
397
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
398
+ * | QCLASS |
399
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
400
+ */
401
+ struct question_record {
402
+ /**
403
+ * [QNAME]
404
+ *
405
+ * a domain name represented as a sequence of labels, where each label consists of a length octet followed by that number of octets. The
406
+ * domain name terminates with the zero length octet for the null label of the root. Note that this field may be an odd number of
407
+ * octets; no padding is used.
408
+ */
409
+ resource_name name{};
410
+
411
+ /**
412
+ * [QTYPE]
413
+ *
414
+ * a two octet code which specifies the type of the query. The values for this field include all codes valid for a TYPE field, together
415
+ * with some more general codes which can match more than one type of RR.
416
+ */
417
+ resource_type type{};
418
+
419
+ /**
420
+ * [QCLASS]
421
+ *
422
+ * a two octet code that specifies the class of the query. For example, the QCLASS field is IN for the Internet.
423
+ */
424
+ resource_class klass{};
425
+
426
+ [[nodiscard]] std::size_t size() const
427
+ {
428
+ std::size_t res = 2 * sizeof(std::uint16_t); // type + class
429
+ for (const auto& label : name.labels) {
430
+ res += sizeof(std::uint8_t) + label.size();
431
+ }
432
+ ++res; // '\0'
433
+ return res;
434
+ }
435
+ };
436
+
437
+ /**
438
+ * 4.1.3. Resource record format
439
+ * =============================
440
+ *
441
+ * The answer, authority, and additional sections all share the same format: a variable number of resource records, where
442
+ * the number of records is specified in the corresponding count field in the header. Each resource record has the
443
+ * following format:
444
+ *
445
+ * 1 1 1 1 1 1
446
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
447
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
448
+ * | |
449
+ * / /
450
+ * / NAME /
451
+ * | |
452
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
453
+ * | TYPE |
454
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
455
+ * | CLASS |
456
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
457
+ * | TTL |
458
+ * | |
459
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
460
+ * | RDLENGTH |
461
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
462
+ * / RDATA /
463
+ * / /
464
+ * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
465
+ *
466
+ * [RDLENGTH]
467
+ *
468
+ * an unsigned 16 bit integer that specifies the length in octets of the RDATA field.
469
+ *
470
+ * [RDATA]
471
+ *
472
+ * a variable length string of octets that describes the resource. The format of this information varies according to the TYPE and CLASS
473
+ * of the resource record. For example, the if the TYPE is A and the CLASS is IN, the RDATA field is a 4 octet ARPA Internet address.
474
+ */
475
+ struct resource_record {
476
+ /**
477
+ * [NAME]
478
+ *
479
+ * a domain name to which this resource record pertains.
480
+ */
481
+ resource_name name{};
482
+
483
+ /**
484
+ * [TYPE]
485
+ *
486
+ * two octets containing one of the RR type codes. This field specifies the meaning of the data in the RDATA field.
487
+ */
488
+ resource_type type{};
489
+
490
+ /**
491
+ * [CLASS]
492
+ *
493
+ * two octets which specify the class of the data in the RDATA field.
494
+ */
495
+ resource_class klass{};
496
+
497
+ /**
498
+ *
499
+ * [TTL]
500
+ *
501
+ * a 32 bit unsigned integer that specifies the time interval (in seconds) that the resource record may be cached before it should be
502
+ * discarded. Zero values are interpreted to mean that the RR can only be used for the transaction in progress, and should not be
503
+ * cached.
504
+ */
505
+ std::uint32_t ttl{};
506
+ };
507
+
508
+ struct srv_record : resource_record {
509
+ std::uint16_t priority{};
510
+ std::uint16_t weight{};
511
+ std::uint16_t port{};
512
+ resource_name target{};
513
+ };
514
+
515
+ /**
516
+ * 4.1. Format
517
+ * ===========
518
+ *
519
+ * All communications inside of the domain protocol are carried in a single format called a message. The top level format of message is
520
+ * divided into 5 sections (some of which are empty in certain cases) shown below:
521
+ *
522
+ * +---------------------+
523
+ * | Header |
524
+ * +---------------------+
525
+ * | Question | the question for the name server
526
+ * +---------------------+
527
+ * | Answer | RRs answering the question
528
+ * +---------------------+
529
+ * | Authority | RRs pointing toward an authority
530
+ * +---------------------+
531
+ * | Additional | RRs holding additional information
532
+ * +---------------------+
533
+ *
534
+ * The header section is always present. The header includes fields that specify which of the remaining sections are present, and also
535
+ * specify whether the message is a query or a response, a standard query or some other opcode, etc.
536
+ *
537
+ * The names of the sections after the header are derived from their use in standard queries. The question section contains fields that
538
+ * describe a question to a name server. These fields are a query type (QTYPE), a query class (QCLASS), and a query domain name (QNAME).
539
+ * The last three sections have the same format: a possibly empty list of concatenated resource records (RRs). The answer section contains
540
+ * RRs that answer the question; the authority section contains RRs that point toward an authoritative name server; the additional records
541
+ * section contains RRs which relate to the query, but are not strictly answers for the question.
542
+ */
543
+ struct dns_message {
544
+ dns_header header{};
545
+ std::vector<question_record> questions{};
546
+ std::vector<srv_record> answers{};
547
+ // the implementation only cares about SRV answers, so ignore everything else
548
+
549
+ [[nodiscard]] std::size_t request_size() const
550
+ {
551
+ std::size_t res = 6 * sizeof(std::uint16_t); // header
552
+ for (const auto& question : questions) {
553
+ res += question.size();
554
+ }
555
+ return res;
556
+ }
557
+ };
558
+ } // namespace couchbase::io::dns