Skip to content

Commit

Permalink
fix dumping expression indexes
Browse files Browse the repository at this point in the history
  • Loading branch information
urkle committed Dec 28, 2018
1 parent 7974a67 commit 773c810
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 27 deletions.
80 changes: 53 additions & 27 deletions lib/schema_plus/core/active_record/schema_dumper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,54 @@ def tables(_)
end
end

TABLE_COLUMN_MATCHES = [
[ # first match expression index case
%r{
^
t\.index \s*
"(?<index_cols>(?:[^"\\]|\\.)*?)" \s*
, \s*
name\: \s* [:'"](?<name>[^"\s]+)[,"]? \s*
,? \s*
(?<options>.*)
$
}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\.(?<type>\S+) \s*
[:'"](?<name>[^"\s]+)[,"]? \s*
,? \s*
(?<options>.*)
$
}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*
\[(?<index_cols>.*?)\] \s*
, \s*
name\: \s* [:'"](?<name>[^"\s]+)[,"]? \s*
,? \s*
(?<options>.*)
$
}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
Expand All @@ -68,34 +116,12 @@ 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\.(?<type>\S+) \s*
[:'"](?<name>[^"\s]+)[,"]? \s*
,? \s*
(?<options>.*)
$
}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*
\[(?<index_cols>.*?)\] \s*
, \s*
name\: \s* [:'"](?<name>[^"\s]+)[,"]? \s*
,? \s*
(?<options>.*)
$
}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
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 }
Expand Down
14 changes: 14 additions & 0 deletions spec/dumper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 773c810

Please sign in to comment.