aerospike 1.0.4 → 1.0.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9637e861d9aa3e0f0a4f7291877deabb198f7390
4
- data.tar.gz: cd148fc3d987d2976a1a977b7212c113dd626dc8
3
+ metadata.gz: 29590c28263bbb25b84e0856deaa101c53e6e1b1
4
+ data.tar.gz: c737c8347a770a959c53d9677346761d0c6f0fcc
5
5
  SHA512:
6
- metadata.gz: 6598cb2fc4b8f5d4cfa1c8f052b1694314d32330bea1a98735310a28be4e71eef1e8f93973e85bdf795ccd734e1d94d44642376dab7fbf0b2bb02a57649af3da
7
- data.tar.gz: 479790b6ffdbeccc639ebf7b33b84ff120bfb0a9dc8e5ff11b96a2acf26f4dcee4586c542cf3f30de280fc7c8920b31f531eb4fb39afdee2d08ff18a7d32e594
6
+ metadata.gz: d06e1e14657badf69828cffa141a967ae02423572b29f107e635b754308c701d3bc9c153ad93c01ea7bd36294fcc84e87cc1b6e50e44bab5b6460add94035992
7
+ data.tar.gz: 5c8e4f46c757aec7d7b4c1f9fcb8ac815016d80aadb218d095cabb127e5af5c061635d08b17b8d42c6b784f40520223d94ae7a27b9f0f9c2fa101f285a1233d9
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## March 25 2015 (1.0.5)
2
+
3
+ Minor improvements.
4
+
5
+ * **New Features**:
6
+
7
+ * Added `:execute_udf_on_query` method to `Aerospike::Client`
8
+
1
9
  ## March 24 2015 (1.0.4)
2
10
 
3
11
  Hot fix.
data/lib/aerospike.rb CHANGED
@@ -71,6 +71,7 @@ require 'aerospike/aerospike_exception'
71
71
  require 'aerospike/user_role'
72
72
 
73
73
  require 'aerospike/task/index_task'
74
+ require 'aerospike/task/execute_task'
74
75
  require 'aerospike/task/udf_remove_task'
75
76
  require 'aerospike/task/udf_register_task'
76
77
  require 'aerospike/task/task'
@@ -525,6 +525,43 @@ module Aerospike
525
525
  raise Aerospike::Exceptions::Aerospike.new(UDF_BAD_RESPONSE, "Invalid UDF return value")
526
526
  end
527
527
 
528
+ # execute_udf_on_query applies user defined function on records that match the statement filter.
529
+ # Records are not returned to the client.
530
+ # This asynchronous server call will return before command is complete.
531
+ # The user can optionally wait for command completion by using the returned
532
+ # ExecuteTask instance.
533
+ #
534
+ # This method is only supported by Aerospike 3 servers.
535
+ # If the policy is nil, the default relevant policy will be used.
536
+ def execute_udf_on_query(statement, package_name, function_name, function_args=[], options={})
537
+ policy = opt_to_query_policy(options)
538
+
539
+ nodes = @cluster.nodes
540
+ if nodes.length == 0
541
+ raise Aerospike::Exceptions::Aerospike.new(Aerospike::ResultCode::SERVER_NOT_AVAILABLE, "Executing UDF failed because cluster is empty.")
542
+ end
543
+
544
+ # TODO: wait until all migrations are finished
545
+ statement.set_aggregate_function(package_name, function_name, function_args, false)
546
+
547
+ # Use a thread per node
548
+ nodes.each do |node|
549
+ Thread.new do
550
+ abort_on_exception = true
551
+ begin
552
+ command = QueryCommand.new(node, policy, statement, nil)
553
+ command.execute
554
+ rescue => e
555
+ Aerospike.logger.error(e)
556
+ raise e
557
+ end
558
+ end
559
+ end
560
+
561
+ ExecuteTask.new(@cluster, statement)
562
+ end
563
+
564
+
528
565
  # Create secondary index.
529
566
  # This asynchronous server call will return before command is complete.
530
567
  # The user can optionally wait for command completion by using the returned
@@ -29,7 +29,7 @@ module Aerospike
29
29
  READ_WRITE = 'read-write'
30
30
 
31
31
  # Allow read transactions with the database.
32
- READ = 'Read'
32
+ READ = 'read'
33
33
 
34
34
  end # module
35
35
 
@@ -92,7 +92,7 @@ module Aerospike
92
92
  @data_offset += @statement.function_name.bytesize + FIELD_HEADER_SIZE
93
93
 
94
94
  if @statement.function_args && @statement.function_args.length > 0
95
- functionArgBuffer = Value.of(@statement.function_args).bytes
95
+ functionArgBuffer = Value.of(@statement.function_args).to_bytes
96
96
  else
97
97
  functionArgBuffer = 0.ord
98
98
  end
@@ -36,6 +36,11 @@ module Aerospike
36
36
  # The only valid server return codes are "ok" and "not found".
37
37
  # If other return codes are received, then abort the batch.
38
38
  if result_code != 0
39
+ # if there is no recordset defined, it means this is an Execute UDF On Query command
40
+ # return successfully
41
+ if (@recordset == nil) && (result_code == Aerospike::ResultCode::KEY_NOT_FOUND_ERROR)
42
+ return nil
43
+ end
39
44
  raise Aerospike::Exceptions::Aerospike.new(result_code)
40
45
  end
41
46
 
@@ -0,0 +1,85 @@
1
+ # Copyright 2013-2014 Aerospike, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Aerospike
16
+
17
+ private
18
+
19
+ # ExecuteTask is used to poll for long running server execute job completion.
20
+ class ExecuteTask < Task
21
+
22
+ # NewExecuteTask initializes task with fields needed to query server nodes.
23
+ def initialize(cluster, statement)
24
+ super(cluster, false)
25
+
26
+ @task_id = statement.task_id
27
+ @scan = statement.is_scan?
28
+
29
+ self
30
+ end
31
+
32
+ # IsDone queries all nodes for task completion status.
33
+ def all_nodes_done?
34
+
35
+ if @scan
36
+ command = 'scan-list'
37
+ else
38
+ command = 'query-list'
39
+ end
40
+
41
+ nodes = @cluster.nodes
42
+ done = false
43
+
44
+ nodes.each do |node|
45
+ conn = node.get_connection(0)
46
+ responseMap, err = Info.request(conn, command)
47
+ node.put_connection(conn)
48
+
49
+ response = responseMap[command]
50
+ find = "job_id=#{@task_id}:"
51
+ index = response.index(find)
52
+
53
+ unless index
54
+ # don't return on first check
55
+ done = true
56
+ next
57
+ end
58
+
59
+ b = index + find.length
60
+ response = response[b, response.length]
61
+ find = 'job_status='
62
+ index = response.index(find)
63
+
64
+ next unless index
65
+
66
+ b = index + find.length
67
+ response = response[b, response.length]
68
+ e = response.index(':')
69
+ status = response[0, e]
70
+
71
+ case status
72
+ when 'ABORTED'
73
+ raise raise Aerospike::Exceptions::QueryTerminated
74
+ when 'IN PROGRESS'
75
+ return false
76
+ when 'DONE'
77
+ done = true
78
+ end
79
+ end
80
+
81
+ done
82
+ end
83
+
84
+ end
85
+ end
@@ -42,8 +42,8 @@ module Aerospike
42
42
  failures = 0
43
43
  while true
44
44
  begin
45
- break if completed?
46
45
  sleep(poll_interval.to_f)
46
+ break if completed?
47
47
  rescue => e
48
48
  Aerospike.logger.error(e)
49
49
  break if failures > allowed_failures
@@ -1,4 +1,4 @@
1
1
  # encoding: utf-8
2
2
  module Aerospike
3
- VERSION = "1.0.4"
3
+ VERSION = "1.0.5"
4
4
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aerospike
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.4
4
+ version: 1.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Khosrow Afroozeh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-24 00:00:00.000000000 Z
11
+ date: 2015-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -110,6 +110,7 @@ files:
110
110
  - lib/aerospike/query/stream_command.rb
111
111
  - lib/aerospike/record.rb
112
112
  - lib/aerospike/result_code.rb
113
+ - lib/aerospike/task/execute_task.rb
113
114
  - lib/aerospike/task/index_task.rb
114
115
  - lib/aerospike/task/task.rb
115
116
  - lib/aerospike/task/udf_register_task.rb