From 3520be1fdc8e2f9c2a02ad26b9bcf8c6c628ef70 Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Fri, 21 Dec 2018 17:18:39 -0500 Subject: [PATCH 1/2] fix dumping expression indexes --- .../core/active_record/schema_dumper.rb | 81 ++++++++++++------- spec/dumper_spec.rb | 14 ++++ 2 files changed, 68 insertions(+), 27 deletions(-) diff --git a/lib/schema_plus/core/active_record/schema_dumper.rb b/lib/schema_plus/core/active_record/schema_dumper.rb index 4d1d591..c460856 100644 --- a/lib/schema_plus/core/active_record/schema_dumper.rb +++ b/lib/schema_plus/core/active_record/schema_dumper.rb @@ -44,6 +44,54 @@ def tables(_) end end + TABLE_COLUMN_MATCHES = [ + [ # first match expression index case + %r{ + ^ + t\.index \s* + "(?(?:[^"\\]|\\.)*?)" \s* + , \s* + name\: \s* [:'"](?[^"\s]+)[,"]? \s* + ,? \s* + (?.*) + $ + }x, + ->(m) { + index_cols = m[:index_cols].gsub('\\"', '"') + SchemaDump::Table::Index.new name: m[:name], columns: index_cols, options: eval("{" + m[:options] + "}") + } + ], + [ # general matching of columns + %r{ + ^ + t\.(?\S+) \s* + [:'"](?[^"\s]+)[,"]? \s* + ,? \s* + (?.*) + $ + }x, + ->(m) { + SchemaDump::Table::Column.new name: m[:name], type: m[:type], options: eval("{" + m[:options] + "}"), comments: [] + } + ], + [ # index definitions with multiple columns + %r{ + ^ + t\.index \s* + \[(?.*?)\] \s* + , \s* + name\: \s* [:'"](?[^"\s]+)[,"]? \s* + ,? \s* + (?.*) + $ + }x, + ->(m) { + index_cols = m[:index_cols].tr(%q{'":}, '').strip.split(/\s*,\s*/) + SchemaDump::Table::Index.new name: m[:name], columns: index_cols, options: eval("{#{m[:options]}}") + } + ] + ].freeze + def table(table, _) SchemaMonkey::Middleware::Dumper::Table.start(dumper: self, connection: @connection, dump: @dump, table: @dump.tables[table] = SchemaDump::Table.new(name: table)) do |env| stream = StringIO.new @@ -68,34 +116,13 @@ def table(table, _) env.table.trailer = m[:trailer].split("\n").map(&:strip).reject{|s| s.blank?} table_objects = m[:columns].strip.split("\n").map { |col| cs = col.strip - m = cs.match %r{ - ^ - t\.(?\S+) \s* - [:'"](?[^"\s]+)[,"]? \s* - ,? \s* - (?.*) - $ - }x - if !m.nil? - SchemaDump::Table::Column.new name: m[:name], type: m[:type], options: eval("{" + m[:options] + "}"), comments: [] - else - m = cs.match %r{ - ^ - t\.index \s* - \[(?.*?)\] \s* - , \s* - name\: \s* [:'"](?[^"\s]+)[,"]? \s* - ,? \s* - (?.*) - $ - }x - if m.nil? - nil - else - index_cols = m[:index_cols].tr(%q{'":}, '').strip.split(/\s*,\s*/) - SchemaDump::Table::Index.new name: m[:name], columns: index_cols, options: eval("{#{m[:options]}}") - end + result = nil + # find the first regex that matches and grab the column definition + TABLE_COLUMN_MATCHES.find do |(r, l)| + m = cs.match r + result = m.nil? ? nil : l.call(m) end + result }.reject { |o| o.nil? } env.table.columns = table_objects.select { |o| o.is_a? SchemaDump::Table::Column } env.table.indexes = table_objects.select { |o| o.is_a? SchemaDump::Table::Index } diff --git a/spec/dumper_spec.rb b/spec/dumper_spec.rb index 2d2ccc6..6d523ce 100644 --- a/spec/dumper_spec.rb +++ b/spec/dumper_spec.rb @@ -91,6 +91,20 @@ def after(env) Then { expect(dump).to_not match(/create_table "inttable", id: :serial.*default:/m) } end + + context 'expression index handling', postgresql: :only do + before(:each) do + migration.create_table "expressions" do |t| + t.string :field + t.string :column + t.index 'lower(field), id', name: 'index_expression_field' + t.index 'lower("column"), id', name: 'index_expression_column' + end + end + + Then { expect(dump).to match(/index "lower.+field.+, id", :name=>"index_expression_field"/) } + Then { expect(dump).to match(/index "lower.+"column\\".+, id", :name=>"index_expression_column"/) } + end end context TestDumper::Middleware::Dumper::Table do From c1ec84d504257c3069071cdd1d31aad69f0144fd Mon Sep 17 00:00:00 2001 From: Edward Rudd Date: Sun, 30 Dec 2018 16:45:26 -0500 Subject: [PATCH 2/2] bump to version 2.2.3 --- README.md | 1 + lib/schema_plus/core/version.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f654581..b384377 100644 --- a/README.md +++ b/README.md @@ -444,6 +444,7 @@ SchemaPlus::Core provides a state object and of callbacks to various phases of t ## Release Notes +* 2.2.3 Fix dumping complex expression based indexes in AR 5.x * 2.2.2 Fixed dumping tables in postgresql in AR 5.2 when the PK is not a bigint. * 2.2.1 Fixed expression index handling in AR5.x. * 2.2.0 Added AR5.2 support. Thanks to [@jeremyyap](https://github.com/jeremyyap) diff --git a/lib/schema_plus/core/version.rb b/lib/schema_plus/core/version.rb index 1885b69..e769eed 100644 --- a/lib/schema_plus/core/version.rb +++ b/lib/schema_plus/core/version.rb @@ -1,5 +1,5 @@ module SchemaPlus module Core - VERSION = "2.2.2" + VERSION = "2.2.3" end end