aerospike 2.25.0 → 2.26.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/CHANGELOG.md +9 -0
- data/lib/aerospike/cdt/context.rb +136 -69
- data/lib/aerospike/client.rb +3 -1
- data/lib/aerospike/query/filter.rb +44 -32
- data/lib/aerospike/query/query_partition_command.rb +9 -11
- data/lib/aerospike/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 569388197af73988d3965e15f8b7caf42605896f21183a0e6f7d507690dec816
|
4
|
+
data.tar.gz: dfe35172403817d176aecfd83747e6155a961b92960a97f8efc713a6b7540d23
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e4de68155586c168c75a51c71749531becdf066cb22888745f8473237cb775dd9054c6401e44a04b00bee517848859d128141692da3fc7c970df2f202e5e49b9
|
7
|
+
data.tar.gz: 7c041a196f2bf45a3ff575426b9269ba45c10e16f641c82f5ce11e362ace013d2480c407b8f1e9a663a27bcf78df1988d6af46de2bd22d41c0fce5366fb2a52c
|
data/CHANGELOG.md
CHANGED
@@ -2,10 +2,19 @@
|
|
2
2
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
|
5
|
+
## [2.26.0] 2022-12-02
|
6
|
+
|
7
|
+
- **New Features**
|
8
|
+
- [CLIENT-1808] Support creating a secondary index on elements within a CDT using `Context`.
|
9
|
+
- [CLIENT-1991] Add base64 encoding methods to `Context`.
|
10
|
+
- [CLIENT-2007] Support using `Context` in query filters.
|
11
|
+
|
5
12
|
## [2.25.0] 2022-11-28
|
6
13
|
|
7
14
|
- **New Features**
|
8
15
|
|
16
|
+
- [CLIENT-1984] Support scan-show and query-show info commands.
|
17
|
+
|
9
18
|
- [CLIENT-1362] Adds support Aerospike Expression filters. Expression filters are now supported on all commands, including `Client#get`, `Client#put`, `Client#delete`, `Client#operate`, `Client#scan`, `Client#query`, `Client#execute_udf`, etc.
|
10
19
|
|
11
20
|
- Adds `Policy#filter_exp` and `Policy#fail_on_filtered_out`
|
@@ -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,64 +38,64 @@ 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
|
-
|
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
|
98
99
|
|
99
100
|
##
|
100
101
|
# Create map with given type at map key.
|
@@ -102,12 +103,78 @@ module Aerospike
|
|
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
|
data/lib/aerospike/client.rb
CHANGED
@@ -566,7 +566,8 @@ module Aerospike
|
|
566
566
|
# This method is only supported by Aerospike 3 servers.
|
567
567
|
# index_type should be :string, :numeric or :geo2dsphere (requires server version 3.7 or later)
|
568
568
|
# collection_type should be :list, :mapkeys or :mapvalues
|
569
|
-
|
569
|
+
# ctx is an optional list of context. Supported on server v6.1+.
|
570
|
+
def create_index(namespace, set_name, index_name, bin_name, index_type, collection_type = nil, options = nil, ctx: nil)
|
570
571
|
if options.nil? && collection_type.is_a?(Hash)
|
571
572
|
options, collection_type = collection_type, nil
|
572
573
|
end
|
@@ -575,6 +576,7 @@ module Aerospike
|
|
575
576
|
str_cmd = "sindex-create:ns=#{namespace}"
|
576
577
|
str_cmd << ";set=#{set_name}" unless set_name.to_s.strip.empty?
|
577
578
|
str_cmd << ";indexname=#{index_name};numbins=1"
|
579
|
+
str_cmd << ";context=#{CDT::Context.base64(ctx)}" unless ctx.to_a.empty?
|
578
580
|
str_cmd << ";indextype=#{collection_type.to_s.upcase}" if collection_type
|
579
581
|
str_cmd << ";indexdata=#{bin_name},#{index_type.to_s.upcase}"
|
580
582
|
str_cmd << ";priority=normal"
|
@@ -15,39 +15,51 @@
|
|
15
15
|
# the License.
|
16
16
|
|
17
17
|
module Aerospike
|
18
|
-
|
19
18
|
class Filter
|
19
|
+
attr_reader :packed_ctx
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
# open up the class to alias the class methods for naming consistency
|
22
|
+
class << self
|
23
|
+
def equal(bin_name, value, ctx: nil)
|
24
|
+
Filter.new(bin_name, value, value, nil, nil, ctx)
|
25
|
+
end
|
24
26
|
|
25
|
-
|
26
|
-
|
27
|
-
|
27
|
+
def contains(bin_name, value, col_type, ctx: nil)
|
28
|
+
Filter.new(bin_name, value, value, nil, col_type, ctx)
|
29
|
+
end
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def range(bin_name, from, to, col_type = nil, ctx: nil)
|
32
|
+
Filter.new(bin_name, from, to, nil, col_type, ctx)
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
35
|
+
def geo_within_geo_region(bin_name, region, col_type = nil, ctx: nil)
|
36
|
+
region = region.to_json
|
37
|
+
Filter.new(bin_name, region, region, ParticleType::GEOJSON, col_type, ctx)
|
38
|
+
end
|
37
39
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
40
|
+
def geo_within_radius(bin_name, lon, lat, radius_meter, col_type = nil, ctx: nil)
|
41
|
+
region = GeoJSON.new({ type: "AeroCircle", coordinates: [[lon, lat], radius_meter] })
|
42
|
+
geo_within_geo_region(bin_name, region, col_type, ctx: ctx)
|
43
|
+
end
|
42
44
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def geo_contains_geo_point(bin_name, point, col_type = nil, ctx: nil)
|
46
|
+
point = point.to_json
|
47
|
+
Filter.new(bin_name, point, point, ParticleType::GEOJSON, col_type, ctx)
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
-
|
50
|
+
def geo_contains_point(bin_name, lon, lat, col_type = nil, ctx: nil)
|
51
|
+
point = GeoJSON.new({ type: "Point", coordinates: [lon, lat] })
|
52
|
+
geo_contains_geo_point(bin_name, point, col_type, ctx: ctx)
|
53
|
+
end
|
54
|
+
|
55
|
+
# alias the old names for compatibility
|
56
|
+
alias :Equal :equal
|
57
|
+
alias :Contains :contains
|
58
|
+
alias :Range :range
|
59
|
+
alias :geoWithinGeoJSONRegion :geo_within_geo_region
|
60
|
+
alias :geoWithinRadius :geo_within_radius
|
61
|
+
alias :geoContainsGeoJSONPoint :geo_contains_geo_point
|
62
|
+
alias :geoContainsPoint :geo_contains_point
|
51
63
|
end
|
52
64
|
|
53
65
|
def estimate_size
|
@@ -56,21 +68,21 @@ module Aerospike
|
|
56
68
|
|
57
69
|
def write(buf, offset)
|
58
70
|
# Write name.
|
59
|
-
len = buf.write_binary(@name, offset+1)
|
71
|
+
len = buf.write_binary(@name, offset + 1)
|
60
72
|
buf.write_byte(len, offset)
|
61
73
|
offset += len + 1
|
62
74
|
|
63
75
|
# Write particle type.
|
64
76
|
buf.write_byte(@val_type, offset)
|
65
|
-
offset+=1
|
77
|
+
offset += 1
|
66
78
|
|
67
79
|
# Write filter begin.
|
68
|
-
len = @begin.write(buf, offset+4)
|
80
|
+
len = @begin.write(buf, offset + 4)
|
69
81
|
buf.write_int32(len, offset)
|
70
82
|
offset += len + 4
|
71
83
|
|
72
84
|
# Write filter end.
|
73
|
-
len = @end.write(buf, offset+4)
|
85
|
+
len = @end.write(buf, offset + 4)
|
74
86
|
buf.write_int32(len, offset)
|
75
87
|
offset += len + 4
|
76
88
|
|
@@ -98,7 +110,7 @@ module Aerospike
|
|
98
110
|
|
99
111
|
private
|
100
112
|
|
101
|
-
def initialize(bin_name, begin_value, end_value, val_type = nil, col_type = nil)
|
113
|
+
def initialize(bin_name, begin_value, end_value, val_type = nil, col_type = nil, ctx = nil)
|
102
114
|
@name = bin_name
|
103
115
|
@begin = Aerospike::Value.of(begin_value)
|
104
116
|
@end = Aerospike::Value.of(end_value)
|
@@ -107,8 +119,8 @@ module Aerospike
|
|
107
119
|
# but in certain cases caller can override the type.
|
108
120
|
@val_type = val_type || @begin.type
|
109
121
|
@col_type = col_type
|
110
|
-
end
|
111
122
|
|
123
|
+
@packed_ctx = CDT::Context.bytes(ctx)
|
124
|
+
end
|
112
125
|
end # class
|
113
|
-
|
114
126
|
end
|
@@ -82,12 +82,11 @@ module Aerospike
|
|
82
82
|
@data_offset += filter_size
|
83
83
|
field_count += 1
|
84
84
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# end
|
85
|
+
packed_ctx = filter.packed_ctx
|
86
|
+
if packed_ctx
|
87
|
+
@data_offset += FIELD_HEADER_SIZE + packed_ctx.length
|
88
|
+
field_count += 1
|
89
|
+
end
|
91
90
|
end
|
92
91
|
|
93
92
|
@statement.set_task_id
|
@@ -210,11 +209,10 @@ module Aerospike
|
|
210
209
|
@data_offset += @data_buffer.write_byte(1, @data_offset)
|
211
210
|
@data_offset = filter.write(@data_buffer, @data_offset)
|
212
211
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
# end
|
212
|
+
if packed_ctx
|
213
|
+
write_field_header(packed_ctx.length, FieldType::INDEX_CONTEXT)
|
214
|
+
@data_offset += @data_buffer.write_binary(packed_ctx, @data_offset)
|
215
|
+
end
|
218
216
|
end
|
219
217
|
|
220
218
|
if @statement.function_name
|
data/lib/aerospike/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aerospike
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.26.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Khosrow Afroozeh
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-12-02 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|