hbase-jruby 0.1.1-java

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.
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rake/testtask'
3
+ Rake::TestTask.new(:test) do |test|
4
+ test.libs << 'lib' << 'test'
5
+ test.pattern = 'test/**/test_*.rb'
6
+ test.verbose = true
7
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hbase-jruby/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "hbase-jruby"
8
+ gem.version = HBase::JRuby::VERSION
9
+ gem.authors = ["Junegunn Choi"]
10
+ gem.email = ["junegunn.c@gmail.com"]
11
+ gem.description = %q{Ruby-esque interface for accessing HBase from JRuby}
12
+ gem.summary = %q{Ruby-esque interface for accessing HBase from JRuby}
13
+ gem.homepage = "https://github.com/junegunn/hbase-jruby"
14
+ gem.platform = 'java'
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency 'test-unit'
22
+ gem.add_development_dependency 'simplecov'
23
+ end
@@ -0,0 +1,16 @@
1
+ unless RUBY_PLATFORM =~ /java/
2
+ raise LoadError, 'Only supports JRuby'
3
+ end
4
+
5
+ require "hbase-jruby/version"
6
+ require "hbase-jruby/dependency"
7
+ require "hbase-jruby/util"
8
+ require "hbase-jruby/byte_array"
9
+ require "hbase-jruby/column_key"
10
+ require "hbase-jruby/cell"
11
+ require "hbase-jruby/admin"
12
+ require "hbase-jruby/scoped"
13
+ require "hbase-jruby/table"
14
+ require "hbase-jruby/result"
15
+ require 'hbase-jruby/hbase'
16
+
@@ -0,0 +1,29 @@
1
+ require 'thread'
2
+
3
+ class HBase
4
+ module Admin
5
+ private
6
+ def with_admin
7
+ (@admin_mutex ||= Mutex.new).synchronize do
8
+ begin
9
+ admin = HBaseAdmin.new(@config)
10
+ yield admin
11
+ ensure
12
+ admin.close if admin
13
+ end
14
+ end
15
+ end
16
+
17
+ def wait_async_admin admin
18
+ while true
19
+ pair = admin.getAlterStatus(@name.to_java_bytes)
20
+ yet = pair.getFirst
21
+ total = pair.getSecond
22
+
23
+ break if yet == 0
24
+ sleep 1
25
+ end
26
+ end
27
+ end#Admin
28
+ end#HBase
29
+
@@ -0,0 +1,39 @@
1
+ class HBase
2
+ # @private
3
+ class ByteArray
4
+ attr_reader :java
5
+
6
+ def initialize value
7
+ @java = Util.to_bytes value
8
+ end
9
+
10
+ def eql? other
11
+ Arrays.equals(@java, other.java)
12
+ end
13
+ alias == eql?
14
+
15
+ def <=> other
16
+ Bytes.compareTo(@java, other.java)
17
+ end
18
+
19
+ def stopkey_bytes_for_prefix
20
+ arr = @java.to_a
21
+ csr = arr.length - 1
22
+ arr[csr] += 1
23
+ while csr >= 0 && arr[csr] > 127
24
+ csr -= 1
25
+ arr[csr] += 1
26
+ end
27
+ if csr < 0
28
+ nil
29
+ else
30
+ arr[0..csr].to_java(Java::byte)
31
+ end
32
+ end
33
+
34
+ def hash
35
+ Arrays.java_send(:hashCode, [Util::JAVA_BYTE_ARRAY_CLASS], @java)
36
+ end
37
+ end#ByteArray
38
+ end#HBase
39
+
@@ -0,0 +1,122 @@
1
+ class HBase
2
+ # Boxed Ruby class for org.apache.hadoop.hbase.KeyValue
3
+ # @!attribute [r] java
4
+ # @return [org.apache.hadoop.hbase.KeyValue]
5
+ class Cell
6
+ attr_reader :java
7
+
8
+ # Creates a boxed object for a KeyValue object
9
+ # @param [org.apache.hadoop.hbase.KeyValue] key_value
10
+ def initialize key_value
11
+ @java = key_value
12
+ @ck = nil
13
+ end
14
+
15
+ # Returns the rowkey of the cell decoded as the given type
16
+ # @param [Symbol] type The type of the rowkey.
17
+ # Can be one of :string, :symbol, :fixnum, :float, :bignum, :bigdecimal, :boolean and :raw.
18
+ # @return [String, byte[]]
19
+ def rowkey type = :string
20
+ Util.from_bytes type, @java.getRow
21
+ end
22
+
23
+ # Returns the ColumnKey object for the cell
24
+ # @return [ColumnKey]
25
+ def column_key
26
+ @ck ||= ColumnKey.new @java.getFamily, @java.getQualifier
27
+ end
28
+
29
+ # Returns the name of the column family of the cell
30
+ # @return [String]
31
+ def family
32
+ String.from_java_bytes @java.getFamily
33
+ end
34
+ alias cf family
35
+
36
+ # Returns the column qualifier of the cell
37
+ # @param [Symbol] type The type of the qualifier.
38
+ # Can be one of :string, :symbol, :fixnum, :float, :bignum, :bigdecimal, :boolean and :raw.
39
+ # @return [Object]
40
+ def qualifier type = :string
41
+ Util.from_bytes type, @java.getQualifier
42
+ end
43
+ alias cq qualifier
44
+
45
+ # Returns the timestamp of the cell
46
+ # @return [Fixnum]
47
+ def timestamp
48
+ @java.getTimestamp
49
+ end
50
+ alias ts timestamp
51
+
52
+ # Returns the value of the cell as a Java byte array
53
+ # @return [byte[]]
54
+ def value
55
+ @java.getValue
56
+ end
57
+ alias raw value
58
+
59
+ # Returns the column value as a String
60
+ # @return [String]
61
+ def string
62
+ Util.from_bytes :string, value
63
+ end
64
+ alias str string
65
+
66
+ # Returns the column value as a Symbol
67
+ # @return [Symbol]
68
+ def symbol
69
+ Util.from_bytes :symbol, value
70
+ end
71
+ alias sym symbol
72
+
73
+ # Returns the column value as a Fixnum
74
+ # @return [Fixnum]
75
+ def fixnum
76
+ Util.from_bytes :fixnum, value
77
+ end
78
+ alias integer fixnum
79
+ alias int fixnum
80
+
81
+ # Returns the column value as a Bignum
82
+ # @return [Bignum]
83
+ def bignum
84
+ Util.from_bytes :bignum, value
85
+ end
86
+ alias biginteger bignum
87
+ alias bigint bignum
88
+
89
+ # Returns the column value as a BigDecimal
90
+ # @return [BigDecimal]
91
+ def bigdecimal
92
+ Util.from_bytes :bigdecimal, value
93
+ end
94
+
95
+ # Returns the column value as a Float
96
+ # @return [Float]
97
+ def float
98
+ Util.from_bytes :float, value
99
+ end
100
+ alias double float
101
+
102
+ # Returns the column value as a boolean value
103
+ # @return [true, false]
104
+ def boolean
105
+ Util.from_bytes :boolean, value
106
+ end
107
+ alias bool boolean
108
+
109
+ # Implements column key order
110
+ # @param [Cell] other
111
+ # @return [Fixnum] -1, 0, or 1
112
+ def <=> other
113
+ KeyValue.COMPARATOR.compare(@java, other.java)
114
+ end
115
+
116
+ # @return [String]
117
+ def inspect
118
+ %[#{cf}:#{cq} = "#{string}"@#{ts}]
119
+ end
120
+ end#Cell
121
+ end#HBase
122
+
@@ -0,0 +1,63 @@
1
+ class HBase
2
+ class << self
3
+ # Shortcut method to HBase::ColumnKey.new
4
+ # @param [Object] cf Column family
5
+ # @param [Object] cq Column qualifier
6
+ def ColumnKey cf, cq
7
+ ColumnKey.new cf, cq
8
+ end
9
+ end
10
+ # Boxed class for column keys
11
+ class ColumnKey
12
+ attr_reader :cf
13
+ alias family cf
14
+
15
+ # Creates a ColumnKey object
16
+ # @param [Object] cf Column family
17
+ # @param [Object] cq Column qualifier
18
+ def initialize cf, cq
19
+ @cf = String.from_java_bytes Util.to_bytes(cf)
20
+ @cq = Util.to_bytes(cq)
21
+ end
22
+
23
+ # @param [Symbol] type
24
+ def cq type = :string
25
+ Util.from_bytes type, @cq
26
+ end
27
+ alias qualifier cq
28
+
29
+ # @param [Object] other
30
+ def eql? other
31
+ other = other_as_ck(other)
32
+ @cf == other.cf && Arrays.equals(@cq, other.cq(:raw))
33
+ end
34
+ alias == eql?
35
+
36
+ # @param [Object] other
37
+ def <=> other
38
+ other = other_as_ck(other)
39
+ d = @cf <=> other.cf
40
+ d != 0 ? d : Bytes.compareTo(@cq, other.cq(:raw))
41
+ end
42
+
43
+ def hash
44
+ [@cf, Arrays.java_send(:hashCode, [Util::JAVA_BYTE_ARRAY_CLASS], @cq)].hash
45
+ end
46
+
47
+ def to_s
48
+ [@cf, @cq.empty? ? nil : cq].compact.join(':')
49
+ end
50
+
51
+ private
52
+ def other_as_ck other
53
+ case other
54
+ when ColumnKey
55
+ other
56
+ else
57
+ cf, cq = Util.parse_column_name(other)
58
+ ColumnKey.new(cf, cq)
59
+ end
60
+ end
61
+ end#ColumnKey
62
+ end#HBase
63
+
@@ -0,0 +1,69 @@
1
+ require 'java'
2
+ require 'open-uri'
3
+ require 'tempfile'
4
+
5
+ # HBase connection
6
+ class HBase
7
+ class << self
8
+ # Resolve Hadoop and HBase dependency with Maven or hbase command (Experimental)
9
+ # @param [String] dist Distribution version or path to pom.xml file
10
+ # @param [true, false] verbose Verbose output
11
+ # @return [Array<String>] Loaded JAR files
12
+ def resolve_dependency! dist, verbose = false
13
+ silencer = verbose ? '' : '> /dev/null'
14
+ tempfiles = []
15
+ jars =
16
+ if dist == :hbase
17
+ # Check for hbase executable
18
+ hbase = `which hbase`
19
+ raise RuntimeError, "Cannot find executable `hbase`" if hbase.empty?
20
+ `hbase classpath`.split(':')
21
+ else
22
+ # Check for Maven executable
23
+ mvn = `which mvn`
24
+ raise RuntimeError, "Cannot find executable `mvn`" if mvn.empty?
25
+
26
+ distname = dist.downcase.sub(/\.xml$/, '')
27
+ path = [
28
+ File.expand_path("../pom/#{distname}.xml", __FILE__),
29
+ dist.to_s,
30
+ ].select { |f| File.exists? f }.first
31
+
32
+ # Try github head
33
+ unless path
34
+ begin
35
+ xml = open("https://raw.github.com/junegunn/hbase-jruby/master/lib/hbase-jruby/pom/#{distname}.xml").read
36
+ tempfiles << tf = Tempfile.new("#{distname}.xml")
37
+ tf.close(false)
38
+ path = tf.path
39
+ File.open(path, 'w') do |f|
40
+ f << xml
41
+ end
42
+ rescue OpenURI::HTTPError => e
43
+ # No such distribution anywhere
44
+ end
45
+ end
46
+
47
+ raise ArgumentError, "Invalid distribution: #{dist}" unless path
48
+
49
+ # Download dependent JAR files and build classpath string
50
+ tempfiles << tf = Tempfile.new('hbase-jruby-classpath')
51
+ tf.close(false)
52
+ system "mvn org.apache.maven.plugins:maven-dependency-plugin:2.5.1:resolve org.apache.maven.plugins:maven-dependency-plugin:2.5.1:build-classpath -Dsilent=true -Dmdep.outputFile=#{tf.path} -f #{path} #{silencer}"
53
+
54
+ raise RuntimeError.new("Error occurred. Set verbose parameter to see the log.") unless $?.exitstatus == 0
55
+
56
+ File.read(tf.path).split(':')
57
+ end
58
+
59
+ # Load jars
60
+ jars.select { |jar| File.exists?(jar) && File.extname(jar) == '.jar' }.select do |jar|
61
+ require jar
62
+ end
63
+
64
+ Util.import_java_classes!
65
+ ensure
66
+ tempfiles.each { |tempfile| tempfile.unlink rescue nil }
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,77 @@
1
+ require 'java'
2
+
3
+ # @author Junegunn Choi <junegunn.c@gmail.com>
4
+ # @!attribute [r] config
5
+ # @return [org.apache.hadoop.conf.Configuration]
6
+ class HBase
7
+ attr_reader :config
8
+
9
+ include Admin
10
+
11
+ # Connects to HBase
12
+ # @param [Hash] config A key-value pairs to build HBaseConfiguration from
13
+ def initialize config = {}
14
+ Util.import_java_classes!
15
+
16
+ @config =
17
+ case config
18
+ when org.apache.hadoop.conf.Configuration
19
+ config
20
+ else
21
+ HBaseConfiguration.create.tap do |hbcfg|
22
+ config.each do |k, v|
23
+ hbcfg.set k.to_s, v.to_s
24
+ end
25
+ end
26
+ end
27
+ @htable_pool = HTablePool.new @config, java.lang.Integer::MAX_VALUE
28
+ end
29
+
30
+ # Returns an HBaseAdmin object for administration
31
+ # @yield [org.apache.hadoop.hbase.client.HBaseAdmin]
32
+ # @return [org.apache.hadoop.hbase.client.HBaseAdmin]
33
+ def admin
34
+ if block_given?
35
+ with_admin { |admin| yield admin }
36
+ else
37
+ HBaseAdmin.new @config
38
+ end
39
+ end
40
+
41
+ # Closes HTablePool and connection
42
+ # @return [nil]
43
+ def close
44
+ @htable_pool.close
45
+ HConnectionManager.deleteConnection(@config, true)
46
+ end
47
+
48
+ # Returns the list of HBase::Table instances
49
+ # @return [Array<HBase::Table>]
50
+ def tables
51
+ table_names.map { |tn| table(tn) }
52
+ end
53
+
54
+ # Returns the list of table names
55
+ # @return [Array<String>]
56
+ def table_names
57
+ with_admin { |admin| admin.list_tables.map(&:name_as_string) }
58
+ end
59
+
60
+ # Creates HBase::Table instance for the specified name
61
+ # @param [#to_s] table_name The name of the table
62
+ # @return [HBase::Table]
63
+ def table table_name
64
+ ht = HBase::Table.send :new, @config, @htable_pool, table_name
65
+
66
+ if block_given?
67
+ begin
68
+ yield ht
69
+ ensure
70
+ ht.close
71
+ end
72
+ else
73
+ ht
74
+ end
75
+ end
76
+ end
77
+