couchbase 1.3.4-x64-mingw32
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 +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +22 -0
- data/.yardopts +5 -0
- data/CONTRIBUTING.markdown +75 -0
- data/Gemfile +4 -0
- data/LICENSE +201 -0
- data/Makefile +3 -0
- data/README.markdown +649 -0
- data/RELEASE_NOTES.markdown +796 -0
- data/Rakefile +20 -0
- data/couchbase.gemspec +49 -0
- data/examples/chat-em/Gemfile +7 -0
- data/examples/chat-em/README.markdown +45 -0
- data/examples/chat-em/server.rb +82 -0
- data/examples/chat-goliath-grape/Gemfile +5 -0
- data/examples/chat-goliath-grape/README.markdown +50 -0
- data/examples/chat-goliath-grape/app.rb +67 -0
- data/examples/chat-goliath-grape/config/app.rb +20 -0
- data/examples/transcoders/Gemfile +3 -0
- data/examples/transcoders/README.markdown +59 -0
- data/examples/transcoders/cb-zcat +40 -0
- data/examples/transcoders/cb-zcp +45 -0
- data/examples/transcoders/gzip_transcoder.rb +49 -0
- data/examples/transcoders/options.rb +54 -0
- data/ext/couchbase_ext/.gitignore +4 -0
- data/ext/couchbase_ext/arguments.c +956 -0
- data/ext/couchbase_ext/arithmetic.c +307 -0
- data/ext/couchbase_ext/bucket.c +1370 -0
- data/ext/couchbase_ext/context.c +65 -0
- data/ext/couchbase_ext/couchbase_ext.c +1364 -0
- data/ext/couchbase_ext/couchbase_ext.h +644 -0
- data/ext/couchbase_ext/delete.c +163 -0
- data/ext/couchbase_ext/eventmachine_plugin.c +452 -0
- data/ext/couchbase_ext/extconf.rb +168 -0
- data/ext/couchbase_ext/get.c +316 -0
- data/ext/couchbase_ext/gethrtime.c +129 -0
- data/ext/couchbase_ext/http.c +432 -0
- data/ext/couchbase_ext/multithread_plugin.c +1090 -0
- data/ext/couchbase_ext/observe.c +171 -0
- data/ext/couchbase_ext/plugin_common.c +171 -0
- data/ext/couchbase_ext/result.c +129 -0
- data/ext/couchbase_ext/stats.c +163 -0
- data/ext/couchbase_ext/store.c +542 -0
- data/ext/couchbase_ext/timer.c +192 -0
- data/ext/couchbase_ext/touch.c +186 -0
- data/ext/couchbase_ext/unlock.c +176 -0
- data/ext/couchbase_ext/utils.c +551 -0
- data/ext/couchbase_ext/version.c +142 -0
- data/lib/action_dispatch/middleware/session/couchbase_store.rb +38 -0
- data/lib/active_support/cache/couchbase_store.rb +430 -0
- data/lib/couchbase.rb +155 -0
- data/lib/couchbase/bucket.rb +457 -0
- data/lib/couchbase/cluster.rb +119 -0
- data/lib/couchbase/connection_pool.rb +58 -0
- data/lib/couchbase/constants.rb +12 -0
- data/lib/couchbase/result.rb +26 -0
- data/lib/couchbase/transcoder.rb +120 -0
- data/lib/couchbase/utils.rb +62 -0
- data/lib/couchbase/version.rb +21 -0
- data/lib/couchbase/view.rb +506 -0
- data/lib/couchbase/view_row.rb +272 -0
- data/lib/ext/multi_json_fix.rb +56 -0
- data/lib/rack/session/couchbase.rb +108 -0
- data/tasks/benchmark.rake +6 -0
- data/tasks/compile.rake +158 -0
- data/tasks/test.rake +100 -0
- data/tasks/util.rake +21 -0
- data/test/profile/.gitignore +1 -0
- data/test/profile/Gemfile +6 -0
- data/test/profile/benchmark.rb +195 -0
- data/test/setup.rb +178 -0
- data/test/test_arithmetic.rb +185 -0
- data/test/test_async.rb +316 -0
- data/test/test_bucket.rb +250 -0
- data/test/test_cas.rb +235 -0
- data/test/test_couchbase.rb +77 -0
- data/test/test_couchbase_connection_pool.rb +77 -0
- data/test/test_couchbase_rails_cache_store.rb +361 -0
- data/test/test_delete.rb +120 -0
- data/test/test_errors.rb +82 -0
- data/test/test_eventmachine.rb +70 -0
- data/test/test_format.rb +164 -0
- data/test/test_get.rb +407 -0
- data/test/test_stats.rb +57 -0
- data/test/test_store.rb +216 -0
- data/test/test_timer.rb +42 -0
- data/test/test_touch.rb +97 -0
- data/test/test_unlock.rb +119 -0
- data/test/test_utils.rb +58 -0
- data/test/test_version.rb +52 -0
- metadata +336 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Author:: Couchbase <info@couchbase.com>
|
3
|
+
# Copyright:: 2013 Couchbase, Inc.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'bundler'
|
20
|
+
Bundler.setup
|
21
|
+
|
22
|
+
require 'couchbase'
|
23
|
+
|
24
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
25
|
+
require 'gzip_transcoder'
|
26
|
+
require 'options'
|
27
|
+
|
28
|
+
STDERR.puts "Run with arguments: #{OPTIONS.inspect}"
|
29
|
+
begin
|
30
|
+
conn = Couchbase.connect(OPTIONS)
|
31
|
+
conn.transcoder = GzipTranscoder.new
|
32
|
+
|
33
|
+
ARGV.each do |filename|
|
34
|
+
STDERR.print "store \"#{filename}\" ... "
|
35
|
+
if File.exists?(filename)
|
36
|
+
conn.set(filename, File.read(filename))
|
37
|
+
STDERR.puts "ok"
|
38
|
+
else
|
39
|
+
STDERR.puts "not found"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
rescue Couchbase::Error::Base => ex
|
43
|
+
STDERR.puts "ERROR: #{ex}"
|
44
|
+
exit 1
|
45
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2013 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
require 'zlib'
|
19
|
+
require 'stringio'
|
20
|
+
|
21
|
+
# This class wraps any other transcoder and performs compression
|
22
|
+
# using zlib
|
23
|
+
class GzipTranscoder
|
24
|
+
FMT_GZIP = 0x04
|
25
|
+
|
26
|
+
def initialize(base = nil)
|
27
|
+
@base = base || Couchbase::Transcoder::Plain
|
28
|
+
end
|
29
|
+
|
30
|
+
def dump(obj, flags, options = {})
|
31
|
+
obj, flags = @base.dump(obj, flags, options)
|
32
|
+
io = StringIO.new
|
33
|
+
gz = Zlib::GzipWriter.new(io)
|
34
|
+
gz.write(obj)
|
35
|
+
gz.close
|
36
|
+
[io.string, flags|FMT_GZIP]
|
37
|
+
end
|
38
|
+
|
39
|
+
def load(blob, flags, options = {})
|
40
|
+
# decompress value only if gzip flag set
|
41
|
+
if (flags & FMT_GZIP) == FMT_GZIP
|
42
|
+
io = StringIO.new(blob)
|
43
|
+
gz = Zlib::GzipReader.new(io)
|
44
|
+
blob = gz.read
|
45
|
+
gz.close
|
46
|
+
end
|
47
|
+
@base.load(blob, flags, options)
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# Author:: Couchbase <info@couchbase.com>
|
2
|
+
# Copyright:: 2013 Couchbase, Inc.
|
3
|
+
# License:: Apache License, Version 2.0
|
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
|
+
require 'optparse'
|
19
|
+
|
20
|
+
# just output extra empty line on CTRL-C
|
21
|
+
trap("INT") do
|
22
|
+
STDERR.puts
|
23
|
+
exit
|
24
|
+
end
|
25
|
+
|
26
|
+
OPTIONS = {
|
27
|
+
:bucket => "default",
|
28
|
+
:hostname => "127.0.0.1",
|
29
|
+
:port => 8091,
|
30
|
+
:username => nil,
|
31
|
+
:password => nil
|
32
|
+
}
|
33
|
+
|
34
|
+
OptionParser.new do |opts|
|
35
|
+
opts.banner = "Usage: #{$0} [options] keys"
|
36
|
+
opts.on("-h", "--hostname HOSTNAME", "Hostname to connect to (default: #{OPTIONS[:hostname]}:#{OPTIONS[:port]})") do |v|
|
37
|
+
host, port = v.split(':')
|
38
|
+
OPTIONS[:hostname] = host.empty? ? '127.0.0.1' : host
|
39
|
+
OPTIONS[:port] = port.to_i > 0 ? port.to_i : 8091
|
40
|
+
end
|
41
|
+
opts.on("-u", "--user USERNAME", "Username to log with (default: none)") do |v|
|
42
|
+
OPTIONS[:username] = v
|
43
|
+
end
|
44
|
+
opts.on("-p", "--password PASSWORD", "Password to log with (default: none)") do |v|
|
45
|
+
OPTIONS[:password] = v
|
46
|
+
end
|
47
|
+
opts.on("-b", "--bucket NAME", "Name of the bucket to connect to (default: #{OPTIONS[:bucket]})") do |v|
|
48
|
+
OPTIONS[:bucket] = v
|
49
|
+
end
|
50
|
+
opts.on_tail("-?", "--help", "Show this message") do
|
51
|
+
STDERR.puts opts
|
52
|
+
exit
|
53
|
+
end
|
54
|
+
end.parse!
|
@@ -0,0 +1,956 @@
|
|
1
|
+
/* vim: ft=c et ts=8 sts=4 sw=4 cino=
|
2
|
+
*
|
3
|
+
* Copyright 2011, 2012 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
|
+
#include "couchbase_ext.h"
|
19
|
+
|
20
|
+
#define _alloc_data_for_s(type, _type, size, items, ptr) do {\
|
21
|
+
lcb_size_t ii; \
|
22
|
+
\
|
23
|
+
params->cmd.type.num = size; \
|
24
|
+
params->cmd.type.items = calloc(size, sizeof(_type)); \
|
25
|
+
if (params->cmd.type.items == NULL) { \
|
26
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments"); \
|
27
|
+
} \
|
28
|
+
params->cmd.type.ptr = calloc(size, sizeof(_type *)); \
|
29
|
+
if (params->cmd.type.ptr == NULL) { \
|
30
|
+
rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for arguments"); \
|
31
|
+
} \
|
32
|
+
for (ii = 0; ii < size; ++ii) { \
|
33
|
+
params->cmd.type.ptr[ii] = params->cmd.type.items + ii; \
|
34
|
+
} \
|
35
|
+
} while(0)
|
36
|
+
|
37
|
+
#define _alloc_data_for(type, _type) _alloc_data_for_s(type, _type, size, items, ptr)
|
38
|
+
|
39
|
+
|
40
|
+
#define _release_data_for_s(type, items, ptr) \
|
41
|
+
free(params->cmd.type.items); \
|
42
|
+
free(params->cmd.type.ptr);
|
43
|
+
|
44
|
+
#define _release_data_for(type) _release_data_for_s(type, items, ptr)
|
45
|
+
|
46
|
+
static VALUE
|
47
|
+
get_transcoder(struct cb_bucket_st *bucket, VALUE override, int compat, VALUE opts)
|
48
|
+
{
|
49
|
+
VALUE ret = Qundef;
|
50
|
+
|
51
|
+
/* override with symbol */
|
52
|
+
if (TYPE(override) == T_SYMBOL) {
|
53
|
+
if (override == cb_sym_document) {
|
54
|
+
ret = cb_mDocument;
|
55
|
+
} else if (override == cb_sym_marshal) {
|
56
|
+
ret = cb_mMarshal;
|
57
|
+
} else if (override == cb_sym_plain) {
|
58
|
+
ret = cb_mPlain;
|
59
|
+
}
|
60
|
+
} else if (!compat) {
|
61
|
+
/* override with transcoder */
|
62
|
+
if (rb_respond_to(override, cb_id_dump)
|
63
|
+
&& rb_respond_to(override, cb_id_load)) {
|
64
|
+
ret = override;
|
65
|
+
}
|
66
|
+
/* nil is also valid */
|
67
|
+
if (NIL_P(override)) {
|
68
|
+
ret = Qnil;
|
69
|
+
}
|
70
|
+
}
|
71
|
+
if (ret == Qundef) {
|
72
|
+
return bucket->transcoder;
|
73
|
+
} else {
|
74
|
+
rb_hash_aset(opts, cb_sym_forced, Qtrue);
|
75
|
+
return ret;
|
76
|
+
}
|
77
|
+
}
|
78
|
+
|
79
|
+
/* TOUCH */
|
80
|
+
|
81
|
+
static void
|
82
|
+
cb_params_touch_alloc(struct cb_params_st *params, lcb_size_t size)
|
83
|
+
{
|
84
|
+
_alloc_data_for(touch, lcb_touch_cmd_t);
|
85
|
+
}
|
86
|
+
|
87
|
+
static void
|
88
|
+
cb_params_touch_init_item(struct cb_params_st *params, lcb_size_t idx, VALUE key_obj, lcb_time_t exptime)
|
89
|
+
{
|
90
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
91
|
+
rb_ary_push(params->ensurance, key_obj);
|
92
|
+
params->cmd.touch.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
93
|
+
params->cmd.touch.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
94
|
+
params->cmd.touch.items[idx].v.v0.exptime = exptime;
|
95
|
+
params->npayload += RSTRING_LEN(key_obj) + sizeof(exptime);
|
96
|
+
}
|
97
|
+
|
98
|
+
static int
|
99
|
+
cb_params_touch_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
100
|
+
{
|
101
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
102
|
+
cb_params_touch_init_item(params, params->idx++, key, NUM2ULONG(value));
|
103
|
+
return ST_CONTINUE;
|
104
|
+
}
|
105
|
+
|
106
|
+
static void
|
107
|
+
cb_params_touch_parse_options(struct cb_params_st *params, VALUE options)
|
108
|
+
{
|
109
|
+
VALUE tmp;
|
110
|
+
|
111
|
+
if (NIL_P(options)) {
|
112
|
+
return;
|
113
|
+
}
|
114
|
+
tmp = rb_hash_aref(options, cb_sym_ttl);
|
115
|
+
if (tmp != Qnil) {
|
116
|
+
params->cmd.touch.ttl = NUM2ULONG(tmp);
|
117
|
+
}
|
118
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
119
|
+
if (tmp != Qundef) {
|
120
|
+
params->cmd.touch.quiet = RTEST(tmp);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
|
124
|
+
static void
|
125
|
+
cb_params_touch_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
126
|
+
{
|
127
|
+
lcb_size_t ii;
|
128
|
+
|
129
|
+
if (argc < 1) {
|
130
|
+
rb_raise(rb_eArgError, "must be at least one key");
|
131
|
+
}
|
132
|
+
if (argc == 1) {
|
133
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
134
|
+
switch(TYPE(keys)) {
|
135
|
+
case T_ARRAY:
|
136
|
+
/* array of keys as a first argument */
|
137
|
+
params->cmd.touch.array = 1;
|
138
|
+
cb_params_touch_alloc(params, RARRAY_LEN(keys));
|
139
|
+
for (ii = 0; ii < params->cmd.touch.num; ++ii) {
|
140
|
+
cb_params_touch_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.touch.ttl);
|
141
|
+
}
|
142
|
+
break;
|
143
|
+
case T_HASH:
|
144
|
+
/* key-ttl pairs */
|
145
|
+
cb_params_touch_alloc(params, RHASH_SIZE(keys));
|
146
|
+
rb_hash_foreach(keys, cb_params_touch_extract_keys_i,
|
147
|
+
(VALUE)params);
|
148
|
+
break;
|
149
|
+
default:
|
150
|
+
/* single key */
|
151
|
+
cb_params_touch_alloc(params, 1);
|
152
|
+
cb_params_touch_init_item(params, 0, keys, params->cmd.touch.ttl);
|
153
|
+
}
|
154
|
+
} else {
|
155
|
+
/* just list of arguments */
|
156
|
+
cb_params_touch_alloc(params, argc);
|
157
|
+
for (ii = 0; ii < params->cmd.touch.num; ++ii) {
|
158
|
+
cb_params_touch_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.touch.ttl);
|
159
|
+
}
|
160
|
+
}
|
161
|
+
}
|
162
|
+
|
163
|
+
|
164
|
+
/* REMOVE */
|
165
|
+
|
166
|
+
static void
|
167
|
+
cb_params_remove_alloc(struct cb_params_st *params, lcb_size_t size)
|
168
|
+
{
|
169
|
+
_alloc_data_for(remove, lcb_remove_cmd_t);
|
170
|
+
}
|
171
|
+
|
172
|
+
static void
|
173
|
+
cb_params_remove_init_item(struct cb_params_st *params, lcb_size_t idx, VALUE key_obj, lcb_cas_t cas)
|
174
|
+
{
|
175
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
176
|
+
rb_ary_push(params->ensurance, key_obj);
|
177
|
+
params->cmd.remove.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
178
|
+
params->cmd.remove.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
179
|
+
params->cmd.remove.items[idx].v.v0.cas = cas;
|
180
|
+
params->npayload += RSTRING_LEN(key_obj);
|
181
|
+
}
|
182
|
+
|
183
|
+
static int
|
184
|
+
cb_params_remove_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
185
|
+
{
|
186
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
187
|
+
cb_params_remove_init_item(params, params->idx++, key, NUM2ULL(value));
|
188
|
+
return ST_CONTINUE;
|
189
|
+
}
|
190
|
+
|
191
|
+
static void
|
192
|
+
cb_params_remove_parse_options(struct cb_params_st *params, VALUE options)
|
193
|
+
{
|
194
|
+
VALUE tmp;
|
195
|
+
|
196
|
+
if (NIL_P(options)) {
|
197
|
+
return;
|
198
|
+
}
|
199
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
200
|
+
if (tmp != Qundef) {
|
201
|
+
params->cmd.remove.quiet = RTEST(tmp);
|
202
|
+
}
|
203
|
+
tmp = rb_hash_aref(options, cb_sym_cas);
|
204
|
+
if (tmp != Qnil) {
|
205
|
+
params->cmd.remove.cas = NUM2ULL(tmp);
|
206
|
+
}
|
207
|
+
}
|
208
|
+
|
209
|
+
static void
|
210
|
+
cb_params_remove_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
211
|
+
{
|
212
|
+
lcb_size_t ii;
|
213
|
+
|
214
|
+
if (argc < 1) {
|
215
|
+
rb_raise(rb_eArgError, "must be at least one key");
|
216
|
+
}
|
217
|
+
if (argc == 1) {
|
218
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
219
|
+
switch(TYPE(keys)) {
|
220
|
+
case T_ARRAY:
|
221
|
+
/* array of keys as a first argument */
|
222
|
+
params->cmd.remove.array = 1;
|
223
|
+
cb_params_remove_alloc(params, RARRAY_LEN(keys));
|
224
|
+
for (ii = 0; ii < params->cmd.remove.num; ++ii) {
|
225
|
+
cb_params_remove_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.remove.cas);
|
226
|
+
}
|
227
|
+
break;
|
228
|
+
case T_HASH:
|
229
|
+
/* key-cas pairs */
|
230
|
+
cb_params_remove_alloc(params, RHASH_SIZE(keys));
|
231
|
+
rb_hash_foreach(keys, cb_params_remove_extract_keys_i,
|
232
|
+
(VALUE)params);
|
233
|
+
break;
|
234
|
+
default:
|
235
|
+
/* single key */
|
236
|
+
cb_params_remove_alloc(params, 1);
|
237
|
+
cb_params_remove_init_item(params, 0, keys, params->cmd.remove.cas);
|
238
|
+
}
|
239
|
+
} else {
|
240
|
+
/* just list of arguments */
|
241
|
+
cb_params_remove_alloc(params, argc);
|
242
|
+
for (ii = 0; ii < params->cmd.remove.num; ++ii) {
|
243
|
+
cb_params_remove_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.remove.cas);
|
244
|
+
}
|
245
|
+
}
|
246
|
+
}
|
247
|
+
|
248
|
+
|
249
|
+
/* STORE */
|
250
|
+
static void
|
251
|
+
cb_params_store_alloc(struct cb_params_st *params, lcb_size_t size)
|
252
|
+
{
|
253
|
+
_alloc_data_for(store, lcb_store_cmd_t);
|
254
|
+
}
|
255
|
+
|
256
|
+
static void
|
257
|
+
cb_params_store_init_item(struct cb_params_st *params, lcb_size_t idx,
|
258
|
+
VALUE key_obj, VALUE value_obj, lcb_uint32_t flags, lcb_cas_t cas,
|
259
|
+
lcb_time_t exptime)
|
260
|
+
{
|
261
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
262
|
+
value_obj = cb_encode_value(params->cmd.store.transcoder, value_obj, &flags, params->cmd.store.transcoder_opts);
|
263
|
+
if (rb_obj_is_kind_of(value_obj, rb_eStandardError)) {
|
264
|
+
VALUE exc_str = rb_funcall(value_obj, cb_id_to_s, 0);
|
265
|
+
VALUE msg = rb_funcall(rb_mKernel, cb_id_sprintf, 3,
|
266
|
+
rb_str_new2("unable to convert value for key \"%s\": %s"), key_obj, exc_str);
|
267
|
+
VALUE exc = rb_exc_new3(cb_eValueFormatError, msg);
|
268
|
+
rb_ivar_set(exc, cb_id_iv_inner_exception, value_obj);
|
269
|
+
rb_exc_raise(exc);
|
270
|
+
}
|
271
|
+
/* the value must be string after conversion */
|
272
|
+
if (TYPE(value_obj) != T_STRING) {
|
273
|
+
VALUE val = rb_any_to_s(value_obj);
|
274
|
+
rb_raise(cb_eValueFormatError, "unable to convert value for key \"%s\" to string: %s", RSTRING_PTR(key_obj), RSTRING_PTR(val));
|
275
|
+
}
|
276
|
+
rb_ary_push(params->ensurance, key_obj);
|
277
|
+
rb_ary_push(params->ensurance, value_obj);
|
278
|
+
params->cmd.store.items[idx].v.v0.datatype = params->cmd.store.datatype;
|
279
|
+
params->cmd.store.items[idx].v.v0.operation = params->cmd.store.operation;
|
280
|
+
params->cmd.store.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
281
|
+
params->cmd.store.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
282
|
+
params->cmd.store.items[idx].v.v0.bytes = RSTRING_PTR(value_obj);
|
283
|
+
params->cmd.store.items[idx].v.v0.nbytes = RSTRING_LEN(value_obj);
|
284
|
+
params->cmd.store.items[idx].v.v0.flags = flags;
|
285
|
+
params->cmd.store.items[idx].v.v0.cas = cas;
|
286
|
+
params->cmd.store.items[idx].v.v0.exptime = exptime;
|
287
|
+
params->npayload += RSTRING_LEN(key_obj) + RSTRING_LEN(value_obj) + sizeof(flags) + sizeof(exptime);
|
288
|
+
}
|
289
|
+
|
290
|
+
static int
|
291
|
+
cb_params_store_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
292
|
+
{
|
293
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
294
|
+
cb_params_store_init_item(params, params->idx++, key, value,
|
295
|
+
params->cmd.store.flags, 0, params->cmd.store.ttl);
|
296
|
+
return ST_CONTINUE;
|
297
|
+
}
|
298
|
+
|
299
|
+
static void
|
300
|
+
cb_params_store_parse_options(struct cb_params_st *params, VALUE options)
|
301
|
+
{
|
302
|
+
VALUE tmp;
|
303
|
+
|
304
|
+
if (NIL_P(options)) {
|
305
|
+
return;
|
306
|
+
}
|
307
|
+
tmp = rb_hash_aref(options, cb_sym_flags);
|
308
|
+
if (tmp != Qnil) {
|
309
|
+
params->cmd.store.flags = (lcb_uint32_t)NUM2ULONG(tmp);
|
310
|
+
}
|
311
|
+
tmp = rb_hash_aref(options, cb_sym_ttl);
|
312
|
+
if (tmp != Qnil) {
|
313
|
+
params->cmd.store.ttl = NUM2ULONG(tmp);
|
314
|
+
}
|
315
|
+
tmp = rb_hash_aref(options, cb_sym_cas);
|
316
|
+
if (tmp != Qnil) {
|
317
|
+
params->cmd.store.cas = NUM2ULL(tmp);
|
318
|
+
}
|
319
|
+
tmp = rb_hash_aref(options, cb_sym_observe);
|
320
|
+
if (tmp != Qnil) {
|
321
|
+
Check_Type(tmp, T_HASH);
|
322
|
+
rb_funcall(params->bucket->self, cb_id_verify_observe_options, 1, tmp);
|
323
|
+
params->cmd.store.observe = tmp;
|
324
|
+
}
|
325
|
+
tmp = rb_hash_aref(options, cb_sym_format);
|
326
|
+
if (tmp != Qnil) {
|
327
|
+
params->cmd.store.transcoder = get_transcoder(params->bucket,
|
328
|
+
tmp, 1, params->cmd.store.transcoder_opts);
|
329
|
+
}
|
330
|
+
tmp = rb_hash_lookup2(options, cb_sym_transcoder, Qundef);
|
331
|
+
if (tmp != Qundef) {
|
332
|
+
params->cmd.store.transcoder = get_transcoder(params->bucket,
|
333
|
+
tmp, 0, params->cmd.store.transcoder_opts);
|
334
|
+
}
|
335
|
+
}
|
336
|
+
|
337
|
+
static void
|
338
|
+
cb_params_store_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
339
|
+
{
|
340
|
+
VALUE keys;
|
341
|
+
|
342
|
+
if (argc < 1) {
|
343
|
+
rb_raise(rb_eArgError, "the key and value must be specified");
|
344
|
+
}
|
345
|
+
switch (argc) {
|
346
|
+
case 1:
|
347
|
+
keys = rb_ary_entry(argv, 0);
|
348
|
+
switch(TYPE(keys)) {
|
349
|
+
case T_HASH:
|
350
|
+
/* key-value pairs */
|
351
|
+
cb_params_store_alloc(params, RHASH_SIZE(keys));
|
352
|
+
rb_hash_foreach(keys, cb_params_store_extract_keys_i,
|
353
|
+
(VALUE)params);
|
354
|
+
break;
|
355
|
+
default:
|
356
|
+
rb_raise(rb_eArgError, "there must be either Hash with key-value pairs"
|
357
|
+
" or two separate arguments: key and value");
|
358
|
+
}
|
359
|
+
break;
|
360
|
+
case 2:
|
361
|
+
/* just key and value */
|
362
|
+
cb_params_store_alloc(params, 1);
|
363
|
+
cb_params_store_init_item(params, 0, rb_ary_entry(argv, 0), rb_ary_entry(argv, 1),
|
364
|
+
params->cmd.store.flags, params->cmd.store.cas, params->cmd.store.ttl);
|
365
|
+
break;
|
366
|
+
default:
|
367
|
+
rb_raise(rb_eArgError, "too many arguments");
|
368
|
+
}
|
369
|
+
}
|
370
|
+
|
371
|
+
|
372
|
+
/* GET */
|
373
|
+
static void
|
374
|
+
cb_params_get_alloc(struct cb_params_st *params, lcb_size_t size)
|
375
|
+
{
|
376
|
+
if (RTEST(params->cmd.get.replica)) {
|
377
|
+
_alloc_data_for_s(get, lcb_get_replica_cmd_t, size, items_gr, ptr_gr);
|
378
|
+
} else {
|
379
|
+
_alloc_data_for(get, lcb_get_cmd_t);
|
380
|
+
}
|
381
|
+
}
|
382
|
+
|
383
|
+
static void
|
384
|
+
cb_params_get_init_item(struct cb_params_st *params, lcb_size_t idx,
|
385
|
+
VALUE key_obj, lcb_time_t exptime)
|
386
|
+
{
|
387
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
388
|
+
rb_ary_push(params->ensurance, key_obj);
|
389
|
+
if (RTEST(params->cmd.get.replica)) {
|
390
|
+
params->cmd.get.items_gr[idx].version = 1;
|
391
|
+
params->cmd.get.items_gr[idx].v.v1.key = RSTRING_PTR(key_obj);
|
392
|
+
params->cmd.get.items_gr[idx].v.v1.nkey = RSTRING_LEN(key_obj);
|
393
|
+
if (params->cmd.get.replica == cb_sym_first || params->cmd.get.replica == Qtrue) {
|
394
|
+
params->cmd.get.items_gr[idx].v.v1.strategy = LCB_REPLICA_FIRST;
|
395
|
+
} else if (params->cmd.get.replica == cb_sym_all) {
|
396
|
+
params->cmd.get.items_gr[idx].v.v1.strategy = LCB_REPLICA_ALL;
|
397
|
+
} else {
|
398
|
+
params->cmd.get.items_gr[idx].v.v1.strategy = LCB_REPLICA_SELECT;
|
399
|
+
params->cmd.get.items_gr[idx].v.v1.index = FIX2INT(params->cmd.get.replica);
|
400
|
+
}
|
401
|
+
} else {
|
402
|
+
params->cmd.get.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
403
|
+
params->cmd.get.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
404
|
+
params->cmd.get.items[idx].v.v0.exptime = exptime;
|
405
|
+
params->cmd.get.items[idx].v.v0.lock = params->cmd.get.lock;
|
406
|
+
params->npayload += sizeof(exptime);
|
407
|
+
}
|
408
|
+
params->npayload += RSTRING_LEN(key_obj);
|
409
|
+
}
|
410
|
+
|
411
|
+
static int
|
412
|
+
cb_params_get_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
413
|
+
{
|
414
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
415
|
+
rb_ary_push(params->cmd.get.keys_ary, key);
|
416
|
+
cb_params_get_init_item(params, params->idx++, key, NUM2ULONG(value));
|
417
|
+
return ST_CONTINUE;
|
418
|
+
}
|
419
|
+
|
420
|
+
static void
|
421
|
+
cb_params_get_parse_options(struct cb_params_st *params, VALUE options)
|
422
|
+
{
|
423
|
+
VALUE tmp;
|
424
|
+
|
425
|
+
if (NIL_P(options)) {
|
426
|
+
return;
|
427
|
+
}
|
428
|
+
tmp = rb_hash_aref(options, cb_sym_replica);
|
429
|
+
if (tmp == Qtrue || tmp == cb_sym_all || tmp == cb_sym_first) {
|
430
|
+
params->cmd.get.replica = tmp;
|
431
|
+
} else if (TYPE(tmp) == T_FIXNUM) {
|
432
|
+
int nr = NUM2INT(tmp);
|
433
|
+
int max = lcb_get_num_replicas(params->bucket->handle);
|
434
|
+
if (nr < 0 || nr >= max) {
|
435
|
+
rb_raise(rb_eArgError, "replica index should be in interval 0...%d", max);
|
436
|
+
}
|
437
|
+
params->cmd.get.replica = tmp;
|
438
|
+
}
|
439
|
+
params->cmd.get.extended = RTEST(rb_hash_aref(options, cb_sym_extended));
|
440
|
+
params->cmd.get.assemble_hash = RTEST(rb_hash_aref(options, cb_sym_assemble_hash));
|
441
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
442
|
+
if (tmp != Qundef) {
|
443
|
+
params->cmd.get.quiet = RTEST(tmp);
|
444
|
+
}
|
445
|
+
tmp = rb_hash_aref(options, cb_sym_format);
|
446
|
+
if (tmp != Qnil) {
|
447
|
+
params->cmd.get.transcoder = get_transcoder(params->bucket,
|
448
|
+
tmp, 1, params->cmd.get.transcoder_opts);
|
449
|
+
}
|
450
|
+
tmp = rb_hash_lookup2(options, cb_sym_transcoder, Qundef);
|
451
|
+
if (tmp != Qundef) {
|
452
|
+
params->cmd.get.transcoder = get_transcoder(params->bucket,
|
453
|
+
tmp, 0, params->cmd.get.transcoder_opts);
|
454
|
+
}
|
455
|
+
tmp = rb_hash_aref(options, cb_sym_ttl);
|
456
|
+
if (tmp != Qnil) {
|
457
|
+
params->cmd.get.ttl = NUM2ULONG(tmp);
|
458
|
+
}
|
459
|
+
/* boolean or number of seconds to lock */
|
460
|
+
tmp = rb_hash_aref(options, cb_sym_lock);
|
461
|
+
if (tmp != Qnil) {
|
462
|
+
params->cmd.get.lock = RTEST(tmp);
|
463
|
+
if (TYPE(tmp) == T_FIXNUM) {
|
464
|
+
params->cmd.get.ttl = NUM2ULONG(tmp);
|
465
|
+
}
|
466
|
+
}
|
467
|
+
}
|
468
|
+
|
469
|
+
static void
|
470
|
+
cb_params_get_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
471
|
+
{
|
472
|
+
lcb_size_t ii;
|
473
|
+
|
474
|
+
if (argc < 1) {
|
475
|
+
rb_raise(rb_eArgError, "must be at least one key");
|
476
|
+
}
|
477
|
+
if (argc == 1) {
|
478
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
479
|
+
switch(TYPE(keys)) {
|
480
|
+
case T_ARRAY:
|
481
|
+
/* array of keys as a first argument */
|
482
|
+
params->cmd.get.array = 1;
|
483
|
+
cb_params_get_alloc(params, RARRAY_LEN(keys));
|
484
|
+
for (ii = 0; ii < params->cmd.get.num; ++ii) {
|
485
|
+
rb_ary_push(params->cmd.get.keys_ary, rb_ary_entry(keys, ii));
|
486
|
+
cb_params_get_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.get.ttl);
|
487
|
+
}
|
488
|
+
break;
|
489
|
+
case T_HASH:
|
490
|
+
/* key-ttl pairs */
|
491
|
+
if (params->cmd.get.replica) {
|
492
|
+
rb_raise(rb_eArgError, "must be either list of key or single key");
|
493
|
+
}
|
494
|
+
params->cmd.get.gat = 1;
|
495
|
+
cb_params_get_alloc(params, RHASH_SIZE(keys));
|
496
|
+
rb_hash_foreach(keys, cb_params_get_extract_keys_i, (VALUE)params);
|
497
|
+
break;
|
498
|
+
default:
|
499
|
+
/* single key */
|
500
|
+
cb_params_get_alloc(params, 1);
|
501
|
+
rb_ary_push(params->cmd.get.keys_ary, keys);
|
502
|
+
cb_params_get_init_item(params, 0, keys, params->cmd.get.ttl);
|
503
|
+
}
|
504
|
+
} else {
|
505
|
+
/* just list of arguments */
|
506
|
+
cb_params_get_alloc(params, argc);
|
507
|
+
for (ii = 0; ii < params->cmd.get.num; ++ii) {
|
508
|
+
rb_ary_push(params->cmd.get.keys_ary, rb_ary_entry(argv, ii));
|
509
|
+
cb_params_get_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.get.ttl);
|
510
|
+
}
|
511
|
+
}
|
512
|
+
}
|
513
|
+
|
514
|
+
|
515
|
+
/* ARITH */
|
516
|
+
static void
|
517
|
+
cb_params_arith_alloc(struct cb_params_st *params, lcb_size_t size)
|
518
|
+
{
|
519
|
+
_alloc_data_for(arith, lcb_arithmetic_cmd_t);
|
520
|
+
}
|
521
|
+
|
522
|
+
static void
|
523
|
+
cb_params_arith_init_item(struct cb_params_st *params, lcb_size_t idx,
|
524
|
+
VALUE key_obj, lcb_int64_t delta)
|
525
|
+
{
|
526
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
527
|
+
rb_ary_push(params->ensurance, key_obj);
|
528
|
+
params->cmd.arith.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
529
|
+
params->cmd.arith.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
530
|
+
params->cmd.arith.items[idx].v.v0.delta = delta * params->cmd.arith.sign;
|
531
|
+
params->cmd.arith.items[idx].v.v0.exptime = params->cmd.arith.ttl;
|
532
|
+
params->cmd.arith.items[idx].v.v0.create = params->cmd.arith.create;
|
533
|
+
params->cmd.arith.items[idx].v.v0.initial = params->cmd.arith.initial;
|
534
|
+
params->npayload += RSTRING_LEN(key_obj);
|
535
|
+
}
|
536
|
+
|
537
|
+
static int
|
538
|
+
cb_params_arith_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
539
|
+
{
|
540
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
541
|
+
cb_params_arith_init_item(params, params->idx++, key, NUM2ULONG(value) & INT64_MAX);
|
542
|
+
return ST_CONTINUE;
|
543
|
+
}
|
544
|
+
|
545
|
+
static void
|
546
|
+
cb_params_arith_parse_options(struct cb_params_st *params, VALUE options)
|
547
|
+
{
|
548
|
+
VALUE tmp;
|
549
|
+
|
550
|
+
if (NIL_P(options)) {
|
551
|
+
return;
|
552
|
+
}
|
553
|
+
tmp = rb_hash_aref(options, cb_sym_create);
|
554
|
+
if (tmp != Qnil) {
|
555
|
+
params->cmd.arith.create = RTEST(tmp);
|
556
|
+
}
|
557
|
+
params->cmd.arith.extended = RTEST(rb_hash_aref(options, cb_sym_extended));
|
558
|
+
tmp = rb_hash_aref(options, cb_sym_ttl);
|
559
|
+
if (tmp != Qnil) {
|
560
|
+
params->cmd.arith.ttl = NUM2ULONG(tmp);
|
561
|
+
}
|
562
|
+
tmp = rb_hash_aref(options, cb_sym_initial);
|
563
|
+
if (tmp != Qnil) {
|
564
|
+
params->cmd.arith.initial = NUM2ULL(tmp);
|
565
|
+
params->cmd.arith.create = 1;
|
566
|
+
}
|
567
|
+
tmp = rb_hash_aref(options, cb_sym_delta);
|
568
|
+
if (tmp != Qnil) {
|
569
|
+
params->cmd.arith.delta = NUM2ULL(tmp) & INT64_MAX;
|
570
|
+
}
|
571
|
+
tmp = rb_hash_aref(options, cb_sym_format);
|
572
|
+
if (tmp != Qnil) {
|
573
|
+
params->cmd.arith.transcoder = get_transcoder(params->bucket,
|
574
|
+
tmp, 1, params->cmd.arith.transcoder_opts);
|
575
|
+
}
|
576
|
+
tmp = rb_hash_lookup2(options, cb_sym_transcoder, Qundef);
|
577
|
+
if (tmp != Qundef) {
|
578
|
+
params->cmd.arith.transcoder = get_transcoder(params->bucket,
|
579
|
+
tmp, 0, params->cmd.arith.transcoder_opts);
|
580
|
+
}
|
581
|
+
}
|
582
|
+
|
583
|
+
static void
|
584
|
+
cb_params_arith_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
585
|
+
{
|
586
|
+
lcb_size_t ii;
|
587
|
+
|
588
|
+
if (argc < 1) {
|
589
|
+
rb_raise(rb_eArgError, "must be at least one key");
|
590
|
+
}
|
591
|
+
if (argc == 1) {
|
592
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
593
|
+
switch(TYPE(keys)) {
|
594
|
+
case T_ARRAY:
|
595
|
+
/* array of keys as a first argument */
|
596
|
+
params->cmd.arith.array = 1;
|
597
|
+
cb_params_arith_alloc(params, RARRAY_LEN(keys));
|
598
|
+
for (ii = 0; ii < params->cmd.arith.num; ++ii) {
|
599
|
+
cb_params_arith_init_item(params, ii, rb_ary_entry(keys, ii), params->cmd.arith.delta);
|
600
|
+
}
|
601
|
+
break;
|
602
|
+
case T_HASH:
|
603
|
+
/* key-delta pairs */
|
604
|
+
cb_params_arith_alloc(params, RHASH_SIZE(keys));
|
605
|
+
rb_hash_foreach(keys, cb_params_arith_extract_keys_i, (VALUE)params);
|
606
|
+
break;
|
607
|
+
default:
|
608
|
+
/* single key */
|
609
|
+
cb_params_arith_alloc(params, 1);
|
610
|
+
cb_params_arith_init_item(params, 0, keys, params->cmd.arith.delta);
|
611
|
+
}
|
612
|
+
} else {
|
613
|
+
/* just list of arguments */
|
614
|
+
cb_params_arith_alloc(params, argc);
|
615
|
+
for (ii = 0; ii < params->cmd.arith.num; ++ii) {
|
616
|
+
cb_params_arith_init_item(params, ii, rb_ary_entry(argv, ii), params->cmd.arith.delta);
|
617
|
+
}
|
618
|
+
}
|
619
|
+
}
|
620
|
+
|
621
|
+
|
622
|
+
/* STATS */
|
623
|
+
static void
|
624
|
+
cb_params_stats_alloc(struct cb_params_st *params, lcb_size_t size)
|
625
|
+
{
|
626
|
+
_alloc_data_for(stats, lcb_server_stats_cmd_t);
|
627
|
+
}
|
628
|
+
|
629
|
+
static void
|
630
|
+
cb_params_stats_init_item(struct cb_params_st *params, lcb_size_t idx,
|
631
|
+
VALUE key_obj)
|
632
|
+
{
|
633
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
634
|
+
rb_ary_push(params->ensurance, key_obj);
|
635
|
+
params->cmd.stats.items[idx].v.v0.name = RSTRING_PTR(key_obj);
|
636
|
+
params->cmd.stats.items[idx].v.v0.nname = RSTRING_LEN(key_obj);
|
637
|
+
params->npayload += RSTRING_LEN(key_obj);
|
638
|
+
}
|
639
|
+
|
640
|
+
static void
|
641
|
+
cb_params_stats_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
642
|
+
{
|
643
|
+
lcb_size_t ii;
|
644
|
+
|
645
|
+
if (argc == 1) {
|
646
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
647
|
+
switch(TYPE(keys)) {
|
648
|
+
case T_ARRAY:
|
649
|
+
/* array of keys as a first argument */
|
650
|
+
params->cmd.stats.array = 1;
|
651
|
+
cb_params_stats_alloc(params, RARRAY_LEN(keys));
|
652
|
+
for (ii = 0; ii < params->cmd.stats.num; ++ii) {
|
653
|
+
cb_params_stats_init_item(params, ii, rb_ary_entry(keys, ii));
|
654
|
+
}
|
655
|
+
break;
|
656
|
+
default:
|
657
|
+
/* single key */
|
658
|
+
cb_params_stats_alloc(params, 1);
|
659
|
+
cb_params_stats_init_item(params, 0, keys);
|
660
|
+
}
|
661
|
+
} else if (argc == 0) {
|
662
|
+
/* stat without argument (single empty struct) */
|
663
|
+
cb_params_stats_alloc(params, 1);
|
664
|
+
} else {
|
665
|
+
/* just list of arguments */
|
666
|
+
cb_params_stats_alloc(params, argc);
|
667
|
+
for (ii = 0; ii < params->cmd.stats.num; ++ii) {
|
668
|
+
cb_params_stats_init_item(params, ii, rb_ary_entry(argv, ii));
|
669
|
+
}
|
670
|
+
}
|
671
|
+
}
|
672
|
+
|
673
|
+
|
674
|
+
/* REMOVE */
|
675
|
+
|
676
|
+
static void
|
677
|
+
cb_params_observe_alloc(struct cb_params_st *params, lcb_size_t size)
|
678
|
+
{
|
679
|
+
_alloc_data_for(observe, lcb_observe_cmd_t);
|
680
|
+
}
|
681
|
+
|
682
|
+
static void
|
683
|
+
cb_params_observe_init_item(struct cb_params_st *params, lcb_size_t idx, VALUE key_obj)
|
684
|
+
{
|
685
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
686
|
+
rb_ary_push(params->ensurance, key_obj);
|
687
|
+
params->cmd.observe.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
688
|
+
params->cmd.observe.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
689
|
+
params->npayload += RSTRING_LEN(key_obj);
|
690
|
+
}
|
691
|
+
|
692
|
+
static void
|
693
|
+
cb_params_observe_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
694
|
+
{
|
695
|
+
lcb_size_t ii;
|
696
|
+
|
697
|
+
if (argc < 1) {
|
698
|
+
rb_raise(rb_eArgError, "must be at least one key");
|
699
|
+
}
|
700
|
+
if (argc == 1) {
|
701
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
702
|
+
switch(TYPE(keys)) {
|
703
|
+
case T_ARRAY:
|
704
|
+
/* array of keys as a first argument */
|
705
|
+
params->cmd.observe.array = 1;
|
706
|
+
cb_params_observe_alloc(params, RARRAY_LEN(keys));
|
707
|
+
for (ii = 0; ii < params->cmd.observe.num; ++ii) {
|
708
|
+
cb_params_observe_init_item(params, ii, rb_ary_entry(keys, ii));
|
709
|
+
}
|
710
|
+
break;
|
711
|
+
default:
|
712
|
+
/* single key */
|
713
|
+
cb_params_observe_alloc(params, 1);
|
714
|
+
cb_params_observe_init_item(params, 0, keys);
|
715
|
+
}
|
716
|
+
} else {
|
717
|
+
/* just list of arguments */
|
718
|
+
cb_params_observe_alloc(params, argc);
|
719
|
+
for (ii = 0; ii < params->cmd.observe.num; ++ii) {
|
720
|
+
cb_params_observe_init_item(params, ii, rb_ary_entry(argv, ii));
|
721
|
+
}
|
722
|
+
}
|
723
|
+
}
|
724
|
+
|
725
|
+
|
726
|
+
/* UNLOCK */
|
727
|
+
static void
|
728
|
+
cb_params_unlock_alloc(struct cb_params_st *params, lcb_size_t size)
|
729
|
+
{
|
730
|
+
_alloc_data_for(unlock, lcb_unlock_cmd_t);
|
731
|
+
}
|
732
|
+
|
733
|
+
static void
|
734
|
+
cb_params_unlock_init_item(struct cb_params_st *params, lcb_size_t idx, VALUE key_obj, lcb_cas_t cas)
|
735
|
+
{
|
736
|
+
key_obj = cb_unify_key(params->bucket, key_obj, 1);
|
737
|
+
rb_ary_push(params->ensurance, key_obj);
|
738
|
+
params->cmd.unlock.items[idx].v.v0.key = RSTRING_PTR(key_obj);
|
739
|
+
params->cmd.unlock.items[idx].v.v0.nkey = RSTRING_LEN(key_obj);
|
740
|
+
params->cmd.unlock.items[idx].v.v0.cas = cas;
|
741
|
+
params->npayload += RSTRING_LEN(key_obj);
|
742
|
+
}
|
743
|
+
|
744
|
+
static int
|
745
|
+
cb_params_unlock_extract_keys_i(VALUE key, VALUE value, VALUE arg)
|
746
|
+
{
|
747
|
+
struct cb_params_st *params = (struct cb_params_st *)arg;
|
748
|
+
cb_params_unlock_init_item(params, params->idx++, key, NUM2ULL(value));
|
749
|
+
return ST_CONTINUE;
|
750
|
+
}
|
751
|
+
|
752
|
+
static void
|
753
|
+
cb_params_unlock_parse_options(struct cb_params_st *params, VALUE options)
|
754
|
+
{
|
755
|
+
VALUE tmp;
|
756
|
+
|
757
|
+
if (NIL_P(options)) {
|
758
|
+
return;
|
759
|
+
}
|
760
|
+
tmp = rb_hash_aref(options, cb_sym_cas);
|
761
|
+
if (tmp != Qnil) {
|
762
|
+
params->cmd.unlock.cas = NUM2ULL(tmp);
|
763
|
+
}
|
764
|
+
tmp = rb_hash_lookup2(options, cb_sym_quiet, Qundef);
|
765
|
+
if (tmp != Qundef) {
|
766
|
+
params->cmd.unlock.quiet = RTEST(tmp);
|
767
|
+
}
|
768
|
+
}
|
769
|
+
|
770
|
+
static void
|
771
|
+
cb_params_unlock_parse_arguments(struct cb_params_st *params, int argc, VALUE argv)
|
772
|
+
{
|
773
|
+
if (argc == 1) {
|
774
|
+
VALUE keys = rb_ary_entry(argv, 0);
|
775
|
+
switch(TYPE(keys)) {
|
776
|
+
case T_HASH:
|
777
|
+
/* key-cas pairs */
|
778
|
+
cb_params_unlock_alloc(params, RHASH_SIZE(keys));
|
779
|
+
rb_hash_foreach(keys, cb_params_unlock_extract_keys_i, (VALUE)params);
|
780
|
+
break;
|
781
|
+
default:
|
782
|
+
/* single key */
|
783
|
+
cb_params_unlock_alloc(params, 1);
|
784
|
+
cb_params_unlock_init_item(params, 0, keys, params->cmd.unlock.cas);
|
785
|
+
}
|
786
|
+
} else {
|
787
|
+
rb_raise(rb_eArgError, "must be either Hash or single key with cas option");
|
788
|
+
}
|
789
|
+
}
|
790
|
+
|
791
|
+
|
792
|
+
/* VERSION */
|
793
|
+
static void
|
794
|
+
cb_params_version_alloc(struct cb_params_st *params)
|
795
|
+
{
|
796
|
+
params->cmd.version.num = 1;
|
797
|
+
_alloc_data_for_s(version, lcb_server_version_cmd_t, 1, items, ptr);
|
798
|
+
}
|
799
|
+
|
800
|
+
|
801
|
+
/* common stuff */
|
802
|
+
void
|
803
|
+
cb_params_destroy(struct cb_params_st *params)
|
804
|
+
{
|
805
|
+
rb_ary_clear(params->ensurance);
|
806
|
+
params->ensurance = Qfalse;
|
807
|
+
params->args = Qfalse;
|
808
|
+
switch (params->type) {
|
809
|
+
case cb_cmd_get:
|
810
|
+
_release_data_for(get);
|
811
|
+
_release_data_for_s(get, items_gr, ptr_gr);
|
812
|
+
break;
|
813
|
+
case cb_cmd_touch:
|
814
|
+
_release_data_for(touch);
|
815
|
+
break;
|
816
|
+
case cb_cmd_arith:
|
817
|
+
_release_data_for(arith);
|
818
|
+
break;
|
819
|
+
case cb_cmd_remove:
|
820
|
+
_release_data_for(remove);
|
821
|
+
break;
|
822
|
+
case cb_cmd_store:
|
823
|
+
_release_data_for(store);
|
824
|
+
break;
|
825
|
+
case cb_cmd_stats:
|
826
|
+
_release_data_for(stats);
|
827
|
+
break;
|
828
|
+
case cb_cmd_version:
|
829
|
+
_release_data_for(version);
|
830
|
+
break;
|
831
|
+
case cb_cmd_observe:
|
832
|
+
_release_data_for(observe);
|
833
|
+
break;
|
834
|
+
case cb_cmd_unlock:
|
835
|
+
_release_data_for(unlock);
|
836
|
+
break;
|
837
|
+
}
|
838
|
+
}
|
839
|
+
|
840
|
+
static VALUE
|
841
|
+
do_params_build(VALUE ptr)
|
842
|
+
{
|
843
|
+
VALUE opts;
|
844
|
+
/* unpack arguments */
|
845
|
+
struct cb_params_st *params = (struct cb_params_st*)ptr;
|
846
|
+
int argc = RARRAY_LEN(params->args);
|
847
|
+
VALUE argv = params->args;
|
848
|
+
|
849
|
+
/* extract options */
|
850
|
+
if (argc > 1 && TYPE(rb_ary_entry(argv, argc-1)) == T_HASH) {
|
851
|
+
opts = rb_ary_pop(argv);
|
852
|
+
--argc;
|
853
|
+
} else {
|
854
|
+
opts = Qnil;
|
855
|
+
}
|
856
|
+
|
857
|
+
params->npayload = CB_PACKET_HEADER_SIZE; /* size of packet header */
|
858
|
+
switch (params->type) {
|
859
|
+
case cb_cmd_touch:
|
860
|
+
params->cmd.touch.quiet = params->bucket->quiet;
|
861
|
+
params->cmd.touch.ttl = params->bucket->default_ttl;
|
862
|
+
cb_params_touch_parse_options(params, opts);
|
863
|
+
cb_params_touch_parse_arguments(params, argc, argv);
|
864
|
+
break;
|
865
|
+
case cb_cmd_remove:
|
866
|
+
params->cmd.remove.quiet = params->bucket->quiet;
|
867
|
+
if (argc == 2) {
|
868
|
+
int type = TYPE(rb_ary_entry(argv, 1));
|
869
|
+
if (type == T_FIXNUM || type == T_BIGNUM) {
|
870
|
+
/* allow form delete("foo", 0xdeadbeef) */
|
871
|
+
--argc;
|
872
|
+
params->cmd.remove.cas = NUM2ULL(rb_ary_pop(argv));
|
873
|
+
}
|
874
|
+
}
|
875
|
+
cb_params_remove_parse_options(params, opts);
|
876
|
+
cb_params_remove_parse_arguments(params, argc, argv);
|
877
|
+
break;
|
878
|
+
case cb_cmd_store:
|
879
|
+
if (argc == 1 && opts != Qnil) {
|
880
|
+
/* put last hash back because it is the value */
|
881
|
+
rb_ary_push(argv, opts);
|
882
|
+
opts = Qnil;
|
883
|
+
++argc;
|
884
|
+
}
|
885
|
+
params->cmd.store.datatype = 0x00;
|
886
|
+
params->cmd.store.ttl = params->bucket->default_ttl;
|
887
|
+
params->cmd.store.flags = params->bucket->default_flags;
|
888
|
+
params->cmd.store.observe = Qnil;
|
889
|
+
params->cmd.store.transcoder = params->bucket->transcoder;
|
890
|
+
params->cmd.store.transcoder_opts = rb_hash_new();
|
891
|
+
cb_params_store_parse_options(params, opts);
|
892
|
+
cb_params_store_parse_arguments(params, argc, argv);
|
893
|
+
break;
|
894
|
+
case cb_cmd_get:
|
895
|
+
params->cmd.get.quiet = params->bucket->quiet;
|
896
|
+
params->cmd.get.transcoder = params->bucket->transcoder;
|
897
|
+
params->cmd.get.transcoder_opts = rb_hash_new();
|
898
|
+
params->cmd.get.replica = Qfalse;
|
899
|
+
cb_params_get_parse_options(params, opts);
|
900
|
+
cb_params_get_parse_arguments(params, argc, argv);
|
901
|
+
break;
|
902
|
+
case cb_cmd_arith:
|
903
|
+
params->cmd.arith.transcoder = params->bucket->transcoder;
|
904
|
+
params->cmd.arith.transcoder_opts = rb_hash_new();
|
905
|
+
params->cmd.arith.create = params->bucket->default_arith_create;
|
906
|
+
params->cmd.arith.initial = params->bucket->default_arith_init;
|
907
|
+
params->cmd.arith.delta = 1;
|
908
|
+
params->cmd.arith.ttl = params->bucket->default_ttl;
|
909
|
+
if (argc == 2 && TYPE(rb_ary_entry(argv, 1)) == T_FIXNUM) {
|
910
|
+
/* allow form incr("foo", 1) */
|
911
|
+
--argc;
|
912
|
+
params->cmd.arith.delta = NUM2ULL(rb_ary_pop(argv)) & INT64_MAX;
|
913
|
+
}
|
914
|
+
cb_params_arith_parse_options(params, opts);
|
915
|
+
cb_params_arith_parse_arguments(params, argc, argv);
|
916
|
+
break;
|
917
|
+
case cb_cmd_stats:
|
918
|
+
cb_params_stats_parse_arguments(params, argc, argv);
|
919
|
+
break;
|
920
|
+
case cb_cmd_version:
|
921
|
+
cb_params_version_alloc(params);
|
922
|
+
break;
|
923
|
+
case cb_cmd_observe:
|
924
|
+
cb_params_observe_parse_arguments(params, argc, argv);
|
925
|
+
break;
|
926
|
+
case cb_cmd_unlock:
|
927
|
+
params->cmd.unlock.quiet = params->bucket->quiet;
|
928
|
+
if (argc == 2) {
|
929
|
+
int type = TYPE(rb_ary_entry(argv, 1));
|
930
|
+
if (type == T_FIXNUM || type == T_BIGNUM) {
|
931
|
+
/* allow form unlock("foo", 0xdeadbeef) */
|
932
|
+
--argc;
|
933
|
+
params->cmd.unlock.cas = NUM2ULL(rb_ary_pop(argv));
|
934
|
+
}
|
935
|
+
}
|
936
|
+
cb_params_unlock_parse_options(params, opts);
|
937
|
+
cb_params_unlock_parse_arguments(params, argc, argv);
|
938
|
+
break;
|
939
|
+
}
|
940
|
+
|
941
|
+
return Qnil;
|
942
|
+
}
|
943
|
+
|
944
|
+
void
|
945
|
+
cb_params_build(struct cb_params_st *params)
|
946
|
+
{
|
947
|
+
int fail = 0;
|
948
|
+
params->ensurance = rb_ary_new();
|
949
|
+
|
950
|
+
rb_protect(do_params_build, (VALUE)params, &fail);
|
951
|
+
if (fail) {
|
952
|
+
cb_params_destroy(params);
|
953
|
+
/* raise exception from protected block */
|
954
|
+
rb_jump_tag(fail);
|
955
|
+
}
|
956
|
+
}
|