aerospike 2.10.0 → 2.11.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 +9 -0
- data/lib/aerospike.rb +9 -0
- data/lib/aerospike/client.rb +1 -1
- data/lib/aerospike/command/field_type.rb +1 -0
- data/lib/aerospike/geo_json.rb +69 -0
- data/lib/aerospike/query/pred_exp.rb +192 -0
- data/lib/aerospike/query/pred_exp/and_or.rb +32 -0
- data/lib/aerospike/query/pred_exp/geo_json_value.rb +41 -0
- data/lib/aerospike/query/pred_exp/integer_value.rb +32 -0
- data/lib/aerospike/query/pred_exp/op.rb +27 -0
- data/lib/aerospike/query/pred_exp/regex.rb +32 -0
- data/lib/aerospike/query/pred_exp/regex_flags.rb +23 -0
- data/lib/aerospike/query/pred_exp/string_value.rb +29 -0
- data/lib/aerospike/query/query_command.rb +15 -0
- data/lib/aerospike/query/recordset.rb +4 -4
- data/lib/aerospike/query/statement.rb +4 -2
- data/lib/aerospike/utils/unpacker.rb +6 -1
- data/lib/aerospike/version.rb +1 -1
- metadata +10 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02e8ccb3f64b4605bc10b58af760e35373209b7323b2c06cc04f133dd12c4b7d
|
4
|
+
data.tar.gz: 2b396aec824a2057daef8a6bd054c00bb103e2afd32f2d4c30de6e97853997f3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eb54355ef98807e3523c93bce1b5c2b440a1340387d351da5fb310f11c513d69622f60e309129ac4ea8897d26f5f3bf38362b3c6995a8241d023e383e17a887
|
7
|
+
data.tar.gz: 217f6f2a2a0b782d0309e7a487416bf47be2e9225dce5899d1d9e54b2b7578a26e9e0535d9ce5dc1a53bf3b1be87c865218482a59ba4e216a68803328c7608ba
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,15 @@ All notable changes to this project will be documented in this file.
|
|
4
4
|
|
5
5
|
## [Unreleased]
|
6
6
|
|
7
|
+
## [2.11.0] - 2019-05-17
|
8
|
+
|
9
|
+
* **New Features**
|
10
|
+
* Support for predicate expressions in queries. Thanks to [@Minus10Degrees](https://github.com/Minus10Degrees)! [[#78](https://github.com/aerospike/aerospike-client-ruby/issues/78)]
|
11
|
+
|
12
|
+
* **Bug Fixes**
|
13
|
+
* Client#execute\_udf\_on\_query should not modify the statement argument. [[#79](https://github.com/aerospike/aerospike-client-ruby/issues/79)]
|
14
|
+
* Encoding::UndefinedConversionError when reading blob data from CDT list/map bin. [[#84](https://github.com/aerospike/aerospike-client-ruby/issues/84)]
|
15
|
+
|
7
16
|
## [2.10.0] - 2019-05-10
|
8
17
|
|
9
18
|
* **New Features**
|
data/lib/aerospike.rb
CHANGED
@@ -142,6 +142,15 @@ require 'aerospike/query/stream_command'
|
|
142
142
|
require 'aerospike/query/query_command'
|
143
143
|
require 'aerospike/query/scan_command'
|
144
144
|
require 'aerospike/query/statement'
|
145
|
+
require 'aerospike/query/pred_exp'
|
146
|
+
|
147
|
+
require 'aerospike/query/pred_exp/and_or'
|
148
|
+
require 'aerospike/query/pred_exp/geo_json_value'
|
149
|
+
require 'aerospike/query/pred_exp/integer_value'
|
150
|
+
require 'aerospike/query/pred_exp/op'
|
151
|
+
require 'aerospike/query/pred_exp/regex'
|
152
|
+
require 'aerospike/query/pred_exp/regex_flags'
|
153
|
+
require 'aerospike/query/pred_exp/string_value'
|
145
154
|
|
146
155
|
module Aerospike
|
147
156
|
extend Loggable
|
data/lib/aerospike/client.rb
CHANGED
@@ -526,7 +526,7 @@ module Aerospike
|
|
526
526
|
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing UDF failed because cluster is empty.")
|
527
527
|
end
|
528
528
|
|
529
|
-
|
529
|
+
statement = statement.clone
|
530
530
|
statement.set_aggregate_function(package_name, function_name, function_args, false)
|
531
531
|
|
532
532
|
# Use a thread per node
|
data/lib/aerospike/geo_json.rb
CHANGED
@@ -52,6 +52,75 @@ module Aerospike
|
|
52
52
|
other.to_json == self.to_json
|
53
53
|
end
|
54
54
|
|
55
|
+
def lng
|
56
|
+
case type
|
57
|
+
when 'Point'
|
58
|
+
coordinates.first
|
59
|
+
when 'AeroCircle'
|
60
|
+
coordinates.first.first
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def lat
|
65
|
+
case type
|
66
|
+
when 'Point'
|
67
|
+
coordinates.last
|
68
|
+
when 'AeroCircle'
|
69
|
+
coordinates.first.last
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def radius
|
74
|
+
return nil unless circle?
|
75
|
+
|
76
|
+
coordinates.last
|
77
|
+
end
|
78
|
+
|
79
|
+
def coordinates
|
80
|
+
to_h['coordinates']
|
81
|
+
end
|
82
|
+
|
83
|
+
def type
|
84
|
+
to_h['type']
|
85
|
+
end
|
86
|
+
|
87
|
+
def point?
|
88
|
+
type == 'Point'
|
89
|
+
end
|
90
|
+
|
91
|
+
def circle?
|
92
|
+
type == 'AeroCircle'
|
93
|
+
end
|
94
|
+
|
95
|
+
def polygon?
|
96
|
+
type == 'Polygon'
|
97
|
+
end
|
98
|
+
|
99
|
+
def self.point(lng, lat)
|
100
|
+
new(type: 'Point', coordinates: [lng, lat])
|
101
|
+
end
|
102
|
+
|
103
|
+
def self.circle(lng, lat, radius)
|
104
|
+
new(type: 'AeroCircle', coordinates: [[lng, lat], radius])
|
105
|
+
end
|
106
|
+
|
107
|
+
def self.polygon(coordinates)
|
108
|
+
new(type: 'Polygon', coordinates: coordinates)
|
109
|
+
end
|
110
|
+
|
111
|
+
def to_circle(radius)
|
112
|
+
raise TypeError, 'Cannot create a Circle from a Polygon' if polygon?
|
113
|
+
|
114
|
+
self.class.circle(lng, lat, radius)
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_point
|
118
|
+
return self if point?
|
119
|
+
raise TypeError, 'Cannot create a Point from a Polygon' if polygon?
|
120
|
+
|
121
|
+
self.class.point(lng, lat)
|
122
|
+
end
|
123
|
+
|
55
124
|
protected
|
56
125
|
|
57
126
|
attr_accessor :json_data
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
AND = 1
|
6
|
+
OR = 2
|
7
|
+
NOT = 3
|
8
|
+
INTEGER_VALUE = 10
|
9
|
+
STRING_VALUE = 11
|
10
|
+
GEOJSON_VALUE = 12
|
11
|
+
INTEGER_BIN = 100
|
12
|
+
STRING_BIN = 101
|
13
|
+
GEOJSON_BIN = 102
|
14
|
+
LIST_BIN = 103
|
15
|
+
MAP_BIN = 104
|
16
|
+
INTEGER_VAR = 120
|
17
|
+
STRING_VAR = 121
|
18
|
+
GEOJSON_VAR = 122
|
19
|
+
RECSIZE = 150
|
20
|
+
LAST_UPDATE = 151
|
21
|
+
VOID_TIME = 152
|
22
|
+
INTEGER_EQUAL = 200
|
23
|
+
INTEGER_UNEQUAL = 201
|
24
|
+
INTEGER_GREATER = 202
|
25
|
+
INTEGER_GREATEREQ = 203
|
26
|
+
INTEGER_LESS = 204
|
27
|
+
INTEGER_LESSEQ = 205
|
28
|
+
STRING_EQUAL = 210
|
29
|
+
STRING_UNEQUAL = 211
|
30
|
+
STRING_REGEX = 212
|
31
|
+
GEOJSON_WITHIN = 220
|
32
|
+
GEOJSON_CONTAINS = 221
|
33
|
+
LIST_ITERATE_OR = 250
|
34
|
+
MAPKEY_ITERATE_OR = 251
|
35
|
+
MAPVAL_ITERATE_OR = 252
|
36
|
+
LIST_ITERATE_AND = 253
|
37
|
+
MAPKEY_ITERATE_AND = 254
|
38
|
+
MAPVAL_ITERATE_AND = 255
|
39
|
+
|
40
|
+
def self.and(nexp)
|
41
|
+
AndOr.new(AND, nexp)
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.or(nexp)
|
45
|
+
AndOr.new(OR, nexp)
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.not
|
49
|
+
Op.new(NOT)
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.integer_value(value)
|
53
|
+
IntegerValue.new(value, INTEGER_VALUE)
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.string_value(value)
|
57
|
+
StringValue.new(value, STRING_VALUE)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.geojson_value(value)
|
61
|
+
raise(ArgumentError, "value must be a GeoJSON object!") unless value.is_a?(Aerospike::GeoJSON)
|
62
|
+
GeoJsonValue.new(value.to_s, GEOJSON_VALUE)
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.integer_bin(name)
|
66
|
+
StringValue.new(name, INTEGER_BIN)
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.string_bin(name)
|
70
|
+
StringValue.new(name, STRING_BIN)
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.geojson_bin(name)
|
74
|
+
StringValue.new(name, GEOJSON_BIN)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.list_bin(name)
|
78
|
+
StringValue.new(name, LIST_BIN)
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.map_bin(name)
|
82
|
+
StringValue.new(name, MAP_BIN)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.integer_var(name)
|
86
|
+
StringValue.new(name, INTEGER_VAR)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.string_var(name)
|
90
|
+
StringValue.new(name, STRING_VAR)
|
91
|
+
end
|
92
|
+
|
93
|
+
def self.geojson_var(name)
|
94
|
+
StringValue.new(name, GEOJSON_VAR)
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.record_size
|
98
|
+
Op.new(RECSIZE)
|
99
|
+
end
|
100
|
+
|
101
|
+
def self.last_update
|
102
|
+
Op.new(LAST_UPDATE)
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.void_time
|
106
|
+
Op.new(VOID_TIME)
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.integer_equal
|
110
|
+
Op.new(INTEGER_EQUAL)
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.integer_unequal
|
114
|
+
Op.new(INTEGER_UNEQUAL)
|
115
|
+
end
|
116
|
+
|
117
|
+
def self.integer_greater
|
118
|
+
Op.new(INTEGER_GREATER)
|
119
|
+
end
|
120
|
+
|
121
|
+
def self.integer_greater_eq
|
122
|
+
Op.new(INTEGER_GREATEREQ)
|
123
|
+
end
|
124
|
+
|
125
|
+
def self.integer_less
|
126
|
+
Op.new(INTEGER_LESS)
|
127
|
+
end
|
128
|
+
|
129
|
+
def self.integer_less_eq
|
130
|
+
Op.new(INTEGER_LESSEQ)
|
131
|
+
end
|
132
|
+
|
133
|
+
def self.string_equal
|
134
|
+
Op.new(STRING_EQUAL)
|
135
|
+
end
|
136
|
+
|
137
|
+
def self.string_unequal
|
138
|
+
Op.new(STRING_UNEQUAL)
|
139
|
+
end
|
140
|
+
|
141
|
+
def self.string_regex(flags)
|
142
|
+
Regex.new(STRING_REGEX, flags)
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.geojson_within
|
146
|
+
Op.new(GEOJSON_WITHIN)
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.geojson_contains
|
150
|
+
Op.new(GEOJSON_CONTAINS)
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.list_iterate_or(var_name)
|
154
|
+
StringValue.new(var_name, LIST_ITERATE_OR)
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.list_iterate_and(var_name)
|
158
|
+
StringValue.new(var_name, LIST_ITERATE_AND)
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.mapkey_iterate_or(var_name)
|
162
|
+
StringValue.new(var_name, MAPKEY_ITERATE_OR)
|
163
|
+
end
|
164
|
+
|
165
|
+
def self.mapkey_iterate_and(var_name)
|
166
|
+
StringValue.new(var_name, MAPKEY_ITERATE_AND)
|
167
|
+
end
|
168
|
+
|
169
|
+
def self.mapval_iterate_or(var_name)
|
170
|
+
StringValue.new(var_name, MAPVAL_ITERATE_OR)
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.mapval_iterate_and(var_name)
|
174
|
+
StringValue.new(var_name, MAPVAL_ITERATE_AND)
|
175
|
+
end
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
def self.estimate_size(predexp)
|
180
|
+
return 0 unless predexp
|
181
|
+
predexp.map(&:estimate_size).inject { |sum, size| sum + size }
|
182
|
+
end
|
183
|
+
|
184
|
+
def self.write(predexp, buffer, offset)
|
185
|
+
predexp.each do |p|
|
186
|
+
offset = p.write(buffer, offset)
|
187
|
+
end
|
188
|
+
|
189
|
+
offset
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class AndOr < PredExp
|
6
|
+
def initialize(op, nexp)
|
7
|
+
@op = op
|
8
|
+
@nexp = nexp
|
9
|
+
end
|
10
|
+
|
11
|
+
def estimate_size
|
12
|
+
8
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(buffer, offset)
|
16
|
+
# write type
|
17
|
+
buffer.write_int16(@op, offset)
|
18
|
+
offset += 2
|
19
|
+
|
20
|
+
# write length
|
21
|
+
buffer.write_int32(2, offset)
|
22
|
+
offset += 4
|
23
|
+
|
24
|
+
# write predicate count
|
25
|
+
buffer.write_int16(@nexp, offset)
|
26
|
+
offset += 2
|
27
|
+
|
28
|
+
offset
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class GeoJsonValue < PredExp
|
6
|
+
def initialize(value, type)
|
7
|
+
@value = value
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def estimate_size
|
12
|
+
@value.bytesize + 9
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(buffer, offset)
|
16
|
+
# tag
|
17
|
+
buffer.write_uint16(@type, offset)
|
18
|
+
offset += 2
|
19
|
+
|
20
|
+
# len
|
21
|
+
buffer.write_uint32(@value.bytesize + 3, offset)
|
22
|
+
offset += 4
|
23
|
+
|
24
|
+
# flags
|
25
|
+
|
26
|
+
buffer.write_byte(0, offset)
|
27
|
+
offset += 1
|
28
|
+
|
29
|
+
# ncells
|
30
|
+
buffer.write_uint16(0, offset)
|
31
|
+
offset += 2
|
32
|
+
|
33
|
+
# value
|
34
|
+
len = buffer.write_binary(@value, offset)
|
35
|
+
offset += len
|
36
|
+
|
37
|
+
offset
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class IntegerValue < PredExp
|
6
|
+
def initialize(value, type)
|
7
|
+
@value = value
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def estimate_size
|
12
|
+
14
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(buffer, offset)
|
16
|
+
# Write type
|
17
|
+
buffer.write_int16(@type, offset)
|
18
|
+
offset += 2
|
19
|
+
|
20
|
+
# Write length
|
21
|
+
buffer.write_int32(8, offset)
|
22
|
+
offset += 4
|
23
|
+
|
24
|
+
# Write value.
|
25
|
+
buffer.write_int64(@value, offset)
|
26
|
+
offset += 8
|
27
|
+
|
28
|
+
offset
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class Op < PredExp
|
6
|
+
def initialize(op)
|
7
|
+
@op = op
|
8
|
+
end
|
9
|
+
|
10
|
+
def estimate_size
|
11
|
+
6
|
12
|
+
end
|
13
|
+
|
14
|
+
def write(buffer, offset)
|
15
|
+
# write type
|
16
|
+
buffer.write_int16(@op, offset)
|
17
|
+
offset += 2
|
18
|
+
|
19
|
+
# write zero length
|
20
|
+
buffer.write_int32(0, offset)
|
21
|
+
offset += 4
|
22
|
+
|
23
|
+
offset
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class Regex < PredExp
|
6
|
+
def initialize(op, flag = Flags::NONE)
|
7
|
+
@op = op
|
8
|
+
@flag = flag
|
9
|
+
end
|
10
|
+
|
11
|
+
def estimate_size
|
12
|
+
10
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(buffer, offset)
|
16
|
+
# write op type
|
17
|
+
buffer.write_int16(@op, offset)
|
18
|
+
offset += 2
|
19
|
+
|
20
|
+
# write length
|
21
|
+
buffer.write_int32(4, offset)
|
22
|
+
offset += 4
|
23
|
+
|
24
|
+
# write predicate count
|
25
|
+
buffer.write_int32(@flag, offset)
|
26
|
+
offset += 4
|
27
|
+
|
28
|
+
offset
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# fr# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
# Regex bit flags
|
6
|
+
module RegexFlags
|
7
|
+
# Regex defaults
|
8
|
+
NONE = 0
|
9
|
+
|
10
|
+
# Use POSIX Extended Regular Expression syntax when interpreting regex.
|
11
|
+
EXTENDED = 1
|
12
|
+
|
13
|
+
# Do not differentiate case.
|
14
|
+
ICASE = 2
|
15
|
+
|
16
|
+
# Do not report position of matches.
|
17
|
+
NOSUB = 4
|
18
|
+
|
19
|
+
# Match-any-character operators don't match a newline.
|
20
|
+
NEWLINE = 8
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aerospike
|
4
|
+
class PredExp
|
5
|
+
class StringValue < PredExp
|
6
|
+
def initialize(value, type)
|
7
|
+
@value = value
|
8
|
+
@type = type
|
9
|
+
end
|
10
|
+
|
11
|
+
def estimate_size
|
12
|
+
@value.bytesize + 6
|
13
|
+
end
|
14
|
+
|
15
|
+
def write(buffer, offset)
|
16
|
+
buffer.write_int16(@type, offset)
|
17
|
+
offset += 2
|
18
|
+
|
19
|
+
buffer.write_int32(@value.bytesize, offset)
|
20
|
+
offset += 4
|
21
|
+
|
22
|
+
len = buffer.write_binary(@value, offset)
|
23
|
+
offset += len
|
24
|
+
|
25
|
+
offset
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -35,6 +35,7 @@ module Aerospike
|
|
35
35
|
fieldCount = 0
|
36
36
|
filterSize = 0
|
37
37
|
binNameSize = 0
|
38
|
+
predSize = 0
|
38
39
|
|
39
40
|
begin_cmd
|
40
41
|
|
@@ -92,6 +93,13 @@ module Aerospike
|
|
92
93
|
@data_offset += 8 + FIELD_HEADER_SIZE
|
93
94
|
fieldCount+=1
|
94
95
|
|
96
|
+
if @statement.predexp
|
97
|
+
@data_offset += FIELD_HEADER_SIZE
|
98
|
+
predSize = Aerospike::PredExp.estimate_size(@statement.predexp)
|
99
|
+
@data_offset += predSize
|
100
|
+
fieldCount += 1
|
101
|
+
end
|
102
|
+
|
95
103
|
if @statement.function_name
|
96
104
|
@data_offset += FIELD_HEADER_SIZE + 1 # udf type
|
97
105
|
@data_offset += @statement.package_name.bytesize + FIELD_HEADER_SIZE
|
@@ -176,6 +184,13 @@ module Aerospike
|
|
176
184
|
@data_buffer.write_int64(@statement.task_id, @data_offset)
|
177
185
|
@data_offset += 8
|
178
186
|
|
187
|
+
if @statement.predexp
|
188
|
+
write_field_header(predSize, Aerospike::FieldType::PREDEXP)
|
189
|
+
@data_offset = Aerospike::PredExp.write(
|
190
|
+
@statement.predexp, @data_buffer, @data_offset
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
179
194
|
if @statement.function_name
|
180
195
|
write_field_header(1, Aerospike::FieldType::UDF_OP)
|
181
196
|
if @statement.return_data
|
@@ -20,7 +20,7 @@ module Aerospike
|
|
20
20
|
# a producer is a thread that fetches records from one node and puts them on this queue
|
21
21
|
# a consumer fetches records from this queue
|
22
22
|
# so the production and the consumptoin are decoupled
|
23
|
-
# there can be an unlimited count of producer threads and consumer threads
|
23
|
+
# there can be an unlimited count of producer threads and consumer threads
|
24
24
|
class Recordset
|
25
25
|
|
26
26
|
attr_reader :records
|
@@ -29,7 +29,7 @@ module Aerospike
|
|
29
29
|
queue_size = thread_count if queue_size < thread_count
|
30
30
|
@records = SizedQueue.new(queue_size)
|
31
31
|
|
32
|
-
# holds the count of active threads.
|
32
|
+
# holds the count of active threads.
|
33
33
|
# when it reaches zero it means the whole operations of fetching records from server nodes is finished
|
34
34
|
@active_threads = Atomic.new(thread_count)
|
35
35
|
|
@@ -48,7 +48,7 @@ module Aerospike
|
|
48
48
|
# if the operation is not finished and the queue is empty it blocks and waits for new records
|
49
49
|
# it sets the exception if it reaches the EOF mark, and returns nil
|
50
50
|
# EOF means the operation has finished and no more records are comming from server nodes
|
51
|
-
# it re-raises the exception occurred in threads, or which was set after reaching the EOF in the previous call
|
51
|
+
# it re-raises the exception occurred in threads, or which was set after reaching the EOF in the previous call
|
52
52
|
def next_record
|
53
53
|
raise @thread_exception.get unless @thread_exception.get.nil?
|
54
54
|
|
@@ -76,7 +76,7 @@ module Aerospike
|
|
76
76
|
|
77
77
|
# this is called by a thread who faced an exception to singnal to terminate the whole operation
|
78
78
|
# it also may be called by the user to terminate the command in the middle of fetching records from server nodes
|
79
|
-
# it clears the queue so that if any threads are waiting for the queue get unblocked and find out about the cancellation
|
79
|
+
# it clears the queue so that if any threads are waiting for the queue get unblocked and find out about the cancellation
|
80
80
|
def cancel(expn=nil)
|
81
81
|
set_exception(expn)
|
82
82
|
@cancelled.set(true)
|
@@ -20,7 +20,7 @@ module Aerospike
|
|
20
20
|
|
21
21
|
attr_accessor :namespace, :set_name, :index_name, :bin_names, :task_id
|
22
22
|
attr_accessor :filters, :package_name, :function_name, :function_args
|
23
|
-
attr_accessor :return_data
|
23
|
+
attr_accessor :predexp, :return_data
|
24
24
|
|
25
25
|
def initialize(namespace, set_name, bin_names=[])
|
26
26
|
# Namespace determines query Namespace
|
@@ -43,6 +43,9 @@ module Aerospike
|
|
43
43
|
# aggregation function.
|
44
44
|
@filters = []
|
45
45
|
|
46
|
+
# Predicate expressions
|
47
|
+
@predexp = nil
|
48
|
+
|
46
49
|
@package_name = nil
|
47
50
|
@function_name = nil
|
48
51
|
@function_args = nil
|
@@ -76,5 +79,4 @@ module Aerospike
|
|
76
79
|
RAND_MAX = 2**63
|
77
80
|
|
78
81
|
end # class
|
79
|
-
|
80
82
|
end
|
@@ -85,7 +85,12 @@ module Aerospike
|
|
85
85
|
def normalize_elem(elem)
|
86
86
|
case elem
|
87
87
|
when String
|
88
|
-
|
88
|
+
ptype = elem.ord
|
89
|
+
value = elem[1..-1]
|
90
|
+
if (ptype == ParticleType::STRING)
|
91
|
+
value.encode!(Aerospike.encoding)
|
92
|
+
end
|
93
|
+
value
|
89
94
|
when Array
|
90
95
|
normalize_strings_in_array(elem)
|
91
96
|
when Hash
|
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.11.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: 2019-05-
|
12
|
+
date: 2019-05-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: msgpack
|
@@ -140,6 +140,14 @@ files:
|
|
140
140
|
- lib/aerospike/policy/scan_policy.rb
|
141
141
|
- lib/aerospike/policy/write_policy.rb
|
142
142
|
- lib/aerospike/query/filter.rb
|
143
|
+
- lib/aerospike/query/pred_exp.rb
|
144
|
+
- lib/aerospike/query/pred_exp/and_or.rb
|
145
|
+
- lib/aerospike/query/pred_exp/geo_json_value.rb
|
146
|
+
- lib/aerospike/query/pred_exp/integer_value.rb
|
147
|
+
- lib/aerospike/query/pred_exp/op.rb
|
148
|
+
- lib/aerospike/query/pred_exp/regex.rb
|
149
|
+
- lib/aerospike/query/pred_exp/regex_flags.rb
|
150
|
+
- lib/aerospike/query/pred_exp/string_value.rb
|
143
151
|
- lib/aerospike/query/query_command.rb
|
144
152
|
- lib/aerospike/query/recordset.rb
|
145
153
|
- lib/aerospike/query/scan_command.rb
|