mysql_parser 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +5 -0
- data/README +3 -3
- data/Rakefile +1 -1
- data/lib/mysql_parser.rb +34 -33
- data/lib/mysql_parser/statement_parser.rb +100 -0
- data/lib/mysql_parser/value_parser.rb +4 -7
- data/lib/mysql_parser/version.rb +2 -2
- data/spec/mysql_parser/statement_parser_spec.rb +35 -0
- data/spec/mysql_parser/value_parser_spec.rb +43 -0
- metadata +18 -9
- data/spec/mysql_parser_spec/value_parser_spec.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3de1a91ad6044bb63b5a963c7775e9f6c2a0a3e9
|
4
|
+
data.tar.gz: 8a9538f93d7d2c067b7a1220bc0b82ab1c4d1c3c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7dd4828d7eea7c2d6ffc2138cc698da466881a686b5c5a756c8e0f72d56e2bd718b766ec8ec663e2da21bcefeb0aedceb25e047282413fd27b679b3c8e6f0e08
|
7
|
+
data.tar.gz: 4041bf4e6dd443d678f1da294dc9f51c2dc5c1aad02be88fdd529e13685ea9cdddeb99f5fd202613d6e339dc20c249db641c4fe66f5e0743dd7f5203b787ce1b
|
data/ChangeLog
CHANGED
data/README
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
== VERSION
|
4
4
|
|
5
|
-
This documentation refers to mysql_parser version 0.0
|
5
|
+
This documentation refers to mysql_parser version 0.1.0
|
6
6
|
|
7
7
|
|
8
8
|
== DESCRIPTION
|
@@ -12,7 +12,7 @@ A parser for MySQL DDL statements.
|
|
12
12
|
|
13
13
|
== LINKS
|
14
14
|
|
15
|
-
Documentation:: https://blackwinter.github.
|
15
|
+
Documentation:: https://blackwinter.github.com/mysql_parser
|
16
16
|
Source code:: https://github.com/blackwinter/mysql_parser
|
17
17
|
RubyGem:: https://rubygems.org/gems/mysql_parser
|
18
18
|
Travis CI:: https://travis-ci.org/blackwinter/mysql_parser
|
@@ -25,7 +25,7 @@ Travis CI:: https://travis-ci.org/blackwinter/mysql_parser
|
|
25
25
|
|
26
26
|
== LICENSE AND COPYRIGHT
|
27
27
|
|
28
|
-
Copyright (C) 2014 Jens Wille
|
28
|
+
Copyright (C) 2014-2015 Jens Wille
|
29
29
|
|
30
30
|
mysql_parser is free software: you can redistribute it and/or modify it
|
31
31
|
under the terms of the GNU Affero General Public License as published by
|
data/Rakefile
CHANGED
data/lib/mysql_parser.rb
CHANGED
@@ -29,11 +29,6 @@ class MysqlParser
|
|
29
29
|
DEFAULT_NAME = '__DEFAULT__'.freeze
|
30
30
|
DEFAULT_TABLE = '__DEFAULT__'.freeze
|
31
31
|
|
32
|
-
USE_RE = /\AUSE\s+`(.+?)`/i
|
33
|
-
CREATE_TABLE_RE = /\ACREATE\s+TABLE\s+`(.+?)`/i
|
34
|
-
TABLE_COLUMN_RE = /\A\s+`(.+?)`/
|
35
|
-
FINISH_TABLE_RE = /\A\).*;\Z/
|
36
|
-
INSERT_VALUES_RE = /\AINSERT\s+INTO\s+`(.+?)`\s+(?:\((.+?)\)\s+)?VALUES\s*(.*);\Z/i
|
37
32
|
CLEAN_COLUMNS_RE = /[\s`]+/
|
38
33
|
|
39
34
|
def self.parse(input, &block)
|
@@ -46,11 +41,14 @@ class MysqlParser
|
|
46
41
|
end
|
47
42
|
|
48
43
|
def reset
|
49
|
-
@name
|
50
|
-
@table
|
51
|
-
|
52
|
-
@
|
53
|
-
@
|
44
|
+
@name = DEFAULT_NAME
|
45
|
+
@table = DEFAULT_TABLE
|
46
|
+
|
47
|
+
@tables = {}
|
48
|
+
@columns = Hash.new { |h, k| h[k] = [] }
|
49
|
+
|
50
|
+
@value_parser = ValueParser.new
|
51
|
+
@statement_parser = StatementParser.new
|
54
52
|
end
|
55
53
|
|
56
54
|
attr_reader :tables
|
@@ -68,31 +66,33 @@ class MysqlParser
|
|
68
66
|
}
|
69
67
|
end
|
70
68
|
|
71
|
-
name, table, columns, value_parser, block_given =
|
72
|
-
@name, @table, @columns, @value_parser, block_given?
|
69
|
+
name, table, columns, statement_parser, value_parser, block_given =
|
70
|
+
@name, @table, @columns, @statement_parser, @value_parser, block_given?
|
73
71
|
|
74
72
|
input.each { |line|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
_columns.
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
73
|
+
statement_parser.parse(line) { |context, *data|
|
74
|
+
case context
|
75
|
+
when :use
|
76
|
+
name = data[0]
|
77
|
+
yield context, name if block_given
|
78
|
+
when :create
|
79
|
+
table = data[0]
|
80
|
+
when :column
|
81
|
+
columns[table] << data[0] if table
|
82
|
+
when :table
|
83
|
+
yield context, name, table, columns[table] if block_given
|
84
|
+
table = nil
|
85
|
+
when :insert
|
86
|
+
_table, _columns, _values = data
|
87
|
+
|
88
|
+
_columns = _columns.nil? ? columns[_table] :
|
89
|
+
_columns.gsub(CLEAN_COLUMNS_RE, '').split(',')
|
90
|
+
|
91
|
+
value_parser.parse(_values) { |values|
|
92
|
+
block[context, name, _table, _columns, values]
|
93
|
+
} unless _columns.empty?
|
94
|
+
end
|
95
|
+
}
|
96
96
|
}
|
97
97
|
|
98
98
|
@name, @table = name, table
|
@@ -104,5 +104,6 @@ end
|
|
104
104
|
|
105
105
|
MySQLParser = MysqlParser
|
106
106
|
|
107
|
+
require_relative 'mysql_parser/statement_parser'
|
107
108
|
require_relative 'mysql_parser/value_parser'
|
108
109
|
require_relative 'mysql_parser/version'
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# mysql_parser -- Parse MySQL statements #
|
5
|
+
# #
|
6
|
+
# Copyright (C) 2014 Jens Wille #
|
7
|
+
# #
|
8
|
+
# Authors: #
|
9
|
+
# Jens Wille <jens.wille@gmail.com> #
|
10
|
+
# #
|
11
|
+
# mysql_parser is free software; you can redistribute it and/or modify it #
|
12
|
+
# under the terms of the GNU Affero General Public License as published by #
|
13
|
+
# the Free Software Foundation; either version 3 of the License, or (at your #
|
14
|
+
# option) any later version. #
|
15
|
+
# #
|
16
|
+
# mysql_parser is distributed in the hope that it will be useful, but WITHOUT #
|
17
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
18
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License #
|
19
|
+
# for more details. #
|
20
|
+
# #
|
21
|
+
# You should have received a copy of the GNU Affero General Public License #
|
22
|
+
# along with mysql_parser. If not, see <http://www.gnu.org/licenses/>. #
|
23
|
+
# #
|
24
|
+
###############################################################################
|
25
|
+
#++
|
26
|
+
|
27
|
+
class MysqlParser
|
28
|
+
|
29
|
+
class StatementParser
|
30
|
+
|
31
|
+
QUOTED_NAME_RE = %r{
|
32
|
+
`
|
33
|
+
( .*? )
|
34
|
+
`
|
35
|
+
}xi
|
36
|
+
|
37
|
+
USE_RE = %r{
|
38
|
+
\A
|
39
|
+
USE
|
40
|
+
\s+
|
41
|
+
#{QUOTED_NAME_RE}
|
42
|
+
}xi
|
43
|
+
|
44
|
+
CREATE_TABLE_RE = %r{
|
45
|
+
\A
|
46
|
+
CREATE \s+ TABLE
|
47
|
+
\s+
|
48
|
+
#{QUOTED_NAME_RE}
|
49
|
+
}xi
|
50
|
+
|
51
|
+
TABLE_COLUMN_RE = %r{
|
52
|
+
\A
|
53
|
+
\s+
|
54
|
+
#{QUOTED_NAME_RE}
|
55
|
+
}xi
|
56
|
+
|
57
|
+
FINISH_TABLE_RE = %r{
|
58
|
+
\A
|
59
|
+
\)
|
60
|
+
.*
|
61
|
+
;
|
62
|
+
\Z
|
63
|
+
}xi
|
64
|
+
|
65
|
+
INSERT_VALUES_RE = %r{
|
66
|
+
\A
|
67
|
+
INSERT \s+ INTO
|
68
|
+
\s+
|
69
|
+
#{QUOTED_NAME_RE}
|
70
|
+
\s+
|
71
|
+
(?:
|
72
|
+
\(
|
73
|
+
( .+? )
|
74
|
+
\)
|
75
|
+
\s+
|
76
|
+
)?
|
77
|
+
VALUES
|
78
|
+
\s*
|
79
|
+
( .* )
|
80
|
+
;
|
81
|
+
\Z
|
82
|
+
}xi
|
83
|
+
|
84
|
+
def self.parse(input)
|
85
|
+
new.parse(input)
|
86
|
+
end
|
87
|
+
|
88
|
+
def parse(input)
|
89
|
+
case input
|
90
|
+
when USE_RE then yield :use, $1
|
91
|
+
when CREATE_TABLE_RE then yield :create, $1
|
92
|
+
when TABLE_COLUMN_RE then yield :column, $1
|
93
|
+
when FINISH_TABLE_RE then yield :table
|
94
|
+
when INSERT_VALUES_RE then yield :insert, $1, $2, $3
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
# #
|
4
4
|
# mysql_parser -- Parse MySQL statements #
|
5
5
|
# #
|
6
|
-
# Copyright (C) 2014 Jens Wille
|
6
|
+
# Copyright (C) 2014-2015 Jens Wille #
|
7
7
|
# #
|
8
8
|
# Authors: #
|
9
9
|
# Jens Wille <jens.wille@gmail.com> #
|
@@ -47,7 +47,7 @@ class MysqlParser
|
|
47
47
|
break unless @input.scan(/,\s*/)
|
48
48
|
end
|
49
49
|
|
50
|
-
@input.
|
50
|
+
@input.skip(/;/)
|
51
51
|
|
52
52
|
error('Unexpected data') unless @input.eos?
|
53
53
|
|
@@ -116,11 +116,8 @@ class MysqlParser
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def error(message)
|
119
|
-
|
120
|
-
|
121
|
-
else
|
122
|
-
raise "#{message} at #{$.}:#{@input.pos}: #{@input.peek(16).inspect}"
|
123
|
-
end
|
119
|
+
raise @input.eos? ? "Unexpected end of input (#{message})." :
|
120
|
+
"#{message} at #{$.}:#{@input.pos}: #{@input.peek(16).inspect}"
|
124
121
|
end
|
125
122
|
|
126
123
|
end
|
data/lib/mysql_parser/version.rb
CHANGED
@@ -0,0 +1,35 @@
|
|
1
|
+
describe MysqlParser::StatementParser do
|
2
|
+
|
3
|
+
def parsing(input)
|
4
|
+
lambda { |b| @statement_parser.parse(input, &b) }
|
5
|
+
end
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@statement_parser = MysqlParser::StatementParser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
example do
|
12
|
+
parsing('').should_not yield_control
|
13
|
+
end
|
14
|
+
|
15
|
+
example do
|
16
|
+
parsing('USE `foo`').should yield_with_args(:use, 'foo')
|
17
|
+
end
|
18
|
+
|
19
|
+
example do
|
20
|
+
parsing('CREATE TABLE `bar` (').should yield_with_args(:create, 'bar')
|
21
|
+
end
|
22
|
+
|
23
|
+
example do
|
24
|
+
parsing(' `baz` INTEGER').should yield_with_args(:column, 'baz')
|
25
|
+
end
|
26
|
+
|
27
|
+
example do
|
28
|
+
parsing(');').should yield_with_args(:table)
|
29
|
+
end
|
30
|
+
|
31
|
+
example do
|
32
|
+
parsing('INSERT INTO `bar` VALUES (42);').should yield_with_args(:insert, 'bar', nil, '(42)')
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
describe MysqlParser::ValueParser do
|
2
|
+
|
3
|
+
def parsing(input)
|
4
|
+
@value_parser.parse(input)
|
5
|
+
end
|
6
|
+
|
7
|
+
before :all do
|
8
|
+
@value_parser = MysqlParser::ValueParser.new
|
9
|
+
end
|
10
|
+
|
11
|
+
example do
|
12
|
+
parsing('').should == []
|
13
|
+
end
|
14
|
+
|
15
|
+
example do
|
16
|
+
parsing('(42)').should == [[42]]
|
17
|
+
end
|
18
|
+
|
19
|
+
example do
|
20
|
+
parsing('(2.3)').should == [[2.3]]
|
21
|
+
end
|
22
|
+
|
23
|
+
example do
|
24
|
+
parsing("('foo')").should == [['foo']]
|
25
|
+
end
|
26
|
+
|
27
|
+
example do
|
28
|
+
parsing('(NULL)').should == [[nil]]
|
29
|
+
end
|
30
|
+
|
31
|
+
example do
|
32
|
+
parsing("('foo',NULL,42)").should == [['foo', nil, 42]]
|
33
|
+
end
|
34
|
+
|
35
|
+
example do
|
36
|
+
parsing("('foo',NULL,42), ('bar', 'baz', 2.3)").should == [['foo', nil, 42], ['bar', 'baz', 2.3]]
|
37
|
+
end
|
38
|
+
|
39
|
+
example do
|
40
|
+
lambda { parsing('("foo")') }.should raise_error(RuntimeError, /Unclosed row/)
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
metadata
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mysql_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jens Wille
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: hen
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.8'
|
17
20
|
- - ">="
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
22
|
+
version: 0.8.3
|
20
23
|
type: :development
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0.8'
|
24
30
|
- - ">="
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
32
|
+
version: 0.8.3
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: rake
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,10 +72,12 @@ files:
|
|
66
72
|
- README
|
67
73
|
- Rakefile
|
68
74
|
- lib/mysql_parser.rb
|
75
|
+
- lib/mysql_parser/statement_parser.rb
|
69
76
|
- lib/mysql_parser/value_parser.rb
|
70
77
|
- lib/mysql_parser/version.rb
|
78
|
+
- spec/mysql_parser/statement_parser_spec.rb
|
79
|
+
- spec/mysql_parser/value_parser_spec.rb
|
71
80
|
- spec/mysql_parser_spec.rb
|
72
|
-
- spec/mysql_parser_spec/value_parser_spec.rb
|
73
81
|
- spec/spec_helper.rb
|
74
82
|
homepage: http://github.com/blackwinter/mysql_parser
|
75
83
|
licenses:
|
@@ -77,13 +85,14 @@ licenses:
|
|
77
85
|
metadata: {}
|
78
86
|
post_install_message: |2+
|
79
87
|
|
80
|
-
mysql_parser-0.0
|
88
|
+
mysql_parser-0.1.0 [2015-10-02]:
|
81
89
|
|
82
|
-
*
|
90
|
+
* Extracted MysqlParser::StatementParser from MysqlParser.
|
91
|
+
* Minor refactorings.
|
83
92
|
|
84
93
|
rdoc_options:
|
85
94
|
- "--title"
|
86
|
-
- mysql_parser Application documentation (v0.0
|
95
|
+
- mysql_parser Application documentation (v0.1.0)
|
87
96
|
- "--charset"
|
88
97
|
- UTF-8
|
89
98
|
- "--line-numbers"
|
@@ -104,7 +113,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
113
|
version: '0'
|
105
114
|
requirements: []
|
106
115
|
rubyforge_project:
|
107
|
-
rubygems_version: 2.
|
116
|
+
rubygems_version: 2.4.8
|
108
117
|
signing_key:
|
109
118
|
specification_version: 4
|
110
119
|
summary: Parse MySQL statements.
|
@@ -1,39 +0,0 @@
|
|
1
|
-
describe MysqlParser::ValueParser do
|
2
|
-
|
3
|
-
before :all do
|
4
|
-
@value_parser = MysqlParser::ValueParser.new
|
5
|
-
end
|
6
|
-
|
7
|
-
example do
|
8
|
-
@value_parser.parse('').should == []
|
9
|
-
end
|
10
|
-
|
11
|
-
example do
|
12
|
-
@value_parser.parse('(42)').should == [[42]]
|
13
|
-
end
|
14
|
-
|
15
|
-
example do
|
16
|
-
@value_parser.parse('(2.3)').should == [[2.3]]
|
17
|
-
end
|
18
|
-
|
19
|
-
example do
|
20
|
-
@value_parser.parse("('foo')").should == [['foo']]
|
21
|
-
end
|
22
|
-
|
23
|
-
example do
|
24
|
-
@value_parser.parse('(NULL)').should == [[nil]]
|
25
|
-
end
|
26
|
-
|
27
|
-
example do
|
28
|
-
@value_parser.parse("('foo',NULL,42)").should == [['foo', nil, 42]]
|
29
|
-
end
|
30
|
-
|
31
|
-
example do
|
32
|
-
@value_parser.parse("('foo',NULL,42), ('bar', 'baz', 2.3)").should == [['foo', nil, 42], ['bar', 'baz', 2.3]]
|
33
|
-
end
|
34
|
-
|
35
|
-
example do
|
36
|
-
lambda { @value_parser.parse('("foo")') }.should raise_error(RuntimeError, /Unclosed row/)
|
37
|
-
end
|
38
|
-
|
39
|
-
end
|