aerospike 2.19.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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +354 -244
  3. data/lib/aerospike/atomic/atomic.rb +1 -1
  4. data/lib/aerospike/cdt/context.rb +137 -70
  5. data/lib/aerospike/cdt/list_return_type.rb +4 -0
  6. data/lib/aerospike/cdt/map_operation.rb +6 -6
  7. data/lib/aerospike/cdt/map_policy.rb +16 -2
  8. data/lib/aerospike/cdt/map_return_type.rb +13 -1
  9. data/lib/aerospike/client.rb +137 -115
  10. data/lib/aerospike/cluster/create_connection.rb +1 -1
  11. data/lib/aerospike/cluster.rb +41 -4
  12. data/lib/aerospike/command/admin_command.rb +368 -52
  13. data/lib/aerospike/command/batch_index_command.rb +4 -8
  14. data/lib/aerospike/command/batch_index_exists_command.rb +1 -1
  15. data/lib/aerospike/command/batch_index_node.rb +1 -1
  16. data/lib/aerospike/command/batch_item.rb +1 -1
  17. data/lib/aerospike/command/command.rb +180 -123
  18. data/lib/aerospike/command/field_type.rb +25 -24
  19. data/lib/aerospike/command/login_command.rb +164 -0
  20. data/lib/aerospike/command/multi_command.rb +25 -2
  21. data/lib/aerospike/command/operate_args.rb +99 -0
  22. data/lib/aerospike/command/operate_command.rb +6 -11
  23. data/lib/aerospike/command/read_command.rb +2 -2
  24. data/lib/aerospike/connection/authenticate.rb +36 -3
  25. data/lib/aerospike/exp/exp.rb +1329 -0
  26. data/lib/aerospike/exp/exp_bit.rb +388 -0
  27. data/lib/aerospike/exp/exp_hll.rb +169 -0
  28. data/lib/aerospike/exp/exp_list.rb +403 -0
  29. data/lib/aerospike/exp/exp_map.rb +493 -0
  30. data/lib/aerospike/exp/operation.rb +56 -0
  31. data/lib/aerospike/features.rb +22 -9
  32. data/lib/aerospike/host/parse.rb +2 -2
  33. data/lib/aerospike/key.rb +10 -1
  34. data/lib/aerospike/node/refresh/info.rb +1 -1
  35. data/lib/aerospike/node/verify/name.rb +1 -1
  36. data/lib/aerospike/node/verify/partition_generation.rb +1 -1
  37. data/lib/aerospike/node/verify/peers_generation.rb +1 -1
  38. data/lib/aerospike/node/verify/rebalance_generation.rb +1 -1
  39. data/lib/aerospike/node_validator.rb +6 -1
  40. data/lib/aerospike/operation.rb +20 -22
  41. data/lib/aerospike/policy/auth_mode.rb +36 -0
  42. data/lib/aerospike/policy/client_policy.rb +4 -1
  43. data/lib/aerospike/policy/policy.rb +29 -13
  44. data/lib/aerospike/policy/query_policy.rb +35 -2
  45. data/lib/aerospike/policy/scan_policy.rb +19 -2
  46. data/lib/aerospike/privilege.rb +133 -0
  47. data/lib/aerospike/query/filter.rb +44 -32
  48. data/lib/aerospike/query/node_partitions.rb +39 -0
  49. data/lib/aerospike/query/partition_filter.rb +66 -0
  50. data/lib/aerospike/{command/roles.rb → query/partition_status.rb} +16 -19
  51. data/lib/aerospike/query/partition_tracker.rb +347 -0
  52. data/lib/aerospike/query/query_command.rb +20 -10
  53. data/lib/aerospike/query/query_executor.rb +71 -0
  54. data/lib/aerospike/query/query_partition_command.rb +267 -0
  55. data/lib/aerospike/query/recordset.rb +9 -9
  56. data/lib/aerospike/query/scan_command.rb +3 -2
  57. data/lib/aerospike/query/scan_executor.rb +71 -0
  58. data/lib/aerospike/query/scan_partition_command.rb +49 -0
  59. data/lib/aerospike/query/statement.rb +8 -1
  60. data/lib/aerospike/query/stream_command.rb +17 -0
  61. data/lib/aerospike/result_code.rb +83 -8
  62. data/lib/aerospike/role.rb +55 -0
  63. data/lib/aerospike/task/execute_task.rb +19 -16
  64. data/lib/aerospike/task/index_task.rb +1 -1
  65. data/lib/aerospike/user_role.rb +26 -1
  66. data/lib/aerospike/utils/buffer.rb +93 -29
  67. data/lib/aerospike/utils/packer.rb +7 -6
  68. data/lib/aerospike/utils/pool.rb +1 -1
  69. data/lib/aerospike/value/particle_type.rb +1 -12
  70. data/lib/aerospike/value/value.rb +35 -60
  71. data/lib/aerospike/version.rb +1 -1
  72. data/lib/aerospike.rb +156 -136
  73. metadata +24 -6
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2020 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may not
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at 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, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ module Aerospike
18
+
19
+ # Role provides granular access to database entities for users.
20
+ class Role
21
+
22
+ # Role name
23
+ attr_accessor :name
24
+
25
+ # List of assigned privileges
26
+ attr_accessor :privileges
27
+
28
+ # List of allowable IP addresses
29
+ attr_accessor :allowlist
30
+
31
+ # Maximum reads per second limit for the role
32
+ attr_accessor :read_quota
33
+
34
+ # Maximum writes per second limit for the role
35
+ attr_accessor :write_quota
36
+
37
+ # The following aliases are for backward compatibility reasons
38
+ USER_ADMIN = Privilege::USER_ADMIN # :nodoc:
39
+ SYS_ADMIN = Privilege::SYS_ADMIN # :nodoc:
40
+ DATA_ADMIN = Privilege::DATA_ADMIN # :nodoc:
41
+ UDF_ADMIN = Privilege::UDF_ADMIN # :nodoc:
42
+ SINDEX_ADMIN = Privilege::SINDEX_ADMIN # :nodoc:
43
+ READ_WRITE_UDF = Privilege::READ_WRITE_UDF # :nodoc:
44
+ READ_WRITE = Privilege::READ_WRITE # :nodoc:
45
+ READ = Privilege::READ # :nodoc:
46
+ WRITE = Privilege::WRITE # :nodoc:
47
+ TRUNCATE = Privilege::TRUNCATE # :nodoc:
48
+
49
+ def to_s
50
+ "Role [name=#{@name}, privileges=#{@privileges}, allowlist=#{@allowlist}, readQuota=#{@read_quota}, writeQuota=#{@write_quota}]";
51
+ end
52
+
53
+ end # class
54
+
55
+ end # module
@@ -13,7 +13,6 @@
13
13
  # limitations under the License.
14
14
 
15
15
  module Aerospike
16
-
17
16
  private
18
17
 
19
18
  # ExecuteTask is used to poll for long running server execute job completion.
@@ -29,19 +28,24 @@ module Aerospike
29
28
  self
30
29
  end
31
30
 
32
- # IsDone queries all nodes for task completion status.
31
+ # queries all nodes for task completion status.
33
32
  def all_nodes_done?
34
-
35
- if @scan
36
- command = 'scan-list'
37
- else
38
- command = 'query-list'
39
- end
33
+ modul = @scan ? "scan" : "query"
34
+ cmd1 = "query-show:trid=#{@task_id}"
35
+ cmd2 = modul + "-show:trid=#{@task_id}"
36
+ cmd3 = "jobs:module=" + modul + ";cmd=get-job;trid=#{@task_id}"
40
37
 
41
38
  nodes = @cluster.nodes
42
39
  done = false
43
40
 
44
41
  nodes.each do |node|
42
+ command = cmd3
43
+ if node.supports_feature?(Aerospike::Features::PARTITION_QUERY)
44
+ command = cmd1
45
+ elsif node.supports_feature?(Aerospike::Features::QUERY_SHOW)
46
+ command = cmd2
47
+ end
48
+
45
49
  conn = node.get_connection(0)
46
50
  responseMap, _ = Info.request(conn, command)
47
51
  node.put_connection(conn)
@@ -58,28 +62,27 @@ module Aerospike
58
62
 
59
63
  b = index + find.length
60
64
  response = response[b, response.length]
61
- find = 'job_status='
65
+ find = "job_status="
62
66
  index = response.index(find)
63
67
 
64
68
  next unless index
65
69
 
66
70
  b = index + find.length
67
71
  response = response[b, response.length]
68
- e = response.index(':')
72
+ e = response.index(":")
69
73
  status = response[0, e]
70
74
 
71
75
  case status
72
- when 'ABORTED'
73
- raise raise Aerospike::Exceptions::QueryTerminated
74
- when 'IN PROGRESS'
76
+ when "ABORTED"
77
+ raise Aerospike::Exceptions::QueryTerminated
78
+ when "IN PROGRESS"
75
79
  return false
76
- when 'DONE'
80
+ when "DONE"
77
81
  done = true
78
82
  end
79
83
  end
80
84
 
81
85
  done
82
86
  end
83
-
84
87
  end
85
- end
88
+ end
@@ -25,7 +25,7 @@ module Aerospike
25
25
 
26
26
  class IndexTask < Task
27
27
 
28
- MATCHER = /.*load_pct=(?<load_pct>\d+(\.\d+)?).*/
28
+ MATCHER = /.*load_pct=(?<load_pct>\d+(\.\d+)?).*/.freeze
29
29
 
30
30
  def initialize(cluster, namespace, index_name, done=false)
31
31
  super(cluster, done)
@@ -25,6 +25,31 @@ module Aerospike
25
25
  # List of assigned roles.
26
26
  attr_accessor :roles
27
27
 
28
+ # List of read statistics. List may be nil.
29
+ # Current statistics by offset are:
30
+ #
31
+ # 0: read quota in records per second
32
+ # 1: single record read transaction rate (TPS)
33
+ # 2: read scan/query record per second rate (RPS)
34
+ # 3: number of limitless read scans/queries
35
+ #
36
+ # Future server releases may add additional statistics.
37
+ attr_accessor :read_info
38
+
39
+ # List of write statistics. List may be nil.
40
+ # Current statistics by offset are:
41
+ #
42
+ # 0: write quota in records per second
43
+ # 1: single record write transaction rate (TPS)
44
+ # 2: write scan/query record per second rate (RPS)
45
+ # 3: number of limitless write scans/queries
46
+ #
47
+ # Future server releases may add additional statistics.
48
+ attr_accessor :write_info
49
+
50
+ # Number of currently open connections for the user
51
+ attr_accessor :conns_in_use
52
+
28
53
  end
29
54
 
30
- end
55
+ end
@@ -17,34 +17,34 @@
17
17
  # License for the specific language governing permissions and limitations under
18
18
  # the License.
19
19
 
20
- require 'aerospike/utils/pool'
20
+ require "aerospike/utils/pool"
21
21
 
22
22
  module Aerospike
23
-
24
23
  private
25
24
 
26
25
  # Buffer class to ease the work around
27
26
  class Buffer #:nodoc:
28
-
29
27
  @@buf_pool = Pool.new
30
28
  @@buf_pool.create_proc = Proc.new { Buffer.new }
31
29
 
32
30
  attr_accessor :buf
33
31
 
34
- INT16 = 's>'
35
- UINT16 = 'n'
36
- INT32 = 'l>'
37
- UINT32 = 'N'
38
- INT64 = 'q>'
39
- UINT64 = 'Q>'
40
- DOUBLE = 'G'
32
+ INT16 = "s>"
33
+ UINT16 = "n"
34
+ UINT16LE = "v"
35
+ INT32 = "l>"
36
+ UINT32 = "N"
37
+ INT64 = "q>"
38
+ UINT64 = "Q>"
39
+ UINT64LE = "Q"
40
+ DOUBLE = "G"
41
41
 
42
42
  DEFAULT_BUFFER_SIZE = 16 * 1024
43
43
  MAX_BUFFER_SIZE = 10 * 1024 * 1024
44
44
 
45
- def initialize(size=DEFAULT_BUFFER_SIZE, buf = nil)
45
+ def initialize(size = DEFAULT_BUFFER_SIZE, buf = nil)
46
46
  @buf = (buf ? buf : ("%0#{size}d" % 0))
47
- @buf.force_encoding('binary')
47
+ @buf.force_encoding("binary")
48
48
  @slice_end = @buf.bytesize
49
49
  end
50
50
 
@@ -59,6 +59,7 @@ module Aerospike
59
59
  def size
60
60
  @buf.bytesize
61
61
  end
62
+
62
63
  alias_method :length, :size
63
64
 
64
65
  def eat!(n)
@@ -66,6 +67,12 @@ module Aerospike
66
67
  end
67
68
 
68
69
  def resize(length)
70
+ # Corrupted data streams can result in a hug.length.
71
+ # Do a sanity check here.
72
+ if length > MAX_BUFFER_SIZE
73
+ raise Aerospike::Exceptions::Parse.new("Invalid size for buffer: #{length}")
74
+ end
75
+
69
76
  if @buf.bytesize < length
70
77
  @buf.concat("%0#{length - @buf.bytesize}d" % 0)
71
78
  end
@@ -92,6 +99,11 @@ module Aerospike
92
99
  2
93
100
  end
94
101
 
102
+ def write_uint16_little_endian(i, offset)
103
+ @buf[offset, 2] = [i].pack(UINT16LE)
104
+ 2
105
+ end
106
+
95
107
  def write_int32(i, offset)
96
108
  @buf[offset, 4] = [i].pack(INT32)
97
109
  4
@@ -112,12 +124,17 @@ module Aerospike
112
124
  8
113
125
  end
114
126
 
127
+ def write_uint64_little_endian(i, offset)
128
+ @buf[offset, 8] = [i].pack(UINT64LE)
129
+ 8
130
+ end
131
+
115
132
  def write_double(f, offset)
116
133
  @buf[offset, 8] = [f].pack(DOUBLE)
117
134
  8
118
135
  end
119
136
 
120
- def read(offset, len=nil)
137
+ def read(offset, len = nil)
121
138
  if len
122
139
  @buf[offset, len]
123
140
  else
@@ -126,56 +143,103 @@ module Aerospike
126
143
  end
127
144
 
128
145
  def read_int16(offset)
129
- vals = @buf[offset..offset+1]
146
+ vals = @buf[offset..offset + 1]
130
147
  vals.unpack(INT16)[0]
131
148
  end
132
149
 
150
+ def read_uint16(offset)
151
+ vals = @buf[offset..offset + 1]
152
+ vals.unpack(UINT16)[0]
153
+ end
154
+
133
155
  def read_int32(offset)
134
- vals = @buf[offset..offset+3]
156
+ vals = @buf[offset..offset + 3]
135
157
  vals.unpack(INT32)[0]
136
158
  end
137
159
 
160
+ def read_uint32(offset)
161
+ vals = @buf[offset..offset + 3]
162
+ vals.unpack(UINT32)[0]
163
+ end
164
+
138
165
  def read_int64(offset)
139
- vals = @buf[offset..offset+7]
166
+ vals = @buf[offset..offset + 7]
140
167
  vals.unpack(INT64)[0]
141
168
  end
142
169
 
170
+ def read_uint64_little_endian(offset)
171
+ vals = @buf[offset..offset + 7]
172
+ vals.unpack(UINT64LE)[0]
173
+ end
174
+
175
+ def read_uint64(offset)
176
+ vals = @buf[offset..offset + 7]
177
+ vals.unpack(UINT64)[0]
178
+ end
179
+
143
180
  def read_var_int64(offset, len)
144
181
  val = 0
145
182
  i = 0
146
183
  while i < len
147
184
  val <<= 8
148
- val |= @buf[offset+i].ord & 0xFF
185
+ val |= @buf[offset + i].ord & 0xFF
149
186
  i = i.succ
150
187
  end
151
188
  val
152
189
  end
153
190
 
154
191
  def read_double(offset)
155
- vals = @buf[offset..offset+7]
192
+ vals = @buf[offset..offset + 7]
156
193
  vals.unpack(DOUBLE)[0]
157
194
  end
158
195
 
196
+ def read_bool(offset, length)
197
+ length <= 0 ? false : @buf[offset].ord != 0
198
+ end
199
+
159
200
  def to_s
160
- @buf[0..@slice_end-1]
201
+ @buf[0..@slice_end - 1]
161
202
  end
162
203
 
163
204
  def reset
164
- for i in 0..@buf.size-1
165
- @buf[i] = ' '
205
+ for i in 0..@buf.size - 1
206
+ @buf[i] = " "
166
207
  end
167
208
  end
168
209
 
169
- def dump(from=nil, to=nil)
170
- from ||= 0
171
- to ||= @slice_end - 1
210
+ def dump(start = 0, finish = nil)
211
+ buf ||= @buf.bytes
212
+ finish ||= @slice_end - 1
213
+ width = 16
214
+
215
+ ascii = "|"
216
+ counter = 0
217
+
218
+ print "%08x " % start
219
+ @buf.bytes[start...finish].each do |c|
220
+ if counter >= start
221
+ print "%02x " % c
222
+ ascii << (c.between?(32, 126) ? c : ?.)
223
+ print " " if ascii.length == (width / 2 + 1)
224
+ if ascii.length > width
225
+ ascii << "|"
226
+ puts ascii
227
+ ascii = "|"
228
+ print "%08x " % (counter + 1)
229
+ end
230
+ end
231
+ counter += 1
232
+ end
172
233
 
173
- @buf.bytes[from...to].each do |c|
174
- print c.ord.to_s(16)
175
- putc ' '
234
+ # print the remainder in buffer
235
+ if ascii.length.positive?
236
+ fill_size = ((width - ascii.length + 1) * 3)
237
+ fill_size += 1 if ascii.length <= (width / 2)
238
+ filler = " " * fill_size
239
+ print filler
240
+ ascii << "|"
241
+ puts ascii
176
242
  end
177
243
  end
178
-
179
244
  end # buffer
180
-
181
245
  end # module
@@ -14,13 +14,11 @@
14
14
  # License for the specific language governing permissions and limitations under
15
15
  # the License.
16
16
 
17
- require 'msgpack'
18
- require 'aerospike/utils/pool'
17
+ require "msgpack"
18
+ require "aerospike/utils/pool"
19
19
 
20
20
  module Aerospike
21
-
22
21
  class Packer < MessagePack::Packer #:nodoc:
23
-
24
22
  AS_EXT_TYPE = -1
25
23
 
26
24
  @@pool = Pool.new
@@ -44,9 +42,12 @@ module Aerospike
44
42
  buffer << [val].pack("S>")
45
43
  end
46
44
 
45
+ def write_raw(buf)
46
+ buffer.write(buf)
47
+ end
48
+
47
49
  def bytes
48
- self.to_s.force_encoding('binary')
50
+ self.to_s.force_encoding("binary")
49
51
  end
50
52
  end
51
-
52
53
  end
@@ -53,7 +53,7 @@ module Aerospike
53
53
  end
54
54
 
55
55
  def empty?
56
- @pool.length == 0
56
+ @pool.empty?
57
57
  end
58
58
 
59
59
  def length
@@ -23,19 +23,8 @@ module Aerospike
23
23
  DOUBLE = 2
24
24
  STRING = 3
25
25
  BLOB = 4
26
- #TIMESTAMP = 5
27
- #DIGEST = 6
28
- #JBLOB = 7
29
- #CSHARP_BLOB = 8
30
- #PYTHON_BLOB = 9
31
26
  RUBY_BLOB = 10
32
- #PHP_BLOB = 11
33
- #ERLANG_BLOB = 12
34
- #SEGMENT_POINTER = 13
35
- #RTA_LIST = 14
36
- #RTA_DICT = 15
37
- #RTA_APPEND_DICT = 16
38
- #RTA_APPEND_LIST = 17
27
+ BOOL = 17
39
28
  HLL = 18
40
29
  MAP = 19
41
30
  LIST = 20