Module: Exwiw::DdlPostprocessor
- Defined in:
- lib/exwiw/ddl_postprocessor.rb
Overview
Rewrites raw CREATE statements emitted by mysqldump / pg_dump / sqlite_master.sql into idempotent forms so the generated ‘insert-000-schema.sql` file can be re-applied without error.
Constant Summary collapse
- ADD_CONSTRAINT_RE =
‘ALTER TABLE … ADD CONSTRAINT …;` is not idempotent on its own. PostgreSQL’s PL/pgSQL has no IF-NOT-EXISTS clause for ADD CONSTRAINT, so wrap each statement in a DO block that swallows ‘duplicate_object`. Matches only statements whose ALTER TABLE clause leads directly into ADD CONSTRAINT (no intervening ALTER COLUMN / DROP / etc) so that unrelated ALTER TABLE statements in the same dump are not absorbed.
/^[ \t]*ALTER\s+TABLE\s+(?:ONLY\s+)?[^\s;,]+\s+(?:\n[ \t]*)?ADD\s+CONSTRAINT\b[^;]*;/m.freeze
Class Method Summary collapse
-
.add_if_not_exists_to_create_index(sql) ⇒ Object
‘CREATE [UNIQUE] INDEX [name]` → `CREATE [UNIQUE] INDEX IF NOT EXISTS [name]`.
-
.add_if_not_exists_to_create_schema(sql) ⇒ Object
‘CREATE SCHEMA [name]` → `CREATE SCHEMA IF NOT EXISTS [name]`.
-
.add_if_not_exists_to_create_sequence(sql) ⇒ Object
‘CREATE SEQUENCE [name]` → `CREATE SEQUENCE IF NOT EXISTS [name]`.
-
.add_if_not_exists_to_create_table(sql) ⇒ Object
‘CREATE TABLE [name]` → `CREATE TABLE IF NOT EXISTS [name]`.
- .wrap_add_constraint_in_do_block(sql) ⇒ Object
Class Method Details
.add_if_not_exists_to_create_index(sql) ⇒ Object
‘CREATE [UNIQUE] INDEX [name]` → `CREATE [UNIQUE] INDEX IF NOT EXISTS [name]`. Use only for databases that support it (PostgreSQL, SQLite). MySQL does NOT support `CREATE INDEX IF NOT EXISTS` — do not call from the MySQL adapter.
21 22 23 24 25 26 |
# File 'lib/exwiw/ddl_postprocessor.rb', line 21 def add_if_not_exists_to_create_index(sql) sql.gsub(/\bCREATE(\s+UNIQUE)?\s+INDEX\b(?!\s+IF\s+NOT\s+EXISTS)/i) do unique = Regexp.last_match(1) || "" "CREATE#{unique} INDEX IF NOT EXISTS" end end |
.add_if_not_exists_to_create_schema(sql) ⇒ Object
‘CREATE SCHEMA [name]` → `CREATE SCHEMA IF NOT EXISTS [name]`.
29 30 31 32 33 |
# File 'lib/exwiw/ddl_postprocessor.rb', line 29 def add_if_not_exists_to_create_schema(sql) sql.gsub(/\bCREATE\s+SCHEMA\b(?!\s+IF\s+NOT\s+EXISTS)/i) do |m| "#{m} IF NOT EXISTS" end end |
.add_if_not_exists_to_create_sequence(sql) ⇒ Object
‘CREATE SEQUENCE [name]` → `CREATE SEQUENCE IF NOT EXISTS [name]`.
36 37 38 39 40 |
# File 'lib/exwiw/ddl_postprocessor.rb', line 36 def add_if_not_exists_to_create_sequence(sql) sql.gsub(/\bCREATE\s+SEQUENCE\b(?!\s+IF\s+NOT\s+EXISTS)/i) do |m| "#{m} IF NOT EXISTS" end end |
.add_if_not_exists_to_create_table(sql) ⇒ Object
‘CREATE TABLE [name]` → `CREATE TABLE IF NOT EXISTS [name]`. `TEMP` / `TEMPORARY` variants and already-IF-NOT-EXISTS lines are skipped.
12 13 14 15 16 |
# File 'lib/exwiw/ddl_postprocessor.rb', line 12 def add_if_not_exists_to_create_table(sql) sql.gsub(/\bCREATE\s+TABLE\b(?!\s+IF\s+NOT\s+EXISTS)/i) do |m| "#{m} IF NOT EXISTS" end end |
.wrap_add_constraint_in_do_block(sql) ⇒ Object
50 51 52 53 54 55 56 57 58 59 |
# File 'lib/exwiw/ddl_postprocessor.rb', line 50 def wrap_add_constraint_in_do_block(sql) sql.gsub(ADD_CONSTRAINT_RE) do |stmt| <<~SQL.chomp DO $exwiw$ BEGIN #{stmt.strip} EXCEPTION WHEN duplicate_object THEN NULL; END $exwiw$; SQL end end |