Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add force_datetime_default_format options and tests #18

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
pkg
.rspec_status
.DS_Store
3 changes: 3 additions & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
--format documentation
--color
--require spec_helper
21 changes: 21 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,30 @@ GEM
minitest (~> 5.1)
tzinfo (~> 1.1)
zeitwerk (~> 2.1, >= 2.1.8)
coderay (1.1.2)
concurrent-ruby (1.1.5)
diff-lcs (1.3)
i18n (1.6.0)
concurrent-ruby (~> 1.0)
method_source (0.9.2)
minitest (5.11.3)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
rake (0.9.6)
rspec (3.8.0)
rspec-core (~> 3.8.0)
rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.8.0)
rspec-core (3.8.2)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.4)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.2)
thread_safe (0.3.6)
tzinfo (1.2.5)
thread_safe (~> 0.1)
Expand All @@ -33,7 +52,9 @@ PLATFORMS

DEPENDENCIES
activerecord-clean-db-structure!
pry
rake (~> 0)
rspec

BUNDLED WITH
1.17.3
22 changes: 22 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ INSERT INTO "schema_migrations" (version) VALUES
;
```

You can also deal with default dates in the structure file if they're the common source of merge conflicts - this usually happens when using `DateTime.current` as a default and having your team run the migrations at different times.

You can set the `force_datetime_default_format` option to a `Time` object like so:

```ruby
Rails.application.configure do
config.activerecord_clean_db_structure.force_datetime_default_format = Time.new(2019, 5, 6, 16, 44, 22)
end
```

And it will set every date default to the passed date.

Alternatively, you can set the `force_datetime_default_format` option to `true`:

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

Which will only cut out the miliseconds from every datetime default.

## Authors

* [Lukas Fittl](https://github.com/lfittl)
Expand Down
2 changes: 2 additions & 0 deletions activerecord-clean-db-structure.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ Gem::Specification.new do |s|
s.add_dependency('activerecord', '>= 4.2')

s.add_development_dependency 'rake', '~> 0'
s.add_development_dependency 'rspec'
s.add_development_dependency 'pry'
end
12 changes: 12 additions & 0 deletions lib/activerecord-clean-db-structure/clean_dump.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ def run
if options[:order_column_definitions] == true
dump.replace(order_column_definitions(dump))
end

if options[:force_datetime_default_format].is_a?(Time)
# force ALL default dates in the schema to be the same date
datestring = options[:force_datetime_default_format].strftime('%F %T')
dump.gsub!(/DEFAULT '\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2}(\.\d{1,6})?'/, "DEFAULT '#{datestring}'")
elsif options[:force_datetime_default_format] == true
# alternatively only cut out miliseconds if they're present
date_regexp = /DEFAULT '(\d{4}-\d{1,2}-\d{1,2} \d{1,2}:\d{1,2}:\d{1,2})(\.\d{1,6})?'/m
dump.scan(date_regexp).each do |date|
dump.gsub!(/DEFAULT '#{date.join}'/, "DEFAULT '#{date[0]}'")
end
end
end

def order_column_definitions(source)
Expand Down
123 changes: 123 additions & 0 deletions spec/clean_dump_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# frozen_string_literal: true

RSpec.describe ActiveRecordCleanDbStructure::CleanDump do
context 'with empty comment lines' do
let(:sql_dump) { file_fixture('spec/fixtures/empty_comments.sql').read }
let(:cleaner) { described_class.new sql_dump.clone }
let(:expected_columns) do
[
');',
'',
'-- useless comment'
]
end

it 'removes empty comments lines' do
cleaner.run
expect(cleaner.dump.split("\n").last(3)).to eq expected_columns
end
end

context 'with unnecessary whitespace' do
let(:sql_dump) { file_fixture('spec/fixtures/ending_whitespace.sql').read }
let(:cleaner) { described_class.new sql_dump.clone }

it 'removes empty whitespace lines' do
cleaner.run
expect(cleaner.dump).to end_with ");\n\n"
end
end

context 'with order_column_definitions option' do
let(:sql_dump) { file_fixture('spec/fixtures/unordered_columns.sql').read }
let(:cleaner) { described_class.new sql_dump.clone, order_column_definitions: true }
let(:expected_columns) do
[
'CREATE TABLE public.model (',
' alpha character varying(255),',
' beta character varying(255),',
' gamma character varying(255),',
' id SERIAL PRIMARY KEY',
');'
]
end

it 'sorts columns alphabetically' do
cleaner.run
expect(cleaner.dump.split("\n").last(6)).to eq expected_columns
end
end

context 'without order_column_definitions option' do
let(:sql_dump) { file_fixture('spec/fixtures/unordered_columns.sql').read }
let(:cleaner) { described_class.new sql_dump.clone }
let(:expected_columns) do
[
'CREATE TABLE public.model (',
' id SERIAL PRIMARY KEY,',
' beta character varying(255),',
' gamma character varying(255),',
' alpha character varying(255)',
');'
]
end

it 'does not sort columns' do
cleaner.run
expect(cleaner.dump.split("\n").last(6)).to eq expected_columns
end
end

context 'with force_datetime_default_format' do
context 'with Time object passed' do
let(:sql_dump) { file_fixture('spec/fixtures/dates.sql').read }
let(:cleaner) { described_class.new sql_dump.clone, force_datetime_default_format: Time.new(2019, 5, 6, 16, 44, 22) }
let(:expected_columns) do
[
" alpha timestamp without time zone DEFAULT '2019-05-06 16:44:22'::timestamp without time zone,",
" beta timestamp without time zone DEFAULT '2019-05-06 16:44:22'::timestamp without time zone",
');'
]
end

it 'forces all dates to be same datetime' do
cleaner.run
expect(cleaner.dump.split("\n").last(3)).to eq expected_columns
end
end

context 'with true passed' do
let(:sql_dump) { file_fixture('spec/fixtures/dates.sql').read }
let(:cleaner) { described_class.new sql_dump.clone, force_datetime_default_format: true }
let(:expected_columns) do
[
" alpha timestamp without time zone DEFAULT '2015-12-18 23:38:27'::timestamp without time zone,",
" beta timestamp without time zone DEFAULT '2016-05-10 14:01:06'::timestamp without time zone",
');'
]
end

it 'forces all dates to be same format' do
cleaner.run
expect(cleaner.dump.split("\n").last(3)).to eq expected_columns
end
end
end

context 'without force_datetime_default_format' do
let(:sql_dump) { file_fixture('spec/fixtures/dates.sql').read }
let(:cleaner) { described_class.new sql_dump.clone }
let(:expected_columns) do
[
" alpha timestamp without time zone DEFAULT '2015-12-18 23:38:27.804383'::timestamp without time zone,",
" beta timestamp without time zone DEFAULT '2016-05-10 14:01:06'::timestamp without time zone",
');'
]
end

it 'leaves dates defaults as is' do
cleaner.run
expect(cleaner.dump.split("\n").last(3)).to eq expected_columns
end
end
end
16 changes: 16 additions & 0 deletions spec/fixtures/dates.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

-- PostgreSQL database dump

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;

CREATE TABLE public.model (
id SERIAL PRIMARY KEY,
alpha timestamp without time zone DEFAULT '2015-12-18 23:38:27.804383'::timestamp without time zone,
beta timestamp without time zone DEFAULT '2016-05-10 14:01:06'::timestamp without time zone
);
18 changes: 18 additions & 0 deletions spec/fixtures/empty_comments.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

-- PostgreSQL database dump

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;

CREATE TABLE public.model (
id SERIAL PRIMARY KEY,
name character varying(255)
);
--
-- useless comment
--
21 changes: 21 additions & 0 deletions spec/fixtures/ending_whitespace.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@

-- PostgreSQL database dump

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;

CREATE TABLE public.model (
id SERIAL PRIMARY KEY,
name character varying(255)
);






17 changes: 17 additions & 0 deletions spec/fixtures/unordered_columns.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

-- PostgreSQL database dump

SET statement_timeout = 0;
SET lock_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET client_min_messages = warning;

CREATE TABLE public.model (
id SERIAL PRIMARY KEY,
beta character varying(255),
gamma character varying(255),
alpha character varying(255)
);
30 changes: 30 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

ENV['RACK_ENV'] = 'test'

require 'bundler/setup'
require 'activerecord-clean-db-structure/clean_dump'
require 'pry'

RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = '.rspec_status'

# Disable RSpec exposing methods globally on `Module` and `main`
config.disable_monkey_patching!

config.expect_with :rspec do |c|
c.syntax = :expect
end
end

def file_fixture(fixture_name)
path = Pathname.new(File.join(fixture_name))

if path.exist?
path
else
msg = "file does not exist: '%s'"
raise ArgumentError, format(msg, fixture_name)
end
end