ddl_parser 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ MTc1NWY4Y2ViMWVhNmM3OTNmNTk5NWFhZDZlYzNhZDg5ZmJlYTRiYw==
5
+ data.tar.gz: !binary |-
6
+ ZjQzNjgwOTZkZmJhMWY3M2M2NTNlN2RkMzlmOTIwZmY4YzNkOWUwYg==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ YTJmZjViYzQwOGQ1NmVmNWE0ODZkZTI4NDk0MTYzZmQwNjg5NDllODE2ODYw
10
+ YWM0ODMzNjI5YzI5NzkzYjI1ZmVkOWIyOTU0OWY4YTk0YjcyYmQwZTY1NjBk
11
+ MGNiODU1OTcyN2IwNjA3ZjU0ODlhZjAwMWNlNmQ4N2U0ZjU2ZmU=
12
+ data.tar.gz: !binary |-
13
+ N2U4YzIyNTcwNTQzNTc3NmRlYzYzYTMwZWFlNWU4ZDI4ZGMwODM5ZGI1ZTI5
14
+ NWQ0Nzk5ZjhiNzZmNDRlNjUwM2Q4YTI5OWEwNDQyODMxN2MyNjIxY2JmYzk2
15
+ MTZkNTk5NWM0NWI0MWY4NDcwM2JkNWE0MTdmYzg1YTAzZTI0ZmM=
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+
19
+ .idea/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ddl_parser.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Rasmus Bergholdt
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # DDLParser
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'DDL_parser'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install DDL_parser
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ddl_parser/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ddl_parser"
8
+ spec.version = DDLParser::VERSION
9
+ spec.authors = ["Rasmus Bergholdt"]
10
+ spec.email = ["raber@eg.dk"]
11
+ spec.description = %q{Parse SQL and DDL statements}
12
+ spec.summary = %q{will parse statements and make it possible to extract content }
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "parslet", "~> 1.5"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.3"
24
+ spec.add_development_dependency "rake", "~> 10.1"
25
+ spec.add_development_dependency "rspec", "~> 2.2"
26
+ end
@@ -0,0 +1,112 @@
1
+ module DDLParser
2
+ module DDL
3
+ module DB2
4
+ class Parser < Parslet::Parser
5
+
6
+ include DDLParser::SharedRules::Constants
7
+ include DDLParser::SharedRules::LogicalOperators
8
+ include DDLParser::SharedRules::DataTypes
9
+
10
+ # column options
11
+ rule(:option_not_null) { str("not null") }
12
+ rule(:column_option) { (option_not_null).as(:column_option) }
13
+ #rule(:lob_options)
14
+ rule(:primary_key) { (str("primary key") >> spaces >> references).as(:primary_key) }
15
+ rule(:constraint) { (str("constraint") >> spaces >> identifier.as(:column_name) >> spaces >> (str("unique") | str("foreign key")).as(:constraint_type) >>
16
+ spaces >> references.as(:constraint_arglist) >> spaces >> reference_clause.maybe).as(:constraint)}
17
+ #rule(:unique)
18
+ rule(:references) { lparen >> space? >> arglist >> space? >> rparen }
19
+ rule(:reference_clause) { str("references") >> spaces >> identifier >> spaces >> references.as(:reference_arglist) >> (identifier >> spaces).repeat }
20
+ #rule(:check)
21
+ #rule(:check_condition)
22
+ #rule(:constraint_attr)
23
+ rule(:gen_col_def) { str("generated always") | str("generated by default") }
24
+ rule(:default_value) { const | current_timestamp | function }
25
+ rule(:default_values) { (default_value >> space?).repeat }
26
+ rule(:default_clause) { ((str("with") >> space?).maybe >> str("default") >> space? >> default_values).as(:default_clause) }
27
+ rule(:identity_options) { (str("as identity") >> space? >> lparen >> str("start with") >> spaces >>
28
+ integer.as(:start_value) >> (comma|space) >> spaces.maybe >>str("increment by") >> spaces >> integer.as(:increment_value)>> (spaces >> str("cache")>>spaces>>integer.as(:cache_value)).maybe >> spaces.maybe >>rparen).as(:identity) }
29
+
30
+ rule(:column_options) { ((gen_col_def | column_option | default_clause | identity_options) >> spaces).repeat }
31
+
32
+ rule(:column_name) { identifier }
33
+ rule(:constraint_name) { identifier }
34
+ rule(:column_sort) { str("ascending") | str("descending")}
35
+
36
+ rule(:column_definition) { (column_name.as(:field) >> space.repeat >> data_type >> space.repeat >> (column_options.maybe).as(:options)).as(:column)}
37
+
38
+ rule(:index_column_definition) { column_name.as(:field) >> space.repeat >> (column_sort.as(:sort_id) >> space.repeat).maybe }
39
+
40
+ rule(:element_list) { (lparen >> space? >> (column_definition | constraint | primary_key) >> space? >>
41
+ (comma >> space? >> (column_definition | constraint | primary_key) >> space?).repeat >> rparen).as(:elements)
42
+ }
43
+
44
+ rule(:element_list_index) { space? >> index_column_definition >>
45
+ (comma >> space? >> index_column_definition).repeat
46
+ }
47
+
48
+ rule(:add_constraint_clause) { (str("add constraint") >> space? >>
49
+ constraint_name.as(:constraint_name) >> space? >>
50
+ foreign_key_clause.as(:foreign_key_clause)).as(:add_constraint)
51
+ }
52
+ rule(:foreign_key_clause) {str("foreign key") >> space? >> lparen >>
53
+ element_list_index.as(:member_fields) >> space? >> rparen >> space? >>
54
+ reference_clause.as(:reference_clause) >> space? >>
55
+ (on_delete_clause.as(:on_delete_clause) >> space?).maybe >>
56
+ (on_update_clause >> space?).maybe
57
+ }
58
+ rule(:on_delete_clause) {str("on delete") >> space? >>
59
+ (str('no action')|str('restrict')|str('cascade')|str('set null')).as(:on_delete_option) >> space?
60
+ }
61
+ rule(:on_update_clause) {str("on update") >> space? >>
62
+ (str('no action')|str('restrict')).as(:on_update_option) >> space?
63
+ }
64
+
65
+ rule(:alter_table_add_column) do
66
+ (str("add") >> space? >> (str("column") >> space? >> column_definition) | primary_key).as(:add)
67
+ end
68
+
69
+ rule(:alter_table_element) { (alter_table_add_column | add_constraint_clause) >> spaces.maybe }
70
+
71
+ #rule(:alter_table_alter) { }
72
+ #rule(:alter_table_drop) { }
73
+
74
+ rule(:term) { const | item }
75
+
76
+ rule(:function) {
77
+ identifier.as(:function) >> space? >>
78
+ lparen >> arglist.as(:arguments) >> rparen
79
+ }
80
+
81
+ rule(:item) { function | identifier | string }
82
+ rule(:arglist) {
83
+ item.as(:item) >> (comma >> item.as(:item)).repeat
84
+ }
85
+
86
+ rule(:create_table_statement) {
87
+ str('create table').as(:operation) >> space? >> (identifier).as(:table_name)
88
+ }
89
+ rule(:alter_table_statement) {
90
+ str('alter table').as(:operation) >> space? >> (identifier).as(:table_name)
91
+ }
92
+ rule(:create_index_statement) {
93
+ str('create').as(:operation) >> (space? >> str('unique').as(:object_property)).maybe >> space? >> str('index').as(:object_type) >> space? >>
94
+ (identifier).as(:index_name) >> space? >> str('on') >> space? >> (identifier).as(:table_name)
95
+ }
96
+ rule(:create_table) {
97
+ spaces.maybe >> create_table_statement >> spaces >> element_list >> spaces.maybe >> (item >> spaces.maybe).repeat
98
+ }
99
+ rule(:alter_table) {
100
+ spaces.maybe >> alter_table_statement >> spaces >> (alter_table_element.repeat).as(:elements)
101
+ }
102
+ rule(:create_index) {
103
+ spaces.maybe >> create_index_statement >> spaces >> lparen >> element_list_index >> spaces.maybe >> rparen
104
+ }
105
+
106
+ rule(:expression) { create_table | alter_table | create_index}
107
+ root :expression
108
+ end
109
+ end
110
+ end
111
+ end
112
+
@@ -0,0 +1,4 @@
1
+ module DB2
2
+ end
3
+
4
+ require "ddl_parser/ddl/db2/parser"
@@ -0,0 +1,4 @@
1
+ module DDLParser::DDL
2
+ end
3
+
4
+ require "ddl_parser/ddl/db2"
@@ -0,0 +1,48 @@
1
+ class DDLParser::Parser
2
+
3
+ attr_accessor :statement_type, :parse_tree
4
+
5
+ def initialize(statement)
6
+ @statement = statement
7
+ @parse_tree = nil
8
+ @parse_error = nil
9
+ begin
10
+ case @statement.strip
11
+ when /\Acreate\stable.*/i
12
+ @statement_type = :create_table
13
+ @parse_tree = DDLParser::DDL::DB2::Parser.new.create_table.parse(@statement)
14
+ when /\Aalter\stable.*/i
15
+ @statement_type = :alter_table
16
+ @parse_tree = DDLParser::DDL::DB2::Parser.new.alter_table.parse(@statement)
17
+ when /\Acreate.*index.*/i
18
+ @statement_type = :create_index
19
+ @parse_tree = DDLParser::DDL::DB2::Parser.new.create_index.parse(@statement)
20
+ else
21
+ raise "Unknown DDL statement"
22
+ end
23
+ rescue Parslet::ParseFailed => error
24
+ @parse_error = error
25
+ end
26
+ end
27
+
28
+ def valid?
29
+ @parse_error == nil && @parse_tree && @parse_tree.count > 0
30
+ end
31
+
32
+ def errors
33
+ @parse_error.to_s if @parse_error
34
+ end
35
+
36
+ def translate
37
+ case statement_type
38
+ when :create_table
39
+ DDLParser::Translater::CreateTable.new(parse_tree)
40
+ when :alter_table
41
+ DDLParser::Translater::AlterTable.new(parse_tree)
42
+ when :create_index
43
+ DDLParser::Translater::Createindex.new(parse_tree)
44
+ end
45
+ end
46
+
47
+
48
+ end
@@ -0,0 +1,50 @@
1
+ module DDLParser
2
+ module SharedRules
3
+ module Constants
4
+ include Parslet
5
+
6
+ rule(:digit) { match["0-9"] }
7
+ rule(:integer) { (str("-").maybe >> digit.repeat(1)).as(:integer) }
8
+ rule(:float) { (str("-").maybe >> digit.repeat(1) >> str(".") >> digit.repeat(1)).as(:float) }
9
+
10
+ rule(:space) { match('\s').repeat(1) }
11
+ rule(:space?) { space.maybe }
12
+ rule(:newline) { str("\n") }
13
+ rule(:spaces) { (space | (comment? >> newline)).repeat }
14
+ rule(:comment?) { (str("--") >> (newline.absent? >> any).repeat).maybe }
15
+
16
+ rule(:comma) { str(',') >> space? }
17
+ rule(:lparen) { str('(') >> space? }
18
+ rule(:rparen) { str(')') >> space? }
19
+
20
+ rule(:boolean) { (str("true") | str("false")).as(:boolean) }
21
+ rule(:datetime) { (digit.repeat(4) >> str("-") >>
22
+ digit.repeat(2) >> str("-") >>
23
+ digit.repeat(2) >> str("T") >>
24
+ digit.repeat(2) >> str(":") >>
25
+ digit.repeat(2) >> str(":") >>
26
+ digit.repeat(2) >> str("Z")).as(:datetime) }
27
+
28
+
29
+ rule(:string) {
30
+ str("'") >>
31
+ (
32
+ str('\\') >> any |
33
+ str("'").absent? >> any
34
+ ).repeat >>
35
+ str("'")
36
+ }
37
+
38
+ rule(:const) {
39
+ integer | float | string | boolean | datetime
40
+ }
41
+
42
+ rule(:identifier) { match('\\w').repeat(1) }
43
+ rule(:current_timestamp) { str("current timestamp") }
44
+
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+
@@ -0,0 +1,33 @@
1
+ module DDLParser
2
+ module SharedRules
3
+ module DataTypes
4
+ include Parslet
5
+ include DDLParser::SharedRules::Constants
6
+
7
+ # Build-in data types
8
+ rule(:type_smallint) {str("smallint")}
9
+ rule(:type_integer) {(str("integer")| str("int"))}
10
+ rule(:type_bigint) {str("bigint").as(:bigint)}
11
+ rule(:type_decimal) {(((str("decimal") | str('dec') | str('numeric') | str('num')) >>
12
+ (lparen >> integer.as(:total) >> comma >> integer.as(:scale) >> rparen).as(:precision))).as(:decimal)}
13
+ rule(:type_float) {(str("float") >> (lparen >> integer >> rparen).as(:precision)).as(:float)}
14
+ rule(:type_real) {str("real")}
15
+ rule(:type_double) {str("double")}
16
+ rule(:type_char) {((str("character") | str("char")) >> (lparen >> integer >> rparen).as(:length)).as(:char)}
17
+ rule(:type_varchar) {(str("varchar") >> (lparen >> integer >> rparen).as(:length)).as(:varchar)}
18
+ rule(:type_clob) {(str("clob") >> (lparen >> integer >> rparen).as(:length)).as(:clob)}
19
+ rule(:type_date) {str("date")}
20
+ rule(:type_timestamp) {str("timestamp")}
21
+ rule(:type_time) {type_timestamp.absent? >> str("time")}
22
+
23
+
24
+ rule(:data_type) { (type_smallint | type_integer | type_bigint | type_decimal | type_float | type_real |
25
+ type_double | type_char | type_varchar | type_clob | type_date | type_time | type_timestamp).as(:data_type)}
26
+
27
+
28
+ end
29
+ end
30
+ end
31
+
32
+
33
+
@@ -0,0 +1,17 @@
1
+ module DDLParser
2
+ module SharedRules
3
+ module LogicalOperators
4
+ include Parslet
5
+
6
+ # logical operators
7
+ rule(:eq) { str('=') }
8
+ rule(:neq) { str('!=') | str('<>') }
9
+ rule(:gt) { str('>') }
10
+ rule(:lt) { str('<') }
11
+ rule(:geq) { str('>=') }
12
+ rule(:leq) { str('<=') }
13
+ rule(:like) { str('like') }
14
+ rule(:binop) { eq | neq | gt | lt | geq | leq | like}
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,6 @@
1
+ module DDLParser::SharedRules
2
+ end
3
+
4
+ require "ddl_parser/shared_rules/constants"
5
+ require "ddl_parser/shared_rules/data_types"
6
+ require "ddl_parser/shared_rules/logical_operators"
@@ -0,0 +1,67 @@
1
+ module DDLParser
2
+ module SQL
3
+ module DB2
4
+ class SelectParser < Parslet::Parser
5
+
6
+ include DDLParser::SharedRules::Constants
7
+ include DDLParser::SharedRules::LogicalOperators
8
+
9
+ rule(:term) { const | item }
10
+
11
+ rule(:bool_and) { str('and') }
12
+ rule(:bool_or) { str('or') }
13
+
14
+ rule(:identifier) { match('\\w').repeat(1) }
15
+
16
+ rule(:function) {
17
+ identifier.as(:function) >> space? >>
18
+ lparen >> arglist.as(:arguments) >> rparen
19
+ }
20
+
21
+ rule(:item) { function | identifier | string }
22
+
23
+ rule(:arglist) {
24
+ item.as(:item) >> (comma >> item.as(:item)).repeat
25
+ }
26
+ rule(:namelist) {
27
+ identifier.as(:name) >> (comma >> identifier.as(:name)).repeat
28
+ }
29
+
30
+ rule(:between_cond){
31
+ term.as(:lhs) >> space? >> str('between').as(:op) >> space? >> (const.as(:btw_from) >> space? >> bool_and >> space? >> const.as(:btw_to)).as(:rhs)
32
+ }
33
+
34
+ rule(:single_cond){
35
+ (term.as(:lhs) >> space? >> binop.as(:op) >> space? >> term.as(:rhs)) | between_cond
36
+ }
37
+
38
+ rule(:condition) {
39
+ single_cond.as(:lhs) >> space? >>
40
+ ((bool_and.as(:op) | bool_or.as(:op)) >>
41
+ space? >>
42
+ condition.as(:rhs)).maybe
43
+ }
44
+
45
+ rule(:select_s) {
46
+ str('select').as(:op) >> space? >> (arglist | str('*')).as(:select)
47
+ }
48
+ rule(:from_s) {
49
+ str('from') >> space? >> namelist.as(:from)
50
+ }
51
+ rule(:where_s) {
52
+ str('where') >> space? >> condition.as(:where)
53
+ }
54
+ rule(:group_s) {
55
+ str('group') >> space? >> str('by') >> space? >> item.as(:group_by)
56
+ }
57
+ rule(:select) {
58
+ select_s >> space? >> from_s >> space? >>
59
+ (where_s >> space? >> group_s.maybe | group_s).maybe
60
+ }
61
+
62
+ rule(:expression) { select } #| insert | create }
63
+ root :expression
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,4 @@
1
+ module DB2
2
+ end
3
+
4
+ require "ddl_parser/sql/db2/select_parser"
@@ -0,0 +1,4 @@
1
+ module DDLParser::SQL
2
+ end
3
+
4
+ require "ddl_parser/sql/db2"
@@ -0,0 +1,20 @@
1
+ class DDLParser::Translater::AlterTable
2
+
3
+ attr_accessor :parse_tree
4
+ def initialize(parse_tree)
5
+ @parse_tree=parse_tree
6
+ end
7
+
8
+ def elements
9
+ [@parse_tree[:elements]].flatten
10
+ end
11
+
12
+ def table_name
13
+ @parse_tree[:table_name]
14
+ end
15
+
16
+ def add_columns
17
+ elements.map{|e|e[:add]}.compact.map{|e|e[:column]}.compact
18
+ end
19
+
20
+ end
@@ -0,0 +1,24 @@
1
+ class DDLParser::Translater::CreateIndex
2
+
3
+ attr_accessor :parse_tree
4
+ def initialize(parse_tree)
5
+ @parse_tree=parse_tree
6
+ end
7
+
8
+ def elements
9
+ [@parse_tree[:elements]].flatten
10
+ end
11
+
12
+ def table_name
13
+ @parse_tree[:table_name]
14
+ end
15
+
16
+ def columns
17
+ elements.map{|e|e[:column]}.compact
18
+ end
19
+
20
+ def primary_key
21
+ elements.map{|e| e[:primary_key]}.compact.first[:item]
22
+ end
23
+
24
+ end
@@ -0,0 +1,27 @@
1
+ class DDLParser::Translater::CreateTable
2
+ attr_accessor :parse_tree
3
+ def initialize(parse_tree)
4
+ @parse_tree=parse_tree
5
+ end
6
+
7
+ def elements
8
+ [@parse_tree[:elements]].flatten
9
+ end
10
+
11
+ def table_name
12
+ @parse_tree[:table_name].to_s
13
+ end
14
+
15
+ def columns
16
+ elements.map{|e|e[:column]}.compact
17
+ end
18
+
19
+ def primary_key
20
+ elements.map{|e| e[:primary_key]}.compact.first[:item]
21
+ end
22
+
23
+ def constraints
24
+ elements.map{|e|e[:constraint]}.compact
25
+ end
26
+
27
+ end
@@ -0,0 +1,6 @@
1
+ module DDLParser::Translater
2
+ end
3
+
4
+ require "ddl_parser/translater/create_table"
5
+ require "ddl_parser/translater/alter_table"
6
+ require "ddl_parser/translater/create_index"
@@ -0,0 +1,3 @@
1
+ module DDLParser
2
+ VERSION = "0.0.2"
3
+ end
data/lib/ddl_parser.rb ADDED
@@ -0,0 +1,16 @@
1
+ require "parslet"
2
+ require "time"
3
+ require "parslet_extentions"
4
+ require "ddl_parser/version"
5
+
6
+ module DDLParser
7
+ Error = Class.new StandardError
8
+ ParseError = Class.new Error
9
+ end
10
+
11
+ require "ddl_parser/shared_rules"
12
+ require "ddl_parser/sql"
13
+ require "ddl_parser/ddl"
14
+ require "ddl_parser/parser"
15
+ require "ddl_parser/translater"
16
+
@@ -0,0 +1,17 @@
1
+ module Parslet
2
+
3
+ class Source
4
+
5
+ # make new version thats case insensitive
6
+ alias sensitive_matches? matches?
7
+ def matches?(pattern)
8
+ if pattern.is_a?(String)
9
+ @str.downcase.index(pattern.downcase, @pos) == @pos
10
+ else
11
+ sensitive_matches?(pattern)
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ end