aerospike 2.19.0 → 2.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +354 -244
- data/lib/aerospike/atomic/atomic.rb +1 -1
- data/lib/aerospike/cdt/context.rb +137 -70
- data/lib/aerospike/cdt/list_return_type.rb +4 -0
- data/lib/aerospike/cdt/map_operation.rb +6 -6
- data/lib/aerospike/cdt/map_policy.rb +16 -2
- data/lib/aerospike/cdt/map_return_type.rb +13 -1
- data/lib/aerospike/client.rb +137 -115
- data/lib/aerospike/cluster/create_connection.rb +1 -1
- data/lib/aerospike/cluster.rb +41 -4
- data/lib/aerospike/command/admin_command.rb +368 -52
- data/lib/aerospike/command/batch_index_command.rb +4 -8
- data/lib/aerospike/command/batch_index_exists_command.rb +1 -1
- data/lib/aerospike/command/batch_index_node.rb +1 -1
- data/lib/aerospike/command/batch_item.rb +1 -1
- data/lib/aerospike/command/command.rb +180 -123
- data/lib/aerospike/command/field_type.rb +25 -24
- data/lib/aerospike/command/login_command.rb +164 -0
- data/lib/aerospike/command/multi_command.rb +25 -2
- data/lib/aerospike/command/operate_args.rb +99 -0
- data/lib/aerospike/command/operate_command.rb +6 -11
- data/lib/aerospike/command/read_command.rb +2 -2
- data/lib/aerospike/connection/authenticate.rb +36 -3
- data/lib/aerospike/exp/exp.rb +1329 -0
- data/lib/aerospike/exp/exp_bit.rb +388 -0
- data/lib/aerospike/exp/exp_hll.rb +169 -0
- data/lib/aerospike/exp/exp_list.rb +403 -0
- data/lib/aerospike/exp/exp_map.rb +493 -0
- data/lib/aerospike/exp/operation.rb +56 -0
- data/lib/aerospike/features.rb +22 -9
- data/lib/aerospike/host/parse.rb +2 -2
- data/lib/aerospike/key.rb +10 -1
- data/lib/aerospike/node/refresh/info.rb +1 -1
- data/lib/aerospike/node/verify/name.rb +1 -1
- data/lib/aerospike/node/verify/partition_generation.rb +1 -1
- data/lib/aerospike/node/verify/peers_generation.rb +1 -1
- data/lib/aerospike/node/verify/rebalance_generation.rb +1 -1
- data/lib/aerospike/node_validator.rb +6 -1
- data/lib/aerospike/operation.rb +20 -22
- data/lib/aerospike/policy/auth_mode.rb +36 -0
- data/lib/aerospike/policy/client_policy.rb +4 -1
- data/lib/aerospike/policy/policy.rb +29 -13
- data/lib/aerospike/policy/query_policy.rb +35 -2
- data/lib/aerospike/policy/scan_policy.rb +19 -2
- data/lib/aerospike/privilege.rb +133 -0
- data/lib/aerospike/query/filter.rb +44 -32
- data/lib/aerospike/query/node_partitions.rb +39 -0
- data/lib/aerospike/query/partition_filter.rb +66 -0
- data/lib/aerospike/{command/roles.rb → query/partition_status.rb} +16 -19
- data/lib/aerospike/query/partition_tracker.rb +347 -0
- data/lib/aerospike/query/query_command.rb +20 -10
- data/lib/aerospike/query/query_executor.rb +71 -0
- data/lib/aerospike/query/query_partition_command.rb +267 -0
- data/lib/aerospike/query/recordset.rb +9 -9
- data/lib/aerospike/query/scan_command.rb +3 -2
- data/lib/aerospike/query/scan_executor.rb +71 -0
- data/lib/aerospike/query/scan_partition_command.rb +49 -0
- data/lib/aerospike/query/statement.rb +8 -1
- data/lib/aerospike/query/stream_command.rb +17 -0
- data/lib/aerospike/result_code.rb +83 -8
- data/lib/aerospike/role.rb +55 -0
- data/lib/aerospike/task/execute_task.rb +19 -16
- data/lib/aerospike/task/index_task.rb +1 -1
- data/lib/aerospike/user_role.rb +26 -1
- data/lib/aerospike/utils/buffer.rb +93 -29
- data/lib/aerospike/utils/packer.rb +7 -6
- data/lib/aerospike/utils/pool.rb +1 -1
- data/lib/aerospike/value/particle_type.rb +1 -12
- data/lib/aerospike/value/value.rb +35 -60
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +156 -136
- metadata +24 -6
@@ -17,16 +17,17 @@
|
|
17
17
|
# License for the specific language governing permissions and limitations under
|
18
18
|
# the License.
|
19
19
|
|
20
|
+
require "base64"
|
21
|
+
|
20
22
|
module Aerospike
|
21
23
|
module CDT
|
22
24
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
##
|
26
|
+
# Nested CDT context. Identifies the location of nested list/map to apply the operation.
|
27
|
+
# for the current level.
|
28
|
+
# An array of CTX identifies location of the list/map on multiple
|
29
|
+
# levels on nesting.
|
28
30
|
class Context
|
29
|
-
|
30
31
|
attr_accessor :id, :value
|
31
32
|
|
32
33
|
def initialize(id, value)
|
@@ -37,77 +38,143 @@ module Aerospike
|
|
37
38
|
##
|
38
39
|
# Create list with given type at index offset, given an order and pad.
|
39
40
|
def self.list_index_create(index, order, pad)
|
40
|
-
|
41
|
-
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
41
|
+
Context.new(0x10 | ListOrder.flag(order, pad), index)
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# Lookup list by index offset.
|
46
|
+
# If the index is negative, the resolved index starts backwards from end of list.
|
47
|
+
# If an index is out of bounds, a parameter error will be returned.
|
48
|
+
# Examples:
|
49
|
+
# 0: First item.
|
50
|
+
# 4: Fifth item.
|
51
|
+
# -1: Last item.
|
52
|
+
# -3: Third to last item.
|
53
|
+
def self.list_index(index)
|
54
|
+
Context.new(0x10, index)
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Lookup list by rank.
|
59
|
+
# 0 = smallest value
|
60
|
+
# N = Nth smallest value
|
61
|
+
# -1 = largest value
|
62
|
+
def self.list_rank(rank)
|
63
|
+
Context.new(0x11, rank)
|
64
|
+
end
|
65
|
+
|
66
|
+
##
|
67
|
+
# Lookup list by value.
|
68
|
+
def self.list_value(key)
|
69
|
+
Context.new(0x13, key)
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Lookup map by index offset.
|
74
|
+
# If the index is negative, the resolved index starts backwards from end of list.
|
75
|
+
# If an index is out of bounds, a parameter error will be returned.
|
76
|
+
# Examples:
|
77
|
+
# 0: First item.
|
78
|
+
# 4: Fifth item.
|
79
|
+
# -1: Last item.
|
80
|
+
# -3: Third to last item.
|
81
|
+
def self.map_index(index)
|
82
|
+
Context.new(0x20, index)
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Lookup map by rank.
|
87
|
+
# 0 = smallest value
|
88
|
+
# N = Nth smallest value
|
89
|
+
# -1 = largest value
|
90
|
+
def self.map_rank(rank)
|
91
|
+
Context.new(0x21, rank)
|
92
|
+
end
|
93
|
+
|
94
|
+
##
|
95
|
+
# Lookup map by key.
|
96
|
+
def self.map_key(key)
|
97
|
+
Context.new(0x22, key)
|
98
|
+
end
|
99
|
+
|
99
100
|
##
|
100
101
|
# Create map with given type at map key.
|
101
102
|
def self.map_key_create(key, order)
|
102
103
|
Context.new(0x22 | order[:flag], key)
|
103
104
|
end
|
104
105
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
106
|
+
##
|
107
|
+
# Lookup map by value.
|
108
|
+
def self.map_value(key)
|
109
|
+
Context.new(0x23, key)
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Encodes the context via message pack.
|
114
|
+
def self.pack(packer, ctx)
|
115
|
+
unless ctx.to_a.empty?
|
116
|
+
packer.write_array_header(2)
|
117
|
+
ctx.each do |c|
|
118
|
+
packer.write(c.id)
|
119
|
+
Value.of(c.value)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Encodes the context via message pack and return the results.
|
126
|
+
def self.bytes(ctx)
|
127
|
+
unless ctx.to_a.empty?
|
128
|
+
Packer.use do |packer|
|
129
|
+
packer.write_array_header(ctx.length * 2)
|
130
|
+
ctx.each do |c|
|
131
|
+
packer.write(c.id)
|
132
|
+
Value.of(c.value).pack(packer)
|
133
|
+
end
|
134
|
+
return packer.bytes
|
135
|
+
end
|
136
|
+
end
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
def ==(other)
|
141
|
+
self.id == other.id && self.value == other.value
|
142
|
+
end
|
110
143
|
|
144
|
+
##
|
145
|
+
# decodes the base64 encoded messagepack byte array
|
146
|
+
# and converts it to an array of Context.
|
147
|
+
def self.from_bytes(buf)
|
148
|
+
list = nil
|
149
|
+
Unpacker.use do |unpacker|
|
150
|
+
list = unpacker.unpack(buf)
|
151
|
+
end
|
152
|
+
|
153
|
+
unless list.length % 2 == 0
|
154
|
+
raise Exceptions::Aerospike.new(Aerospike::ResultCode::PARAMETER_ERROR, "Invalid buffer")
|
155
|
+
end
|
156
|
+
|
157
|
+
list.each_slice(2).map { |id, value| Context.new(id, value) }
|
158
|
+
end
|
159
|
+
|
160
|
+
##
|
161
|
+
# Encodes the context array to messagepack and then encodes
|
162
|
+
# the resulting byte array to base64.
|
163
|
+
def self.base64(ctx)
|
164
|
+
unless ctx.to_a.empty?
|
165
|
+
data = self.bytes(ctx)
|
166
|
+
return Base64.strict_encode64(data).force_encoding("binary")
|
167
|
+
end
|
168
|
+
""
|
169
|
+
end
|
170
|
+
|
171
|
+
##
|
172
|
+
# Decodes the byte array to messagepack and then decodes
|
173
|
+
# the resulting byte array to an array of Context.
|
174
|
+
def self.from_base64(buf)
|
175
|
+
bytes = Base64.strict_decode64(buf)
|
176
|
+
self.from_bytes(bytes)
|
177
|
+
end
|
111
178
|
end
|
112
179
|
end
|
113
180
|
end
|
@@ -138,9 +138,7 @@ module Aerospike
|
|
138
138
|
# The map policy dictates the type of map to create when it does not exist.
|
139
139
|
# The map policy also specifies the flags used when writing items to the map.
|
140
140
|
def self.put(bin_name, key, value, ctx: nil, policy: MapPolicy::DEFAULT)
|
141
|
-
if policy.flags
|
142
|
-
MapOperation.new(Operation::CDT_MODIFY, PUT, bin_name, key, value, policy.order[:attr], policy.flags, ctx: ctx)
|
143
|
-
else
|
141
|
+
if policy.flags == MapWriteFlags::DEFAULT
|
144
142
|
case policy.write_mode
|
145
143
|
when MapWriteMode::UPDATE_ONLY
|
146
144
|
# Replace doesn't allow map order because it does not create on non-existing key.
|
@@ -150,6 +148,8 @@ module Aerospike
|
|
150
148
|
else
|
151
149
|
MapOperation.new(Operation::CDT_MODIFY, PUT, bin_name, key, value, policy.order[:attr], ctx: ctx)
|
152
150
|
end
|
151
|
+
else
|
152
|
+
MapOperation.new(Operation::CDT_MODIFY, PUT, bin_name, key, value, policy.order[:attr], policy.flags, ctx: ctx)
|
153
153
|
end
|
154
154
|
end
|
155
155
|
|
@@ -160,9 +160,7 @@ module Aerospike
|
|
160
160
|
# The map policy dictates the type of map to create when it does not exist.
|
161
161
|
# The map policy also specifies the flags used when writing items to the map.
|
162
162
|
def self.put_items(bin_name, values, ctx: nil, policy: MapPolicy::DEFAULT)
|
163
|
-
if policy.flags
|
164
|
-
MapOperation.new(Operation::CDT_MODIFY, PUT_ITEMS, bin_name, values, policy.order[:attr], policy.flags, ctx: ctx)
|
165
|
-
else
|
163
|
+
if policy.flags == MapWriteFlags::DEFAULT
|
166
164
|
case policy.write_mode
|
167
165
|
when MapWriteMode::UPDATE_ONLY
|
168
166
|
# Replace doesn't allow map order because it does not create on non-existing key.
|
@@ -172,6 +170,8 @@ module Aerospike
|
|
172
170
|
else
|
173
171
|
MapOperation.new(Operation::CDT_MODIFY, PUT_ITEMS, bin_name, values, policy.order[:attr], ctx: ctx)
|
174
172
|
end
|
173
|
+
else
|
174
|
+
MapOperation.new(Operation::CDT_MODIFY, PUT_ITEMS, bin_name, values, policy.order[:attr], policy.flags, ctx: ctx)
|
175
175
|
end
|
176
176
|
end
|
177
177
|
|
@@ -17,8 +17,8 @@
|
|
17
17
|
module Aerospike
|
18
18
|
module CDT
|
19
19
|
class MapPolicy
|
20
|
-
|
21
20
|
attr_accessor :order, :write_mode, :flags
|
21
|
+
attr_accessor :item_command, :items_command, :attributes
|
22
22
|
|
23
23
|
def initialize(order: nil, write_mode: nil, flags: nil)
|
24
24
|
if write_mode && flags
|
@@ -28,10 +28,24 @@ module Aerospike
|
|
28
28
|
@order = order || MapOrder::DEFAULT
|
29
29
|
@write_mode = write_mode || MapWriteMode::DEFAULT
|
30
30
|
@flags = flags || MapWriteFlags::DEFAULT
|
31
|
+
@attributes = order ? order[:attr] : 0
|
32
|
+
|
33
|
+
case @write_mode
|
34
|
+
when CDT::MapWriteMode::DEFAULT
|
35
|
+
@item_command = CDT::MapOperation::PUT
|
36
|
+
@items_command = CDT::MapOperation::PUT_ITEMS
|
37
|
+
when CDT::MapWriteMode::UPDATE_ONLY
|
38
|
+
@item_command = CDT::MapOperation::REPLACE
|
39
|
+
@items_command = CDT::MapOperation::REPLACE_ITEMS
|
40
|
+
when CDT::MapWriteMode::CREATE_ONLY
|
41
|
+
@item_command = CDT::MapOperation::ADD
|
42
|
+
@items_command = CDT::MapOperation::ADD_ITEMS
|
43
|
+
else
|
44
|
+
raise Exceptions.new(ResultCode::PARAMETER_ERROR, "invalid value for MapWriteMode #{write_mode}")
|
45
|
+
end
|
31
46
|
end
|
32
47
|
|
33
48
|
DEFAULT = MapPolicy.new
|
34
|
-
|
35
49
|
end
|
36
50
|
end
|
37
51
|
end
|
@@ -65,10 +65,22 @@ module Aerospike
|
|
65
65
|
# Return key/value items.
|
66
66
|
KEY_VALUE = 8
|
67
67
|
|
68
|
+
##
|
69
|
+
# Return true if count > 0.
|
70
|
+
EXISTS = 13
|
71
|
+
|
72
|
+
##
|
73
|
+
# :private
|
74
|
+
#
|
75
|
+
# TODO: Should be like ListOperation and Implement InvertibleMapOperation
|
76
|
+
# Inverts meaning of map command and return values. For example:
|
77
|
+
# map_remove_by_key_range(bin_name, key_begin, key_end, MapReturnType::KEY | MapReturnType::INVERTED)
|
78
|
+
# With the INVERTED flag enabled, the keys outside of the specified key range will be removed and returned.
|
79
|
+
INVERTED = 0x10000
|
80
|
+
|
68
81
|
##
|
69
82
|
# Default return type: NONE
|
70
83
|
DEFAULT_RETURN_TYPE = NONE
|
71
|
-
|
72
84
|
end
|
73
85
|
end
|
74
86
|
end
|