libcouchbase 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Build Status](https://secure.travis-ci.org/cotag/libcouchbase.svg)](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; }
|