From fa7eaf3f9726b28d9bc20dcc36e47ff1c622bbe4 Mon Sep 17 00:00:00 2001 From: Nicke van Oorschot Date: Sat, 18 Apr 2020 12:24:53 +0200 Subject: [PATCH 1/3] Split primary_keys and sequences cleanups --- .../clean_dump.rb | 51 ++++++++++++++----- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/lib/activerecord-clean-db-structure/clean_dump.rb b/lib/activerecord-clean-db-structure/clean_dump.rb index 8abb6c5..dbeeda7 100644 --- a/lib/activerecord-clean-db-structure/clean_dump.rb +++ b/lib/activerecord-clean-db-structure/clean_dump.rb @@ -38,21 +38,10 @@ def run # Remove useless comment lines dump.gsub!(/^--$/, '') + # Reduce noise for id fields by making them (BIG)SERIAL instead of integer+sequence stuff unless options[:ignore_ids] == true - # Reduce noise for id fields by making them SERIAL instead of integer+sequence stuff - # - # This is a bit optimistic, but works as long as you don't have an id field thats not a sequence/uuid - dump.gsub!(/^ id integer NOT NULL(,)?$/, ' id SERIAL PRIMARY KEY\1') - dump.gsub!(/^ id bigint NOT NULL(,)?$/, ' id BIGSERIAL PRIMARY KEY\1') - dump.gsub!(/^ id uuid DEFAULT ([\w_]+\.)?uuid_generate_v4\(\) NOT NULL(,)?$/, ' id uuid DEFAULT \1uuid_generate_v4() PRIMARY KEY\2') - dump.gsub!(/^ id uuid DEFAULT ([\w_]+\.)?gen_random_uuid\(\) NOT NULL(,)?$/, ' id uuid DEFAULT \1gen_random_uuid() PRIMARY KEY\2') - dump.gsub!(/^CREATE SEQUENCE [\w\.]+_id_seq\s+(AS integer\s+)?START WITH 1\s+INCREMENT BY 1\s+NO MINVALUE\s+NO MAXVALUE\s+CACHE 1;$/, '') - dump.gsub!(/^ALTER SEQUENCE [\w\.]+_id_seq OWNED BY .*;$/, '') - dump.gsub!(/^ALTER TABLE ONLY [\w\.]+ ALTER COLUMN id SET DEFAULT nextval\('[\w\.]+_id_seq'::regclass\);$/, '') - dump.gsub!(/^ALTER TABLE ONLY [\w\.]+\s+ADD CONSTRAINT [\w\.]+_pkey PRIMARY KEY \(id\);$/, '') - dump.gsub!(/^-- Name: (\w+\s+)?id; Type: DEFAULT$/, '') - dump.gsub!(/^-- .*_id_seq; Type: SEQUENCE.*/, '') - dump.gsub!(/^-- Name: (\w+\s+)?\w+_pkey; Type: CONSTRAINT$/, '') + sequences_cleanup + primary_keys_cleanup end # Remove inherited tables @@ -173,6 +162,40 @@ def order_column_definitions(source) private + # Reduce noise for id fields by making them (BIG)SERIAL instead of integer+sequence stuff + # + # WARN: might add the (BIG)SERIAL property to columns for which no sequence was originally defined. + # NOTE: does not work work for columns with a name other than 'id' + # NOTE: does not work for SMALLSERIAL + def sequences_cleanup + dump.gsub!(/^ id integer NOT NULL(,)?$/, ' id SERIAL\1') + dump.gsub!(/^ id bigint NOT NULL(,)?$/, ' id BIGSERIAL\1') + dump.gsub!(/^CREATE SEQUENCE [\w\.]+_id_seq\s+(AS integer\s+)?START WITH 1\s+INCREMENT BY 1\s+NO MINVALUE\s+NO MAXVALUE\s+CACHE 1;$/, '') + dump.gsub!(/^ALTER SEQUENCE [\w\.]+_id_seq OWNED BY .*;$/, '') + dump.gsub!(/^ALTER TABLE ONLY [\w\.]+ ALTER COLUMN id SET DEFAULT nextval\('[\w\.]+_id_seq'::regclass\);$/, '') + dump.gsub!(/^-- Name: (\w+\s+)?id; Type: DEFAULT$/, '') + dump.gsub!(/^-- .*_id_seq; Type: SEQUENCE.*/, '') + end + + # Moves the separate primary key statements to the create table statements. + def primary_keys_cleanup + primary_keys = [] + + # Removes the ADD CONSTRAINT statements for primary keys and stores the info of which statements have been removed. + dump.gsub!(/^-- Name: [\w\s]+?(?\w+_pkey); Type: CONSTRAINT[\s-]+ALTER TABLE ONLY (?[\w.]+)\s+ADD CONSTRAINT \k PRIMARY KEY \((?[^,\)]+)\);$/) do + primary_keys.push([$LAST_MATCH_INFO[:table], $LAST_MATCH_INFO[:column]]) + + '' + end + + # Adds the PRIMARY KEY property to each column for which it's statement has just been removed. + primary_keys.each do |table, column| + dump.gsub!(/^(?CREATE TABLE #{table} \(.*\s+#{column}\s+[^,]+)/) do + "#{$LAST_MATCH_INFO[:statement].remove(/ NOT NULL\z/)} PRIMARY KEY" + end + end + end + # Cleanup of schema_migrations values to prevent merge conflicts: # - sorts all values chronological # - places the comma's in front of each value (except for the first) From 6977044d701c4d1d9c38c63b965bb44830b544e4 Mon Sep 17 00:00:00 2001 From: Nicke van Oorschot Date: Mon, 29 Jun 2020 12:57:33 +0200 Subject: [PATCH 2/3] Fix bug where pk column is last in the table --- lib/activerecord-clean-db-structure/clean_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/activerecord-clean-db-structure/clean_dump.rb b/lib/activerecord-clean-db-structure/clean_dump.rb index dbeeda7..773f33b 100644 --- a/lib/activerecord-clean-db-structure/clean_dump.rb +++ b/lib/activerecord-clean-db-structure/clean_dump.rb @@ -190,7 +190,7 @@ def primary_keys_cleanup # Adds the PRIMARY KEY property to each column for which it's statement has just been removed. primary_keys.each do |table, column| - dump.gsub!(/^(?CREATE TABLE #{table} \(.*\s+#{column}\s+[^,]+)/) do + dump.gsub!(/^(?CREATE TABLE #{table} \(.*\s+#{column}\s+[^,\n]+)/) do "#{$LAST_MATCH_INFO[:statement].remove(/ NOT NULL\z/)} PRIMARY KEY" end end From 33e6ee4d876ade551121ac655d938e47f59f5dc2 Mon Sep 17 00:00:00 2001 From: Nicke van Oorschot Date: Mon, 26 Oct 2020 12:14:13 +0100 Subject: [PATCH 3/3] Fix for primary keys not defined as the first column --- lib/activerecord-clean-db-structure/clean_dump.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/activerecord-clean-db-structure/clean_dump.rb b/lib/activerecord-clean-db-structure/clean_dump.rb index 773f33b..281fb40 100644 --- a/lib/activerecord-clean-db-structure/clean_dump.rb +++ b/lib/activerecord-clean-db-structure/clean_dump.rb @@ -190,7 +190,7 @@ def primary_keys_cleanup # Adds the PRIMARY KEY property to each column for which it's statement has just been removed. primary_keys.each do |table, column| - dump.gsub!(/^(?CREATE TABLE #{table} \(.*\s+#{column}\s+[^,\n]+)/) do + dump.gsub!(/^(?CREATE TABLE #{table} \(.*?\s+#{column}\s+[^,\n]+)/m) do "#{$LAST_MATCH_INFO[:statement].remove(/ NOT NULL\z/)} PRIMARY KEY" end end