Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

* ...

## 0.5.0 2025-07-09

### Added
* Introduced `:meta_tables_after_main` option as a more flexible replacement for `:indexes_after_tables`.
This option places indexes and deferrable constraints after their respective `CREATE TABLE` statements.

### Deprecated
* `:indexes_after_tables` is now deprecated and will be removed in version 1.0.0.
Please migrate to the new `:meta_tables_after_main` option.

## 0.4.3 2024-09-22

* Fix additional regexp warnings from "rake test". [#50](https://github.com/lfittl/activerecord-clean-db-structure/pull/50)
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
activerecord-clean-db-structure (0.4.3)
activerecord-clean-db-structure (0.5.0)
activerecord (>= 4.2)

GEM
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ end

## Other options

### indexes_after_tables
### meta_tables_after_main

You can optionally have indexes following the respective tables setting `indexes_after_tables`:
You can optionally place indexes and constraints (limited to deferrable ones) after the main tables by setting meta_tables_after_main:

```ruby
Rails.application.configure do
config.activerecord_clean_db_structure.indexes_after_tables = true
config.activerecord_clean_db_structure.meta_tables_after_main = true
end
```

Expand All @@ -61,6 +61,7 @@ CREATE TABLE public.users (

CREATE INDEX index_users_on_tentant_id ON public.users USING btree (tenant_id);
CREATE UNIQUE INDEX index_users_on_email ON public.users USING btree (email);
ALTER TABLE public.users ADD CONSTRAINT unique_tenant UNIQUE (tenant_id) DEFERRABLE INITIALLY DEFERRED;
```

### order_column_definitions
Expand Down
23 changes: 20 additions & 3 deletions lib/activerecord-clean-db-structure/clean_dump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,34 @@ def clean_options
dump.gsub!(/^(INSERT INTO schema_migrations .*)\n\n/, "\\1\n")
end

if options[:indexes_after_tables] == true
# Extract indexes, remove comments and place them just after the respective tables
# TODO: Remove support for :indexes_after_tables in version 1.0.0
if options[:indexes_after_tables]
warn "[DEPRECATION] The :indexes_after_tables option is deprecated and will be removed in version 1.0.0. Use :meta_tables_after_main instead."
end

if options[:indexes_after_tables] || options[:meta_tables_after_main]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to leave a comment to indicate options[:indexes_after_tables] is the old option and is deprecated, and maybe specify a version where it will be removed? We could also add the deprecation announcement into the release notes.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andyatkinson like so?

# Extract indexes
indexes =
dump
.scan(/^CREATE.+INDEX.+ON.+\n/)
.group_by { |line| line.scan(/\b\w+\.\w+\b/).first }
.transform_values(&:join)

# Extract deferrable constraints
deferrable_constraints =
dump
.scan(/^ALTER.+TABLE.+ONLY.+\n.+DEFERRABLE.+\n/)
.group_by { |line| line.scan(/\b\w+\.\w+\b/).first }
.transform_values(&:join)

# Remove indexes and deferrable constraints from the dump
dump.gsub!(/^CREATE( UNIQUE)? INDEX \w+ ON .+\n+/, '')
dump.gsub!(/^-- Name: \w+; Type: INDEX; Schema: \w+\n+/, '')
indexes.each do |table, indexes_for_table|

dump.gsub!(/^-- Name.+\n\nALTER.+TABLE.+ONLY.+\n.+DEFERRABLE.+\n+/, '')

indexes_and_constraints = indexes.merge(deferrable_constraints) { |_, v1, v2| v1 + v2 }
indexes_and_constraints.each do |table, indexes_for_table|
dump.gsub!(/^(CREATE TABLE #{table}\b(:?[^;\n]*\n)+\);*\n(?:.*);*)/) { $1 + "\n\n" + indexes_for_table }
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/activerecord-clean-db-structure/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module ActiveRecordCleanDbStructure
VERSION = '0.4.3'
VERSION = '0.5.0'
end
4 changes: 2 additions & 2 deletions test/clean_dump_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ def test_order_schema_migrations_values
assert_cleans_dump "data/input.sql", "expectations/order_schema_migrations_values.sql", order_schema_migrations_values: true
end

def test_indexes_after_tables
assert_cleans_dump "data/input.sql", "expectations/indexes_after_tables.sql", indexes_after_tables: true
def test_meta_tables_after_main
assert_cleans_dump "data/input.sql", "expectations/meta_tables_after_main.sql", meta_tables_after_main: true
end

def test_keep_extensions_all
Expand Down
5 changes: 5 additions & 0 deletions test/data/input.sql
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,11 @@ ALTER TABLE ONLY public.ar_internal_metadata
ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT delayed_jobs_pkey PRIMARY KEY (id);

--
-- Name: unique_locked_by_locked_at; Type: CONSTRAINT
--
ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

--
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
Expand Down
5 changes: 5 additions & 0 deletions test/expectations/default_props.sql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ CREATE TABLE public.schema_migrations (
ALTER TABLE ONLY public.ar_internal_metadata
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);

-- Name: unique_locked_by_locked_at; Type: CONSTRAINT

ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

ALTER TABLE ONLY public.schema_migrations
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);

Expand Down
5 changes: 5 additions & 0 deletions test/expectations/ignore_ids.sql
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ ALTER TABLE ONLY public.ar_internal_metadata
ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT delayed_jobs_pkey PRIMARY KEY (id);

-- Name: unique_locked_by_locked_at; Type: CONSTRAINT

ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT

ALTER TABLE ONLY public.schema_migrations
Expand Down
5 changes: 5 additions & 0 deletions test/expectations/keep_extensions_all.sql
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ CREATE TABLE public.schema_migrations (
ALTER TABLE ONLY public.ar_internal_metadata
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);

-- Name: unique_locked_by_locked_at; Type: CONSTRAINT

ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

ALTER TABLE ONLY public.schema_migrations
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ WITH (fillfactor='85');
CREATE INDEX index_delayed_jobs_on_locked_by ON public.delayed_jobs USING btree (locked_by);
CREATE INDEX index_delayed_jobs_on_queue ON public.delayed_jobs USING btree (queue);
CREATE INDEX index_delayed_jobs_on_run_at ON public.delayed_jobs USING btree (run_at) WHERE (locked_at IS NULL);
ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

-- Name: schema_migrations; Type: TABLE

Expand Down
5 changes: 5 additions & 0 deletions test/expectations/order_column_definitions.sql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ CREATE TABLE public.schema_migrations (
ALTER TABLE ONLY public.ar_internal_metadata
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);

-- Name: unique_locked_by_locked_at; Type: CONSTRAINT

ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

ALTER TABLE ONLY public.schema_migrations
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);

Expand Down
5 changes: 5 additions & 0 deletions test/expectations/order_schema_migrations_values.sql
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ CREATE TABLE public.schema_migrations (
ALTER TABLE ONLY public.ar_internal_metadata
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);

-- Name: unique_locked_by_locked_at; Type: CONSTRAINT

ALTER TABLE ONLY public.delayed_jobs
ADD CONSTRAINT unique_locked_by_locked_at UNIQUE (locked_by, locked_at) DEFERRABLE INITIALLY DEFERRED;

ALTER TABLE ONLY public.schema_migrations
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);

Expand Down