libcouchbase 0.0.9 → 0.1.0
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.
- checksums.yaml +4 -4
- data/.travis.yml +4 -4
- data/README.md +4 -0
- data/ext/libcouchbase/CMakeLists.txt +1 -1
- data/ext/libcouchbase/RELEASE_NOTES.markdown +42 -0
- data/ext/libcouchbase/cmake/Modules/GetVersionInfo.cmake +3 -3
- data/ext/libcouchbase/cmake/source_files.cmake +1 -0
- data/ext/libcouchbase/include/libcouchbase/cntl.h +27 -1
- data/ext/libcouchbase/include/libcouchbase/couchbase.h +0 -10
- data/ext/libcouchbase/include/libcouchbase/error.h +8 -1
- data/ext/libcouchbase/include/memcached/protocol_binary.h +12 -3
- data/ext/libcouchbase/src/auth.cc +0 -4
- data/ext/libcouchbase/src/cntl.cc +11 -1
- data/ext/libcouchbase/src/connspec.cc +18 -0
- data/ext/libcouchbase/src/connspec.h +10 -0
- data/ext/libcouchbase/src/dns-srv.cc +13 -14
- data/ext/libcouchbase/src/errmap.cc +107 -0
- data/ext/libcouchbase/src/errmap.h +113 -0
- data/ext/libcouchbase/src/hostlist.cc +0 -35
- data/ext/libcouchbase/src/hostlist.h +38 -64
- data/ext/libcouchbase/src/http/http.cc +6 -1
- data/ext/libcouchbase/src/instance.cc +1 -1
- data/ext/libcouchbase/src/internal.h +10 -0
- data/ext/libcouchbase/src/mcserver/mcserver.cc +119 -3
- data/ext/libcouchbase/src/mcserver/mcserver.h +3 -1
- data/ext/libcouchbase/src/mcserver/negotiate.cc +130 -37
- data/ext/libcouchbase/src/nodeinfo.cc +1 -1
- data/ext/libcouchbase/src/settings.c +3 -0
- data/ext/libcouchbase/src/settings.h +5 -0
- data/ext/libcouchbase/src/ssl/ssl_common.c +2 -0
- data/ext/libcouchbase/tests/basic/t_host.cc +67 -75
- data/ext/libcouchbase/tests/iotests/mock-environment.h +2 -1
- data/ext/libcouchbase/tests/iotests/t_confmon.cc +3 -4
- data/ext/libcouchbase/tests/iotests/t_errmap.cc +97 -0
- data/lib/libcouchbase/bucket.rb +27 -12
- data/lib/libcouchbase/callbacks.rb +1 -1
- data/lib/libcouchbase/connection.rb +18 -5
- data/lib/libcouchbase/version.rb +1 -1
- data/spec/connection_spec.rb +1 -1
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a694a8d99cf0101482777db2e8c4f81c9a2e3575
|
4
|
+
data.tar.gz: 3b484eb067a3ba40c9bf9b852cac90f48616db62
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3cf8f41d050d5bbb1ff2337de189c8893f36bae402c687d9543e1f996a327610e6f8d6ca7f84cc2cec0e27e8e958d3bb0e5ee05acee4101f70082a7ffaa12e83
|
7
|
+
data.tar.gz: bfeadf7d0eca8959258c9dccb64f03c6b5a9f4391da856d2ddcdc7aa60631421cb0f37f332809a93e69c6516b364c4b6e553d1f5a8eb76281ebe1c383a45f6d6
|
data/.travis.yml
CHANGED
@@ -3,10 +3,10 @@ rvm:
|
|
3
3
|
- ruby-2.3.1
|
4
4
|
- ruby-2.2.5
|
5
5
|
- ruby-head
|
6
|
-
- rubinius-3.62
|
7
|
-
- rubinius
|
8
6
|
- jruby-9.1.5.0
|
9
7
|
- jruby-head
|
8
|
+
- rubinius
|
9
|
+
# - rubinius-3.62 # blocked by https://github.com/rubinius/rubinius/issues/3706
|
10
10
|
branches:
|
11
11
|
only:
|
12
12
|
- master
|
@@ -14,8 +14,8 @@ before_install:
|
|
14
14
|
- git submodule update --init --recursive
|
15
15
|
- gem install ffi
|
16
16
|
- sudo apt-get install libev-dev
|
17
|
-
- sudo wget
|
18
|
-
- sudo dpkg -i couchbase-server-enterprise_4.
|
17
|
+
- sudo wget https://packages.couchbase.com/releases/4.6.1/couchbase-server-enterprise_4.6.1-ubuntu14.04_amd64.deb
|
18
|
+
- sudo dpkg -i couchbase-server-enterprise_4.6.1-ubuntu14.04_amd64.deb
|
19
19
|
- sleep 4
|
20
20
|
- sudo service couchbase-server status
|
21
21
|
- /opt/couchbase/bin/couchbase-cli cluster-init -c 127.0.0.1:8091 --cluster-username=admin --cluster-password=password --cluster-ramsize=320 --cluster-index-ramsize=256 --cluster-fts-ramsize=256 --services=data,index,query,fts
|
data/README.md
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
# libcouchbase FFI bindings for Ruby
|
2
2
|
|
3
|
+
[](http://travis-ci.org/cotag/libcouchbase)
|
4
|
+
|
3
5
|
An alternative to the official [couchbase-client](https://github.com/couchbase/couchbase-ruby-client)
|
4
6
|
|
5
7
|
* This client is non-blocking where possible using Fibers, which makes it simple to write performant code in Frameworks like [Rails](http://rubyonrails.org/).
|
6
8
|
* Client is threadsafe and reentrant
|
7
9
|
|
10
|
+
This is a low level wrapper around libcouchbase. For a more friendly ActiveModel interface see [couchbase-orm](https://github.com/acaprojects/couchbase-orm)
|
11
|
+
|
8
12
|
|
9
13
|
## Runtime Support:
|
10
14
|
|
@@ -21,7 +21,7 @@ CMAKE_MINIMUM_REQUIRED(VERSION 2.8.9)
|
|
21
21
|
# These variables can be modified as needed
|
22
22
|
|
23
23
|
# Couchbase mock path to download
|
24
|
-
SET(COUCHBASE_MOCK_VERSION CouchbaseMock-1.4.
|
24
|
+
SET(COUCHBASE_MOCK_VERSION CouchbaseMock-1.4.7.jar)
|
25
25
|
# Maven repository where ${COUCHBASE_MOCK_VERSION} is to be found
|
26
26
|
SET(COUCHBASE_MOCK_DLSERVER http://packages.couchbase.com/clients/c/mock)
|
27
27
|
project(libcouchbase)
|
@@ -1,5 +1,47 @@
|
|
1
1
|
# Release Notes
|
2
2
|
|
3
|
+
## 2.7.3 (March 21 2017)
|
4
|
+
|
5
|
+
* Provide the ability to send the `SELECT_BUCKET` when establishing a
|
6
|
+
to a server. This is a building block allowing us to use 'RBAC'/username
|
7
|
+
auth in the future.
|
8
|
+
Note that this requires the `select_bucket=true` option in the connection
|
9
|
+
string or equivalent, and that this feature as a whole is considered
|
10
|
+
experimental.
|
11
|
+
* Priority: Major
|
12
|
+
* Issues: [CCBC-758](https://issues.couchbase.com/browse/CCBC-758)
|
13
|
+
|
14
|
+
* Provide an option to disable DNS-SRV lookups. Because DNS SRV lookups often
|
15
|
+
result in no result (i.e. `NXDOMAIN`) - which takes longer, allowing to
|
16
|
+
disable such lookups may speed up startup time.
|
17
|
+
This option is available via the connection string, using `dnssrv=off`
|
18
|
+
* Priority: Minor
|
19
|
+
* Issues: [CCBC-756](https://issues.couchbase.com/browse/CCBC-756)
|
20
|
+
|
21
|
+
* Send client/user-specific identifier in `User-Agent` HTTP header.
|
22
|
+
The library already does this for data nodes (Memcached). Using it in HTTP
|
23
|
+
services allows better supportability when diagnosing issues by reading the
|
24
|
+
HTTP logs.
|
25
|
+
* Priority: Major
|
26
|
+
* Issues: [CCBC-755](https://issues.couchbase.com/browse/CCBC-755)
|
27
|
+
|
28
|
+
* Fix bug where DNS SRV hostnames would not be used.
|
29
|
+
While DNS SRV lookup was working, the library would not actually attempt
|
30
|
+
bootstrap off those received hostnames.
|
31
|
+
* Priority: Major
|
32
|
+
* Issues: [CCBC-753](https://issues.couchbase.com/browse/CCBC-753)
|
33
|
+
|
34
|
+
* Provide experimental Analytics support.
|
35
|
+
This allows access to the Couchbase Analytics Service, available in
|
36
|
+
some pre-release builds. API and syntax wise, Analytics is very similar
|
37
|
+
to N1QL.
|
38
|
+
To use the analytics service, set the `LCB_CMDN1QL_F_CBASQUERY` bit in
|
39
|
+
`lcb_CMDN1QL::cmdflags`, and provide the appropriate _host:port_ combination
|
40
|
+
in the `lcb_CMDN1QL::host` field. - Currently, analytics support is not
|
41
|
+
used in the cluster map/configuration.
|
42
|
+
* Priority: Major
|
43
|
+
* Issues: [CCBC-734](https://issues.couchbase.com/browse/CCBC-734)
|
44
|
+
|
3
45
|
## 2.7.2 (February 21 2017)
|
4
46
|
|
5
47
|
This release consists of additional internal refactoring and some improved
|
@@ -42,13 +42,13 @@ ENDIF()
|
|
42
42
|
|
43
43
|
IF (NOT LCB_VERSION)
|
44
44
|
SET(LCB_NOGITVERSION ON)
|
45
|
-
SET(LCB_VERSION "2.7.
|
45
|
+
SET(LCB_VERSION "2.7.3")
|
46
46
|
ENDIF()
|
47
47
|
IF (NOT LCB_VERSION_CHANGESET)
|
48
48
|
SET(LCB_VERSION_CHANGESET "0xdeadbeef")
|
49
49
|
ENDIF()
|
50
50
|
IF (NOT LCB_VERSION_HEX)
|
51
|
-
SET(LCB_VERSION_HEX
|
51
|
+
SET(LCB_VERSION_HEX 0x020703)
|
52
52
|
ENDIF()
|
53
53
|
|
54
54
|
# Now parse the version string
|
@@ -63,7 +63,7 @@ IF(APPLE)
|
|
63
63
|
ELSE()
|
64
64
|
SET(LCB_SONAME_MAJOR "2")
|
65
65
|
ENDIF()
|
66
|
-
SET(LCB_SONAME_FULL "${LCB_SONAME_MAJOR}.0.
|
66
|
+
SET(LCB_SONAME_FULL "${LCB_SONAME_MAJOR}.0.43")
|
67
67
|
|
68
68
|
MESSAGE(STATUS
|
69
69
|
"libcouchbase ${LCB_VERSION_MAJOR},${LCB_VERSION_MINOR},${LCB_VERSION_PATCH}")
|
@@ -924,8 +924,34 @@ typedef const char *lcb_BUCKETCRED[2];
|
|
924
924
|
*/
|
925
925
|
#define LCB_CNTL_READ_CHUNKSIZE 0x42
|
926
926
|
|
927
|
+
/**
|
928
|
+
* Enable/Disable the Error Map feature. This is disabled by default.
|
929
|
+
* Works only on servers which support error map
|
930
|
+
*
|
931
|
+
* Use `enable_errmap` in the connection string
|
932
|
+
*
|
933
|
+
* @volatile
|
934
|
+
* @cntl_arg_both{int* (as boolean)}
|
935
|
+
*/
|
936
|
+
#define LCB_CNTL_ENABLE_ERRMAP 0x43
|
937
|
+
|
938
|
+
/**
|
939
|
+
* Enable/Disable sending the SELECT_BUCKET command after authentication.
|
940
|
+
* This is useful to test auth, and should not be set by end-users.
|
941
|
+
*
|
942
|
+
* Note that even if this feature is enabled (the default), the client will
|
943
|
+
* only send `SELECT_BUCKET` if the server indicates that it is supported
|
944
|
+
* during negotiation.
|
945
|
+
*
|
946
|
+
* Use `select_bucket` in the connection string
|
947
|
+
*
|
948
|
+
* @volatile
|
949
|
+
* @cntl_arg_both{int* (as boolean)}
|
950
|
+
*/
|
951
|
+
#define LCB_CNTL_SELECT_BUCKET 0x44
|
952
|
+
|
927
953
|
/** This is not a command, but rather an indicator of the last item */
|
928
|
-
#define LCB_CNTL__MAX
|
954
|
+
#define LCB_CNTL__MAX 0x45
|
929
955
|
/**@}*/
|
930
956
|
|
931
957
|
#ifdef __cplusplus
|
@@ -3679,16 +3679,6 @@ lcb_histogram_read(const lcb_HISTOGRAM *hg, const void *cookie,
|
|
3679
3679
|
LCB_INTERNAL_API
|
3680
3680
|
void lcb_histogram_print(lcb_HISTOGRAM* hg, FILE* stream);
|
3681
3681
|
|
3682
|
-
struct hostlist_st;
|
3683
|
-
|
3684
|
-
LCB_INTERNAL_API
|
3685
|
-
lcb_error_t
|
3686
|
-
lcb_dnssrv_query(const char *, struct hostlist_st*);
|
3687
|
-
|
3688
|
-
LCB_INTERNAL_API
|
3689
|
-
struct hostlist_st*
|
3690
|
-
lcb_dnssrv_getbslist(const char *, int, lcb_error_t*);
|
3691
|
-
|
3692
3682
|
/* Post-include some other headers */
|
3693
3683
|
#ifdef __cplusplus
|
3694
3684
|
}
|
@@ -502,7 +502,14 @@ typedef enum {
|
|
502
502
|
X(LCB_UNKNOWN_SDCMD, 0x4D, LCB_ERRTYPE_INPUT, "Unknown subdocument command") \
|
503
503
|
X(LCB_ENO_COMMANDS, 0x4E, LCB_ERRTYPE_INPUT, "No commands specified") \
|
504
504
|
X(LCB_QUERY_ERROR, 0x4F, LCB_ERRTYPE_SRVGEN, \
|
505
|
-
"Query execution failed. Inspect raw response object for information")
|
505
|
+
"Query execution failed. Inspect raw response object for information") \
|
506
|
+
\
|
507
|
+
X(LCB_GENERIC_TMPERR, 0x50, LCB_ERRTYPE_TRANSIENT|LCB_ERRTYPE_SRVGEN, \
|
508
|
+
"Generic temporary error received from server") \
|
509
|
+
X(LCB_GENERIC_SUBDOCERR, 0x51, LCB_ERRTYPE_SUBDOC|LCB_ERRTYPE_SRVGEN, \
|
510
|
+
"Generic subdocument error received from server") \
|
511
|
+
X(LCB_GENERIC_CONSTRAINT_ERR, 0x52, LCB_ERRTYPE_INPUT|LCB_ERRTYPE_SRVGEN, \
|
512
|
+
"Generic constraint error received from server")
|
506
513
|
|
507
514
|
/** Error codes returned by the library. */
|
508
515
|
typedef enum {
|
@@ -224,6 +224,8 @@ extern "C"
|
|
224
224
|
|
225
225
|
PROTOCOL_BINARY_CMD_GET_REPLICA = 0x83,
|
226
226
|
|
227
|
+
PROTOCOL_BINARY_CMD_SELECT_BUCKET = 0x89,
|
228
|
+
|
227
229
|
PROTOCOL_BINARY_CMD_OBSERVE_SEQNO = 0x91,
|
228
230
|
PROTOCOL_BINARY_CMD_OBSERVE = 0x92,
|
229
231
|
|
@@ -264,6 +266,9 @@ extern "C"
|
|
264
266
|
/* Subdoc additions for Spock: */
|
265
267
|
PROTOCOL_BINARY_CMD_SUBDOC_GET_COUNT = 0xd2,
|
266
268
|
|
269
|
+
/* get error code mappings */
|
270
|
+
PROTOCOL_BINARY_CMD_GET_ERROR_MAP = 0xfe,
|
271
|
+
|
267
272
|
/* Reserved for being able to signal invalid opcode */
|
268
273
|
PROTOCOL_BINARY_CMD_INVALID = 0xff
|
269
274
|
} protocol_binary_command;
|
@@ -665,11 +670,13 @@ extern "C"
|
|
665
670
|
PROTOCOL_BINARY_FEATURE_TCPNODELAY = 0x03,
|
666
671
|
PROTOCOL_BINARY_FEATURE_MUTATION_SEQNO = 0x04,
|
667
672
|
PROTOCOL_BINARY_FEATURE_TCPDELAY = 0x05,
|
668
|
-
PROTOCOL_BINARY_FEATURE_XATTR = 0x06
|
673
|
+
PROTOCOL_BINARY_FEATURE_XATTR = 0x06,
|
674
|
+
PROTOCOL_BINARY_FEATURE_XERROR = 0x07,
|
675
|
+
PROTOCOL_BINARY_FEATURE_SELECT_BUCKET = 0x08
|
669
676
|
} protocol_binary_hello_features;
|
670
677
|
|
671
678
|
#define MEMCACHED_FIRST_HELLO_FEATURE 0x01
|
672
|
-
#define MEMCACHED_TOTAL_HELLO_FEATURES
|
679
|
+
#define MEMCACHED_TOTAL_HELLO_FEATURES 10
|
673
680
|
|
674
681
|
#define protocol_feature_2_text(a) \
|
675
682
|
(a == PROTOCOL_BINARY_FEATURE_DATATYPE) ? "Datatype" : \
|
@@ -677,7 +684,9 @@ extern "C"
|
|
677
684
|
(a == PROTOCOL_BINARY_FEATURE_TCPNODELAY) ? "TCP NODELAY" : \
|
678
685
|
(a == PROTOCOL_BINARY_FEATURE_MUTATION_SEQNO) ? "Mutation seqno" : \
|
679
686
|
(a == PROTOCOL_BINARY_FEATURE_TCPDELAY) ? "TCP DELAY" : \
|
680
|
-
(a == PROTOCOL_BINARY_FEATURE_XATTR) ? "XATTR" :
|
687
|
+
(a == PROTOCOL_BINARY_FEATURE_XATTR) ? "XATTR" : \
|
688
|
+
(a == PROTOCOL_BINARY_FEATURE_XERROR) ? "Error Map": \
|
689
|
+
(a == PROTOCOL_BINARY_FEATURE_SELECT_BUCKET) ? "Select Bucket": "Unknown"
|
681
690
|
|
682
691
|
/**
|
683
692
|
* The HELLO command is used by the client and the server to agree
|
@@ -90,10 +90,6 @@ Authenticator::init(const std::string& username_, const std::string& bucket,
|
|
90
90
|
m_username = (!username_.empty()) ? username_ : bucket;
|
91
91
|
m_password = passwd;
|
92
92
|
|
93
|
-
if (conntype == LCB_TYPE_BUCKET && m_username != bucket) {
|
94
|
-
return LCB_INVALID_USERNAME;
|
95
|
-
}
|
96
|
-
|
97
93
|
m_buckets[bucket] = m_password;
|
98
94
|
return LCB_SUCCESS;
|
99
95
|
}
|
@@ -183,6 +183,12 @@ HANDLER(kv_hg_handler) {
|
|
183
183
|
HANDLER(read_chunk_size_handler) {
|
184
184
|
RETURN_GET_SET(lcb_U32, LCBT_SETTING(instance, read_chunk_size));
|
185
185
|
}
|
186
|
+
HANDLER(enable_errmap_handler) {
|
187
|
+
RETURN_GET_SET(int, LCBT_SETTING(instance, use_errmap));
|
188
|
+
}
|
189
|
+
HANDLER(select_bucket_handler) {
|
190
|
+
RETURN_GET_SET(int, LCBT_SETTING(instance, select_bucket));
|
191
|
+
}
|
186
192
|
|
187
193
|
HANDLER(get_kvb) {
|
188
194
|
lcb_cntl_vbinfo_st *vbi = reinterpret_cast<lcb_cntl_vbinfo_st*>(arg);
|
@@ -586,7 +592,9 @@ static ctl_handler handlers[] = {
|
|
586
592
|
client_string_handler, /* LCB_CNTL_CLIENT_STRING */
|
587
593
|
bucket_auth_handler, /* LCB_CNTL_BUCKET_CRED */
|
588
594
|
timeout_common, /* LCB_CNTL_RETRY_NMV_DELAY */
|
589
|
-
read_chunk_size_handler /*LCB_CNTL_READ_CHUNKSIZE */
|
595
|
+
read_chunk_size_handler, /*LCB_CNTL_READ_CHUNKSIZE */
|
596
|
+
enable_errmap_handler, /* LCB_CNTL_ENABLE_ERRMAP */
|
597
|
+
select_bucket_handler /* LCB_CNTL_SELECT_BUCKET */
|
590
598
|
};
|
591
599
|
|
592
600
|
/* Union used for conversion to/from string functions */
|
@@ -738,6 +746,8 @@ static cntl_OPCODESTRS stropcode_map[] = {
|
|
738
746
|
{"retry_nmv_delay", LCB_CNTL_RETRY_NMV_INTERVAL, convert_timeout},
|
739
747
|
{"bucket_cred", LCB_CNTL_BUCKET_CRED, NULL},
|
740
748
|
{"read_chunk_size", LCB_CNTL_READ_CHUNKSIZE, convert_u32},
|
749
|
+
{"enable_errmap", LCB_CNTL_ENABLE_ERRMAP, convert_intbool},
|
750
|
+
{"select_bucket", LCB_CNTL_SELECT_BUCKET, convert_intbool},
|
741
751
|
{NULL, -1}
|
742
752
|
};
|
743
753
|
|
@@ -244,6 +244,24 @@ Connspec::parse_options(
|
|
244
244
|
if (sscanf(value, "%d", &m_loglevel) != 1) {
|
245
245
|
SET_ERROR("console_log_level must be a numeric value");
|
246
246
|
}
|
247
|
+
} else if (!strcmp(key, "dnssrv")) {
|
248
|
+
if ((m_flags & F_DNSSRV_EXPLICIT) == F_DNSSRV_EXPLICIT) {
|
249
|
+
SET_ERROR("Cannot use dnssrv scheme with dnssrv option");
|
250
|
+
}
|
251
|
+
int btmp = 0;
|
252
|
+
if (!strcmp(value, "on") || !strcmp(value, "true")) {
|
253
|
+
btmp = 1;
|
254
|
+
} else if (!strcmp(value, "off") || !strcmp(value, "false")) {
|
255
|
+
btmp = 0;
|
256
|
+
} else if (sscanf(value, "%d", &btmp) != 1) {
|
257
|
+
printf("Coldn't parse value!\n");
|
258
|
+
SET_ERROR("dnssrv must have numeric (boolean) value");
|
259
|
+
}
|
260
|
+
if (btmp) {
|
261
|
+
m_flags |= F_DNSSRV;
|
262
|
+
} else {
|
263
|
+
m_flags &= ~F_DNSSRV_EXPLICIT;
|
264
|
+
}
|
247
265
|
} else {
|
248
266
|
m_ctlopts.push_back(std::make_pair(key, value));
|
249
267
|
}
|
@@ -20,9 +20,11 @@
|
|
20
20
|
|
21
21
|
#include <libcouchbase/couchbase.h>
|
22
22
|
#include "config.h"
|
23
|
+
|
23
24
|
#include <string>
|
24
25
|
#include <vector>
|
25
26
|
#include <set>
|
27
|
+
#include "hostlist.h"
|
26
28
|
|
27
29
|
#ifdef _MSC_VER
|
28
30
|
/*
|
@@ -126,6 +128,14 @@ private:
|
|
126
128
|
#define LCB_SPECSCHEME_MCCOMPAT "memcached://"
|
127
129
|
#define LCB_SPECSCHEME_SRV "couchbase+dnssrv://"
|
128
130
|
#define LCB_SPECSCHEME_SRV_SSL "couchbases+dnssrv://"
|
131
|
+
|
132
|
+
// Standalone functionality:
|
133
|
+
lcb_error_t
|
134
|
+
dnssrv_query(const char *name, Hostlist& hostlist);
|
135
|
+
|
136
|
+
Hostlist *
|
137
|
+
dnssrv_getbslist(const char *addr, bool is_ssl, lcb_error_t& errout);
|
138
|
+
|
129
139
|
} // namespace
|
130
140
|
|
131
141
|
#endif
|
@@ -2,6 +2,8 @@
|
|
2
2
|
|
3
3
|
#include "config.h"
|
4
4
|
#include "hostlist.h"
|
5
|
+
#include "connspec.h"
|
6
|
+
#include "hostlist.h"
|
5
7
|
|
6
8
|
#ifndef _WIN32
|
7
9
|
#include <string>
|
@@ -20,9 +22,8 @@
|
|
20
22
|
#include <netinet/in.h>
|
21
23
|
#include <resolv.h>
|
22
24
|
|
23
|
-
LCB_INTERNAL_API
|
24
25
|
lcb_error_t
|
25
|
-
|
26
|
+
lcb::dnssrv_query(const char* name, lcb::Hostlist& hostlist)
|
26
27
|
{
|
27
28
|
ns_msg msg;
|
28
29
|
|
@@ -82,7 +83,7 @@ lcb_dnssrv_query(const char *name, hostlist_t hostlist)
|
|
82
83
|
ns_name_uncompress(
|
83
84
|
ns_msg_base(msg), ns_msg_end(msg),
|
84
85
|
rdata, &dname[0], NS_MAXDNAME);
|
85
|
-
hostlist
|
86
|
+
hostlist.add(&dname[0], srv_port);
|
86
87
|
}
|
87
88
|
return LCB_SUCCESS;
|
88
89
|
}
|
@@ -92,9 +93,8 @@ lcb_dnssrv_query(const char *name, hostlist_t hostlist)
|
|
92
93
|
#include <windns.h>
|
93
94
|
#define CAN_SRV_LOOKUP
|
94
95
|
/* Implement via DnsQuery() */
|
95
|
-
LCB_INTERNAL_API
|
96
96
|
lcb_error_t
|
97
|
-
|
97
|
+
lcb::dnssrv_query(const char *addr, Hostlist& hs)
|
98
98
|
{
|
99
99
|
DNS_STATUS status;
|
100
100
|
PDNS_RECORDA root, cur;
|
@@ -108,7 +108,7 @@ lcb_dnssrv_query(const char *addr, hostlist_t hs)
|
|
108
108
|
for (cur = root; cur; cur = cur->pNext) {
|
109
109
|
// Use the ASCII version of the DNS lookup structure
|
110
110
|
const DNS_SRV_DATAA *srv = &cur->Data.SRV;
|
111
|
-
|
111
|
+
hs.add(srv->pNameTarget, srv->wPort);
|
112
112
|
}
|
113
113
|
DnsRecordListFree(root, DnsFreeRecordList);
|
114
114
|
return LCB_SUCCESS;
|
@@ -118,7 +118,7 @@ lcb_dnssrv_query(const char *addr, hostlist_t hs)
|
|
118
118
|
|
119
119
|
|
120
120
|
#ifndef CAN_SRV_LOOKUP
|
121
|
-
|
121
|
+
lcb_error_t lcb::dnssrv_query(const char *, Hostlist&) {
|
122
122
|
return LCB_CLIENT_FEATURE_UNAVAILABLE;
|
123
123
|
}
|
124
124
|
#endif
|
@@ -126,18 +126,17 @@ LCB_INTERNAL_API lcb_error_t lcb_dnssrv_query(const char *, hostlist_t) {
|
|
126
126
|
#define SVCNAME_PLAIN "_couchbase._tcp."
|
127
127
|
#define SVCNAME_SSL "_couchbases._tcp."
|
128
128
|
|
129
|
-
|
130
|
-
|
131
|
-
lcb_dnssrv_getbslist(const char *addr, int is_ssl, lcb_error_t *errp) {
|
129
|
+
lcb::Hostlist*
|
130
|
+
lcb::dnssrv_getbslist(const char *addr, bool is_ssl, lcb_error_t& errp) {
|
132
131
|
std::string ss;
|
133
|
-
|
132
|
+
Hostlist *ret = new Hostlist();
|
134
133
|
ss.append(is_ssl ? SVCNAME_SSL : SVCNAME_PLAIN);
|
135
134
|
ss.append(addr);
|
136
135
|
|
137
|
-
|
138
|
-
if (
|
136
|
+
errp = dnssrv_query(ss.c_str(), *ret);
|
137
|
+
if (errp != LCB_SUCCESS) {
|
139
138
|
delete ret;
|
140
139
|
ret = NULL;
|
141
140
|
}
|
142
|
-
return
|
141
|
+
return ret;
|
143
142
|
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
#include "internal.h"
|
2
|
+
#include "errmap.h"
|
3
|
+
#include "contrib/lcb-jsoncpp/lcb-jsoncpp.h"
|
4
|
+
|
5
|
+
using namespace lcb::errmap;
|
6
|
+
|
7
|
+
ErrorMap::ErrorMap() : revision(0), version(0) {
|
8
|
+
}
|
9
|
+
|
10
|
+
static ErrorAttribute getAttribute(const std::string& s) {
|
11
|
+
#define X(c, s_) if (s == s_) { return c; }
|
12
|
+
LCB_XERRMAP_ATTRIBUTES(X)
|
13
|
+
#undef X
|
14
|
+
return INVALID_ATTRIBUTE;
|
15
|
+
}
|
16
|
+
|
17
|
+
const uint32_t ErrorMap::MAX_VERSION = 1;
|
18
|
+
|
19
|
+
ErrorMap::ParseStatus
|
20
|
+
ErrorMap::parse(const char *s, size_t n, std::string& errmsg) {
|
21
|
+
Json::Value root_nonconst;
|
22
|
+
Json::Reader reader;
|
23
|
+
if (!reader.parse(s, s + n, root_nonconst)) {
|
24
|
+
errmsg = "Invalid JSON";
|
25
|
+
return PARSE_ERROR;
|
26
|
+
}
|
27
|
+
|
28
|
+
const Json::Value& root = root_nonconst;
|
29
|
+
const Json::Value& verJson = root["version"];
|
30
|
+
if (!verJson.isNumeric()) {
|
31
|
+
errmsg = "'version' is not a number";
|
32
|
+
return PARSE_ERROR;
|
33
|
+
}
|
34
|
+
|
35
|
+
if (verJson.asUInt() > MAX_VERSION) {
|
36
|
+
errmsg = "'version' is unreasonably high";
|
37
|
+
return UNKNOWN_VERSION;
|
38
|
+
}
|
39
|
+
|
40
|
+
const Json::Value& revJson = root["revision"];
|
41
|
+
if (!revJson.isNumeric()) {
|
42
|
+
errmsg = "'revision' is not a number";
|
43
|
+
return PARSE_ERROR;
|
44
|
+
}
|
45
|
+
|
46
|
+
if (revJson.asUInt() <= revision) {
|
47
|
+
return NOT_UPDATED;
|
48
|
+
}
|
49
|
+
|
50
|
+
const Json::Value& errsJson = root["errors"];
|
51
|
+
if (!errsJson.isObject()) {
|
52
|
+
errmsg = "'errors' is not an object";
|
53
|
+
return PARSE_ERROR;
|
54
|
+
}
|
55
|
+
|
56
|
+
Json::Value::const_iterator ii = errsJson.begin();
|
57
|
+
for (; ii != errsJson.end(); ++ii) {
|
58
|
+
// Key is the version in hex
|
59
|
+
unsigned ec = 0;
|
60
|
+
if (sscanf(ii.key().asCString(), "%x", &ec) != 1) {
|
61
|
+
errmsg = "key " + ii.key().asString() + " is not a hex number";
|
62
|
+
return PARSE_ERROR;
|
63
|
+
}
|
64
|
+
|
65
|
+
const Json::Value& errorJson = *ii;
|
66
|
+
|
67
|
+
// Descend into the error attributes
|
68
|
+
Error error;
|
69
|
+
error.code = static_cast<uint16_t>(ec);
|
70
|
+
|
71
|
+
error.shortname = errorJson["name"].asString();
|
72
|
+
error.description = errorJson["desc"].asString();
|
73
|
+
|
74
|
+
const Json::Value& attrs = errorJson["attrs"];
|
75
|
+
if (!attrs.isArray()) {
|
76
|
+
errmsg = "'attrs' is not an array";
|
77
|
+
return PARSE_ERROR;
|
78
|
+
}
|
79
|
+
|
80
|
+
Json::Value::const_iterator jj = attrs.begin();
|
81
|
+
for (; jj != attrs.end(); ++jj) {
|
82
|
+
ErrorAttribute attr = getAttribute(jj->asString());
|
83
|
+
if (attr == INVALID_ATTRIBUTE) {
|
84
|
+
errmsg = "unknown attribute received";
|
85
|
+
return UNKNOWN_VERSION;
|
86
|
+
}
|
87
|
+
error.attributes.insert(attr);
|
88
|
+
}
|
89
|
+
errors.insert(MapType::value_type(ec, error));
|
90
|
+
}
|
91
|
+
|
92
|
+
return UPDATED;
|
93
|
+
}
|
94
|
+
|
95
|
+
const Error& ErrorMap::getError(uint16_t code) const {
|
96
|
+
static const Error invalid;
|
97
|
+
MapType::const_iterator it = errors.find(code);
|
98
|
+
|
99
|
+
if (it != errors.end()) {
|
100
|
+
return it->second;
|
101
|
+
} else {
|
102
|
+
return invalid;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
|
106
|
+
ErrorMap *lcb_errmap_new() { return new ErrorMap(); }
|
107
|
+
void lcb_errmap_free(ErrorMap* m) { delete m; }
|