hbase-jruby 0.1.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+