hbase-jruby 0.1.6-java → 0.2.0-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,109 @@
1
+ class HBase
2
+ class Table
3
+ # Returns a read-only org.apache.hadoop.hbase.HTableDescriptor object
4
+ # @return [org.apache.hadoop.hbase.client.UnmodifyableHTableDescriptor]
5
+ def descriptor
6
+ htable.get_table_descriptor
7
+ end
8
+
9
+ # Returns table properties
10
+ # @return [Hash]
11
+ def properties
12
+ desc = descriptor
13
+ {}.tap { |props|
14
+ TABLE_PROPERTIES.each do |prop, gs|
15
+ get = gs[:get]
16
+ if get && desc.respond_to?(get)
17
+ props[prop] = parse_property desc.send get
18
+ end
19
+ end
20
+ }
21
+ end
22
+
23
+ # Returns raw String-to-String map of table properties
24
+ # @return [Hash]
25
+ def raw_properties
26
+ parse_raw_map descriptor.values
27
+ end
28
+
29
+ # Returns properties of column families indexed by family name
30
+ # @return [Hash]
31
+ def families
32
+ {}.tap { |ret|
33
+ descriptor.families.each do |family|
34
+ name = family.name_as_string
35
+ ret[name] =
36
+ {}.tap { |props|
37
+ COLUMN_PROPERTIES.each do |prop, gs|
38
+ get = gs[:get]
39
+ if get && family.respond_to?(get)
40
+ props[prop] = parse_property family.send get
41
+ end
42
+ end
43
+ }
44
+ end
45
+ }
46
+ end
47
+
48
+ # Returns raw String-to-String map of column family properties indexed by name
49
+ # @return [Hash]
50
+ def raw_families
51
+ {}.tap { |ret|
52
+ descriptor.families.each do |family|
53
+ name = family.name_as_string
54
+ ret[name] = parse_raw_map family.values
55
+ end
56
+ }
57
+ end
58
+
59
+ # Returns region information
60
+ # @return [Hash]
61
+ def regions
62
+ with_admin do |admin|
63
+ _regions admin
64
+ end
65
+ end
66
+
67
+ # Returns a printable version of the table description
68
+ # @return [String] Table description
69
+ def inspect
70
+ if exists?
71
+ descriptor.toStringCustomizedValues
72
+ else
73
+ # FIXME
74
+ "{NAME => '#{@name}'}"
75
+ end
76
+ end
77
+
78
+ private
79
+ def _regions admin
80
+ admin.getTableRegions(@name.to_java_bytes).map { |ri|
81
+ {}.tap { |r|
82
+ r[:name] = ri.region_name
83
+ r[:id] = ri.region_id
84
+ r[:start_key] = nil_if_empty ri.start_key
85
+ r[:end_key] = nil_if_empty ri.end_key
86
+ r[:root] = ri.is_root_region
87
+ r[:meta] = ri.is_meta_region
88
+ r[:online] = !ri.is_offline
89
+ }
90
+ }
91
+ end
92
+
93
+ def nil_if_empty v
94
+ v.empty? ? nil : v
95
+ end
96
+
97
+ def parse_property v
98
+ if v.is_a?(java.lang.Enum)
99
+ v.to_s
100
+ else
101
+ v
102
+ end
103
+ end
104
+
105
+ def parse_raw_map m
106
+ Hash[ m.keys.map { |e| e.get.to_s }.zip m.values.map { |e| e.get.to_s } ]
107
+ end
108
+ end#Table
109
+ end#HBase
@@ -13,234 +13,27 @@ class Table
13
13
  include Enumerable
14
14
  include Admin
15
15
  include Scoped::Aggregation::Admin
16
+ include HBase::Util
16
17
 
17
- # Returns a read-only org.apache.hadoop.hbase.HTableDescriptor object
18
- # @return [org.apache.hadoop.hbase.client.UnmodifyableHTableDescriptor]
19
- def descriptor
20
- htable.get_table_descriptor
18
+ # (INTERNAL) Returns the underlying org.apache.hadoop.hbase.client.HTable object (local to current thread)
19
+ # @return [org.apache.hadoop.hbase.client.HTable]
20
+ def htable
21
+ check_closed
22
+
23
+ local_htables = Thread.current[:htable] ||= {}
24
+ local_htables[@name] ||= @pool.get_table(@name)
21
25
  end
22
26
 
23
- # Closes the table and returns HTable object back to the HTablePool.
27
+ # @deprecated
24
28
  # @return [nil]
25
29
  def close
26
- Thread.current[:htable] ||= {}
27
- ht = Thread.current[:htable].delete(@name)
28
- ht.close if ht
29
30
  nil
30
31
  end
31
32
 
32
- # Checks if the table of the name exists
33
- # @return [true, false] Whether table exists
34
- def exists?
35
- with_admin { |admin| admin.tableExists @name }
36
- end
37
-
38
- # Checks if the table is enabled
39
- # @return [true, false] Whether table is enabled
40
- def enabled?
41
- with_admin { |admin| admin.isTableEnabled(@name) }
42
- end
43
-
44
- # Checks if the table is disabled
45
- # @return [true, false] Whether table is disabled
46
- def disabled?
47
- !enabled?
48
- end
49
-
50
- # Creates the table
51
- # @overload create!(column_family_name, props = {})
52
- # Create the table with one column family of the given name
53
- # @param [#to_s] The name of the column family
54
- # @param [Hash] props Table properties
55
- # @return [nil]
56
- # @overload create!(column_family_hash, props = {})
57
- # Create the table with the specified column families
58
- # @param [Hash] Column family properties
59
- # @param [Hash] props Table properties
60
- # @return [nil]
61
- # @example
62
- # table.create!(
63
- # # Column family with default options
64
- # :cf1 => {},
65
- # # Another column family with custom properties
66
- # :cf2 => {
67
- # :blockcache => true,
68
- # :blocksize => 128 * 1024,
69
- # :bloomfilter => :row,
70
- # :compression => :snappy,
71
- # :in_memory => true,
72
- # :keep_deleted_cells => true,
73
- # :min_versions => 2,
74
- # :replication_scope => 0,
75
- # :ttl => 100,
76
- # :versions => 5
77
- # }
78
- # )
79
- # @overload create!(table_descriptor)
80
- # Create the table with the given HTableDescriptor
81
- # @param [org.apache.hadoop.hbase.HTableDescriptor] Table descriptor
82
- # @return [nil]
83
- def create! desc, props = {}
84
- todo = nil
85
- with_admin do |admin|
86
- raise RuntimeError, 'Table already exists' if admin.tableExists(@name)
87
-
88
- case desc
89
- when HTableDescriptor
90
- patch_table_descriptor! desc, props
91
- admin.createTable desc
92
- when Symbol, String
93
- todo = lambda { create!({desc => {}}, props) }
94
- when Hash
95
- htd = HTableDescriptor.new(@name.to_java_bytes)
96
- patch_table_descriptor! htd, props
97
- desc.each do |name, opts|
98
- htd.addFamily hcd(name, opts)
99
- end
100
-
101
- admin.createTable htd
102
- else
103
- raise ArgumentError, 'Invalid table description'
104
- end
105
- end
106
- todo.call if todo # Avoids mutex relocking
107
- end
108
-
109
- # Alters the table (synchronous)
110
- # @param [Hash] props Table properties
111
- # @return [nil]
112
- # @example
113
- # table.alter!(
114
- # :max_filesize => 512 * 1024 ** 2,
115
- # :memstore_flushsize => 64 * 1024 ** 2,
116
- # :readonly => false,
117
- # :deferred_log_flush => true
118
- # )
119
- def alter! props, &block
120
- _alter props, true, &block
121
- end
122
-
123
- # Alters the table (asynchronous)
124
- # @see HBase::Table#alter!
125
- def alter props
126
- _alter props, false
127
- end
128
-
129
- # Adds the column family (synchronous)
130
- # @param [#to_s] name The name of the column family
131
- # @param [Hash] opts Column family properties
132
- # @return [nil]
133
- def add_family! name, opts, &block
134
- _add_family name, opts, true, &block
135
- end
136
-
137
- # Adds the column family (asynchronous)
138
- # @see HBase::Table#add_family!
139
- def add_family name, opts
140
- _add_family name, opts, false
141
- end
142
-
143
- # Alters the column family
144
- # @param [#to_s] name The name of the column family
145
- # @param [Hash] opts Column family properties
146
- # @return [nil]
147
- def alter_family! name, opts, &block
148
- _alter_family name, opts, true, &block
149
- end
150
-
151
- # Alters the column family (asynchronous)
152
- # @see HBase::Table#alter_family!
153
- def alter_family name, opts
154
- _alter_family name, opts, false
155
- end
156
-
157
- # Removes the column family
158
- # @param [#to_s] name The name of the column family
159
- # @return [nil]
160
- def delete_family! name, &block
161
- _delete_family name, true, &block
162
- end
163
-
164
- # Removes the column family (asynchronous)
165
- # @see HBase::Table#delete_family!
166
- def delete_family name
167
- _delete_family name, false
168
- end
169
-
170
- # Adds the table coprocessor to the table
171
- # @param [String] class_name Full class name of the coprocessor
172
- # @param [Hash] props Coprocessor properties
173
- # @option props [String] path The path of the JAR file
174
- # @option props [Fixnum] priority Coprocessor priority
175
- # @option props [Hash<#to_s, #to_s>] params Arbitrary key-value parameter pairs passed into the coprocessor
176
- def add_coprocessor! class_name, props = {}, &block
177
- _add_coprocessor class_name, props, true, &block
178
- end
179
-
180
- # Adds the table coprocessor to the table (asynchronous)
181
- def add_coprocessor class_name, props = {}
182
- _add_coprocessor class_name, props, false
183
- end
184
-
185
- # Removes the coprocessor from the table.
186
- # @param [String] class_name Full class name of the coprocessor
187
- # @return [nil]
188
- def remove_coprocessor! class_name, &block
189
- _remove_coprocessor class_name, true, &block
190
- end
191
-
192
- # Removes the coprocessor from the table (asynchronous)
193
- # @see HBase::Table#remove_coprocessor!
194
- def remove_coprocessor class_name
195
- _remove_coprocessor class_name, false
196
- end
197
-
198
- # Return if the table has the coprocessor of the given class name
199
- # @param [String] class_name Full class name of the coprocessor
200
- # @return [true, false]
201
- def has_coprocessor? class_name
202
- descriptor.hasCoprocessor(class_name)
203
- end
204
-
205
- # Enables the table
206
- # @return [nil]
207
- def enable!
208
- with_admin do |admin|
209
- admin.enableTable @name unless admin.isTableEnabled(@name)
210
- end
211
- end
212
-
213
- # Disables the table
214
- # @return [nil]
215
- def disable!
216
- with_admin do |admin|
217
- admin.disableTable @name if admin.isTableEnabled(@name)
218
- end
219
- end
220
-
221
- # Truncates the table by dropping it and recreating it.
222
- # @return [nil]
223
- def truncate!
224
- htd = htable.get_table_descriptor
225
- drop!
226
- create! htd
227
- end
228
-
229
- # Drops the table
230
- # @return [nil]
231
- def drop!
232
- with_admin do |admin|
233
- raise RuntimeError, 'Table does not exist' unless admin.tableExists @name
234
-
235
- admin.disableTable @name if admin.isTableEnabled(@name)
236
- admin.deleteTable @name
237
- close
238
- end
239
- end
240
-
241
33
  [:get, :count, :aggregate,
242
34
  :range, :project, :filter, :while,
243
- :limit, :versions, :caching, :batch
35
+ :limit, :versions, :caching, :batch,
36
+ :time_range, :at
244
37
  ].each do |method|
245
38
  define_method(method) do |*args|
246
39
  self.each.send(method, *args)
@@ -286,11 +79,11 @@ class Table
286
79
  # @return [nil]
287
80
  # @example
288
81
  # table.delete('a000', 'cf1:col1')
289
- # @overload delete(rowkey, column, timestamp)
290
- # Deletes a version of a column
82
+ # @overload delete(rowkey, column, *timestamps)
83
+ # Deletes specified versions of a column
291
84
  # @param [Object] rowkey
292
85
  # @param [String, Array] column Column expression in String "FAMILY:QUALIFIER", or in Array [FAMILY, QUALIFIER]
293
- # @param [Fixnum] timestamp Timestamp.
86
+ # @param [*Fixnum] timestamps Timestamps.
294
87
  # @return [nil]
295
88
  # @example
296
89
  # table.delete('a000', 'cf1:col1', 1352978648642)
@@ -314,7 +107,7 @@ class Table
314
107
  Delete.new(Util.to_bytes rowkey).tap { |del|
315
108
  if !ts.empty?
316
109
  ts.each do |t|
317
- del.deleteColumn cf, cq, t
110
+ del.deleteColumn cf, cq, time_to_long(t)
318
111
  end
319
112
  elsif cq
320
113
  # Delete all versions
@@ -358,9 +151,12 @@ class Table
358
151
  end
359
152
 
360
153
  # Scan through the table
361
- # @yield [HBase::Result] Yields each row in the scope
154
+ # @yield [row] Yields each row in the scope
155
+ # @yieldparam [HBase::Result] row
362
156
  # @return [HBase::Scoped]
363
157
  def each
158
+ check_closed
159
+
364
160
  if block_given?
365
161
  Scoped.send(:new, self).each { |r| yield r }
366
162
  else
@@ -368,40 +164,16 @@ class Table
368
164
  end
369
165
  end
370
166
 
371
- # Returns the underlying org.apache.hadoop.hbase.client.HTable object (local to current thread)
372
- # @return [org.apache.hadoop.hbase.client.HTable]
373
- def htable
374
- # @htable ||= @pool.get_table(@name)
375
- (local_htables = Thread.current[:htable] ||= {})[@name] ||
376
- (local_htables[@name] = @pool.get_table(@name))
377
- end
378
-
379
- # Returns a printable version of the table description
380
- # @return [String] Table description
381
- def inspect
382
- if exists?
383
- htable.get_table_descriptor.to_s
384
- else
385
- # FIXME
386
- "{NAME => '#{@name}'}"
387
- end
388
- end
389
-
390
167
  private
391
- def initialize config, htable_pool, name
392
- @config = config
393
- @pool = htable_pool
394
- @name = name.to_s
395
- @htable = nil
168
+ def initialize hbase, config, htable_pool, name
169
+ @hbase = hbase
170
+ @config = config
171
+ @pool = htable_pool
172
+ @name = name.to_s
396
173
  end
397
174
 
398
- def while_disabled admin
399
- begin
400
- admin.disableTable @name if admin.isTableEnabled(@name)
401
- yield
402
- ensure
403
- admin.enableTable @name
404
- end
175
+ def check_closed
176
+ raise RuntimeError, "HBase connection is already closed" if @hbase.closed?
405
177
  end
406
178
 
407
179
  def putify rowkey, props
@@ -412,9 +184,9 @@ private
412
184
  when Hash
413
185
  val.each do |t, v|
414
186
  case t
415
- # Timestamp
416
- when Fixnum
417
- put.add cf, cq, t, Util.to_bytes(v)
187
+ # Timestamp / Ruby Time
188
+ when Time, Fixnum
189
+ put.add cf, cq, time_to_long(t), Util.to_bytes(v)
418
190
  # Types: :byte, :short, :int, ...
419
191
  else
420
192
  put.add cf, cq, Util.to_bytes(t => v)
@@ -426,137 +198,6 @@ private
426
198
  end
427
199
  }
428
200
  end
429
-
430
- def hcd name, opts
431
- method_map = {
432
- :blockcache => :setBlockCacheEnabled,
433
- :blocksize => :setBlocksize,
434
- :bloomfilter => :setBloomFilterType,
435
- :compression => :setCompressionType,
436
- :data_block_encoding => :setDataBlockEncoding,
437
- :encode_on_disk => :setEncodeOnDisk,
438
- :in_memory => :setInMemory,
439
- :keep_deleted_cells => :setKeepDeletedCells,
440
- :min_versions => :setMinVersions,
441
- :replication_scope => :setScope,
442
- :ttl => :setTimeToLive,
443
- :versions => :setMaxVersions,
444
- }
445
- HColumnDescriptor.new(name.to_s).tap do |hcd|
446
- opts.each do |key, val|
447
- if method_map[key]
448
- hcd.send method_map[key],
449
- ({
450
- :bloomfilter => proc { |v|
451
- const_shortcut StoreFile::BloomType, v, "Invalid bloom filter type"
452
- },
453
- :compression => proc { |v|
454
- const_shortcut Compression::Algorithm, v, "Invalid compression algorithm"
455
- }
456
- }[key] || proc { |a| a }).call(val)
457
- else
458
- raise ArgumentError, "Invalid option: #{key}"
459
- end
460
- end#opts
461
- end
462
- end
463
-
464
- def const_shortcut base, v, message
465
- vs = v.to_s.upcase
466
- # const_get doesn't work with symbols in 1.8 compatibility mode
467
- if base.constants.map { |c| base.const_get c }.any? { |cv| v == cv }
468
- v
469
- elsif base.constants.map(&:to_s).include?(vs)
470
- base.const_get vs
471
- else
472
- raise ArgumentError, [message, v.to_s].join(': ')
473
- end
474
- end
475
-
476
- def patch_table_descriptor! htd, props
477
- props.each do |key, value|
478
- method = {
479
- :max_filesize => :setMaxFileSize,
480
- :readonly => :setReadOnly,
481
- :memstore_flushsize => :setMemStoreFlushSize,
482
- :deferred_log_flush => :setDeferredLogFlush
483
- }[key]
484
- raise ArgumentError, "Invalid table property: #{key}" unless method
485
-
486
- htd.send method, value
487
- end
488
- htd
489
- end
490
-
491
- def _alter props, bang, &block
492
- with_admin do |admin|
493
- htd = admin.get_table_descriptor(@name.to_java_bytes)
494
- patch_table_descriptor! htd, props
495
- while_disabled(admin) do
496
- admin.modifyTable @name.to_java_bytes, htd
497
- wait_async_admin(admin, &block) if bang
498
- end
499
- end
500
- end
501
-
502
- def _add_family name, opts, bang, &block
503
- with_admin do |admin|
504
- while_disabled(admin) do
505
- admin.addColumn @name, hcd(name.to_s, opts)
506
- wait_async_admin(admin, &block) if bang
507
- end
508
- end
509
- end
510
-
511
- def _alter_family name, opts, bang, &block
512
- with_admin do |admin|
513
- while_disabled(admin) do
514
- admin.modifyColumn @name, hcd(name.to_s, opts)
515
- wait_async_admin(admin, &block) if bang
516
- end
517
- end
518
- end
519
-
520
- def _delete_family name, bang, &block
521
- with_admin do |admin|
522
- while_disabled(admin) do
523
- admin.deleteColumn @name, name.to_s
524
- wait_async_admin(admin, &block) if bang
525
- end
526
- end
527
- end
528
-
529
- def _add_coprocessor class_name, props = {}, bang, &block
530
- with_admin do |admin|
531
- while_disabled(admin) do
532
-
533
- htd = admin.get_table_descriptor(@name.to_java_bytes)
534
- if props.empty?
535
- htd.addCoprocessor class_name
536
- else
537
- path, priority, params = props.values_at :path, :priority, :params
538
- params = Hash[ params.map { |k, v| [k.to_s, v.to_s] } ]
539
- htd.addCoprocessor class_name, path, priority || Coprocessor::PRIORITY_USER, params
540
- end
541
- admin.modifyTable @name.to_java_bytes, htd
542
- wait_async_admin(admin, &block) if bang
543
- end
544
- end
545
- end
546
-
547
- def _remove_coprocessor name, bang, &block
548
- unless org.apache.hadoop.hbase.HTableDescriptor.respond_to?(:removeCoprocessor)
549
- raise NotImplementedError, "org.apache.hadoop.hbase.HTableDescriptor.removeCoprocessor not implemented"
550
- end
551
- with_admin do |admin|
552
- while_disabled(admin) do
553
- htd = admin.get_table_descriptor(@name.to_java_bytes)
554
- htd.removeCoprocessor name
555
- admin.modifyTable @name.to_java_bytes, htd
556
- wait_async_admin(admin, &block) if bang
557
- end
558
- end
559
- end
560
201
  end#Table
561
202
  end#HBase
562
203
 
@@ -15,6 +15,8 @@ module Util
15
15
  # @return [byte[]]
16
16
  def to_bytes v
17
17
  case v
18
+ when Array
19
+ v.to_java(Java::byte)
18
20
  when String, ByteArray
19
21
  v.to_java_bytes
20
22
  when Fixnum
@@ -47,7 +49,7 @@ module Util
47
49
  Bytes.java_send :toBytes, [Java::int], val
48
50
  when :short
49
51
  Bytes.java_send :toBytes, [Java::short], val
50
- when :long, :fixnum
52
+ when :long, :fixnum
51
53
  Bytes.java_send :toBytes, [Java::long], val
52
54
  else
53
55
  raise ArgumentError, "Invalid value format"
@@ -123,6 +125,19 @@ module Util
123
125
  end
124
126
  end
125
127
  end
128
+
129
+ private
130
+ # @private
131
+ def time_to_long ts
132
+ case ts
133
+ when Fixnum
134
+ ts
135
+ when Time
136
+ (ts.to_f * 1000).to_i
137
+ else
138
+ raise ArgumentError, "Invalid time format"
139
+ end
140
+ end
126
141
  end#Util
127
142
  end#HBase
128
143
 
@@ -1,5 +1,5 @@
1
1
  class HBase
2
2
  module JRuby
3
- VERSION = "0.1.6"
3
+ VERSION = "0.2.0"
4
4
  end
5
5
  end
data/lib/hbase-jruby.rb CHANGED
@@ -12,6 +12,8 @@ require "hbase-jruby/admin"
12
12
  require "hbase-jruby/scoped/aggregation"
13
13
  require "hbase-jruby/scoped"
14
14
  require "hbase-jruby/table"
15
+ require "hbase-jruby/table/admin"
16
+ require "hbase-jruby/table/inspection"
15
17
  require "hbase-jruby/result"
16
18
  require 'hbase-jruby/hbase'
17
19
 
data/test/helper.rb CHANGED
@@ -8,13 +8,10 @@ SimpleCov.start
8
8
  RECREATE = false
9
9
 
10
10
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
11
- require "hbase-jruby"
12
11
 
13
- # Required
14
- unless HBase.resolve_dependency!(ENV.fetch 'HBASE_JRUBY_TEST_DIST').all? { |f| File.exists? f }
15
- puts "Invalid return value from HBase.resolve_dependency!"
16
- exit 1
17
- end
12
+ require "hbase-jruby"
13
+ HBase.resolve_dependency!(ENV.fetch('HBASE_JRUBY_TEST_DIST'), :verbose => true)
14
+ HBase.log4j = { 'log4j.threshold' => 'ERROR' }
18
15
 
19
16
  class TestHBaseJRubyBase < Test::Unit::TestCase
20
17
  TABLE = 'test_hbase_jruby'
@@ -36,7 +33,7 @@ class TestHBaseJRubyBase < Test::Unit::TestCase
36
33
  @table.create!(
37
34
  :cf1 => { :compression => :none, :bloomfilter => :row },
38
35
  :cf2 => { :bloomfilter => :rowcol },
39
- :cf3 => { :versions => 1, :bloomfilter => org.apache.hadoop.hbase.regionserver.StoreFile::BloomType::ROWCOL }
36
+ :cf3 => { :versions => 1, :bloomfilter => :rowcol }
40
37
  ) unless @table.exists?
41
38
  @table.enable! if @table.disabled?
42
39
 
data/test/test_cell.rb CHANGED
@@ -31,12 +31,12 @@ class TestCell < Test::Unit::TestCase
31
31
  assert_instance_of String, cell.inspect
32
32
  end
33
33
  end
34
-
34
+
35
35
  def test_order
36
36
  ts = Time.now.to_i * 1000
37
37
 
38
38
  val = "val".to_java_bytes
39
- cells =
39
+ cells =
40
40
  [
41
41
  KeyValue.new("rowkey".to_java_bytes, "apple".to_java_bytes, "alpha".to_java_bytes, ts, val),
42
42
  KeyValue.new("rowkey".to_java_bytes, "apple".to_java_bytes, "alpha".to_java_bytes, ts - 1000, val),