voltdbjruby 0.4.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38794425576b17d4745051ebe50c75e9e3964a21
4
+ data.tar.gz: c0ea95079164c86758049a4a52e91e0a0a9009ec
5
+ SHA512:
6
+ metadata.gz: 0723df7ddb29fab72fcb02b5f146720aa5b1aaa24fd1f486b0ca5111decf3fde67a9cb69299e6eda6a33a6ec5c001eda66bac612404691f18b4f64ae55f8b668
7
+ data.tar.gz: 2ca413757b0747856bd20e80c2a8218be3903819997791cbb15cb032a4271aa3b093d5cde00919de4aa7dc234b575e0a1cf8ed430983917bb885bb9ce9a0483e
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .ruby-version
11
+ examples.txt
12
+ *.gem
13
+ Jarfile
14
+ Jarfile.lock
15
+ .jbundler
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at alberto@albertogrespan.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [http://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: http://contributor-covenant.org
74
+ [version]: http://contributor-covenant.org/version/1/4/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in voltdb.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Alberto Grespan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # Voltdb JRuby Client
2
+
3
+ A thin wrapper around the VoltDB Java client.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem "voltdbjruby"
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install voltdbjruby
18
+
19
+ Use `jbundler`, `lock_jar` or a similar to download and load the `voltdbclient`
20
+ jar in the CLASSPATH. For example using `jbundler`:
21
+
22
+ echo "jar \"org.voltdb:voltdbclient\", \"6.8\"" > Jarfile
23
+
24
+ Install out java dependencies
25
+
26
+ jruby -S jbundle install
27
+
28
+ Then require `jbundler` in your code to load it in the CLASSPATH
29
+
30
+ require "jbundler"
31
+
32
+ ## Usage
33
+
34
+ ### Basic example
35
+
36
+ ```ruby
37
+ require "voltdb"
38
+
39
+ # Create a config
40
+ config = Voltdb::ClientConfig.new()
41
+
42
+ # Create a client and pass the config
43
+ voltdb_client = Voltdb::Client.create_client(config)
44
+
45
+ # Create a connection
46
+ voltdb_client.create_connection("localhost")
47
+
48
+ # Synchronous example
49
+ response = voltdb_client.call_procedure("SampleProc", 123, "abc")
50
+
51
+ # Asynchronous example
52
+ queued = voltdb_client.call_procedure("SampleProc", 123, "abc") do |response|
53
+ # interact with the async response...
54
+ end
55
+ ```
56
+
57
+ ### Utilities
58
+
59
+ Utilities are a custom addition from Full 360 to DRY things a little and add
60
+ some Ruby idioms.
61
+
62
+ #### ClientResponse utilities
63
+
64
+ ```ruby
65
+ ...
66
+
67
+ User = Struct.new(:id, :name)
68
+
69
+ # Synchronous example
70
+ response = voltdb_client.call_procedure("GetUsers")
71
+
72
+ response.map(0) do |row|
73
+ User.new(row.get_long(0), row.get_string(1))
74
+ end
75
+
76
+ response = voltdb_client.call_procedure("GetUser", 1)
77
+
78
+ response.map_first_row(0) do |row|
79
+ User.new(row.get_long(0), row.get_string(1))
80
+ end
81
+
82
+ # Asynchronous example
83
+ queued = voltdb_client.call_procedure("GetUsers") do |response|
84
+ response.map(0) do |row|
85
+ User.new(row.get_long(0), row.get_string(1))
86
+ end
87
+ end
88
+ ```
89
+
90
+ #### VoltTableRow utilities
91
+
92
+ ```ruby
93
+ User = Struct.new(:id, :name, :active, :created_at)
94
+
95
+ response = voltdb_client.call_procedure("GetUser", 1)
96
+
97
+ response.map_first_row(0) do |row|
98
+ User.new(
99
+ row.get_long(0),
100
+ row.get_string(1),
101
+ row.get_long_as_boolean(2),
102
+ row.get_timestamp_as_ruby_time(3)
103
+ )
104
+ end
105
+ ```
106
+
107
+ ## Development
108
+
109
+ After checking out the repo, run `bin/setup` to install dependencies. You can
110
+ also run `bin/console` for an interactive prompt that will allow you to
111
+ experiment.
112
+
113
+ To install this gem onto your local machine, run `bundle exec rake install`. To
114
+ release a new version, update the version number in `version.rb`, and then run
115
+ `bundle exec rake release`, which will create a git tag for the version, push
116
+ git commits and tags, and push the `.gem` file to
117
+ [rubygems.org](https://rubygems.org).
118
+
119
+ ## Contributing
120
+
121
+ Bug reports and pull requests are welcome on GitHub at
122
+ https://github.com/full360/voltdb-client-jruby. This project is intended to be a
123
+ safe, welcoming space for collaboration, and contributors are expected to adhere
124
+ to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
125
+
126
+ ## License
127
+
128
+ The gem is available as open source under the terms of the [MIT
129
+ License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,5 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ Dir["tasks/**/*.rake"].each { |task| load task }
4
+
5
+ task default: %w(spec)
data/bin/console ADDED
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "voltdb"
5
+ require "pry"
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Create the Jarfile with the voltdbclient
9
+ echo "jar \"org.voltdb:voltdbclient\", \"6.8\"" > Jarfile
10
+ # Install our java dependencies
11
+ jruby -S jbundle install
data/lib/voltdb.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "forwardable"
2
+ require "date"
3
+
4
+ module Voltdb
5
+ autoload :ClientResponseStatusError, "voltdb/exceptions"
6
+ autoload :ClientConfig, "voltdb/client_config"
7
+ autoload :ClientUtils, "voltdb/client_utils"
8
+ autoload :Client, "voltdb/client"
9
+ autoload :ProcCallback, "voltdb/callbacks"
10
+ autoload :BulkLoaderFailureCallback, "voltdb/callbacks"
11
+ autoload :AllPartitionProcCallback, "voltdb/callbacks"
12
+ autoload :ClientResponseUtils, "voltdb/client_response_utils"
13
+ autoload :VoltTableUtils, "voltdb/volt_table_utils"
14
+ autoload :VoltTableRowUtils, "voltdb/volt_table_row_utils"
15
+ autoload :VERSION, "voltdb/version"
16
+ end
@@ -0,0 +1,48 @@
1
+ module Voltdb
2
+ class ProcCallback
3
+ include Java::OrgVoltdbClient::ClientResponse
4
+ include Java::OrgVoltdbClient::ProcedureCallback
5
+
6
+ def initialize(&block)
7
+ @block = block
8
+ end
9
+
10
+ def client_callback(client_response)
11
+ client_response.extend(ClientResponseUtils)
12
+ @block.call(client_response)
13
+ end
14
+ end
15
+
16
+ class BulkLoaderFailureCallback
17
+ java_import "org.voltdb.client.VoltBulkLoader.BulkLoaderFailureCallBack"
18
+ include Java::OrgVoltdbClient::ClientResponse
19
+ include Java::OrgVoltdbClientVoltBulkLoader::BulkLoaderFailureCallBack
20
+
21
+ def initialize(&block)
22
+ @block = block
23
+ end
24
+
25
+ def failure_callback(row_handle, field_list, client_response)
26
+ client_response.extend(ClientResponseUtils)
27
+ @block.call(row_handle, field_list.to_ary, client_response)
28
+ end
29
+ end
30
+
31
+ class AllPartitionProcCallback
32
+ java_import Java::OrgVoltdbClient::ClientResponseWithPartitionKey
33
+ include Java::OrgVoltdbClient::AllPartitionProcedureCallback
34
+
35
+ def initialize(&block)
36
+ @block = block
37
+ end
38
+
39
+ def client_callback(client_response_with_partition_key)
40
+ response = client_response_with_partition_key.map do |partition|
41
+ partition.response.extend(ClientResponseUtils)
42
+ partition
43
+ end
44
+
45
+ @block.call(response)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,198 @@
1
+ module Voltdb
2
+ class Client
3
+ include ClientUtils
4
+ extend Forwardable
5
+
6
+ java_import Java::OrgVoltdbClient::Client
7
+ java_import Java::OrgVoltdbClient::ClientFactory
8
+
9
+ # Persist ClientResponseImpl to avoid the warning when we extend the object
10
+ Java::OrgVoltdb::ClientResponseImpl.__persistent__ = true
11
+
12
+ attr_reader :java_client
13
+
14
+ # Factory of Voltdb::Client
15
+ #
16
+ # @param config Voltdb::ClientConfig
17
+ # @return Voltdb::Client
18
+ def self.create_client(config)
19
+ client = ClientFactory.create_client(config)
20
+
21
+ self.new(client)
22
+ end
23
+
24
+ def initialize(java_client)
25
+ @java_client = java_client
26
+ end
27
+
28
+ # Invokes a voltdb stored procedure based on its procedure name, a list of
29
+ # params and a block only if an asynchronous call is required
30
+ #
31
+ # @param proc_name [String] the stored procedure name
32
+ # @param *params [Array<Object>] a list of params
33
+ # @return [Java::OrgVoltdbClient::ClientResponse, True, False] Voltdb
34
+ # client response if the procedure was called synchronously, else will
35
+ # return true if the procedure was properly queued or false if it was not
36
+ # @raise [ProcCallException, NoConnectionsException, IOException]
37
+ # ProcCallException will be returned if called synchronously
38
+ def call_procedure(proc_name, *params, &block)
39
+ if block_given?
40
+ cb = ProcCallback.new(&block)
41
+ java_client.call_procedure(cb, proc_name, *params_to_java_objects(*params))
42
+ else
43
+ response = java_client.call_procedure(proc_name, *params_to_java_objects(*params))
44
+ response.extend(ClientResponseUtils)
45
+ response
46
+ end
47
+ end
48
+
49
+ # Invokes a voltdb stored procedure with an specific timeout a procedure
50
+ # name, a list of params and a block only if an asynchronous call is
51
+ # required
52
+ #
53
+ # @param query_timeout [Fixnum] the stored procedure timeout
54
+ # @param proc_name [String] the stored procedure name
55
+ # @param *params [Array<Object>] a list of params
56
+ # @return [Java::OrgVoltdbClient::ClientResponse, True, False] Voltdb
57
+ # client response if the procedure was called synchronously, else will
58
+ # return true if the procedure was properly queued or false if it was not
59
+ # @raise [ProcCallException, NoConnectionsException, IOException]
60
+ # ProcCallException will be returned if called synchronously
61
+ def call_procedure_with_timeout(query_timeout, proc_name, *params, &block)
62
+ if block_given?
63
+ cb = ProcCallback.new(&block)
64
+ java_client.call_procedure_with_timeout(cb, query_timeout, proc_name, *params_to_java_objects(*params))
65
+ else
66
+ response = java_client.call_procedure_with_timeout(query_timeout, proc_name, *params_to_java_objects(*params))
67
+ response.extend(ClientResponseUtils)
68
+ response
69
+ end
70
+ end
71
+
72
+ # This method is a convenience method that is equivalent to reading the
73
+ # catalog file into a byte array in Java code, then calling call_procedure
74
+ # with "@UpdateApplicationCatalog" as the procedure name, followed by they
75
+ # bytes of the catalog and the string value of the deployment file. If a
76
+ # block is passed to the method an asyncronous call will be made
77
+ #
78
+ # @param catalog_path [String] the path to the voltdb catalog
79
+ # @param deployment_path [String] deployment_path the path to the
80
+ # deployment.xml file
81
+ # @return [Java::OrgVoltdbClient::ClientResponse, True, False] Voltdb
82
+ # client response if the procedure was called synchronously, else will
83
+ # return true if the procedure was properly queued or false if it was not
84
+ # @raise [ProcCallException, NoConnectionsException, IOException]
85
+ # ProcCallException will be returned if called synchronously
86
+ def update_application_catalog(catalog_path, deployment_path, &block)
87
+ if block_given?
88
+ cb = ProcCallback.new(&block)
89
+ java_client.update_application_catalog(cb, catalog_path, deployment_path)
90
+ else
91
+ response = java_client.update_application_catalog(catalog_path, deployment_path)
92
+ response.extend(ClientResponseUtils)
93
+ response
94
+ end
95
+ end
96
+
97
+ # This method is a convenience method that is equivalent to reading a
98
+ # jarfile containing to be added/updated into a byte array in Java code,
99
+ # then calling call_procedure with "@UpdateClasses" as the procedure name,
100
+ # followed by the bytes of the jarfile and a string containing a
101
+ # comma-separates list of classes to delete from the catalog.If a block is
102
+ # passed to the method an asyncronous call will be made
103
+ #
104
+ # @param jar_path [String] path to the jar file with new/update clases
105
+ # @param classes_to_delete [String,String] comma-separated list of classes
106
+ # to delete
107
+ # @return [Java::OrgVoltdbClient::ClientResponse, True, False] Voltdb
108
+ # client response if the procedure was called synchronously, else will
109
+ # return true if the procedure was properly queued or false if it was not
110
+ # @raise [ProcCallException, NoConnectionsException, IOException]
111
+ # ProcCallException will be returned if called synchronously
112
+ def update_classes(jar_path, classes_to_delete, &block)
113
+ if block_given?
114
+ cb = ProcCallback.new(&block)
115
+ java_client.update_classes(cb, jar_path, classes_to_delete)
116
+ else
117
+ response = java_client.update_classes(jar_path, classes_to_delete)
118
+ response.extend(ClientResponseUtils)
119
+ response
120
+ end
121
+ end
122
+
123
+ # Get an identifier for the cluster that this client is currently connected
124
+ # to. This will be null if the client has not been connected. Currently
125
+ # these values have logical meaning, but they should just be interpreted as
126
+ # a unique per-cluster value
127
+ #
128
+ # @return [Array<Fixnum>] An array of Fixnum containing the millisecond
129
+ # timestamp when the cluster was started and the leader IP address
130
+ def get_instance_id
131
+ java_client.get_instance_id.to_ary
132
+ end
133
+
134
+ # Get the instantaneous values of the rate limiting values for this client
135
+ #
136
+ # @return [Array<Fixnum>] Array of Fixnum representing max throughput/sec
137
+ # and max outstanding txns
138
+ def get_throughput_and_outstanding_txn_limits
139
+ java_client.get_throughput_and_outstanding_txn_limits.to_ary
140
+ end
141
+
142
+ # Get the list of VoltDB server hosts that this client has open TCP
143
+ # connections to
144
+ #
145
+ # @return [Array<InetSocketAddress>] An list of InetSocketAddress
146
+ # representing the connected hosts
147
+ def get_connected_host_list
148
+ java_client.get_connected_host_list.to_ary
149
+ end
150
+
151
+ # Creates a new instance of a VoltBulkLoader that is bound to this Client.
152
+ # Multiple instances of a VoltBulkLoader created by a single Client will
153
+ # share some resources, particularly if they are inserting into the same
154
+ # table
155
+ #
156
+ # @param table_name [String] that bulk inserts are to be applied to
157
+ # @param max_batch_size [Fixnum] to collect for the table before pushing a
158
+ # bulk insert
159
+ # @param [Boolean] upsert true if want upsert instead of insert
160
+ # @return [VoltBulkLoader]
161
+ # @raise [Exception] if tableName can't be found in the catalog
162
+ def get_new_bulk_loader(table_name, max_batch_size, upsert, &block)
163
+ cb = BulkLoaderFailureCallback.new(&block)
164
+
165
+ if upsert
166
+ java_client.get_new_bulk_loader(table_name, max_batch_size, upsert, cb)
167
+ else
168
+ java_client.get_new_bulk_loader(table_name, max_batch_size, cb)
169
+ end
170
+ end
171
+
172
+ # The method uses system procedure @GetPartitionKeys to get a set of
173
+ # partition values and then execute the stored procedure one partition at a
174
+ # time, and return an aggregated response. If a block is passed to the
175
+ # method an asyncronous call will be made
176
+ #
177
+ # @param proc_name [String] proc_name the stored procedure name
178
+ # @param *param [Array<Object>] a list of params
179
+ # @return [ClientResponseWithPartitionKey, True, False] instances of
180
+ # procedure call results
181
+ # @raise [ProcCallException, NoConnectionsException, IOException]
182
+ def call_all_partition_procedure(proc_name, *params, &block)
183
+ if block_given?
184
+ cb = AllPartitionProcCallback.new(&block)
185
+ java_client.call_all_partition_procedure(cb, proc_name, *params_to_java_objects(*params))
186
+ else
187
+ java_client.call_all_partition_procedure(proc_name, *params_to_java_objects(*params)).map do |partition|
188
+ partition.response.extend(ClientResponseUtils)
189
+ partition
190
+ end
191
+ end
192
+ end
193
+
194
+ def_delegators :java_client,
195
+ :create_connection, :drain, :close, :create_stats_context,
196
+ :get_build_string, :write_summary_csv
197
+ end
198
+ end
@@ -0,0 +1,3 @@
1
+ module Voltdb
2
+ class ClientConfig < Java::OrgVoltdbClient::ClientConfig; end
3
+ end
@@ -0,0 +1,85 @@
1
+ module Voltdb
2
+ module ClientResponseUtils
3
+ java_import Java::OrgVoltdbClient::Client
4
+ java_import Java::OrgVoltdbClient::ClientResponse
5
+ java_import Java::OrgVoltdb::VoltTableRow
6
+
7
+ # This method is used for mapping VoltTableRows to an object. It receives
8
+ # the index of the VoltTable that we want to map and a block that will be
9
+ # executed in that context
10
+ #
11
+ # @param client_response [ClientResponseImpl] a voltdb ClientResponse
12
+ # interface implementation
13
+ # @param index [Fixnum] VoltTable index
14
+ # @param validate_status [Boolean] validate status of the client response
15
+ # @yield [VoltTableRow]
16
+ # @return [Array<Object, Object>]
17
+ def self.map_client_response_result(client_response, index, validate_status = true, &block)
18
+ validate_client_response_status(client_response) if (validate_status)
19
+ VoltTableUtils.map_volt_table(client_response.get_results[index], &block)
20
+ end
21
+
22
+ # This method is used for mapping the first row from a VoltTableRow to an
23
+ # object. It receives the index of the VoltTable that we want to map and a
24
+ # block that will be executed in that context
25
+ #
26
+ # @param client_response [ClientResponseImpl] a voltdb ClientResponse
27
+ # interface implementation
28
+ # @param index [Fixnum] VoltTable index
29
+ # @param validate_status [Boolean] validate status of the client response
30
+ # @yield [VoltTableRow]
31
+ # @return [Array<Object>]
32
+ def self.map_first_row_from_client_response_result(client_response, index, validate_status = true, &block)
33
+ validate_client_response_status(client_response) if (validate_status)
34
+ VoltTableUtils.map_first_row_from_volt_table(client_response.get_results[index], &block)
35
+ end
36
+
37
+ # Checks that the status of the client response is SUCCESS. If not, it
38
+ # throws an exception
39
+ #
40
+ # @param client_response [ClientResponseImpl] a voltdb ClientResponse
41
+ # interface implementation
42
+ # @return the same client response passed in when its status is equal to
43
+ # <code>ClientResponse.SUCCESS</code>
44
+ # @raise [ClientResponseStatusError] if the status is not SUCCESS
45
+ def self.validate_client_response_status(client_response)
46
+ unless ClientResponse.SUCCESS == client_response.get_status
47
+ raise ClientResponseStatusError.new(client_response)
48
+ end
49
+
50
+ client_response
51
+ end
52
+
53
+ # This method is used when we extend the Voltdb ClientResponse interface
54
+ # and it's used for mapping VoltTableRows to an object. It receives the
55
+ # index of the VoltTable that we want to map and a block that will be
56
+ # executed in that context
57
+ #
58
+ # @param index [Fixnum] VoltTable index
59
+ # @yield [VoltTableRow]
60
+ # @return [Array<Object, Object>]
61
+ def map(index, validate_status = true, &block)
62
+ ClientResponseUtils.map_client_response_result(self, index, validate_status, &block)
63
+ end
64
+
65
+ # This method is used when we extend the Voltdb ClientResponse interface
66
+ # and it's used for mapping the first row from a VoltTableRow to an object.
67
+ # It receives the index of the VoltTable that we want to map and a block
68
+ # that will be executed in that context
69
+ #
70
+ # @param index [Fixnum] VoltTable index
71
+ # @yield [VoltTableRow]
72
+ # @return [Array<Object>]
73
+ def map_first_row(index, validate_status = true, &block)
74
+ ClientResponseUtils.map_first_row_from_client_response_result(self, index, validate_status, &block)
75
+ end
76
+
77
+ # This method is used when we extend the Voltdb ClientResponse interface
78
+ # and it's used for valitation on the client response
79
+ #
80
+ # @return [client_response]
81
+ def validate_status
82
+ ClientResponseUtils.validate_client_response_status(self)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,39 @@
1
+ module Voltdb
2
+ module ClientUtils
3
+ java_import Java::OrgVoltdbTypes::TimestampType
4
+ java_import Java::OrgVoltdbClient::Client
5
+
6
+ # Transform Ruby objects to Java objects that VoltDB understands
7
+ #
8
+ # @param *params [Array<Object>] list of params
9
+ # @return [Array<JavaObjects>]
10
+ def params_to_java_objects(*params)
11
+ params.map do |param|
12
+ case param
13
+ when DateTime, Date, Time
14
+ TimestampType.new(param.strftime("%F %T.%L"))
15
+ else
16
+ param
17
+ end
18
+ end
19
+ end
20
+
21
+ # Transform a host:port or a host into an array of host and port
22
+ #
23
+ # @param address [String] voltdb server address
24
+ # @param default_port [Fixnum] override the default voltdb server port
25
+ # @return [Array<String, Fixnum>] represents host address and port
26
+ def host_and_port_from_address(address, default_port = Client.VOLTDB_SERVER_PORT)
27
+ s = address.split(":")
28
+
29
+ case s.size
30
+ when 1
31
+ ["#{s[0]}", default_port]
32
+ when 2
33
+ ["#{s[0]}", s[1].to_i]
34
+ else
35
+ ["", 0]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,10 @@
1
+ module Voltdb
2
+ class ClientResponseStatusError < StandardError
3
+ attr_reader :client_response
4
+
5
+ def initialize(client_response, message = "Client response not successful")
6
+ @client_response = client_response
7
+ super(message)
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,3 @@
1
+ module Voltdb
2
+ VERSION = "0.4.0"
3
+ end
@@ -0,0 +1,58 @@
1
+ module Voltdb
2
+ module VoltTableRowUtils
3
+
4
+ # Get a long value from a VoltTableRow as a boolean value
5
+ #
6
+ # @param column_index_or_name [Fixnum, String]
7
+ # @return [Boolean]
8
+ def get_long_as_boolean(column_index_or_name)
9
+ self.get_long(column_index_or_name) == 1
10
+ end
11
+
12
+ # Get the value of the column or nil
13
+ #
14
+ # @param column_index_or_name [Fixnum, String]
15
+ # @return [VoltType, Boolean]
16
+ def get_long_or_nil(column_index_or_name)
17
+ value = self.get_long(column_index_or_name)
18
+
19
+ self.was_null? ? nil : value
20
+ end
21
+
22
+ # Get a Ruby DateTime from a VoltTableRow timestamp type value
23
+ #
24
+ # @param column_index_or_name [Fixnum, String]
25
+ # @return [DateTime]
26
+ def get_timestamp_as_ruby_date_time(column_index_or_name)
27
+ timestamp = get_timestamp_for_ruby(column_index_or_name)
28
+
29
+ timestamp ? DateTime.parse(timestamp.to_s) : timestamp
30
+ end
31
+
32
+ # Get a Ruby Date from a VoltTableRow timestamp type value
33
+ #
34
+ # @param column_index_or_name [Fixnum, String]
35
+ # @return [Date]
36
+ def get_timestamp_as_ruby_date(column_index_or_name)
37
+ timestamp = get_timestamp_for_ruby(column_index_or_name)
38
+
39
+ timestamp ? Date.parse(timestamp.to_s) : timestamp
40
+ end
41
+
42
+ # Get a Ruby Time from a VoltTableRow timestamp type value
43
+ #
44
+ # @param column_index_or_name [Fixnum, String]
45
+ # @return [Time]
46
+ def get_timestamp_as_ruby_time(column_index_or_name)
47
+ timestamp = get_timestamp_for_ruby(column_index_or_name)
48
+
49
+ timestamp ? Time.parse(timestamp.to_s) : timestamp
50
+ end
51
+
52
+ private
53
+
54
+ def get_timestamp_for_ruby(column_index_or_name)
55
+ self.get_timestamp_as_sql_timestamp(column_index_or_name)
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,68 @@
1
+ module Voltdb
2
+ module VoltTableUtils
3
+ java_import Java::OrgVoltdb::VoltTable
4
+ java_import Java::OrgVoltdb::VoltTableRow
5
+
6
+ # Persist VoltTable to avoid the warning when we duplicate the object to
7
+ # extend it
8
+ Java::OrgVoltdb::VoltTable.__persistent__ = true
9
+
10
+ # This method is used when we extend the VoltDB VoltTable interface and
11
+ # it's used to iterate over a VoltTableRow while also adding VoltTableRow
12
+ # Ruby Utils
13
+ #
14
+ # @param volt_table [VoltTable]
15
+ # @yield [VoltTableRow]
16
+ # @return [Array<Object, Object>]
17
+ def self.map_volt_table(volt_table, &block)
18
+ results = []
19
+
20
+ volt_table.reset_row_position
21
+ volt_table.extend(VoltTableRowUtils)
22
+
23
+ while(volt_table.advance_row) do
24
+ results << block.call(volt_table)
25
+ end
26
+
27
+ results
28
+ end
29
+
30
+ # This method is used when we extend the VoltDB VoltTable interface and
31
+ # it's used to iterate over the first row of a VoltTableRow while also
32
+ # adding VoltTableRow Ruby Utils
33
+ #
34
+ # @param volt_table [VoltTable]
35
+ # @yield [VoltTableRow]
36
+ # @return [Object, nil]
37
+ def self.map_first_row_from_volt_table(volt_table, &block)
38
+ volt_table.reset_row_position
39
+ volt_table.extend(VoltTableRowUtils)
40
+
41
+ if(volt_table.advance_row)
42
+ block.call(volt_table)
43
+ else
44
+ nil
45
+ end
46
+ end
47
+
48
+ # This method is used when we extend the VoltDB VoltTable interface and
49
+ # it's used to iterate over a VoltTableRow while also adding VoltTableRow
50
+ # Ruby Utils
51
+ #
52
+ # @yield [VoltTableRow]
53
+ # @return [Array<Object, Object>]
54
+ def map
55
+ VoltTableUtils.map_volt_table(self, &block)
56
+ end
57
+
58
+ # This method is used when we extend the VoltDB VoltTable interface and
59
+ # it's used to iterate over the first row of a VoltTableRow while also
60
+ # adding VoltTableRow Ruby Utils
61
+ #
62
+ # @yield [VoltTableRow]
63
+ # @return [Object, nil]
64
+ def map_first_row
65
+ VoltTableUtils.map_first_row_from_volt_table(self, &block)
66
+ end
67
+ end
68
+ end
data/tasks/rspec.rake ADDED
@@ -0,0 +1,3 @@
1
+ require "rspec/core/rake_task"
2
+
3
+ RSpec::Core::RakeTask.new
data/voltdb.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'voltdb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "voltdbjruby"
8
+ spec.version = Voltdb::VERSION
9
+ spec.authors = ["Alberto Grespan"]
10
+ spec.email = ["alberto@albertogrespan.com"]
11
+
12
+ spec.summary = %q{JRuby VoltDB client wrapper}
13
+ spec.description = %q{JRuby VoltDB java client wrapper}
14
+ spec.homepage = "https://github.com/full360/voltdb-client-jruby"
15
+ spec.license = "MIT"
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
18
+ f.match(%r{^(test|spec|features)/})
19
+ end
20
+ spec.bindir = "exe"
21
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
+ spec.require_paths = ["lib"]
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.13"
25
+ spec.add_development_dependency "rake", "~> 10.0"
26
+ spec.add_development_dependency "pry", "~> 0.10"
27
+ spec.add_development_dependency "rspec", "~> 3.5"
28
+ spec.add_development_dependency "jbundler", "~> 0.9"
29
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: voltdbjruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.4.0
5
+ platform: ruby
6
+ authors:
7
+ - Alberto Grespan
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-03-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.13'
19
+ name: bundler
20
+ prerelease: false
21
+ type: :development
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.13'
27
+ - !ruby/object:Gem::Dependency
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - "~>"
31
+ - !ruby/object:Gem::Version
32
+ version: '10.0'
33
+ name: rake
34
+ prerelease: false
35
+ type: :development
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: '0.10'
47
+ name: pry
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '0.10'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '3.5'
61
+ name: rspec
62
+ prerelease: false
63
+ type: :development
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.5'
69
+ - !ruby/object:Gem::Dependency
70
+ requirement: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '0.9'
75
+ name: jbundler
76
+ prerelease: false
77
+ type: :development
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '0.9'
83
+ description: JRuby VoltDB java client wrapper
84
+ email:
85
+ - alberto@albertogrespan.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - CODE_OF_CONDUCT.md
93
+ - Gemfile
94
+ - LICENSE.txt
95
+ - README.md
96
+ - Rakefile
97
+ - bin/console
98
+ - bin/setup
99
+ - lib/voltdb.rb
100
+ - lib/voltdb/callbacks.rb
101
+ - lib/voltdb/client.rb
102
+ - lib/voltdb/client_config.rb
103
+ - lib/voltdb/client_response_utils.rb
104
+ - lib/voltdb/client_utils.rb
105
+ - lib/voltdb/exceptions.rb
106
+ - lib/voltdb/version.rb
107
+ - lib/voltdb/volt_table_row_utils.rb
108
+ - lib/voltdb/volt_table_utils.rb
109
+ - tasks/rspec.rake
110
+ - voltdb.gemspec
111
+ homepage: https://github.com/full360/voltdb-client-jruby
112
+ licenses:
113
+ - MIT
114
+ metadata: {}
115
+ post_install_message:
116
+ rdoc_options: []
117
+ require_paths:
118
+ - lib
119
+ required_ruby_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ requirements:
126
+ - - ">="
127
+ - !ruby/object:Gem::Version
128
+ version: '0'
129
+ requirements: []
130
+ rubyforge_project:
131
+ rubygems_version: 2.6.11
132
+ signing_key:
133
+ specification_version: 4
134
+ summary: JRuby VoltDB client wrapper
135
+ test_files: []