aerospike 2.19.0 → 2.26.0

Sign up to get free protection for your applications and to get access to all the features.
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