Skip to content

Commit d53cfe4

Browse files
authored
Merge pull request #46 from ghiculescu/patch-1
Handle tables with custom `fillfactor` + add tests + add CI
2 parents 4ad3632 + 2c31cd2 commit d53cfe4

File tree

13 files changed

+752
-15
lines changed

13 files changed

+752
-15
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: CI
2+
on:
3+
pull_request:
4+
jobs:
5+
test:
6+
runs-on: ubuntu-latest
7+
strategy:
8+
matrix:
9+
ruby: ["3.1", "3.2"]
10+
steps:
11+
- uses: actions/checkout@v3
12+
- uses: ruby/setup-ruby@v1
13+
with:
14+
ruby-version: ${{ matrix.ruby }}
15+
bundler-cache: true
16+
- run: bundle exec rake test

Gemfile.lock

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,45 @@ PATH
77
GEM
88
remote: https://rubygems.org/
99
specs:
10-
activemodel (7.0.4.3)
11-
activesupport (= 7.0.4.3)
12-
activerecord (7.0.4.3)
13-
activemodel (= 7.0.4.3)
14-
activesupport (= 7.0.4.3)
15-
activesupport (7.0.4.3)
16-
concurrent-ruby (~> 1.0, >= 1.0.2)
10+
activemodel (7.2.1)
11+
activesupport (= 7.2.1)
12+
activerecord (7.2.1)
13+
activemodel (= 7.2.1)
14+
activesupport (= 7.2.1)
15+
timeout (>= 0.4.0)
16+
activesupport (7.2.1)
17+
base64
18+
bigdecimal
19+
concurrent-ruby (~> 1.0, >= 1.3.1)
20+
connection_pool (>= 2.2.5)
21+
drb
1722
i18n (>= 1.6, < 2)
23+
logger (>= 1.4.2)
1824
minitest (>= 5.1)
19-
tzinfo (~> 2.0)
20-
concurrent-ruby (1.3.3)
25+
securerandom (>= 0.3)
26+
tzinfo (~> 2.0, >= 2.0.5)
27+
base64 (0.2.0)
28+
bigdecimal (3.1.8)
29+
concurrent-ruby (1.3.4)
30+
connection_pool (2.4.1)
31+
drb (2.2.1)
2132
i18n (1.14.5)
2233
concurrent-ruby (~> 1.0)
23-
minitest (5.24.1)
24-
rake (13.0.6)
34+
logger (1.6.1)
35+
minitest (5.25.1)
36+
rake (13.2.1)
37+
securerandom (0.3.1)
38+
timeout (0.4.1)
2539
tzinfo (2.0.6)
2640
concurrent-ruby (~> 1.0)
2741

2842
PLATFORMS
43+
arm64-darwin-22
2944
ruby
3045

3146
DEPENDENCIES
3247
activerecord-clean-db-structure!
3348
rake (~> 13)
3449

3550
BUNDLED WITH
36-
1.17.3
51+
2.5.18

Rakefile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
11
require 'rubygems'
22
require 'bundler/setup'
33
require 'bundler/gem_tasks'
4+
require "rake/testtask"
5+
6+
Rake::TestTask.new(:test) do |t|
7+
t.libs << "test"
8+
t.libs << "lib"
9+
t.test_files = FileList["test/**/*_test.rb"]
10+
end
11+
12+
task default: %i[test]

lib/activerecord-clean-db-structure/clean_dump.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ def run
8484
partitioned_tables += dump.scan(partitioned_tables_regexp2).map(&:first)
8585

8686
partitioned_tables.each do |partitioned_table|
87-
partitioned_schema_name, partitioned_table_name_only = partitioned_table.split('.', 2)
87+
_partitioned_schema_name, partitioned_table_name_only = partitioned_table.split('.', 2)
8888
dump.gsub!(/-- Name: #{partitioned_table_name_only}; Type: TABLE/, '')
8989
dump.gsub!(/CREATE TABLE #{partitioned_table} \([^;]+;/m, '')
9090
dump.gsub!(/ALTER TABLE ONLY ([\w_\.]+) ATTACH PARTITION #{partitioned_table}[^;]+;/m, '')
@@ -124,7 +124,7 @@ def run
124124
dump.gsub!(/^CREATE( UNIQUE)? INDEX \w+ ON .+\n+/, '')
125125
dump.gsub!(/^-- Name: \w+; Type: INDEX\n+/, '')
126126
indexes.each do |table, indexes_for_table|
127-
dump.gsub!(/^(CREATE TABLE #{table}\b(:?[^;\n]*\n)+\);\n)/) { $1 + "\n" + indexes_for_table }
127+
dump.gsub!(/^(CREATE TABLE #{table}\b(:?[^;\n]*\n)+\);*\n(?:.*);*)/) { $1 + "\n\n" + indexes_for_table }
128128
end
129129
end
130130

@@ -151,7 +151,7 @@ def order_column_definitions(source)
151151
inside_table = true
152152
columns = []
153153
result << source_line
154-
elsif source_line.start_with?(");")
154+
elsif source_line.start_with?(")")
155155
if inside_table
156156
inside_table = false
157157
columns.sort_by!(&:first)

test/clean_dump_test.rb

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
require "test_helper"
2+
3+
class CleanDumpTest < Minitest::Test
4+
def test_basic_case
5+
assert_cleans_dump "expectations/default_props.sql", {}
6+
end
7+
8+
def test_ignore_ids
9+
assert_cleans_dump "expectations/ignore_ids.sql", { ignore_ids: true }
10+
end
11+
12+
def test_order_column_definitions
13+
assert_cleans_dump "expectations/order_column_definitions.sql", { order_column_definitions: true }
14+
end
15+
16+
def test_order_schema_migrations_values
17+
assert_cleans_dump "expectations/order_schema_migrations_values.sql", { order_schema_migrations_values: true }
18+
end
19+
20+
def test_indexes_after_tables
21+
assert_cleans_dump "expectations/indexes_after_tables.sql", { indexes_after_tables: true }
22+
end
23+
24+
def test_keep_extensions_all
25+
assert_cleans_dump "expectations/keep_extensions_all.sql", { keep_extensions: :all }
26+
end
27+
28+
private
29+
30+
def assert_cleans_dump(expected_output_path, props)
31+
cleaner = ActiveRecordCleanDbStructure::CleanDump.new(File.read(File.join(__dir__, "data/input.sql")), props)
32+
cleaner.run
33+
assert_equal File.read(File.join(__dir__, expected_output_path)), cleaner.dump
34+
end
35+
end

test/data/input.sql

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
SET statement_timeout = 0;
2+
SET lock_timeout = 0;
3+
SET idle_in_transaction_session_timeout = 0;
4+
SET client_encoding = 'UTF8';
5+
SET standard_conforming_strings = on;
6+
SELECT pg_catalog.set_config('search_path', '', false);
7+
SET check_function_bodies = false;
8+
SET xmloption = content;
9+
SET client_min_messages = warning;
10+
SET row_security = off;
11+
12+
--
13+
-- Name: pg_stat_statements; Type: EXTENSION; Schema: -; Owner: -
14+
--
15+
16+
CREATE EXTENSION IF NOT EXISTS pg_stat_statements WITH SCHEMA public;
17+
18+
19+
--
20+
-- Name: EXTENSION pg_stat_statements; Type: COMMENT; Schema: -; Owner: -
21+
--
22+
23+
COMMENT ON EXTENSION pg_stat_statements IS 'track execution statistics of all SQL statements executed';
24+
25+
26+
SET default_tablespace = '';
27+
28+
SET default_table_access_method = heap;
29+
30+
--
31+
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
32+
--
33+
34+
CREATE TABLE public.ar_internal_metadata (
35+
key character varying NOT NULL,
36+
value character varying,
37+
created_at timestamp(6) without time zone NOT NULL,
38+
updated_at timestamp(6) without time zone NOT NULL
39+
);
40+
41+
42+
--
43+
-- Name: delayed_jobs; Type: TABLE; Schema: public; Owner: -
44+
--
45+
46+
CREATE TABLE public.delayed_jobs (
47+
id bigint NOT NULL,
48+
priority integer DEFAULT 0,
49+
attempts integer DEFAULT 0,
50+
handler text,
51+
last_error text,
52+
run_at timestamp without time zone,
53+
locked_at timestamp without time zone,
54+
failed_at timestamp without time zone,
55+
locked_by character varying(255),
56+
queue character varying(255),
57+
created_at timestamp without time zone NOT NULL,
58+
updated_at timestamp without time zone NOT NULL,
59+
metadata jsonb DEFAULT '{}'::jsonb,
60+
whodunnit text
61+
)
62+
WITH (fillfactor='85');
63+
64+
65+
--
66+
-- Name: delayed_jobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
67+
--
68+
69+
CREATE SEQUENCE public.delayed_jobs_id_seq
70+
START WITH 1
71+
INCREMENT BY 1
72+
NO MINVALUE
73+
NO MAXVALUE
74+
CACHE 1;
75+
76+
77+
--
78+
-- Name: delayed_jobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
79+
--
80+
81+
ALTER SEQUENCE public.delayed_jobs_id_seq OWNED BY public.delayed_jobs.id;
82+
83+
84+
--
85+
-- Name: schema_migrations; Type: TABLE; Schema: public; Owner: -
86+
--
87+
88+
CREATE TABLE public.schema_migrations (
89+
version character varying NOT NULL
90+
);
91+
92+
93+
--
94+
-- Name: delayed_jobs id; Type: DEFAULT; Schema: public; Owner: -
95+
--
96+
97+
ALTER TABLE ONLY public.delayed_jobs ALTER COLUMN id SET DEFAULT nextval('public.delayed_jobs_id_seq'::regclass);
98+
99+
100+
--
101+
-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -
102+
--
103+
104+
ALTER TABLE ONLY public.ar_internal_metadata
105+
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);
106+
107+
108+
--
109+
-- Name: delayed_jobs delayed_jobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
110+
--
111+
112+
ALTER TABLE ONLY public.delayed_jobs
113+
ADD CONSTRAINT delayed_jobs_pkey PRIMARY KEY (id);
114+
115+
116+
--
117+
-- Name: schema_migrations schema_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
118+
--
119+
120+
ALTER TABLE ONLY public.schema_migrations
121+
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
122+
123+
124+
--
125+
-- Name: index_delayed_jobs_on_locked_by; Type: INDEX; Schema: public; Owner: -
126+
--
127+
128+
CREATE INDEX index_delayed_jobs_on_locked_by ON public.delayed_jobs USING btree (locked_by);
129+
130+
131+
--
132+
-- Name: index_delayed_jobs_on_queue; Type: INDEX; Schema: public; Owner: -
133+
--
134+
135+
CREATE INDEX index_delayed_jobs_on_queue ON public.delayed_jobs USING btree (queue);
136+
137+
138+
--
139+
-- Name: index_delayed_jobs_on_run_at; Type: INDEX; Schema: public; Owner: -
140+
--
141+
142+
CREATE INDEX index_delayed_jobs_on_run_at ON public.delayed_jobs USING btree (run_at) WHERE (locked_at IS NULL);
143+
144+
145+
--
146+
-- PostgreSQL database dump complete
147+
--
148+
149+
SET search_path TO "$user", public;
150+
151+
INSERT INTO "schema_migrations" (version) VALUES
152+
('20240822225012'),
153+
('20240822224954'),
154+
('20240725043656'),
155+
('20240621041110'),
156+
('20240621020038'),
157+
('20220802204003'),
158+
('20211125055031'),
159+
('20211012054749'),
160+
('20210923052631'),
161+
('20210903003251');
162+
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
SET statement_timeout = 0;
2+
SET lock_timeout = 0;
3+
SET client_encoding = 'UTF8';
4+
SET standard_conforming_strings = on;
5+
SELECT pg_catalog.set_config('search_path', '', false);
6+
SET check_function_bodies = false;
7+
SET client_min_messages = warning;
8+
9+
SET default_tablespace = '';
10+
11+
-- Name: ar_internal_metadata; Type: TABLE
12+
13+
CREATE TABLE public.ar_internal_metadata (
14+
key character varying NOT NULL,
15+
value character varying,
16+
created_at timestamp(6) without time zone NOT NULL,
17+
updated_at timestamp(6) without time zone NOT NULL
18+
);
19+
20+
-- Name: delayed_jobs; Type: TABLE
21+
22+
CREATE TABLE public.delayed_jobs (
23+
id BIGSERIAL PRIMARY KEY,
24+
priority integer DEFAULT 0,
25+
attempts integer DEFAULT 0,
26+
handler text,
27+
last_error text,
28+
run_at timestamp without time zone,
29+
locked_at timestamp without time zone,
30+
failed_at timestamp without time zone,
31+
locked_by character varying(255),
32+
queue character varying(255),
33+
created_at timestamp without time zone NOT NULL,
34+
updated_at timestamp without time zone NOT NULL,
35+
metadata jsonb DEFAULT '{}'::jsonb,
36+
whodunnit text
37+
)
38+
WITH (fillfactor='85');
39+
40+
-- Name: schema_migrations; Type: TABLE
41+
42+
CREATE TABLE public.schema_migrations (
43+
version character varying NOT NULL
44+
);
45+
46+
ALTER TABLE ONLY public.ar_internal_metadata
47+
ADD CONSTRAINT ar_internal_metadata_pkey PRIMARY KEY (key);
48+
49+
ALTER TABLE ONLY public.schema_migrations
50+
ADD CONSTRAINT schema_migrations_pkey PRIMARY KEY (version);
51+
52+
-- Name: index_delayed_jobs_on_locked_by; Type: INDEX
53+
54+
CREATE INDEX index_delayed_jobs_on_locked_by ON public.delayed_jobs USING btree (locked_by);
55+
56+
-- Name: index_delayed_jobs_on_queue; Type: INDEX
57+
58+
CREATE INDEX index_delayed_jobs_on_queue ON public.delayed_jobs USING btree (queue);
59+
60+
-- Name: index_delayed_jobs_on_run_at; Type: INDEX
61+
62+
CREATE INDEX index_delayed_jobs_on_run_at ON public.delayed_jobs USING btree (run_at) WHERE (locked_at IS NULL);
63+
64+
-- PostgreSQL database dump complete
65+
66+
SET search_path TO "$user", public;
67+
68+
INSERT INTO "schema_migrations" (version) VALUES
69+
('20240822225012'),
70+
('20240822224954'),
71+
('20240725043656'),
72+
('20240621041110'),
73+
('20240621020038'),
74+
('20220802204003'),
75+
('20211125055031'),
76+
('20211012054749'),
77+
('20210923052631'),
78+
('20210903003251');

0 commit comments

Comments
 (0)