jvertica 0.0.1

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: 2e6da18153fa70023014d8a66ec2980b8daa7b00
4
+ data.tar.gz: b8491ddb36584fe748447c52c9cf4aabcde572af
5
+ SHA512:
6
+ metadata.gz: f26634201be35948073aa79471cf0e74a12fc000877133627256980a1d09e3f2d5a9a4f39e72ae4424b49712853bd51431c4ec9e6d430b8a68e61b8386b2a9f4
7
+ data.tar.gz: 4f28345e2eb54e0a2b11bfc091cdf19ebdcf507d107cf5858e6793897a5e4e3e1238b625eb4f16497ea817e799a11ca5d09d7fcb9c709fbe2c80d941115efca9
data/.gitignore ADDED
@@ -0,0 +1,15 @@
1
+ /.yardoc
2
+ /Gemfile.lock
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ *.bundle
10
+ *.so
11
+ *.o
12
+ *.a
13
+ mkmf.log
14
+ example
15
+ vendor
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ jruby-1.7.16
data/.travis.yml ADDED
@@ -0,0 +1,3 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.4
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jdbc-vertica-more.gemspec
4
+ gemspec
5
+
6
+ gem 'sequel'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 takahiro.nakayama
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Jvertica
2
+
3
+ jvertica presents wrapper methods of jdbc-vertica java native methods.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'jvertica'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install jvertica
20
+
21
+ ## Usage
22
+
23
+ ```ruby
24
+ require 'jvertica'
25
+
26
+ conn_opts = {
27
+ host: 'vertica.com',
28
+ port: 5433,
29
+ user: 'xxxxxx',
30
+ password: 'xxxxxx',
31
+ }
32
+
33
+ sql = 'select * from sandbox.jdbc_tests;'
34
+
35
+ c = Jvertica.connect conn_opts
36
+ c.query sql do |row|
37
+ p row
38
+ end
39
+ ```
40
+
41
+ ## Connection Options
42
+
43
+ see [the url](http://my.vertica.com/docs/7.1.x/HTML/index.htm#Authoring/ProgrammersGuide/ClientJDBC/JDBCConnectionProperties.htm)
44
+
45
+
46
+ ## Loading data into Vertica using COPY
47
+
48
+ ```ruby
49
+ connection.copy("COPY table FROM STDIN ...") do |stdin|
50
+ File.open('data.tsv', 'r') do |f|
51
+ begin
52
+ stdin << f.gets
53
+ end until f.eof?
54
+ end
55
+ end
56
+ ```
57
+
58
+ ## Contributing
59
+
60
+ 1. Fork it ( https://github.com/[my-github-username]/jvertica/fork )
61
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
62
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
63
+ 4. Push to the branch (`git push origin my-new-feature`)
64
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
7
+
data/jvertica.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jvertica/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "jvertica"
8
+ spec.version = Jvertica::VERSION
9
+ spec.authors = ["takahiro.nakayama"]
10
+ spec.email = ["civitaspo@gmail.com"]
11
+ spec.summary = %q{jvertica}
12
+ spec.description = %q{jvertica presents wrapper methods of jdbc-vertica java native methods.}
13
+ spec.homepage = "https://github.com/civitaspo/jvertica"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ spec.add_development_dependency "rspec"
24
+
25
+ spec.add_dependency "jdbc-vertica"
26
+ end
@@ -0,0 +1,3 @@
1
+ class Jvertica
2
+ VERSION = "0.0.1"
3
+ end
data/lib/jvertica.rb ADDED
@@ -0,0 +1,390 @@
1
+ require 'java'
2
+ require 'jvertica/version'
3
+ require 'jdbc-vertica'
4
+ require Jdbc::Vertica.driver_jar
5
+
6
+ class Jvertica
7
+ unless %r{java} === RUBY_PLATFORM
8
+ warn "only for use with JRuby"
9
+ end
10
+
11
+ @@default_option_value = {
12
+ host: 'localhost',
13
+ port: 5433,
14
+ database: 'vdb',
15
+ password: '',
16
+ user: 'dbadmin',
17
+ AutoCommit: false,
18
+ }
19
+
20
+ def self.connect options = {}
21
+ new options
22
+ end
23
+
24
+ attr_reader :host, :port, :database
25
+
26
+ def initialize options
27
+ options = @@default_option_value.merge(options).to_sym
28
+ @host = options[:host]
29
+ @port = options[:port]
30
+ @database = options[:database]
31
+ %w(:host :port :database).map do |key|
32
+ options.delete key
33
+ end
34
+
35
+ prop = Properties.new
36
+ options.each do |key, value|
37
+ prop.put key.to_s, value
38
+ end
39
+
40
+ @connection = begin
41
+ DriverManager.getConnection "jdbc:vertica://#{host}:#{port}/#{database}", prop
42
+ rescue => e
43
+ raise ConnectionError.new("Connection Failed.\n" +
44
+ "Error Message => #{e.message}\n" +
45
+ "see documentation => #{@@connection_property_document_url}\n")
46
+ end
47
+ end
48
+
49
+ def close
50
+ @connection.close
51
+ end
52
+
53
+ def commit
54
+ @connection.commit
55
+ end
56
+
57
+ #def prepare query
58
+ # @pstmt = @connection.prepareStatement query
59
+ #end
60
+
61
+ #def prepared?
62
+ # @pstmt.present?
63
+ #end
64
+
65
+ #def execute *args, &blk
66
+ # TODO
67
+ #end
68
+
69
+ def property key, value = nil
70
+ key = key.to_s
71
+ if value.nil?
72
+ @connection.getProperty key
73
+ else
74
+ @connection.setProperty key, value
75
+ end
76
+ end
77
+
78
+ def query query, &blk
79
+ stmt = @connection.createStatement
80
+ case query
81
+ when %r{\A\s*copy}miu then raise InvalidQuery.new('cannot use "copy".')
82
+ when %r{\A\s*insert}miu then return stmt.executeUpdate query
83
+ when %r{\A\s*update}miu then return stmt.executeUpdate query
84
+ when %r{\A\s*delete}miu then return stmt.executeUpdate query
85
+ when %r{\A\s*drop}miu then return stmt.execute query
86
+ when %r{\A\s*create}miu then return stmt.execute query
87
+ else rs = stmt.executeQuery query
88
+ end
89
+
90
+ if block_given?
91
+ ResultSet.new(rs).each do |row|
92
+ yield row
93
+ end
94
+ else
95
+ ResultSet.new rs
96
+ end
97
+ end
98
+
99
+ def copy query, source = nil, &blk
100
+ raise InvalidQuery.new('can use only "copy".') unless %r{\A\s*copy}miu === query
101
+ stream = com.vertica.jdbc.VerticaCopyStream.new @connection, query
102
+ stream.start
103
+ begin
104
+ if !source.nil?
105
+
106
+ if source.is_a? IO
107
+ stream.addStream org.jruby.util.IOInputStream.new(source)
108
+ else
109
+ raise InvalidObject.new("source must be a IO.")
110
+ end
111
+
112
+ elsif block_given?
113
+ rio, wio = IO.pipe
114
+ begin
115
+ yield(wio)
116
+ stream.addStream org.jruby.util.IOInputStream.new(rio)
117
+ rescue => e
118
+ raise e
119
+ ensure
120
+ wio.close
121
+ rio.close
122
+ end
123
+
124
+ end
125
+ rescue => e
126
+ r = stream.finish
127
+ raise e.class.new("[affected rows: #{r}] #{e.message}")
128
+ end
129
+
130
+ begin
131
+ stream.execute
132
+ results = stream.finish
133
+ rescue => e
134
+ raise e
135
+ end
136
+
137
+ results
138
+ end
139
+
140
+ private
141
+ class ConnectionError < StandardError
142
+ end
143
+
144
+ class InvalidQuery < StandardError
145
+ end
146
+
147
+ class InvalidObject < StandardError
148
+ end
149
+
150
+ class InsufficientArgument < StandardError
151
+ end
152
+
153
+ class ResultSet
154
+ include Enumerable
155
+
156
+ def each
157
+ return enum_for(:each) unless block_given?
158
+ return if closed?
159
+
160
+ while @nrow
161
+ idx = 0
162
+ row = Jvertica::Row.new(
163
+ @col_labels,
164
+ @col_labels_d,
165
+ @getters.map{|gt|
166
+ case gt
167
+ when :getBigNum
168
+ v = @rset.getBigDecimal idx+=1
169
+ @rset.was_null ? nil : v.toPlainString.to_i
170
+ when :getBigDecimal
171
+ v = @rset.getBigDecimal idx+=1
172
+ @rset.was_null ? nil : BigDecimal.new(v.toPlainString)
173
+ else
174
+ v = @rset.send gt, idx+=1
175
+ @rset.was_null ? nil : v
176
+ end
177
+ },
178
+ @rownum += 1
179
+ )
180
+ close unless @nrow = @rset.next
181
+ yield row
182
+ end
183
+ close
184
+ end
185
+
186
+ def close
187
+ return if closed?
188
+
189
+ @rset.close
190
+ @close_callback.call if @close_callback
191
+ @closed = true
192
+ end
193
+
194
+ def closed?
195
+ @closed
196
+ end
197
+
198
+ def initialize rset, &close_callback
199
+ unless rset.respond_to? :get_meta_data
200
+ rset.close if rset
201
+ @closed = true
202
+ return
203
+ end
204
+
205
+ @close_callback = close_callback
206
+ @rset = rset
207
+ @rsmd = @rset.get_meta_data
208
+ @num_col = @rsmd.get_column_count
209
+ @getters = []
210
+ @col_labels = []
211
+ @col_labels_d = []
212
+ (1..@num_col).each do |i|
213
+ type = @rsmd.get_column_type i
214
+
215
+ @getters <<
216
+ case type
217
+ when java.sql.Types::NUMERIC, java.sql.Types::DECIMAL
218
+ precision = @rsmd.get_precision i
219
+ scale = @rsmd.get_scale i
220
+
221
+ if precision > 0 and scale >= 0
222
+ if scale > 0 then :getBigDecimal
223
+ else
224
+
225
+ if precision <= 9 then :getInt
226
+ elsif precision <= 18 then :getLong
227
+ else :getBigNum
228
+ end
229
+
230
+ end
231
+ else :getBigDecimal
232
+ end
233
+
234
+ else Jvertica::Constant::GETTER_MAP.fetch type, :get_string
235
+ end
236
+
237
+ label = @rsmd.get_column_label i
238
+ @col_labels << label
239
+ @col_labels_d << label.downcase
240
+ end
241
+
242
+ @rownum = -1
243
+ @nrow = @rset.next
244
+ @closed = false
245
+ end
246
+ end
247
+
248
+ class Row
249
+ attr_reader :labels, :values, :rownum
250
+ alias_method :keys, :labels
251
+
252
+ include Enumerable
253
+
254
+ def [] *idx
255
+ return @values[*idx] if idx.length > 1
256
+
257
+ idx = idx.first
258
+ case idx
259
+ when Fixnum
260
+ raise RangeError.new("Index out of bound") if idx >= @values.length
261
+ @values[idx]
262
+ when String, Symbol
263
+ vidx = @labels_d.index(idx.to_s.downcase) or
264
+ raise NameError.new("Unknown column label: #{idx}")
265
+ @values[vidx]
266
+ else
267
+ @values[idx]
268
+ end
269
+ end
270
+
271
+ def each(&blk)
272
+ @values.each do |v|
273
+ yield v
274
+ end
275
+ end
276
+
277
+ def inspect
278
+ strs = []
279
+ @labels.each do |col|
280
+ strs << "#{col}: #{self[col] || '(null)'}"
281
+ end
282
+ '[' + strs.join(', ') + ']'
283
+ end
284
+
285
+ def to_a
286
+ @values
287
+ end
288
+
289
+ def join sep = $OUTPUT_FIELD_SEPARATOR
290
+ to_a.join sep
291
+ end
292
+
293
+ def eql? other
294
+ self.hash == other.hash
295
+ end
296
+
297
+ def hash
298
+ @labels.zip(@values).sort.hash
299
+ end
300
+
301
+ def to_h
302
+ Hash[@labels.zip @values]
303
+ end
304
+
305
+ alias :== :eql?
306
+
307
+ def initialize col_labels, col_labels_d, values, rownum
308
+ @labels = col_labels
309
+ @labels_d = col_labels_d
310
+ @values = values
311
+ @rownum = rownum
312
+ end
313
+
314
+ def method_missing symb, *args
315
+ if vidx = @labels_d.index(symb.to_s.downcase)
316
+ @values[vidx]
317
+ elsif @values.respond_to? symb
318
+ @values.send symb, *args
319
+ else
320
+ raise NoMethodError.new("undefined method or attribute `#{symb}'")
321
+ end
322
+ end
323
+
324
+ [:id, :tap, :gem, :display, :class, :method, :methods, :trust].select do |s|
325
+ method_defined? s
326
+ end.each do |m|
327
+ undef_method m
328
+ end
329
+ end
330
+
331
+ class DriverManager < java.sql.DriverManager
332
+ end
333
+
334
+ class Properties < java.util.Properties
335
+ end
336
+
337
+ class DataSource < com.vertica.jdbc.DataSource
338
+ end
339
+
340
+ module Constant
341
+ CONNECTION_PROPERTY_DOCUMENT_URL =
342
+ 'http://my.vertica.com/docs/7.1.x/HTML/index.htm#Authoring/ProgrammersGuide/ClientJDBC/JDBCConnectionProperties.htm'
343
+
344
+ RUBY_SQL_TYPE_MAP = {
345
+ Fixnum => java.sql.Types::INTEGER,
346
+ Bignum => java.sql.Types::BIGINT,
347
+ String => java.sql.Types::VARCHAR,
348
+ Float => java.sql.Types::DOUBLE,
349
+ Time => java.sql.Types::TIMESTAMP
350
+ }
351
+ GETTER_MAP = {
352
+ java.sql.Types::TINYINT => :getInt,
353
+ java.sql.Types::SMALLINT => :getInt,
354
+ java.sql.Types::INTEGER => :getInt,
355
+ java.sql.Types::BIGINT => :getLong,
356
+ java.sql.Types::CHAR => :getString,
357
+ java.sql.Types::VARCHAR => :getString,
358
+ java.sql.Types::LONGVARCHAR => :getString,
359
+ (java.sql.Types::NCHAR rescue nil) => :getString,
360
+ (java.sql.Types::NVARCHAR rescue nil) => :getString,
361
+ (java.sql.Types::LONGNVARCHAR rescue nil) => :getString,
362
+ java.sql.Types::BINARY => :getBinaryStream,
363
+ java.sql.Types::VARBINARY => :getBinaryStream,
364
+ java.sql.Types::LONGVARBINARY => :getBinaryStream,
365
+ java.sql.Types::REAL => :getDouble,
366
+ java.sql.Types::FLOAT => :getFloat,
367
+ java.sql.Types::DOUBLE => :getDouble,
368
+ java.sql.Types::DATE => :getDate,
369
+ java.sql.Types::TIME => :getTime,
370
+ java.sql.Types::TIMESTAMP => :getTimestamp,
371
+ java.sql.Types::BLOB => :getBlob,
372
+ java.sql.Types::CLOB => :getString,
373
+ (java.sql.Types::NCLOB rescue nil) => :getString,
374
+ java.sql.Types::BOOLEAN => :getBoolean
375
+ }
376
+ end
377
+ end
378
+
379
+ class Hash
380
+ def to_sym
381
+ self.inject self.class.new do |h, (k, v)|
382
+ h[k.to_sym] = if v.is_a? self.class
383
+ v.to_sym
384
+ else
385
+ v
386
+ end
387
+ h
388
+ end
389
+ end
390
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe Jvertica do
4
+ it 'has a version number' do
5
+ expect(Jvertica::VERSION).not_to be nil
6
+ end
7
+
8
+ it 'does something useful' do
9
+ expect(false).to eq(true)
10
+ end
11
+ end
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'jvertica'
metadata ADDED
@@ -0,0 +1,115 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jvertica
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - takahiro.nakayama
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-11-19 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.7'
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.7'
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'
47
+ name: rspec
48
+ prerelease: false
49
+ type: :development
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ name: jdbc-vertica
62
+ prerelease: false
63
+ type: :runtime
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: jvertica presents wrapper methods of jdbc-vertica java native methods.
70
+ email:
71
+ - civitaspo@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - .ruby-version
79
+ - .travis.yml
80
+ - Gemfile
81
+ - LICENSE.txt
82
+ - README.md
83
+ - Rakefile
84
+ - jvertica.gemspec
85
+ - lib/jvertica.rb
86
+ - lib/jvertica/version.rb
87
+ - spec/jvertica_spec.rb
88
+ - spec/spec_helper.rb
89
+ homepage: https://github.com/civitaspo/jvertica
90
+ licenses:
91
+ - MIT
92
+ metadata: {}
93
+ post_install_message:
94
+ rdoc_options: []
95
+ require_paths:
96
+ - lib
97
+ required_ruby_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ required_rubygems_version: !ruby/object:Gem::Requirement
103
+ requirements:
104
+ - - '>='
105
+ - !ruby/object:Gem::Version
106
+ version: '0'
107
+ requirements: []
108
+ rubyforge_project:
109
+ rubygems_version: 2.1.9
110
+ signing_key:
111
+ specification_version: 4
112
+ summary: jvertica
113
+ test_files:
114
+ - spec/jvertica_spec.rb
115
+ - spec/spec_helper.rb