hipster_sql_to_hbase 0.1.2
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 +7 -0
- data/.document +4 -0
- data/Gemfile +5 -0
- data/LICENSE +20 -0
- data/LICENSE.txt +20 -0
- data/README.md +39 -0
- data/README.rdoc +19 -0
- data/Rakefile +31 -0
- data/VERSION +1 -0
- data/hipster_sql_to_hbase.gemspec +55 -0
- data/lib/adapter/Hbase.thrift +914 -0
- data/lib/adapter/hbase.rb +59 -0
- data/lib/adapter/hbase/hbase.rb +2966 -0
- data/lib/adapter/hbase/hbase_constants.rb +14 -0
- data/lib/adapter/hbase/hbase_types.rb +282 -0
- data/lib/datatype_extras.rb +18 -0
- data/lib/executor.rb +91 -0
- data/lib/hipster_sql_to_hbase.rb +167 -0
- data/lib/result_tree_to_hbase_converter.rb +119 -0
- data/lib/result_tree_to_json_converter.rb +40 -0
- data/lib/sql_parser/sql.treetop +21 -0
- data/lib/sql_parser/sql_chars.treetop +5 -0
- data/lib/sql_parser/sql_create_table.treetop +47 -0
- data/lib/sql_parser/sql_datatypes.treetop +71 -0
- data/lib/sql_parser/sql_delete.treetop +64 -0
- data/lib/sql_parser/sql_drop_table.treetop +26 -0
- data/lib/sql_parser/sql_from_clause.treetop +12 -0
- data/lib/sql_parser/sql_group_by_clause.treetop +15 -0
- data/lib/sql_parser/sql_helpers.treetop +19 -0
- data/lib/sql_parser/sql_insert.treetop +118 -0
- data/lib/sql_parser/sql_key_value_pair.treetop +91 -0
- data/lib/sql_parser/sql_limit.treetop +7 -0
- data/lib/sql_parser/sql_order_by_clause.treetop +53 -0
- data/lib/sql_parser/sql_primitives.treetop +118 -0
- data/lib/sql_parser/sql_row_support.treetop +72 -0
- data/lib/sql_parser/sql_select.treetop +82 -0
- data/lib/sql_parser/sql_select_clause.treetop +17 -0
- data/lib/sql_parser/sql_show_tables.treetop +26 -0
- data/lib/sql_parser/sql_tokens.treetop +125 -0
- data/lib/sql_parser/sql_transaction.treetop +43 -0
- data/lib/sql_parser/sql_truncate.treetop +11 -0
- data/lib/sql_parser/sql_update.treetop +82 -0
- data/lib/sql_parser/sql_where_condition.treetop +46 -0
- data/lib/sql_treetop_load.rb +23 -0
- data/spec/hipster_sql_to_hbase_spec.rb +171 -0
- data/spec/spec_helper.rb +3 -0
- metadata +192 -0
@@ -0,0 +1,282 @@
|
|
1
|
+
#
|
2
|
+
# Autogenerated by Thrift Compiler (0.9.1)
|
3
|
+
#
|
4
|
+
# DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
|
5
|
+
#
|
6
|
+
|
7
|
+
module Apache
|
8
|
+
module Hadoop
|
9
|
+
module Hbase
|
10
|
+
module Thrift
|
11
|
+
# TCell - Used to transport a cell value (byte[]) and the timestamp it was
|
12
|
+
# stored with together as a result for get and getRow methods. This promotes
|
13
|
+
# the timestamp of a cell to a first-class value, making it easy to take
|
14
|
+
# note of temporal data. Cell is used all the way from HStore up to HTable.
|
15
|
+
class TCell
|
16
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
17
|
+
VALUE = 1
|
18
|
+
TIMESTAMP = 2
|
19
|
+
|
20
|
+
FIELDS = {
|
21
|
+
VALUE => {:type => ::Thrift::Types::STRING, :name => 'value', :binary => true},
|
22
|
+
TIMESTAMP => {:type => ::Thrift::Types::I64, :name => 'timestamp'}
|
23
|
+
}
|
24
|
+
|
25
|
+
def struct_fields; FIELDS; end
|
26
|
+
|
27
|
+
def validate
|
28
|
+
end
|
29
|
+
|
30
|
+
::Thrift::Struct.generate_accessors self
|
31
|
+
end
|
32
|
+
|
33
|
+
# An HColumnDescriptor contains information about a column family
|
34
|
+
# such as the number of versions, compression settings, etc. It is
|
35
|
+
# used as input when creating a table or adding a column.
|
36
|
+
class ColumnDescriptor
|
37
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
38
|
+
NAME = 1
|
39
|
+
MAXVERSIONS = 2
|
40
|
+
COMPRESSION = 3
|
41
|
+
INMEMORY = 4
|
42
|
+
BLOOMFILTERTYPE = 5
|
43
|
+
BLOOMFILTERVECTORSIZE = 6
|
44
|
+
BLOOMFILTERNBHASHES = 7
|
45
|
+
BLOCKCACHEENABLED = 8
|
46
|
+
TIMETOLIVE = 9
|
47
|
+
|
48
|
+
FIELDS = {
|
49
|
+
NAME => {:type => ::Thrift::Types::STRING, :name => 'name', :binary => true},
|
50
|
+
MAXVERSIONS => {:type => ::Thrift::Types::I32, :name => 'maxVersions', :default => 3},
|
51
|
+
COMPRESSION => {:type => ::Thrift::Types::STRING, :name => 'compression', :default => %q"NONE"},
|
52
|
+
INMEMORY => {:type => ::Thrift::Types::BOOL, :name => 'inMemory', :default => false},
|
53
|
+
BLOOMFILTERTYPE => {:type => ::Thrift::Types::STRING, :name => 'bloomFilterType', :default => %q"NONE"},
|
54
|
+
BLOOMFILTERVECTORSIZE => {:type => ::Thrift::Types::I32, :name => 'bloomFilterVectorSize', :default => 0},
|
55
|
+
BLOOMFILTERNBHASHES => {:type => ::Thrift::Types::I32, :name => 'bloomFilterNbHashes', :default => 0},
|
56
|
+
BLOCKCACHEENABLED => {:type => ::Thrift::Types::BOOL, :name => 'blockCacheEnabled', :default => false},
|
57
|
+
TIMETOLIVE => {:type => ::Thrift::Types::I32, :name => 'timeToLive', :default => -1}
|
58
|
+
}
|
59
|
+
|
60
|
+
def struct_fields; FIELDS; end
|
61
|
+
|
62
|
+
def validate
|
63
|
+
end
|
64
|
+
|
65
|
+
::Thrift::Struct.generate_accessors self
|
66
|
+
end
|
67
|
+
|
68
|
+
# A TRegionInfo contains information about an HTable region.
|
69
|
+
class TRegionInfo
|
70
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
71
|
+
STARTKEY = 1
|
72
|
+
ENDKEY = 2
|
73
|
+
ID = 3
|
74
|
+
NAME = 4
|
75
|
+
VERSION = 5
|
76
|
+
SERVERNAME = 6
|
77
|
+
PORT = 7
|
78
|
+
|
79
|
+
FIELDS = {
|
80
|
+
STARTKEY => {:type => ::Thrift::Types::STRING, :name => 'startKey', :binary => true},
|
81
|
+
ENDKEY => {:type => ::Thrift::Types::STRING, :name => 'endKey', :binary => true},
|
82
|
+
ID => {:type => ::Thrift::Types::I64, :name => 'id'},
|
83
|
+
NAME => {:type => ::Thrift::Types::STRING, :name => 'name', :binary => true},
|
84
|
+
VERSION => {:type => ::Thrift::Types::BYTE, :name => 'version'},
|
85
|
+
SERVERNAME => {:type => ::Thrift::Types::STRING, :name => 'serverName', :binary => true},
|
86
|
+
PORT => {:type => ::Thrift::Types::I32, :name => 'port'}
|
87
|
+
}
|
88
|
+
|
89
|
+
def struct_fields; FIELDS; end
|
90
|
+
|
91
|
+
def validate
|
92
|
+
end
|
93
|
+
|
94
|
+
::Thrift::Struct.generate_accessors self
|
95
|
+
end
|
96
|
+
|
97
|
+
# A Mutation object is used to either update or delete a column-value.
|
98
|
+
class Mutation
|
99
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
100
|
+
ISDELETE = 1
|
101
|
+
COLUMN = 2
|
102
|
+
VALUE = 3
|
103
|
+
WRITETOWAL = 4
|
104
|
+
|
105
|
+
FIELDS = {
|
106
|
+
ISDELETE => {:type => ::Thrift::Types::BOOL, :name => 'isDelete', :default => false},
|
107
|
+
COLUMN => {:type => ::Thrift::Types::STRING, :name => 'column', :binary => true},
|
108
|
+
VALUE => {:type => ::Thrift::Types::STRING, :name => 'value', :binary => true},
|
109
|
+
WRITETOWAL => {:type => ::Thrift::Types::BOOL, :name => 'writeToWAL', :default => true}
|
110
|
+
}
|
111
|
+
|
112
|
+
def struct_fields; FIELDS; end
|
113
|
+
|
114
|
+
def validate
|
115
|
+
end
|
116
|
+
|
117
|
+
::Thrift::Struct.generate_accessors self
|
118
|
+
end
|
119
|
+
|
120
|
+
# A BatchMutation object is used to apply a number of Mutations to a single row.
|
121
|
+
class BatchMutation
|
122
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
123
|
+
ROW = 1
|
124
|
+
MUTATIONS = 2
|
125
|
+
|
126
|
+
FIELDS = {
|
127
|
+
ROW => {:type => ::Thrift::Types::STRING, :name => 'row', :binary => true},
|
128
|
+
MUTATIONS => {:type => ::Thrift::Types::LIST, :name => 'mutations', :element => {:type => ::Thrift::Types::STRUCT, :class => ::Apache::Hadoop::Hbase::Thrift::Mutation}}
|
129
|
+
}
|
130
|
+
|
131
|
+
def struct_fields; FIELDS; end
|
132
|
+
|
133
|
+
def validate
|
134
|
+
end
|
135
|
+
|
136
|
+
::Thrift::Struct.generate_accessors self
|
137
|
+
end
|
138
|
+
|
139
|
+
# For increments that are not incrementColumnValue
|
140
|
+
# equivalents.
|
141
|
+
class TIncrement
|
142
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
143
|
+
TABLE = 1
|
144
|
+
ROW = 2
|
145
|
+
COLUMN = 3
|
146
|
+
AMMOUNT = 4
|
147
|
+
|
148
|
+
FIELDS = {
|
149
|
+
TABLE => {:type => ::Thrift::Types::STRING, :name => 'table', :binary => true},
|
150
|
+
ROW => {:type => ::Thrift::Types::STRING, :name => 'row', :binary => true},
|
151
|
+
COLUMN => {:type => ::Thrift::Types::STRING, :name => 'column', :binary => true},
|
152
|
+
AMMOUNT => {:type => ::Thrift::Types::I64, :name => 'ammount'}
|
153
|
+
}
|
154
|
+
|
155
|
+
def struct_fields; FIELDS; end
|
156
|
+
|
157
|
+
def validate
|
158
|
+
end
|
159
|
+
|
160
|
+
::Thrift::Struct.generate_accessors self
|
161
|
+
end
|
162
|
+
|
163
|
+
# Holds row name and then a map of columns to cells.
|
164
|
+
class TRowResult
|
165
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
166
|
+
ROW = 1
|
167
|
+
COLUMNS = 2
|
168
|
+
|
169
|
+
FIELDS = {
|
170
|
+
ROW => {:type => ::Thrift::Types::STRING, :name => 'row', :binary => true},
|
171
|
+
COLUMNS => {:type => ::Thrift::Types::MAP, :name => 'columns', :key => {:type => ::Thrift::Types::STRING, :binary => true}, :value => {:type => ::Thrift::Types::STRUCT, :class => ::Apache::Hadoop::Hbase::Thrift::TCell}}
|
172
|
+
}
|
173
|
+
|
174
|
+
def struct_fields; FIELDS; end
|
175
|
+
|
176
|
+
def validate
|
177
|
+
end
|
178
|
+
|
179
|
+
::Thrift::Struct.generate_accessors self
|
180
|
+
end
|
181
|
+
|
182
|
+
# A Scan object is used to specify scanner parameters when opening a scanner.
|
183
|
+
class TScan
|
184
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
185
|
+
STARTROW = 1
|
186
|
+
STOPROW = 2
|
187
|
+
TIMESTAMP = 3
|
188
|
+
COLUMNS = 4
|
189
|
+
CACHING = 5
|
190
|
+
FILTERSTRING = 6
|
191
|
+
|
192
|
+
FIELDS = {
|
193
|
+
STARTROW => {:type => ::Thrift::Types::STRING, :name => 'startRow', :binary => true, :optional => true},
|
194
|
+
STOPROW => {:type => ::Thrift::Types::STRING, :name => 'stopRow', :binary => true, :optional => true},
|
195
|
+
TIMESTAMP => {:type => ::Thrift::Types::I64, :name => 'timestamp', :optional => true},
|
196
|
+
COLUMNS => {:type => ::Thrift::Types::LIST, :name => 'columns', :element => {:type => ::Thrift::Types::STRING, :binary => true}, :optional => true},
|
197
|
+
CACHING => {:type => ::Thrift::Types::I32, :name => 'caching', :optional => true},
|
198
|
+
FILTERSTRING => {:type => ::Thrift::Types::STRING, :name => 'filterString', :binary => true, :optional => true}
|
199
|
+
}
|
200
|
+
|
201
|
+
def struct_fields; FIELDS; end
|
202
|
+
|
203
|
+
def validate
|
204
|
+
end
|
205
|
+
|
206
|
+
::Thrift::Struct.generate_accessors self
|
207
|
+
end
|
208
|
+
|
209
|
+
# An IOError exception signals that an error occurred communicating
|
210
|
+
# to the Hbase master or an Hbase region server. Also used to return
|
211
|
+
# more general Hbase error conditions.
|
212
|
+
class IOError < ::Thrift::Exception
|
213
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
214
|
+
def initialize(message=nil)
|
215
|
+
super()
|
216
|
+
self.message = message
|
217
|
+
end
|
218
|
+
|
219
|
+
MESSAGE = 1
|
220
|
+
|
221
|
+
FIELDS = {
|
222
|
+
MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
|
223
|
+
}
|
224
|
+
|
225
|
+
def struct_fields; FIELDS; end
|
226
|
+
|
227
|
+
def validate
|
228
|
+
end
|
229
|
+
|
230
|
+
::Thrift::Struct.generate_accessors self
|
231
|
+
end
|
232
|
+
|
233
|
+
# An IllegalArgument exception indicates an illegal or invalid
|
234
|
+
# argument was passed into a procedure.
|
235
|
+
class IllegalArgument < ::Thrift::Exception
|
236
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
237
|
+
def initialize(message=nil)
|
238
|
+
super()
|
239
|
+
self.message = message
|
240
|
+
end
|
241
|
+
|
242
|
+
MESSAGE = 1
|
243
|
+
|
244
|
+
FIELDS = {
|
245
|
+
MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
|
246
|
+
}
|
247
|
+
|
248
|
+
def struct_fields; FIELDS; end
|
249
|
+
|
250
|
+
def validate
|
251
|
+
end
|
252
|
+
|
253
|
+
::Thrift::Struct.generate_accessors self
|
254
|
+
end
|
255
|
+
|
256
|
+
# An AlreadyExists exceptions signals that a table with the specified
|
257
|
+
# name already exists
|
258
|
+
class AlreadyExists < ::Thrift::Exception
|
259
|
+
include ::Thrift::Struct, ::Thrift::Struct_Union
|
260
|
+
def initialize(message=nil)
|
261
|
+
super()
|
262
|
+
self.message = message
|
263
|
+
end
|
264
|
+
|
265
|
+
MESSAGE = 1
|
266
|
+
|
267
|
+
FIELDS = {
|
268
|
+
MESSAGE => {:type => ::Thrift::Types::STRING, :name => 'message'}
|
269
|
+
}
|
270
|
+
|
271
|
+
def struct_fields; FIELDS; end
|
272
|
+
|
273
|
+
def validate
|
274
|
+
end
|
275
|
+
|
276
|
+
::Thrift::Struct.generate_accessors self
|
277
|
+
end
|
278
|
+
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|
282
|
+
end
|
data/lib/executor.rb
ADDED
@@ -0,0 +1,91 @@
|
|
1
|
+
module HipsterSqlToHbase
|
2
|
+
|
3
|
+
# This class takes the magic provided by the ThriftCallGroup and
|
4
|
+
# turns it into an HBase reality by opening a connection to a
|
5
|
+
# specified host and port and executing the pertinent Thrift calls.
|
6
|
+
class Executor
|
7
|
+
@@host=nil
|
8
|
+
@@port=nil
|
9
|
+
|
10
|
+
# Set class variable <b>host</b> when instantiated.
|
11
|
+
def host=(host_s)
|
12
|
+
self.class.host=host_s
|
13
|
+
end
|
14
|
+
|
15
|
+
# Get class variable <b>host</b> when instantiated.
|
16
|
+
def host
|
17
|
+
self.class.host
|
18
|
+
end
|
19
|
+
|
20
|
+
# Set class variable <b>host</b> when NOT instantiated.
|
21
|
+
def self.host=(host_s)
|
22
|
+
@@host=host_s
|
23
|
+
end
|
24
|
+
|
25
|
+
# Get class variable <b>host</b> when NOT instantiated.
|
26
|
+
def self.host
|
27
|
+
@@host
|
28
|
+
end
|
29
|
+
|
30
|
+
# Set class variable <b>port</b> when instantiated.
|
31
|
+
def port=(port_n)
|
32
|
+
self.class.port=port_n
|
33
|
+
end
|
34
|
+
|
35
|
+
# Get class variable <b>port</b> when instantiated.
|
36
|
+
def port
|
37
|
+
self.class.port
|
38
|
+
end
|
39
|
+
|
40
|
+
# Set class variable <b>port</b> when NOT instantiated.
|
41
|
+
def self.port=(port_n)
|
42
|
+
@@port=port_n
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get class variable <b>port</b> when NOT instantiated.
|
46
|
+
def self.port
|
47
|
+
@@port
|
48
|
+
end
|
49
|
+
|
50
|
+
# Initialize a Thrift connection to the specified host and port
|
51
|
+
# and execute the provided ThriftCallGroup object.
|
52
|
+
def execute(thrift_call_group,host_s=nil,port_n=nil,incr=false)
|
53
|
+
@@host = host_s if !host_s.nil?
|
54
|
+
@@port = port_n if !port_n.nil?
|
55
|
+
socket = Thrift::Socket.new(@@host, @@port)
|
56
|
+
|
57
|
+
transport = Thrift::BufferedTransport.new(socket)
|
58
|
+
transport.open
|
59
|
+
|
60
|
+
protocol = Thrift::BinaryProtocol.new(transport)
|
61
|
+
client = HBase::Client.new(protocol)
|
62
|
+
|
63
|
+
results = []
|
64
|
+
|
65
|
+
if incr
|
66
|
+
not_incr = true
|
67
|
+
c_row = 0
|
68
|
+
end
|
69
|
+
|
70
|
+
thrift_call_group.each do |thrift_call|
|
71
|
+
if incr
|
72
|
+
if not_incr
|
73
|
+
c_row = increment_table_row_index(thrift_call[:arguments][0],thrift_call_group.length,client)
|
74
|
+
not_incr = false
|
75
|
+
end
|
76
|
+
c_row += 1
|
77
|
+
thrift_call[:arguments][1] = c_row.to_s
|
78
|
+
end
|
79
|
+
results << client.send(thrift_call[:method],*thrift_call[:arguments])
|
80
|
+
end
|
81
|
+
|
82
|
+
results
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def increment_table_row_index(table_name,amount,client)
|
88
|
+
client.incrementAndReturn("index:#{table_name}",amount)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require "date"
|
2
|
+
require "time"
|
3
|
+
require "treetop"
|
4
|
+
require_relative "datatype_extras"
|
5
|
+
require_relative "sql_treetop_load"
|
6
|
+
require_relative "result_tree_to_hbase_converter"
|
7
|
+
require_relative "result_tree_to_json_converter"
|
8
|
+
|
9
|
+
# This module provides the methods necessary to parse valid SQL
|
10
|
+
# sentences into:
|
11
|
+
#
|
12
|
+
# * Treetop Syntax Trees
|
13
|
+
# * Hash Trees
|
14
|
+
# * JSON Trees
|
15
|
+
# * HBase (Thrift)
|
16
|
+
#
|
17
|
+
# It also allows to directly execute valid SQL sentences as Thrift methods.
|
18
|
+
module HipsterSqlToHbase
|
19
|
+
|
20
|
+
# Treetop base SQL parser.
|
21
|
+
#
|
22
|
+
# Forked from Scott Taylor's guillotine and perfected by Jean Lescure.
|
23
|
+
#
|
24
|
+
# https://www.github.com/smtlaissezfaire/guillotine/tree/master/lib/guillotine/parser
|
25
|
+
#
|
26
|
+
# https://www.github.com/jeanlescure/hipster_sql_to_hbase
|
27
|
+
class SyntaxParser < SQLParser
|
28
|
+
class ItemsNode < Treetop::Runtime::SyntaxNode
|
29
|
+
def values
|
30
|
+
items.values.unshift(item.value)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ItemNode < Treetop::Runtime::SyntaxNode
|
35
|
+
def values
|
36
|
+
[value]
|
37
|
+
end
|
38
|
+
|
39
|
+
def value
|
40
|
+
text_value.to_sym
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# This class provides the initial parsed result with the methods
|
46
|
+
# necessary to be transformed into HBase (Thrift) or JSON, as well
|
47
|
+
# as to be executed as a Thrift method.
|
48
|
+
class ResultTree < Hash
|
49
|
+
def initialize(hash)
|
50
|
+
hash.each do |k,v|
|
51
|
+
self[k] = v
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# Transforms itself into an HBase (Thrift) method.
|
56
|
+
#
|
57
|
+
# === example:
|
58
|
+
# rt = HipsterSqlToHbase::ResultTree.new({...})
|
59
|
+
# rt.to_hbase #=> {:method => 'mutateRow', :arguments => {...}}
|
60
|
+
def to_hbase
|
61
|
+
HipsterSqlToHbase::ResultTreeToHbaseConverter.new().convert self
|
62
|
+
end
|
63
|
+
|
64
|
+
# Transforms itself into a JSON object.
|
65
|
+
#
|
66
|
+
# === example:
|
67
|
+
# user = HipsterSqlToHbase::ResultTree.new({...})
|
68
|
+
# user.to_json #=> {:user => {:user_name => 'bob', :pass => 'bob1234', ...}}
|
69
|
+
def to_json
|
70
|
+
HipsterSqlToHbase::ResultTreeToJsonConverter.new().convert self
|
71
|
+
end
|
72
|
+
|
73
|
+
# Executes itself as an HBase (Thrift) method.
|
74
|
+
# Short for running .to_hbase and then sending the result to the executor.
|
75
|
+
#
|
76
|
+
# === example:
|
77
|
+
# my_call = HipsterSqlToHbase::ResultTree.new({...})
|
78
|
+
# my_call.execute
|
79
|
+
#
|
80
|
+
# <em>if no arguments are passed the executor will use any previously set host
|
81
|
+
# and port.</em>
|
82
|
+
def execute(host=nil,port=nil)
|
83
|
+
self.to_hbase.execute(host,port)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class << self
|
88
|
+
# Generate a Treetop syntax tree from a valid, SQL string.
|
89
|
+
#
|
90
|
+
# === example:
|
91
|
+
# HipsterSqlToHbase.parse_syntax "INSERT INTO users (user,password) VALUES ('user1','pass123'),('user2','2girls1pass')"
|
92
|
+
#
|
93
|
+
# === outputs:
|
94
|
+
# #<Class:#<Treetop::Runtime::SyntaxNode:0x3274c98>>
|
95
|
+
def parse_syntax(string)
|
96
|
+
HipsterSqlToHbase::SyntaxParser.new.parse(string.squish)
|
97
|
+
end
|
98
|
+
|
99
|
+
# Generate a <b>HipsterSqlToHbase</b>::<b>ResultTree</b> from a valid, SQL string.
|
100
|
+
#
|
101
|
+
# === example:
|
102
|
+
# HipsterSqlToHbase.parse_tree "SELECT user,password FROM users WHERE id=1"
|
103
|
+
#
|
104
|
+
# === outputs:
|
105
|
+
# {
|
106
|
+
# :query_type=>:select,
|
107
|
+
# :query_hash=>{
|
108
|
+
# :select=>["user", "password"],
|
109
|
+
# :from=>"users",
|
110
|
+
# :where=>[{:column=>"id", :condition=>:"=", :value=>1}],
|
111
|
+
# :limit=>nil,
|
112
|
+
# :order_by=>nil
|
113
|
+
# }
|
114
|
+
# }
|
115
|
+
def parse_tree(string)
|
116
|
+
syntax_tree = parse_syntax(string)
|
117
|
+
return nil if syntax_tree.nil?
|
118
|
+
HipsterSqlToHbase::ResultTree.new({:query_type => syntax_tree.query_type, :query_hash => syntax_tree.tree})
|
119
|
+
end
|
120
|
+
|
121
|
+
# Generate a <b>HipsterSqlToHbase</b>::<b>ThriftCallGroup</b> from a valid, SQL string.
|
122
|
+
#
|
123
|
+
# === example:
|
124
|
+
# HipsterSqlToHbase.parse "INSERT INTO `users` (`user`,`pass`) VALUES ('andy','w00dy'),('zaphod','b33bl3br0x')"
|
125
|
+
#
|
126
|
+
# === outputs:
|
127
|
+
# [
|
128
|
+
# {
|
129
|
+
# :method=>"mutateRow",
|
130
|
+
# :arguments=>[
|
131
|
+
# "users",
|
132
|
+
# "c6af1d5b-01d7-477c-9539-f35a1e0758e2",
|
133
|
+
# [<Apache::Hadoop::Hbase::Thrift::Mutation>, <Apache::Hadoop::Hbase::Thrift::Mutation>],
|
134
|
+
# {}
|
135
|
+
# ]
|
136
|
+
# },
|
137
|
+
# {
|
138
|
+
# :method=>"mutateRow",
|
139
|
+
# :arguments=>[
|
140
|
+
# "users",
|
141
|
+
# "b630cf3c-c969-420e-afd9-b646466a6743",
|
142
|
+
# [<Apache::Hadoop::Hbase::Thrift::Mutation>, <Apache::Hadoop::Hbase::Thrift::Mutation>],
|
143
|
+
# {}
|
144
|
+
# ]
|
145
|
+
# }
|
146
|
+
# ]
|
147
|
+
#
|
148
|
+
# === note:
|
149
|
+
#
|
150
|
+
# The resulting ThriftCallGroup can be executed simply by calling its <tt>.execute()</tt> method.
|
151
|
+
def parse(string)
|
152
|
+
result_tree = parse_tree(string)
|
153
|
+
return nil if result_tree.nil?
|
154
|
+
result_tree.to_hbase
|
155
|
+
end
|
156
|
+
|
157
|
+
# Generates and automatically executes a <b>HipsterSqlToHbase</b>::<b>ThriftCallGroup</b>
|
158
|
+
# from a valid, SQL string.
|
159
|
+
#
|
160
|
+
# The returned value varies depending on the SQL query type (i.e. SELECT, INSERT, etc).
|
161
|
+
def execute(string,host=nil,port=nil)
|
162
|
+
parsed_tree = parse_tree(string)
|
163
|
+
return nil if parsed_tree.nil?
|
164
|
+
parsed_tree.execute(host,port)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|