ddl_parser 0.0.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.
@@ -0,0 +1,96 @@
1
+ require "spec_helper"
2
+
3
+ describe 'DDLParser::Parser' do
4
+
5
+ it "knows if it's valid" do
6
+ sql = "CREATE TABLE TEST (ID INT)"
7
+ parser = DDLParser::Parser.new(sql)
8
+ parser.valid?.should == true
9
+ end
10
+
11
+ it "knows if it's invalid" do
12
+ sql = "CREATE TABLE TEST ()"
13
+ parser = DDLParser::Parser.new(sql)
14
+ parser.valid?.should == false
15
+ end
16
+
17
+ it "can report errors" do
18
+ sql = "CREATE TABLE TEST ()"
19
+ parser = DDLParser::Parser.new(sql)
20
+ parser.errors.should include("CREATE_TABLE_STATEMENT")
21
+ end
22
+
23
+ it "statement_type" do
24
+ sql = "CREATE TABLE TEST (ID INT, FOO INT)"
25
+ parser = DDLParser::Parser.new(sql)
26
+ parser.statement_type.should == :create_table
27
+ end
28
+
29
+ it "returns the parse tree" do
30
+ sql = "CREATE TABLE TEST (ID INT, FOO INT)"
31
+ parser = DDLParser::Parser.new(sql)
32
+ parser.parse_tree.should == {:operation=>"CREATE TABLE", :table_name=>"TEST", :elements=>[
33
+ {:column=>{:field=>"ID", :data_type=>"INT", :options=>""}},
34
+ {:column=>{:field=>"FOO", :data_type=>"INT", :options=>""}}]}
35
+ end
36
+
37
+ context "create table translate" do
38
+ it "translate table_name" do
39
+ sql = "CREATE TABLE TEST (ID INT, FOO INT)"
40
+ parser = DDLParser::Parser.new(sql)
41
+ parser.translate.table_name.should == "TEST"
42
+ end
43
+
44
+
45
+ it "translate columns" do
46
+ sql = "CREATE TABLE TEST (ID INT, FOO INT)"
47
+ parser = DDLParser::Parser.new(sql)
48
+ parser.translate.columns.should == [{:field=>"ID", :data_type=>"INT", :options=>""}, {:field=>"FOO", :data_type=>"INT", :options=>""}]
49
+
50
+ sql = "CREATE TABLE TEST (ID INT)"
51
+ parser = DDLParser::Parser.new(sql)
52
+ parser.translate.columns.should == [{:field=>"ID", :data_type=>"INT", :options=>""}]
53
+ end
54
+
55
+ it "translate primary key" do
56
+ sql = "CREATE TABLE TEST (ID INT, PRIMARY KEY (ID))"
57
+ parser = DDLParser::Parser.new(sql)
58
+ parser.translate.primary_key.should == "ID"
59
+ end
60
+ end
61
+
62
+ context "alter table translate" do
63
+ let(:sql) {
64
+ sql = <<EOF
65
+ ALTER TABLE BUDGET
66
+ ADD COLUMN BUDGET_AMOUNT_IN_CO DECIMAL(15,2) NOT NULL DEFAULT 0
67
+ ADD COLUMN BUDGET_AMOUNT_CURR CHARACTER(4)
68
+ EOF
69
+ sql
70
+ }
71
+
72
+ it "translate table_name" do
73
+ parser = DDLParser::Parser.new(sql)
74
+ parser.translate.table_name.should == "BUDGET"
75
+ end
76
+
77
+
78
+ it "translate columns" do
79
+ parser = DDLParser::Parser.new(sql)
80
+ parser.translate.add_columns.should == [{:field=>"BUDGET_AMOUNT_IN_CO",
81
+ :data_type=>{:decimal=>{:precision=>{:total=>{:integer=>"15"}, :scale=>{:integer=>"2"}}}},
82
+ :options=>[{:column_option=>"NOT NULL"},
83
+ {:default_clause=>[{:integer=>"0"}]}]},
84
+ {:field=>"BUDGET_AMOUNT_CURR",
85
+ :data_type=>{:char=>{:length=>{:integer=>"4"}}},
86
+ :options=>""}]
87
+ end
88
+
89
+ it "translate primary key" do
90
+ sql = "CREATE TABLE TEST (ID INT, PRIMARY KEY (ID))"
91
+ parser = DDLParser::Parser.new(sql)
92
+ parser.translate.primary_key.should == "ID"
93
+ end
94
+ end
95
+
96
+ end
@@ -0,0 +1,126 @@
1
+ require "spec_helper"
2
+
3
+ class DummyParser < Parslet::Parser
4
+ include DDLParser::SharedRules::Constants
5
+ end
6
+
7
+ describe DDLParser::SharedRules::Constants do
8
+ let(:parser) { DummyParser.new }
9
+
10
+ it "digits" do
11
+ (0..9).each do |digit|
12
+ expect(parser.digit).to parse(digit.to_s)
13
+ end
14
+ ("a".."z").each do |non_digit|
15
+ expect(parser.digit).not_to parse(non_digit.to_s)
16
+ end
17
+ end
18
+
19
+ it "integer" do
20
+ expect(parser.integer).to parse("1")
21
+ expect(parser.integer).to parse("123456789")
22
+ expect(parser.integer).to parse("-123456789")
23
+ expect(parser.integer).to parse("0123")
24
+ expect(parser.integer).not_to parse("1.2")
25
+ end
26
+
27
+ it "float" do
28
+ expect(parser.float).to parse("-1.1")
29
+ expect(parser.float).to parse("1.1")
30
+ expect(parser.float).to parse("123456.789")
31
+ expect(parser.float).to parse("-123456.789")
32
+ expect(parser.float).not_to parse("12")
33
+ end
34
+
35
+ it "space" do
36
+ expect(parser.space).to parse(" ")
37
+ expect(parser.space).to parse(" ")
38
+ expect(parser.space).to parse("\t")
39
+ expect(parser.space).not_to parse("")
40
+ expect(parser.space).not_to parse("1")
41
+ end
42
+
43
+ it "space?" do
44
+ expect(parser.space?).to parse("")
45
+ expect(parser.space?).to parse(" ")
46
+ expect(parser.space?).to parse(" ")
47
+ expect(parser.space?).not_to parse("1")
48
+ end
49
+
50
+ it "newline" do
51
+ expect(parser.newline).to parse("\n")
52
+ expect(parser.newline).not_to parse(" ")
53
+ expect(parser.newline).not_to parse("\t")
54
+ end
55
+
56
+ it "spaces" do
57
+ expect(parser.spaces).to parse("\n")
58
+ expect(parser.spaces).to parse(" \n \n")
59
+ expect(parser.spaces).to parse("\t ")
60
+ end
61
+
62
+ it "comment?" do
63
+ expect(parser.comment?).to parse("-- foobar")
64
+ expect(parser.comment?).not_to parse("--\nfoobar")
65
+ end
66
+
67
+ it "comma" do
68
+ expect(parser.comma).to parse(",")
69
+ expect(parser.comma).to parse(", ")
70
+ expect(parser.comma).not_to parse(" , ")
71
+ end
72
+
73
+ it "lparen" do
74
+ expect(parser.lparen).to parse("(")
75
+ expect(parser.lparen).to parse("( ")
76
+ expect(parser.lparen).not_to parse(" (")
77
+ end
78
+
79
+ it "rparen" do
80
+ expect(parser.rparen).to parse(")")
81
+ expect(parser.rparen).to parse(") ")
82
+ expect(parser.rparen).not_to parse(" )")
83
+ end
84
+
85
+ it "boolean" do
86
+ expect(parser.boolean).to parse("true")
87
+ expect(parser.boolean).to parse("false")
88
+ expect(parser.boolean).not_to parse("false ")
89
+ end
90
+
91
+ it "datetime" do
92
+ expect(parser.datetime).to parse("2014-02-28T12:01:02Z")
93
+ end
94
+
95
+ it "string" do
96
+ expect(parser.string).to parse("'foobar'")
97
+ expect(parser.string).to parse("'foo bar'")
98
+ expect(parser.string).not_to parse("'foo bar")
99
+ expect(parser.string).not_to parse('"foobar"')
100
+ end
101
+
102
+ it "const" do
103
+ expect(parser.const).to parse("'foobar'")
104
+ expect(parser.const).to parse("1")
105
+ expect(parser.const).to parse("1.1")
106
+ expect(parser.const).to parse("true")
107
+ expect(parser.const).to parse("2014-02-28T12:01:02Z")
108
+ expect(parser.const).not_to parse("(")
109
+ expect(parser.const).not_to parse(',')
110
+ end
111
+
112
+ it "identifier" do
113
+ expect(parser.identifier).to parse("foobar")
114
+ expect(parser.identifier).not_to parse("foo bar")
115
+ expect(parser.identifier).to parse("a")
116
+ expect(parser.identifier).to parse("aB")
117
+ expect(parser.identifier).to parse("A1")
118
+ expect(parser.identifier).to parse("A1_2")
119
+ expect(parser.identifier).not_to parse("A B")
120
+ end
121
+
122
+ it "current_timestamp" do
123
+ expect(parser.current_timestamp).to parse("current timestamp")
124
+ end
125
+
126
+ end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ class DummyParser < Parslet::Parser
4
+ include DDLParser::SharedRules::DataTypes
5
+ end
6
+
7
+ describe DDLParser::SharedRules::DataTypes do
8
+ let(:parser) { DummyParser.new }
9
+
10
+ it "parses data types" do
11
+ parser.data_type.parse("smallint").should == {:data_type=>"smallint"}
12
+ parser.data_type.parse("int").should == {:data_type=>"int"}
13
+ parser.data_type.parse("decimal(1,2)").should == {:data_type=>{:decimal=>{:precision => {:total=>{:integer=>"1"}, :scale=>{:integer=>"2"}}}}}
14
+ parser.data_type.parse("float(1)").should == {:data_type=>{:float=>{:precision=>{:integer=>"1"}}}}
15
+ parser.data_type.parse("real").should == {:data_type=>"real"}
16
+ parser.data_type.parse("double").should == {:data_type=>"double"}
17
+ parser.data_type.parse("char(1)").should == {:data_type=>{:char=>{:length=>{:integer=>"1"}}}}
18
+ parser.data_type.parse("varchar(1)").should == {:data_type=>{:varchar=>{:length=>{:integer=>"1"}}}}
19
+ parser.data_type.parse("clob(50000)").should == {:data_type=>{:clob=>{:length=>{:integer=>"50000"}}}}
20
+ parser.data_type.parse("date").should == {:data_type=>"date"}
21
+ parser.data_type.parse("time").should == {:data_type=>"time"}
22
+ parser.data_type.parse("timestamp").should == {:data_type=>"timestamp"}
23
+ end
24
+
25
+
26
+ end
27
+
@@ -0,0 +1,166 @@
1
+ require "spec_helper"
2
+
3
+ describe DDLParser::SQL::DB2::SelectParser do
4
+ let(:parser) { DDLParser::SQL::DB2::SelectParser.new }
5
+
6
+ context "value parsing" do
7
+
8
+ it "parses integers" do
9
+ expect(parser.const).to parse("1")
10
+ expect(parser.const).to parse("-123")
11
+ expect(parser.const).to parse("120381")
12
+ expect(parser.const).to parse("181")
13
+ expect(parser.const).to parse("0181")
14
+ end
15
+
16
+ it "parses floats" do
17
+ expect(parser.const).to parse("0.1")
18
+ expect(parser.const).to parse("3.14159")
19
+ expect(parser.const).to parse("-0.00001")
20
+ expect(parser.const).to_not parse(".1")
21
+ end
22
+
23
+ it "parses booleans" do
24
+ expect(parser.const).to parse("true")
25
+ expect(parser.const).to parse("false")
26
+ expect(parser.const).to_not parse("truefalse")
27
+ end
28
+
29
+ it "parses datetimes" do
30
+ expect(parser.const).to parse("1979-05-27T07:32:00Z")
31
+ expect(parser.const).to parse("2013-02-24T17:26:21Z")
32
+ expect(parser.const).to_not parse("1979l05-27 07:32:00")
33
+ end
34
+
35
+ it "parses strings" do
36
+ expect(parser.const).to parse("''")
37
+ expect(parser.const).to parse("'hello world'")
38
+ expect(parser.const).to parse("'120.0, ~!@#$\%^&*+_\}{ asdfasf'")
39
+ expect(parser.const).not_to parse('"hello world"')
40
+ end
41
+
42
+ end
43
+
44
+ context "namelist parsing" do
45
+ it "simple" do
46
+ expect(parser.namelist).to parse('a,b,c')
47
+ expect(parser.namelist).to parse('a, b, C')
48
+ end
49
+
50
+ it "not parse invalid" do
51
+ expect(parser.namelist).not_to parse('a b')
52
+ expect(parser.namelist).not_to parse('a: b')
53
+ expect(parser.namelist).not_to parse("a; b" )
54
+ expect(parser.namelist).not_to parse("a, b, 'foo'" )
55
+ expect(parser.namelist).not_to parse("a, b, max(c)" )
56
+ end
57
+
58
+ end
59
+
60
+ context "arglist parsing" do
61
+ it "simple" do
62
+ expect(parser.arglist).to parse('a,b,c')
63
+ expect(parser.arglist).to parse('a, b, c')
64
+ expect(parser.arglist).to parse("a, b, 'foo'" )
65
+ expect(parser.arglist).to parse("a, b, max(c)" )
66
+ end
67
+
68
+ it "not parse invalid" do
69
+ expect(parser.arglist).not_to parse('a b')
70
+ expect(parser.arglist).not_to parse('a: b')
71
+ expect(parser.arglist).not_to parse("a; b" )
72
+ end
73
+
74
+ end
75
+
76
+ context "between parsing" do
77
+ it "should parse between" do
78
+ expect(parser.single_cond).to parse("a between 1 and 2")
79
+ expect(parser.single_cond).to parse("a between 1 and 2")
80
+ expect(parser.single_cond.parse("a between 1 and 2")).to eq(:lhs=>"a", :op=>"between", :rhs=>{:btw_from=>{:integer=>"1"}, :btw_to=>{:integer=>"2"}})
81
+ end
82
+ end
83
+
84
+ context "like parsing" do
85
+ it "should parse" do
86
+ expect(parser.single_cond).to parse("a like '%foo%bar'")
87
+ end
88
+
89
+ end
90
+
91
+ context "condition parsing" do
92
+ it "should parse single" do
93
+ expect(parser.condition).to parse("a = a")
94
+ expect(parser.condition).to parse("a=a")
95
+ expect(parser.condition).to parse("a > a")
96
+ expect(parser.condition).to parse("a < a")
97
+ expect(parser.condition).to parse("a between 1 and 2")
98
+ expect(parser.condition).to parse("a like '%foo%bar'")
99
+ end
100
+
101
+ it "should parse multible" do
102
+ expect(parser.condition).to parse("a = a or b = b")
103
+ expect(parser.condition).to parse("a = a and b = b")
104
+ expect(parser.condition).to parse("a > a and a between 'foo' and 'bar'")
105
+ expect(parser.condition).to parse("a < a and a like '%foo%bar'")
106
+ end
107
+
108
+ end
109
+
110
+ context "select statements" do
111
+ it "parse simple statements" do
112
+ [
113
+ 'select a from b',
114
+ 'select a, b from comme',
115
+ 'select b from far',
116
+ 'select c from d',
117
+ 'select a, c, d,e,f,f from b ',
118
+ 'select count(a) from d',
119
+ ].each do |sql|
120
+ expect(parser).to parse(sql)
121
+ end
122
+ end
123
+
124
+ it "parse statements with where" do
125
+ [
126
+ 'select a from b where a > 20',
127
+ 'select a,b from c where a = 20',
128
+ 'select a,b from c where 20 < a and b < 234',
129
+ 'select a,b from c where 20 < a or b = 234',
130
+ 'select a, b from c where a = ''oo''',
131
+ 'select a, b from c where a = ''oo'' and c > 235',
132
+ ].each do |sql|
133
+ expect(parser).to parse(sql)
134
+ end
135
+ end
136
+
137
+ it "parse statements with group by" do
138
+ [
139
+ 'select a from b group by c',
140
+ 'select a from b where a > 345 group by c',
141
+ 'select a from b where a > 345 and foo = ''hoge'' group by c',
142
+ ].each do |sql|
143
+ expect(parser).to parse(sql)
144
+ end
145
+ end
146
+
147
+ it "not to parse bad selects" do
148
+ [
149
+ 'select',
150
+ 'select a, b from c where a = "120.0, ~!@#$%^&*+_\}{\" asdfa"sf"',
151
+ ].each do |sql|
152
+ expect(parser).not_to parse(sql)
153
+ end
154
+ end
155
+
156
+ end
157
+
158
+ context "extract" do
159
+ it "should fetch select" do
160
+ result = parser.parse("select a from b where a = b")
161
+ #result[:select].should
162
+ end
163
+ end
164
+
165
+
166
+ end
@@ -0,0 +1,23 @@
1
+ RSpec.configure do |config|
2
+ config.treat_symbols_as_metadata_keys_with_true_values = true
3
+ config.run_all_when_everything_filtered = true
4
+ config.filter_run :focus
5
+
6
+ #config.expect_with :rspec do |c|
7
+ # c.syntax = :expect
8
+ #end
9
+
10
+ # Run specs in random order to surface order dependencies. If you find an
11
+ # order dependency and want to debug it, you can fix the order by providing
12
+ # the seed, which is printed after each run.
13
+ # --seed 1234
14
+ config.order = 'random'
15
+ end
16
+
17
+ require "parslet/rig/rspec"
18
+ require "ddl_parser"
19
+ require "yaml"
20
+
21
+ def fixture(filename)
22
+ File.read("spec/fixtures/#{filename}")
23
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ddl_parser
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Rasmus Bergholdt
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: parslet
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ~>
32
+ - !ruby/object:Gem::Version
33
+ version: '1.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ~>
39
+ - !ruby/object:Gem::Version
40
+ version: '1.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '10.1'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '10.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: '2.2'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ~>
67
+ - !ruby/object:Gem::Version
68
+ version: '2.2'
69
+ description: Parse SQL and DDL statements
70
+ email:
71
+ - raber@eg.dk
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - .gitignore
77
+ - .rspec
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - ddl_parser.gemspec
83
+ - lib/ddl_parser.rb
84
+ - lib/ddl_parser/ddl.rb
85
+ - lib/ddl_parser/ddl/db2.rb
86
+ - lib/ddl_parser/ddl/db2/parser.rb
87
+ - lib/ddl_parser/parser.rb
88
+ - lib/ddl_parser/shared_rules.rb
89
+ - lib/ddl_parser/shared_rules/constants.rb
90
+ - lib/ddl_parser/shared_rules/data_types.rb
91
+ - lib/ddl_parser/shared_rules/logical_operators.rb
92
+ - lib/ddl_parser/sql.rb
93
+ - lib/ddl_parser/sql/db2.rb
94
+ - lib/ddl_parser/sql/db2/select_parser.rb
95
+ - lib/ddl_parser/translater.rb
96
+ - lib/ddl_parser/translater/alter_table.rb
97
+ - lib/ddl_parser/translater/create_index.rb
98
+ - lib/ddl_parser/translater/create_table.rb
99
+ - lib/ddl_parser/version.rb
100
+ - lib/parslet_extentions.rb
101
+ - spec/ddl_parser/ddl/db2/alter_table_spec.rb
102
+ - spec/ddl_parser/ddl/db2/create_index_spec.rb
103
+ - spec/ddl_parser/ddl/db2/create_table_spec.rb
104
+ - spec/ddl_parser/parser_spec.rb
105
+ - spec/ddl_parser/shared_rules/constants_spec.rb
106
+ - spec/ddl_parser/shared_rules/data_types_spec.rb
107
+ - spec/ddl_parser/sql/db2/select_parser_spec.rb
108
+ - spec/spec_helper.rb
109
+ homepage: ''
110
+ licenses:
111
+ - MIT
112
+ metadata: {}
113
+ post_install_message:
114
+ rdoc_options: []
115
+ require_paths:
116
+ - lib
117
+ required_ruby_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ! '>='
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ required_rubygems_version: !ruby/object:Gem::Requirement
123
+ requirements:
124
+ - - ! '>='
125
+ - !ruby/object:Gem::Version
126
+ version: '0'
127
+ requirements: []
128
+ rubyforge_project:
129
+ rubygems_version: 2.2.2
130
+ signing_key:
131
+ specification_version: 4
132
+ summary: will parse statements and make it possible to extract content
133
+ test_files:
134
+ - spec/ddl_parser/ddl/db2/alter_table_spec.rb
135
+ - spec/ddl_parser/ddl/db2/create_index_spec.rb
136
+ - spec/ddl_parser/ddl/db2/create_table_spec.rb
137
+ - spec/ddl_parser/parser_spec.rb
138
+ - spec/ddl_parser/shared_rules/constants_spec.rb
139
+ - spec/ddl_parser/shared_rules/data_types_spec.rb
140
+ - spec/ddl_parser/sql/db2/select_parser_spec.rb
141
+ - spec/spec_helper.rb
142
+ has_rdoc: