Class: EachSQL
- Inherits:
-
Object
- Object
- EachSQL
- Includes:
- Enumerable
- Defined in:
- lib/each_sql/each_sql.rb,
lib/each_sql.rb
Overview
Enumerable EachSQL object.
Constant Summary collapse
- Defaults =
EachSQL::Default Hash is a set of pre-defined parsing rules
-
:default: Default parsing rules for vendor-independent SQL scripts
-
:mysql: Parsing rules for MySQL scripts. Understands ‘delimiter’ statements.
-
:oracle: Parsing rules for Oracle scripts. Removes trailing slashes after begin-end blocks.
-
{ :default => { :delimiter => /;+/, :blocks => { /`/ => /`/, /"/ => /"/, /'/ => /'/, /\/\*[^+]/ => /\*\//, /--+/ => $/, }, :nesting_blocks => { /\bdeclare.*?;\s*?begin\b/im => /;\s*?end\b/i, /\bbegin\b/i => /;\s*?end\b/i, }, :nesting_context => [ /\A\s*(begin|declare|create\b[^;]+?\b(procedure|function|trigger|package))\b/im ], :callbacks => {}, :ignore => [], :replace => {}, # Let's assume we don't change delimiters within usual sql scripts :strip_delimiter => lambda { |obj, stmt| stmt.sub(/\A;+/, '').sub(/;+\Z/, '') } }, :mysql => { :delimiter => /;+|delimiter\s+\S+/i, :blocks => { /`/ => /`/, /"/ => /"/, /'/ => /'/, /\/\*[^+]/ => /\*\//, /--+/ => $/, }, :nesting_blocks => { /\bbegin\b/i => /\bend\b/i }, :nesting_context => [ /\A\s*(begin|create\b[^;]+?\b(procedure|function|trigger))\b/im ], # We need to change delimiter on `delimiter' command :callbacks => { /^\s*delimiter\s+(\S+)/i => lambda { |obj, stmt, md| new_delimiter = Regexp.new(Regexp.escape md[1]) obj.delimiter = /(#{new_delimiter})+|delimiter\s+\S+/i obj.delimiter_string = md[1] } }, :ignore => [ /^delimiter\s+\S+$/i ], :replace => {}, :strip_delimiter => lambda { |obj, stmt| stmt.gsub(/(#{Regexp.escape(obj.delimiter_string || ';')})+\Z/, '') } }, :oracle => { :delimiter => /;+/, :blocks => { /`/ => /`/, /"/ => /"/, /'/ => /'/, /\/\*[^+]/ => /\*\//, /--+/ => $/, }, :nesting_blocks => { /\bbegin\b/i => /\bend\b/i, /\bdeclare.*?;\s*?begin\b/im => { :closer => %r{;\s*/}m, # Stops immediately :pop => true }, /\bcreate[^;]+?\b(procedure|function|trigger|package)\b/im => { :closer => %r{;\s*/}m, # Stops immediately :pop => true } }, :nesting_context => [ /\A\s*(\/\s*)*(begin|declare|create\b[^;]+?\b(procedure|function|trigger|package))\b/im ], :callbacks => { /\Abegin\b/ => lambda { |obj, stmt, md| # Oracle needs this stmt << ';' if stmt !~ /;\Z/ } }, :ignore => [], :replace => { %r[\A/] => '' }, :strip_delimiter => lambda { |obj, stmt| stmt.gsub(/(#{stmt =~ /;\s*\// ? '/' : ';'})+\Z/, '') } } }
Instance Attribute Summary collapse
-
#delimiter ⇒ Object
To change delimiter while parsing the input.
-
#delimiter_string ⇒ Object
To change delimiter while parsing the input.
Instance Method Summary collapse
- #each ⇒ Object
-
#initialize(input, options) ⇒ EachSQL
constructor
A new instance of EachSQL.
Constructor Details
#initialize(input, options) ⇒ EachSQL
Returns a new instance of EachSQL.
8 9 10 11 12 13 14 15 16 |
# File 'lib/each_sql/each_sql.rb', line 8 def initialize input, raise NotImplementedError.new if .nil? # immutables @org_input = input && input.sub(/\A#{[65279].pack('U*')}/, '') # BOM @options = @blocks = @options[:blocks] @nblocks = @options[:nesting_blocks] @all_blocks = @blocks.merge @nblocks end |
Instance Attribute Details
#delimiter ⇒ Object
To change delimiter while parsing the input
57 58 59 |
# File 'lib/each_sql/each_sql.rb', line 57 def delimiter @delimiter end |
#delimiter_string ⇒ Object
To change delimiter while parsing the input
57 58 59 |
# File 'lib/each_sql/each_sql.rb', line 57 def delimiter_string @delimiter_string end |
Instance Method Details
#each ⇒ Object
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/each_sql/each_sql.rb', line 18 def each return nil if @org_input.nil? || @org_input.empty? @input = @org_input.dup # Zero out comments and string literals to simplify subsequent parsing @input_c = zero_out @org_input @delimiter = @options[:delimiter] while @input && @input.length > 0 # Extract a statement statement = next_statement # When a non-empty statement is found statement = @options[:strip_delimiter].call self, statement if @options[:strip_delimiter] if statement.length > 0 # Apply replacements @options[:replace].each do |k, v| statement.gsub!(k, v) end statement.strip! # Process callbacks @options[:callbacks].each do |pattern, callback| #md = statement.match pattern md = zero_out(statement).strip.match pattern callback.call self, statement, md if md end # Ignore if (@options[:ignore] || []).all? { |ipat| statement !~ ipat } && statement.empty? == false yield statement @prev_statement = statement end end end nil end |