aerospike 2.19.0 → 2.21.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 +24 -0
- data/lib/aerospike/client.rb +56 -7
- data/lib/aerospike/cluster/create_connection.rb +1 -1
- data/lib/aerospike/cluster.rb +35 -1
- data/lib/aerospike/command/admin_command.rb +367 -51
- 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/command.rb +29 -12
- data/lib/aerospike/command/field_type.rb +1 -0
- data/lib/aerospike/command/login_command.rb +162 -0
- data/lib/aerospike/command/multi_command.rb +17 -0
- data/lib/aerospike/connection/authenticate.rb +35 -3
- data/lib/aerospike/policy/auth_mode.rb +36 -0
- data/lib/aerospike/policy/client_policy.rb +4 -1
- data/lib/aerospike/privilege.rb +133 -0
- data/lib/aerospike/query/query_command.rb +21 -11
- data/lib/aerospike/query/scan_command.rb +3 -2
- data/lib/aerospike/query/stream_command.rb +3 -0
- data/lib/aerospike/result_code.rb +4 -4
- data/lib/aerospike/role.rb +55 -0
- data/lib/aerospike/user_role.rb +25 -0
- data/lib/aerospike/utils/buffer.rb +25 -0
- data/lib/aerospike/value/particle_type.rb +1 -12
- data/lib/aerospike/value/value.rb +9 -4
- data/lib/aerospike/version.rb +1 -1
- data/lib/aerospike.rb +4 -0
- metadata +7 -4
- data/lib/aerospike/command/roles.rb +0 -39
@@ -18,24 +18,40 @@ module Aerospike
|
|
18
18
|
|
19
19
|
private
|
20
20
|
# Commands
|
21
|
-
AUTHENTICATE
|
22
|
-
CREATE_USER
|
23
|
-
DROP_USER
|
24
|
-
SET_PASSWORD
|
25
|
-
CHANGE_PASSWORD
|
26
|
-
GRANT_ROLES
|
27
|
-
REVOKE_ROLES
|
28
|
-
|
29
|
-
|
30
|
-
|
21
|
+
AUTHENTICATE = 0
|
22
|
+
CREATE_USER = 1
|
23
|
+
DROP_USER = 2
|
24
|
+
SET_PASSWORD = 3
|
25
|
+
CHANGE_PASSWORD = 4
|
26
|
+
GRANT_ROLES = 5
|
27
|
+
REVOKE_ROLES = 6
|
28
|
+
QUERY_USERS = 9
|
29
|
+
CREATE_ROLE = 10
|
30
|
+
DROP_ROLE = 11
|
31
|
+
GRANT_PRIVILEGES = 12
|
32
|
+
REVOKE_PRIVILEGES = 13
|
33
|
+
SET_WHITELIST = 14
|
34
|
+
SET_QUOTAS = 15
|
35
|
+
QUERY_ROLES = 16
|
36
|
+
LOGIN = 20
|
31
37
|
|
32
38
|
# Field IDs
|
33
|
-
USER
|
34
|
-
PASSWORD
|
35
|
-
OLD_PASSWORD
|
36
|
-
CREDENTIAL
|
37
|
-
|
38
|
-
|
39
|
+
USER = 0
|
40
|
+
PASSWORD = 1
|
41
|
+
OLD_PASSWORD = 2
|
42
|
+
CREDENTIAL = 3
|
43
|
+
CLEAR_PASSWORD = 4
|
44
|
+
SESSION_TOKEN = 5
|
45
|
+
SESSION_TTL = 6
|
46
|
+
ROLES = 10
|
47
|
+
ROLE = 11
|
48
|
+
PRIVILEGES = 12
|
49
|
+
ALLOWLIST = 13
|
50
|
+
READ_QUOTA = 14
|
51
|
+
WRITE_QUOTA = 15
|
52
|
+
READ_INFO = 16
|
53
|
+
WRITE_INFO = 17
|
54
|
+
CONNECTIONS = 18
|
39
55
|
|
40
56
|
# Misc
|
41
57
|
MSG_VERSION = 2
|
@@ -53,28 +69,6 @@ module Aerospike
|
|
53
69
|
@data_offset = 8
|
54
70
|
end
|
55
71
|
|
56
|
-
def authenticate(conn, user, password)
|
57
|
-
begin
|
58
|
-
set_authenticate(user, password)
|
59
|
-
conn.write(@data_buffer, @data_offset)
|
60
|
-
conn.read(@data_buffer, HEADER_SIZE)
|
61
|
-
|
62
|
-
result = @data_buffer.read(RESULT_CODE)
|
63
|
-
raise Exceptions::Aerospike.new(result, "Authentication failed") if result != 0
|
64
|
-
ensure
|
65
|
-
Buffer.put(@data_buffer)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
def set_authenticate(user, password)
|
70
|
-
write_header(AUTHENTICATE, 2)
|
71
|
-
write_field_str(USER, user)
|
72
|
-
write_field_bytes(CREDENTIAL, password)
|
73
|
-
write_size
|
74
|
-
|
75
|
-
return @data_offset
|
76
|
-
end
|
77
|
-
|
78
72
|
def create_user(cluster, policy, user, password, roles)
|
79
73
|
write_header(CREATE_USER, 3)
|
80
74
|
write_field_str(USER, user)
|
@@ -118,6 +112,61 @@ module Aerospike
|
|
118
112
|
execute_command(cluster, policy)
|
119
113
|
end
|
120
114
|
|
115
|
+
def create_role(cluster, policy, role_name, privileges = [], allowlist = [], read_quota = 0, write_quota = 0)
|
116
|
+
field_count = 1
|
117
|
+
field_count += 1 if privileges.size > 0
|
118
|
+
field_count += 1 if allowlist.size > 0
|
119
|
+
field_count += 1 if read_quota > 0
|
120
|
+
field_count += 1 if write_quota > 0
|
121
|
+
|
122
|
+
write_header(CREATE_ROLE, field_count)
|
123
|
+
write_field_str(ROLE, role_name)
|
124
|
+
|
125
|
+
write_privileges(privileges) if privileges.size > 0
|
126
|
+
write_allowlist(allowlist) if allowlist.size > 0
|
127
|
+
|
128
|
+
write_field_uint32(READ_QUOTA, read_quota) if read_quota > 0
|
129
|
+
write_field_uint32(WRITE_QUOTA, write_quota) if write_quota > 0
|
130
|
+
|
131
|
+
execute_command(cluster, policy)
|
132
|
+
end
|
133
|
+
|
134
|
+
def drop_role(cluster, policy, role)
|
135
|
+
write_header(DROP_ROLE, 1)
|
136
|
+
write_field_str(ROLE, role)
|
137
|
+
execute_command(cluster, policy)
|
138
|
+
end
|
139
|
+
|
140
|
+
def grant_privileges(cluster, policy, role, privileges)
|
141
|
+
write_header(GRANT_PRIVILEGES, 2)
|
142
|
+
write_field_str(ROLE, role)
|
143
|
+
write_privileges(privileges)
|
144
|
+
execute_command(cluster, policy)
|
145
|
+
end
|
146
|
+
|
147
|
+
def revoke_privileges(cluster, policy, role, privileges)
|
148
|
+
write_header(REVOKE_PRIVILEGES, 2)
|
149
|
+
write_field_str(ROLE, role)
|
150
|
+
write_privileges(privileges)
|
151
|
+
execute_command(cluster, policy)
|
152
|
+
end
|
153
|
+
|
154
|
+
def set_allowlist(cluster, policy, role, allowlist = [])
|
155
|
+
field_count = 1
|
156
|
+
field_count += 1 if allowlist.size > 0
|
157
|
+
write_header(SET_WHITELIST, field_count)
|
158
|
+
write_allowlist(allowlist) if allowlist.size > 0
|
159
|
+
execute_command(cluster, policy)
|
160
|
+
end
|
161
|
+
|
162
|
+
def set_quotas(cluster, policy, role, read_quota, write_quota)
|
163
|
+
write_header(SET_QUOTAS, 3)
|
164
|
+
write_field_str(ROLE, role)
|
165
|
+
write_field_uint32(READ_QUOTA, read_quota)
|
166
|
+
write_field_uint32(WRITE_QUOTA, write_quota)
|
167
|
+
execute_command(cluster, policy)
|
168
|
+
end
|
169
|
+
|
121
170
|
def query_user(cluster, policy, user)
|
122
171
|
# TODO: Remove the workaround in the future
|
123
172
|
sleep(0.010)
|
@@ -144,6 +193,32 @@ module Aerospike
|
|
144
193
|
end
|
145
194
|
end
|
146
195
|
|
196
|
+
def query_role(cluster, policy, role)
|
197
|
+
# TODO: Remove the workaround in the future
|
198
|
+
sleep(0.010)
|
199
|
+
|
200
|
+
list = []
|
201
|
+
begin
|
202
|
+
write_header(QUERY_ROLES, 1)
|
203
|
+
write_field_str(ROLE, role)
|
204
|
+
list = read_roles(cluster, policy)
|
205
|
+
return (list.is_a?(Array) && list.length > 0 ? list.first : nil)
|
206
|
+
ensure
|
207
|
+
Buffer.put(@data_buffer)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def query_roles(cluster, policy)
|
212
|
+
# TODO: Remove the workaround in the future
|
213
|
+
sleep(0.010)
|
214
|
+
begin
|
215
|
+
write_header(QUERY_ROLES, 0)
|
216
|
+
return read_roles(cluster, policy)
|
217
|
+
ensure
|
218
|
+
Buffer.put(@data_buffer)
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
147
222
|
def write_roles(roles)
|
148
223
|
offset = @data_offset + FIELD_HEADER_SIZE
|
149
224
|
@data_buffer.write_byte(roles.length.ord, offset)
|
@@ -166,6 +241,54 @@ module Aerospike
|
|
166
241
|
@data_buffer.write_int64(size, 0)
|
167
242
|
end
|
168
243
|
|
244
|
+
def write_privileges(privileges)
|
245
|
+
offset = @data_offset
|
246
|
+
@data_offset += FIELD_HEADER_SIZE
|
247
|
+
write_byte(privileges.size)
|
248
|
+
|
249
|
+
for privilege in privileges
|
250
|
+
write_byte(privilege.to_code)
|
251
|
+
if privilege.can_scope?
|
252
|
+
if privilege.set_name.to_s.size > 0 && privilege.namespace.to_s.size == 0
|
253
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Admin privilege #{privilege.namespace} has a set scope with an empty namespace")
|
254
|
+
end
|
255
|
+
|
256
|
+
write_str(privilege.namespace.to_s)
|
257
|
+
write_str(privilege.set_name.to_s)
|
258
|
+
else
|
259
|
+
if privilege.set_name.to_s.bytesize > 0 || privilege.namespace.to_s.bytesize > 0
|
260
|
+
raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::INVALID_PRIVILEGE, "Admin global privilege #{privilege} can't have a namespace or set")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
size = @data_offset - offset - FIELD_HEADER_SIZE
|
266
|
+
@data_offset = offset
|
267
|
+
write_field_header(PRIVILEGES, size)
|
268
|
+
@data_offset += size
|
269
|
+
end
|
270
|
+
|
271
|
+
def write_allowlist(allowlist)
|
272
|
+
offset = @data_offset
|
273
|
+
@data_offset += FIELD_HEADER_SIZE
|
274
|
+
|
275
|
+
comma = false
|
276
|
+
for addr in allowlist
|
277
|
+
if comma
|
278
|
+
write_byte(",")
|
279
|
+
else
|
280
|
+
comma = true
|
281
|
+
end
|
282
|
+
|
283
|
+
@data_offset += @data_buffer.write_binary(addr, @data_offset)
|
284
|
+
end
|
285
|
+
|
286
|
+
size = @data_offset - offset - FIELD_HEADER_SIZE
|
287
|
+
@data_offset = offset
|
288
|
+
write_field_header(ALLOWLIST, size)
|
289
|
+
@data_offset += size
|
290
|
+
end
|
291
|
+
|
169
292
|
def write_header(command, field_count)
|
170
293
|
# Authenticate header is almost all zeros
|
171
294
|
i = @data_offset
|
@@ -178,12 +301,27 @@ module Aerospike
|
|
178
301
|
@data_offset += 16
|
179
302
|
end
|
180
303
|
|
304
|
+
def write_byte(b)
|
305
|
+
@data_offset += @data_buffer.write_byte(b, @data_offset)
|
306
|
+
end
|
307
|
+
|
308
|
+
def write_str(str)
|
309
|
+
@data_offset += @data_buffer.write_byte(str.bytesize, @data_offset)
|
310
|
+
@data_offset += @data_buffer.write_binary(str, @data_offset)
|
311
|
+
end
|
312
|
+
|
181
313
|
def write_field_str(id, str)
|
182
314
|
len = @data_buffer.write_binary(str, @data_offset+FIELD_HEADER_SIZE)
|
183
315
|
write_field_header(id, len)
|
184
316
|
@data_offset += len
|
185
317
|
end
|
186
318
|
|
319
|
+
def write_field_uint32(id, val)
|
320
|
+
len = @data_buffer.write_uint32(val, @data_offset+FIELD_HEADER_SIZE)
|
321
|
+
write_field_header(id, len)
|
322
|
+
@data_offset += len
|
323
|
+
end
|
324
|
+
|
187
325
|
def write_field_bytes(id, bytes)
|
188
326
|
@data_buffer.write_binary(bytes, @data_offset+FIELD_HEADER_SIZE)
|
189
327
|
write_field_header(id, bytes.bytesize)
|
@@ -284,7 +422,7 @@ module Aerospike
|
|
284
422
|
return (result_code == QUERY_END ? -1 : result_code)
|
285
423
|
end
|
286
424
|
|
287
|
-
|
425
|
+
user_roles = UserRoles.new
|
288
426
|
field_count = @data_buffer.read(@data_offset+3)
|
289
427
|
@data_offset += HEADER_REMAINING
|
290
428
|
|
@@ -298,10 +436,17 @@ module Aerospike
|
|
298
436
|
|
299
437
|
case id
|
300
438
|
when USER
|
301
|
-
|
439
|
+
user_roles.user = @data_buffer.read(@data_offset, len)
|
302
440
|
@data_offset += len
|
303
441
|
when ROLES
|
304
|
-
parse_roles(
|
442
|
+
parse_roles(user_roles)
|
443
|
+
when READ_INFO
|
444
|
+
user_roles.read_info = parse_info
|
445
|
+
when WRITE_INFO
|
446
|
+
user_roles.write_info = parse_info
|
447
|
+
when CONNECTIONS
|
448
|
+
user_roles.conns_in_use = @data_buffer.read_int32(@data_offset)
|
449
|
+
@data_offset += len
|
305
450
|
else
|
306
451
|
@data_offset += len
|
307
452
|
end
|
@@ -309,19 +454,19 @@ module Aerospike
|
|
309
454
|
i = i.succ
|
310
455
|
end
|
311
456
|
|
312
|
-
next if
|
457
|
+
next if user_roles.user == "" && user_roles.roles == nil
|
313
458
|
|
314
|
-
|
315
|
-
list <<
|
459
|
+
user_roles.roles = [] if user_roles.roles == nil
|
460
|
+
list << user_roles
|
316
461
|
end
|
317
462
|
|
318
463
|
return 0, list
|
319
464
|
end
|
320
465
|
|
321
|
-
def parse_roles(
|
466
|
+
def parse_roles(user_roles)
|
322
467
|
size = @data_buffer.read(@data_offset)
|
323
468
|
@data_offset += 1
|
324
|
-
|
469
|
+
user_roles.roles = []
|
325
470
|
|
326
471
|
i = 0
|
327
472
|
while i < size
|
@@ -329,17 +474,188 @@ module Aerospike
|
|
329
474
|
@data_offset += 1
|
330
475
|
role = @data_buffer.read(@data_offset, len)
|
331
476
|
@data_offset += len
|
332
|
-
|
477
|
+
user_roles.roles << role
|
333
478
|
|
334
479
|
i = i.succ
|
335
480
|
end
|
336
481
|
end
|
337
482
|
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
483
|
+
def parse_info
|
484
|
+
size = @data_buffer.read(@data_offset)
|
485
|
+
@data_offset += 1
|
486
|
+
list = []
|
487
|
+
|
488
|
+
i = 0
|
489
|
+
while i < size
|
490
|
+
val = @data_buffer.read_int32(@data_offset)
|
491
|
+
@data_offset += 4
|
492
|
+
list << val
|
493
|
+
|
494
|
+
i = i.succ
|
495
|
+
end
|
496
|
+
|
497
|
+
list
|
342
498
|
end
|
499
|
+
|
500
|
+
def read_roles(cluster, policy)
|
501
|
+
write_size
|
502
|
+
node = cluster.random_node
|
503
|
+
|
504
|
+
timeout = 1
|
505
|
+
timeout = policy.timeout if policy != nil && policy.timeout > 0
|
506
|
+
|
507
|
+
status = -1
|
508
|
+
list = []
|
509
|
+
begin
|
510
|
+
conn = node.get_connection(timeout)
|
511
|
+
conn.write(@data_buffer, @data_offset)
|
512
|
+
status, list = read_role_blocks(conn)
|
513
|
+
node.put_connection(conn)
|
514
|
+
rescue => e
|
515
|
+
conn.close if conn
|
516
|
+
raise e
|
517
|
+
end
|
518
|
+
|
519
|
+
raise Exceptions::Aerospike.new(status) if status > 0
|
520
|
+
|
521
|
+
return list
|
522
|
+
end
|
523
|
+
|
524
|
+
def read_role_blocks(conn)
|
525
|
+
rlist = []
|
526
|
+
status = 0
|
527
|
+
begin
|
528
|
+
while status == 0
|
529
|
+
conn.read(@data_buffer, 8)
|
530
|
+
size = @data_buffer.read_int64(0)
|
531
|
+
receive_size = (size & 0xFFFFFFFFFFFF)
|
532
|
+
|
533
|
+
if receive_size > 0
|
534
|
+
@data_buffer.resize(receive_size) if receive_size > @data_buffer.size
|
535
|
+
|
536
|
+
conn.read(@data_buffer, receive_size)
|
537
|
+
status, list = parse_roles_full(receive_size)
|
538
|
+
rlist.concat(list.to_a)
|
539
|
+
else
|
540
|
+
break
|
541
|
+
end
|
542
|
+
end
|
543
|
+
return status, rlist
|
544
|
+
rescue => e
|
545
|
+
return -1, []
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
def parse_roles_full(receive_size)
|
550
|
+
@data_offset = 0
|
551
|
+
list = []
|
552
|
+
|
553
|
+
while @data_offset < receive_size
|
554
|
+
result_code = @data_buffer.read(@data_offset+1)
|
555
|
+
|
556
|
+
if result_code != 0
|
557
|
+
return (result_code == QUERY_END ? -1 : result_code)
|
558
|
+
end
|
559
|
+
|
560
|
+
role = Role.new
|
561
|
+
field_count = @data_buffer.read(@data_offset+3)
|
562
|
+
@data_offset += HEADER_REMAINING
|
563
|
+
|
564
|
+
i = 0
|
565
|
+
while i < field_count
|
566
|
+
len = @data_buffer.read_int32(@data_offset)
|
567
|
+
@data_offset += 4
|
568
|
+
id = @data_buffer.read(@data_offset)
|
569
|
+
@data_offset += 1
|
570
|
+
len -= 1
|
571
|
+
|
572
|
+
case id
|
573
|
+
when ROLE
|
574
|
+
role.name = @data_buffer.read(@data_offset, len).to_s
|
575
|
+
@data_offset += len
|
576
|
+
when PRIVILEGES
|
577
|
+
parse_privileges(role)
|
578
|
+
when ALLOWLIST
|
579
|
+
role.allowlist = parse_allowlist(len)
|
580
|
+
when READ_QUOTA
|
581
|
+
role.read_quota = @data_buffer.read_uint32(@data_offset)
|
582
|
+
@data_offset += len
|
583
|
+
when WRITE_QUOTA
|
584
|
+
role.write_quota = @data_buffer.read_uint32(@data_offset)
|
585
|
+
@data_offset += len
|
586
|
+
else
|
587
|
+
@data_offset += len
|
588
|
+
end
|
589
|
+
|
590
|
+
i = i.succ
|
591
|
+
end
|
592
|
+
|
593
|
+
next if role.name == "" && role.privileges == nil
|
594
|
+
|
595
|
+
role.privileges ||= []
|
596
|
+
list << role
|
597
|
+
end
|
598
|
+
|
599
|
+
return 0, list
|
600
|
+
end
|
601
|
+
|
602
|
+
def parse_privileges(role)
|
603
|
+
size = @data_buffer.read(@data_offset)
|
604
|
+
@data_offset += 1
|
605
|
+
role.privileges = []
|
606
|
+
|
607
|
+
i = 0
|
608
|
+
while i < size
|
609
|
+
priv = Privilege.new
|
610
|
+
priv.code = Privilege.from(@data_buffer.read(@data_offset))
|
611
|
+
@data_offset += 1
|
612
|
+
|
613
|
+
if priv.can_scope?
|
614
|
+
len = @data_buffer.read(@data_offset)
|
615
|
+
@data_offset += 1
|
616
|
+
priv.namespace = @data_buffer.read(@data_offset, len)
|
617
|
+
@data_offset += len
|
618
|
+
|
619
|
+
len = @data_buffer.read(@data_offset)
|
620
|
+
@data_offset += 1
|
621
|
+
priv.set_name = @data_buffer.read(@data_offset, len)
|
622
|
+
@data_offset += len
|
623
|
+
end
|
624
|
+
|
625
|
+
role.privileges << priv
|
626
|
+
|
627
|
+
i = i.succ
|
628
|
+
end
|
629
|
+
end
|
630
|
+
|
631
|
+
def parse_allowlist(len)
|
632
|
+
list = []
|
633
|
+
begn = @data_offset
|
634
|
+
max = begn + len
|
635
|
+
|
636
|
+
while @data_offset < max
|
637
|
+
if @data_buffer.read(@data_offset) == ','
|
638
|
+
l = @data_offset - begn
|
639
|
+
if l > 0
|
640
|
+
s = @data_buffer.read(begn, l)
|
641
|
+
list << s
|
642
|
+
end
|
643
|
+
@data_offset += 1
|
644
|
+
begn = @data_offset
|
645
|
+
else
|
646
|
+
@data_offset += 1
|
647
|
+
end
|
648
|
+
end
|
649
|
+
|
650
|
+
l = @data_offset - begn
|
651
|
+
if l > 0
|
652
|
+
s = @data_buffer.read(begn, l)
|
653
|
+
list << s
|
654
|
+
end
|
655
|
+
|
656
|
+
list
|
657
|
+
end
|
658
|
+
|
343
659
|
end
|
344
660
|
end
|
345
661
|
|
@@ -110,16 +110,12 @@ module Aerospike
|
|
110
110
|
field_count = @data_buffer.read_int16(18)
|
111
111
|
op_count = @data_buffer.read_int16(20)
|
112
112
|
|
113
|
-
|
113
|
+
skip_key(field_count)
|
114
114
|
req_key = batch.key_for_index(batch_index)
|
115
115
|
|
116
|
-
if
|
117
|
-
|
118
|
-
|
119
|
-
results[batch_index] = record
|
120
|
-
end
|
121
|
-
else
|
122
|
-
Aerospike.logger.warn("Unexpected batch key returned: #{key}")
|
116
|
+
if result_code == 0
|
117
|
+
record = parse_record(req_key, op_count, generation, expiration)
|
118
|
+
results[batch_index] = record
|
123
119
|
end
|
124
120
|
end
|
125
121
|
|
@@ -66,6 +66,8 @@ module Aerospike
|
|
66
66
|
INFO3_LAST = Integer(1 << 0)
|
67
67
|
# Commit to master only before declaring success.
|
68
68
|
INFO3_COMMIT_MASTER = Integer(1 << 1)
|
69
|
+
# Partition is complete response in scan.
|
70
|
+
INFO3_PARTITION_DONE = Integer(1 << 2)
|
69
71
|
# Update only. Merge bins.
|
70
72
|
INFO3_UPDATE_ONLY = Integer(1 << 3)
|
71
73
|
|
@@ -333,7 +335,7 @@ module Aerospike
|
|
333
335
|
mark_compressed(policy)
|
334
336
|
end
|
335
337
|
|
336
|
-
def set_scan(policy, namespace, set_name, bin_names)
|
338
|
+
def set_scan(policy, namespace, set_name, bin_names, partitions)
|
337
339
|
# Estimate buffer size
|
338
340
|
begin_cmd
|
339
341
|
field_count = 0
|
@@ -357,7 +359,10 @@ module Aerospike
|
|
357
359
|
field_count += 1 if predexp_size > 0
|
358
360
|
|
359
361
|
# Estimate scan options size.
|
360
|
-
@data_offset += 2 + FIELD_HEADER_SIZE
|
362
|
+
# @data_offset += 2 + FIELD_HEADER_SIZE
|
363
|
+
# field_count += 1
|
364
|
+
|
365
|
+
@data_offset += partitions.length * 2 + FIELD_HEADER_SIZE
|
361
366
|
field_count += 1
|
362
367
|
|
363
368
|
# Estimate scan timeout size.
|
@@ -392,24 +397,30 @@ module Aerospike
|
|
392
397
|
write_field_string(set_name, Aerospike::FieldType::TABLE)
|
393
398
|
end
|
394
399
|
|
400
|
+
write_field_header(partitions.length * 2, Aerospike::FieldType::PID_ARRAY)
|
401
|
+
for pid in partitions
|
402
|
+
@data_buffer.write_uint16_little_endian(pid, @data_offset)
|
403
|
+
@data_offset += 2
|
404
|
+
end
|
405
|
+
|
395
406
|
if policy.records_per_second > 0
|
396
407
|
write_field_int(policy.records_per_second, Aerospike::FieldType::RECORDS_PER_SECOND)
|
397
408
|
end
|
398
409
|
|
399
410
|
write_predexp(policy.predexp, predexp_size)
|
400
411
|
|
401
|
-
write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
412
|
+
# write_field_header(2, Aerospike::FieldType::SCAN_OPTIONS)
|
402
413
|
|
403
|
-
priority = policy.priority & 0xFF
|
404
|
-
priority <<= 4
|
405
|
-
if policy.fail_on_cluster_change
|
406
|
-
|
407
|
-
end
|
414
|
+
# priority = policy.priority & 0xFF
|
415
|
+
# priority <<= 4
|
416
|
+
# if policy.fail_on_cluster_change
|
417
|
+
# priority |= 0x08
|
418
|
+
# end
|
408
419
|
|
409
|
-
@data_buffer.write_byte(priority, @data_offset)
|
410
|
-
@data_offset += 1
|
411
|
-
@data_buffer.write_byte(policy.scan_percent.to_i.ord, @data_offset)
|
412
|
-
@data_offset += 1
|
420
|
+
# @data_buffer.write_byte(priority, @data_offset)
|
421
|
+
# @data_offset += 1
|
422
|
+
# @data_buffer.write_byte(policy.scan_percent.to_i.ord, @data_offset)
|
423
|
+
# @data_offset += 1
|
413
424
|
|
414
425
|
write_field_header(4, Aerospike::FieldType::SCAN_TIMEOUT)
|
415
426
|
@data_buffer.write_uint32(policy.socket_timeout.to_i, @data_offset)
|
@@ -786,6 +797,12 @@ module Aerospike
|
|
786
797
|
@data_offset += len
|
787
798
|
end
|
788
799
|
|
800
|
+
def write_u16_little_endian(i, ftype)
|
801
|
+
@data_buffer.write_uint16_little_endian(i, @data_offset+FIELD_HEADER_SIZE)
|
802
|
+
write_field_header(2, ftype)
|
803
|
+
@data_offset += 2
|
804
|
+
end
|
805
|
+
|
789
806
|
def write_field_int(i, ftype)
|
790
807
|
@data_buffer.write_int32(i, @data_offset+FIELD_HEADER_SIZE)
|
791
808
|
write_field_header(4, ftype)
|