hash-from_mysql_query_result 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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.md +41 -0
- data/Rakefile +1 -0
- data/bin/q2h +33 -0
- data/hash-from_mysql_query_result.gemspec +24 -0
- data/lib/hash-from_mysql_query_result.rb +128 -0
- data/lib/hash-from_mysql_query_result/version.rb +5 -0
- data/spec/fixtures/describe_pet.txt +11 -0
- data/spec/fixtures/select_database.txt +6 -0
- data/spec/fixtures/select_tables.txt +7 -0
- data/spec/hash-from_mysql_query_result_spec.rb +59 -0
- data/spec/spec.opts +2 -0
- metadata +75 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# hash-from_mysql_query_result
|
2
|
+
|
3
|
+
Create Hash from MySQL query result text.
|
4
|
+
|
5
|
+
## Example
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
data = Hash::FromMysqlQueryResult.parse_text(DATA.lines.to_a.join(""))
|
9
|
+
pp data
|
10
|
+
# => {:header=>["mysql> SELECT * FROM foo;"],
|
11
|
+
# :fields=>["id", "value"],
|
12
|
+
# :records=>
|
13
|
+
# [{"id"=>"1", "value"=>"A"},
|
14
|
+
# {"id"=>"2", "value"=>"b"},
|
15
|
+
# {"id"=>"3", "value"=>"C"}],
|
16
|
+
# :footer=>["3 rows in set (0.01 sec)"]}
|
17
|
+
|
18
|
+
__END__
|
19
|
+
mysql> SELECT * FROM foo;
|
20
|
+
+----+-------+
|
21
|
+
| id | value |
|
22
|
+
+----+-------+
|
23
|
+
| 1 | A |
|
24
|
+
| 2 | b |
|
25
|
+
| 3 | C |
|
26
|
+
+----+-------+
|
27
|
+
3 rows in set (0.01 sec)
|
28
|
+
|
29
|
+
```
|
30
|
+
|
31
|
+
## Output ruby-hash or json by command line
|
32
|
+
|
33
|
+
```
|
34
|
+
% q2h ./spec/fixtures/describe_pet.txt -o json
|
35
|
+
{"header":["mysql> DESCRIBE pet;"],"fields":["Field","Type","Null","Key","Default","Extra"],"records":[{"Field":"name","Type":"varchar(20)","Null":"YES","Key":"","Default":"NULL","Extra":""},{"Field":"owner","Type":"varchar(20)","Null":"YES","Key":"","Default":"NULL","Extra":""},{"Field":"species","Type":"varchar(20)","Null":"YES","Key":"","Default":"NULL","Extra":""},{"Field":"sex","Type":"char(1)","Null":"YES","Key":"","Default":"NULL","Extra":""},{"Field":"birth","Type":"date","Null":"YES","Key":"","Default":"NULL","Extra":""},{"Field":"death","Type":"date","Null":"YES","Key":"","Default":"NULL","Extra":""}],"footer":[]}
|
36
|
+
```
|
37
|
+
|
38
|
+
|
39
|
+
## License
|
40
|
+
|
41
|
+
Released under the MIT License - Copyright (c) 2012 koyachi
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/q2h
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "optparse"
|
3
|
+
require "json"
|
4
|
+
require "hash-from_mysql_query_result"
|
5
|
+
|
6
|
+
def parse_option
|
7
|
+
options = {
|
8
|
+
:file => nil,
|
9
|
+
:output_format => :hash,
|
10
|
+
}
|
11
|
+
OptionParser.new do |opts|
|
12
|
+
opts.banner = "usage: qr2hash filename [--output]"
|
13
|
+
opts.on("-o", "--ouput [FORMAT]", [:hash, :json], "Select output format(hash, json)") do |format|
|
14
|
+
options[:output_format] = format if format
|
15
|
+
end
|
16
|
+
end.parse!
|
17
|
+
options[:file] = ARGV[0]
|
18
|
+
|
19
|
+
if options[:file] == nil
|
20
|
+
puts "file was NOT specified."
|
21
|
+
exit 1
|
22
|
+
end
|
23
|
+
|
24
|
+
options
|
25
|
+
end
|
26
|
+
|
27
|
+
options = parse_option
|
28
|
+
result = Hash::FromMysqlQueryResult.process_file(options[:file])
|
29
|
+
if options[:output_format] == :json
|
30
|
+
puts result.to_json
|
31
|
+
else
|
32
|
+
puts result
|
33
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "hash-from_mysql_query_result/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "hash-from_mysql_query_result"
|
7
|
+
s.version = Hash::FromMysqlQueryResult::VERSION
|
8
|
+
s.authors = ["koyachi"]
|
9
|
+
s.email = ["rtk2106@gmail.com"]
|
10
|
+
s.homepage = "https://github.com/koyachi/ruby-hash-from_mysql_query_result"
|
11
|
+
s.summary = %q{Create Hash from MySQL query result text.}
|
12
|
+
s.description = %q{Create Hash from MySQL query result text.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "hash-from_mysql_query_result"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
# s.add_runtime_dependency "rest-client"
|
24
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require "hash-from_mysql_query_result/version"
|
2
|
+
|
3
|
+
class Hash
|
4
|
+
module FromMysqlQueryResult
|
5
|
+
class << self
|
6
|
+
private
|
7
|
+
PARSE_STATUS = {
|
8
|
+
:header => 1,
|
9
|
+
:table_header => 2,
|
10
|
+
:table_body => 3,
|
11
|
+
:table_footer => 4,
|
12
|
+
:footer => 5
|
13
|
+
}
|
14
|
+
TABLE_FRAME_PATTERN = /\+\-+\+/
|
15
|
+
|
16
|
+
def process_header(lines)
|
17
|
+
result = []
|
18
|
+
lines.each_with_index do |line, i|
|
19
|
+
return result if i != 0 && line.match(TABLE_FRAME_PATTERN)
|
20
|
+
|
21
|
+
line.chomp!
|
22
|
+
result.push(line)
|
23
|
+
end
|
24
|
+
result
|
25
|
+
end
|
26
|
+
|
27
|
+
def process_table_header(lines)
|
28
|
+
lines.each_with_index do |line, i|
|
29
|
+
return if i != 0 && line.match(TABLE_FRAME_PATTERN)
|
30
|
+
next if i == 0 && line.match(TABLE_FRAME_PATTERN)
|
31
|
+
|
32
|
+
line.chomp!
|
33
|
+
headers = line.gsub(/\s/, "").split("|")[1..-1]
|
34
|
+
return headers
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def process_table_body(lines)
|
39
|
+
result = []
|
40
|
+
lines.each_with_index do |line, i|
|
41
|
+
return result if i != 0 && line.match(TABLE_FRAME_PATTERN)
|
42
|
+
next if i == 0 && line.match(TABLE_FRAME_PATTERN)
|
43
|
+
|
44
|
+
line.chomp!
|
45
|
+
rows = line.split("|").map {|s| s.gsub(/\s/, "") }[1..-1]
|
46
|
+
result.push(rows)
|
47
|
+
end
|
48
|
+
result
|
49
|
+
end
|
50
|
+
|
51
|
+
def process_table_footer(lines)
|
52
|
+
result = []
|
53
|
+
lines.each_with_index do |line, i|
|
54
|
+
return result if i != 0 && line.match(TABLE_FRAME_PATTERN)
|
55
|
+
next if i == 0 && line.match(TABLE_FRAME_PATTERN)
|
56
|
+
|
57
|
+
line.chomp!
|
58
|
+
result.push(line)
|
59
|
+
end
|
60
|
+
result
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_footer(lines)
|
64
|
+
# puts "[PROCESS_FOOTER]"
|
65
|
+
# lines.each do |line|
|
66
|
+
# puts " #{line}"
|
67
|
+
# end
|
68
|
+
end
|
69
|
+
|
70
|
+
public
|
71
|
+
def process_file(path)
|
72
|
+
file = open(path)
|
73
|
+
parse_text(file.read)
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_text(text)
|
77
|
+
result = {
|
78
|
+
:header => "",
|
79
|
+
:fields => [],
|
80
|
+
:records => [],
|
81
|
+
:footer => ""
|
82
|
+
}
|
83
|
+
state = PARSE_STATUS[:header]
|
84
|
+
lines = text.lines.to_a
|
85
|
+
text.lines.each_with_index do |line, i|
|
86
|
+
if line.match(TABLE_FRAME_PATTERN)
|
87
|
+
case state
|
88
|
+
when PARSE_STATUS[:table_header]
|
89
|
+
result[:fields] = process_table_header(lines[i..-1])
|
90
|
+
state = PARSE_STATUS[:table_body]
|
91
|
+
|
92
|
+
when PARSE_STATUS[:table_body]
|
93
|
+
records = process_table_body(lines[i..-1])
|
94
|
+
tmp_records = []
|
95
|
+
records.each_with_index do |record, i|
|
96
|
+
tmp = {}
|
97
|
+
result[:fields].each_with_index do |key, i|
|
98
|
+
tmp[key] = record[i]
|
99
|
+
end
|
100
|
+
tmp_records.push(tmp)
|
101
|
+
end
|
102
|
+
|
103
|
+
result[:records] = tmp_records
|
104
|
+
state = PARSE_STATUS[:table_footer]
|
105
|
+
|
106
|
+
when PARSE_STATUS[:table_footer]
|
107
|
+
result[:footer] = process_table_footer(lines[i..-1])
|
108
|
+
state = PARSE_STATUS[:footer]
|
109
|
+
|
110
|
+
when PARSE_STATUS[:footer]
|
111
|
+
process_footer(lines[i..-1])
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
else
|
116
|
+
case state
|
117
|
+
when PARSE_STATUS[:header]
|
118
|
+
result[:header] = process_header(lines[i..-1])
|
119
|
+
state = PARSE_STATUS[:table_header]
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
result
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
mysql> DESCRIBE pet;
|
2
|
+
+---------+-------------+------+-----+---------+-------+
|
3
|
+
| Field | Type | Null | Key | Default | Extra |
|
4
|
+
+---------+-------------+------+-----+---------+-------+
|
5
|
+
| name | varchar(20) | YES | | NULL | |
|
6
|
+
| owner | varchar(20) | YES | | NULL | |
|
7
|
+
| species | varchar(20) | YES | | NULL | |
|
8
|
+
| sex | char(1) | YES | | NULL | |
|
9
|
+
| birth | date | YES | | NULL | |
|
10
|
+
| death | date | YES | | NULL | |
|
11
|
+
+---------+-------------+------+-----+---------+-------+
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
$:.unshift File.dirname(__FILE__)
|
3
|
+
|
4
|
+
require 'hash-from_mysql_query_result'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
describe Hash::FromMysqlQueryResult do
|
8
|
+
def fixture(filename)
|
9
|
+
File.dirname(__FILE__) + '/fixtures/' + filename
|
10
|
+
end
|
11
|
+
|
12
|
+
before do
|
13
|
+
data = <<-TEST_DATA
|
14
|
+
mysql> SELECT * FROM foo;
|
15
|
+
+----+-------+
|
16
|
+
| id | value |
|
17
|
+
+----+-------+
|
18
|
+
| 1 | A |
|
19
|
+
| 2 | b |
|
20
|
+
| 3 | |
|
21
|
+
+----+-------+
|
22
|
+
3 rows in set (0.01 sec)
|
23
|
+
TEST_DATA
|
24
|
+
|
25
|
+
@text = data.lines.to_a.join("")
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should parse_text' do
|
29
|
+
result = Hash::FromMysqlQueryResult.parse_text(@text)
|
30
|
+
result.should eql({
|
31
|
+
:header => ["mysql> SELECT * FROM foo;"],
|
32
|
+
:fields => ["id", "value"],
|
33
|
+
:records => [
|
34
|
+
{"id" => "1", "value" => "A"},
|
35
|
+
{"id" => "2", "value" => "b"},
|
36
|
+
{"id" => "3", "value" => ""}
|
37
|
+
],
|
38
|
+
:footer => ["3 rows in set (0.01 sec)"]
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should process_file' do
|
43
|
+
result = Hash::FromMysqlQueryResult.process_file(fixture("describe_pet.txt"))
|
44
|
+
result.should eql({
|
45
|
+
:header => ["mysql> DESCRIBE pet;"],
|
46
|
+
:fields => ["Field", "Type", "Null", "Key", "Default", "Extra"],
|
47
|
+
:records => [
|
48
|
+
{"Field" => "name", "Type" => "varchar(20)", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
49
|
+
{"Field" => "owner", "Type" => "varchar(20)", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
50
|
+
{"Field" => "species", "Type" => "varchar(20)", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
51
|
+
{"Field" => "sex", "Type" => "char(1)", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
52
|
+
{"Field" => "birth", "Type" => "date", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
53
|
+
{"Field" => "death", "Type" => "date", "Null" => "YES", "Key" => "", "Default" => "NULL", "Extra" => ""},
|
54
|
+
],
|
55
|
+
:footer => []
|
56
|
+
})
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
data/spec/spec.opts
ADDED
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hash-from_mysql_query_result
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- koyachi
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-18 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: &2151836820 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2151836820
|
25
|
+
description: Create Hash from MySQL query result text.
|
26
|
+
email:
|
27
|
+
- rtk2106@gmail.com
|
28
|
+
executables:
|
29
|
+
- q2h
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files: []
|
32
|
+
files:
|
33
|
+
- .gitignore
|
34
|
+
- Gemfile
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- bin/q2h
|
38
|
+
- hash-from_mysql_query_result.gemspec
|
39
|
+
- lib/hash-from_mysql_query_result.rb
|
40
|
+
- lib/hash-from_mysql_query_result/version.rb
|
41
|
+
- spec/fixtures/describe_pet.txt
|
42
|
+
- spec/fixtures/select_database.txt
|
43
|
+
- spec/fixtures/select_tables.txt
|
44
|
+
- spec/hash-from_mysql_query_result_spec.rb
|
45
|
+
- spec/spec.opts
|
46
|
+
homepage: https://github.com/koyachi/ruby-hash-from_mysql_query_result
|
47
|
+
licenses: []
|
48
|
+
post_install_message:
|
49
|
+
rdoc_options: []
|
50
|
+
require_paths:
|
51
|
+
- lib
|
52
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
53
|
+
none: false
|
54
|
+
requirements:
|
55
|
+
- - ! '>='
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '0'
|
58
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
requirements: []
|
65
|
+
rubyforge_project: hash-from_mysql_query_result
|
66
|
+
rubygems_version: 1.8.11
|
67
|
+
signing_key:
|
68
|
+
specification_version: 3
|
69
|
+
summary: Create Hash from MySQL query result text.
|
70
|
+
test_files:
|
71
|
+
- spec/fixtures/describe_pet.txt
|
72
|
+
- spec/fixtures/select_database.txt
|
73
|
+
- spec/fixtures/select_tables.txt
|
74
|
+
- spec/hash-from_mysql_query_result_spec.rb
|
75
|
+
- spec/spec.opts
|