declare_schema 1.4.0.colin.9 → 1.4.0.colin.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +9 -0
- data/Gemfile.lock +1 -1
- data/lib/declare_schema/model/index_definition.rb +1 -1
- data/lib/declare_schema/model.rb +17 -2
- data/lib/declare_schema/schema_change/column_add.rb +4 -2
- data/lib/declare_schema/version.rb +1 -1
- data/lib/declare_schema.rb +13 -3
- data/lib/generators/declare_schema/migration/migrator.rb +1 -1
- data/spec/lib/declare_schema/migration_generator_spec.rb +48 -0
- data/spec/lib/declare_schema_spec.rb +40 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 13075fb086e36e6be6818fd28620cb9015c257083e994f68c216ca790e463896
|
4
|
+
data.tar.gz: 4668a054c8d87a7612ba739e3937a4faf817b3ac558083c8e0af59668aa1c42a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86d9f02bb9cabbb23ecec2eb68098b625b753b04890811858e4a43963d111ac54e5d2e10cd5468dfbdc2c6af39d1cab779002b033dbcbc05e869e4f0bc11f151
|
7
|
+
data.tar.gz: fbc233f25183279a309a23dc9afb395b4c4a47e52a95661126c99d9a9109100c5bd5ac3b200171fca479bd9c569f1a9aa34dbe15c79e8cfe50a95387f683ab7e
|
data/CHANGELOG.md
CHANGED
@@ -10,6 +10,15 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
|
|
10
10
|
### Changed
|
11
11
|
- Deprecate index: 'name' and unique: true|false in favor of index: { name: 'name', unique: true|false }.
|
12
12
|
|
13
|
+
## [1.3.6] - 2024-01-22
|
14
|
+
### Fixed
|
15
|
+
- Add missing commits around connection: and Array check for composite declared primary key.
|
16
|
+
|
17
|
+
## [1.3.5] - 2024-01-22
|
18
|
+
### Fixed
|
19
|
+
- Make `default_charset=` and `default_collation=` lazy so they don't use the database connection to check the
|
20
|
+
MySQL version. Instead, that is checked the first time `default_charset` or `default_collation` is called.
|
21
|
+
|
13
22
|
## [1.3.4] - 2024-01-18
|
14
23
|
### Fixed
|
15
24
|
- Add test for migrating `has_and_belongs_to_many` associations and fix them to properly declare their
|
data/Gemfile.lock
CHANGED
@@ -18,7 +18,7 @@ module DeclareSchema
|
|
18
18
|
|
19
19
|
def initialize(columns, table_name:, name: nil, allow_equivalent: false, unique: false, where: nil, length: nil)
|
20
20
|
@table_name = table_name
|
21
|
-
@name = name || self.class.default_index_name(table_name, columns)
|
21
|
+
@name = (name || self.class.default_index_name(table_name, columns)).to_s
|
22
22
|
@columns = Array.wrap(columns).map(&:to_s)
|
23
23
|
@explicit_name = @name if !allow_equivalent
|
24
24
|
unique.in?([false, true]) or raise ArgumentError, "unique must be true or false: got #{unique.inspect}"
|
data/lib/declare_schema/model.rb
CHANGED
@@ -50,10 +50,23 @@ module DeclareSchema
|
|
50
50
|
|
51
51
|
module ClassMethods
|
52
52
|
def index(columns, name: nil, allow_equivalent: false, unique: false, where: nil, length: nil)
|
53
|
-
|
53
|
+
index_definition = ::DeclareSchema::Model::IndexDefinition.new(
|
54
54
|
columns,
|
55
55
|
name: name, table_name: table_name, allow_equivalent: allow_equivalent, unique: unique, where: where, length: length
|
56
56
|
)
|
57
|
+
|
58
|
+
if (equivalent = index_definitions.find { index_definition.equivalent?(_1) }) # differs only by name
|
59
|
+
if equivalent == index_definition
|
60
|
+
# identical is always idempotent
|
61
|
+
else
|
62
|
+
# equivalent is idempotent iff allow_equivalent: true passed
|
63
|
+
allow_equivalent or
|
64
|
+
raise ArgumentError, "equivalent index definition found (pass allow_equivalent: true to ignore):\n" \
|
65
|
+
"#{index_definition.inspect}\n#{equivalent.inspect}"
|
66
|
+
end
|
67
|
+
else
|
68
|
+
index_definitions << index_definition
|
69
|
+
end
|
57
70
|
end
|
58
71
|
|
59
72
|
def primary_key_index(*columns)
|
@@ -61,11 +74,13 @@ module DeclareSchema
|
|
61
74
|
end
|
62
75
|
|
63
76
|
def constraint(foreign_key_column, parent_table_name: nil, constraint_name: nil, parent_class_name: nil, dependent: nil)
|
64
|
-
|
77
|
+
constraint_definition = ::DeclareSchema::Model::ForeignKeyDefinition.new(
|
65
78
|
foreign_key_column.to_s,
|
66
79
|
constraint_name: constraint_name,
|
67
80
|
child_table_name: table_name, parent_table_name: parent_table_name, parent_class_name: parent_class_name, dependent: dependent
|
68
81
|
)
|
82
|
+
|
83
|
+
constraint_definitions << constraint_definition # Set<> implements idempotent insert.
|
69
84
|
end
|
70
85
|
|
71
86
|
# tell the migration generator to ignore the named index. Useful for existing indexes, or for indexes
|
@@ -6,8 +6,10 @@ module DeclareSchema
|
|
6
6
|
module SchemaChange
|
7
7
|
class ColumnAdd < Base
|
8
8
|
def initialize(table_name, column_name, column_type, **column_options)
|
9
|
-
|
10
|
-
|
9
|
+
table_name.is_a?(String) || table_name.is_a?(Symbol) or raise ArgumentError, "must provide String|Symbol table_name; got #{table_name.inspect}"
|
10
|
+
column_name.is_a?(String) || column_name.is_a?(Symbol) or raise ArgumentError, "must provide String|Symbol column_name; got #{column_name.inspect}"
|
11
|
+
@table_name = table_name
|
12
|
+
@column_name = column_name
|
11
13
|
@column_type = column_type or raise ArgumentError, "must provide column_type"
|
12
14
|
@column_options = column_options
|
13
15
|
end
|
data/lib/declare_schema.rb
CHANGED
@@ -36,7 +36,7 @@ module DeclareSchema
|
|
36
36
|
|
37
37
|
class << self
|
38
38
|
attr_writer :mysql_version
|
39
|
-
attr_reader :
|
39
|
+
attr_reader :default_text_limit, :default_string_limit, :default_null,
|
40
40
|
:default_generate_foreign_keys, :default_generate_indexing, :db_migrate_command,
|
41
41
|
:max_index_and_constraint_name_length
|
42
42
|
|
@@ -81,12 +81,22 @@ module DeclareSchema
|
|
81
81
|
|
82
82
|
def default_charset=(charset)
|
83
83
|
charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
|
84
|
-
@
|
84
|
+
@default_charset_before_normalization = charset
|
85
|
+
@default_charset = nil
|
86
|
+
end
|
87
|
+
|
88
|
+
def default_charset
|
89
|
+
@default_charset ||= normalize_charset(@default_charset_before_normalization)
|
85
90
|
end
|
86
91
|
|
87
92
|
def default_collation=(collation)
|
88
93
|
collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
|
89
|
-
@
|
94
|
+
@default_collation_before_normalization = collation
|
95
|
+
@default_collation = nil
|
96
|
+
end
|
97
|
+
|
98
|
+
def default_collation
|
99
|
+
@default_collation ||= normalize_collation(@default_collation_before_normalization)
|
90
100
|
end
|
91
101
|
|
92
102
|
def default_text_limit=(text_limit)
|
@@ -352,7 +352,7 @@ module Generators
|
|
352
352
|
|
353
353
|
db_columns = model.connection.columns(current_table_name).index_by(&:name)
|
354
354
|
if (pk = model._declared_primary_key.presence)
|
355
|
-
pk_was_in_db_columns = db_columns.delete(pk)
|
355
|
+
pk_was_in_db_columns = pk.is_a?(Array) || db_columns.delete(pk)
|
356
356
|
end
|
357
357
|
|
358
358
|
model_column_names = model.field_specs.keys.map(&:to_s)
|
@@ -1437,5 +1437,53 @@ RSpec.describe 'DeclareSchema Migration Generator' do
|
|
1437
1437
|
end
|
1438
1438
|
end
|
1439
1439
|
end
|
1440
|
+
|
1441
|
+
context 'index' do
|
1442
|
+
before do
|
1443
|
+
class Advert < active_record_base_class.constantize
|
1444
|
+
declare_schema { }
|
1445
|
+
belongs_to :ad_category
|
1446
|
+
end
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
it "is idempotent and doesn't raise" do
|
1450
|
+
expect do
|
1451
|
+
Advert.index [:ad_category_id], name: :index_adverts_on_ad_category_id
|
1452
|
+
end.to_not change { Advert.index_definitions.size }
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
it "when equivalent but not marked to allow, it raises" do
|
1456
|
+
expect do
|
1457
|
+
Advert.index [:ad_category_id], name: :on_ad_category_id
|
1458
|
+
end.to raise_exception(ArgumentError, /equivalent index definition found/i)
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
it "when equivalent and marked to allow, it is idempotent and doesn't raise" do
|
1462
|
+
expect do
|
1463
|
+
Advert.index [:ad_category_id], name: :on_ad_category_id, allow_equivalent: true
|
1464
|
+
end.to_not change { Advert.index_definitions.size }
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
context 'constraint' do
|
1468
|
+
before do
|
1469
|
+
class Advert < active_record_base_class.constantize
|
1470
|
+
declare_schema { }
|
1471
|
+
belongs_to :ad_category
|
1472
|
+
end
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
it "when exactly equal, it is idempotent and doesn't raise" do
|
1476
|
+
expect do
|
1477
|
+
Advert.constraint :ad_category_id, parent_table_name: 'ad_categories', constraint_name: :index_adverts_on_ad_category_id, parent_class_name: 'AdCategory'
|
1478
|
+
end.to_not change { Advert.index_definitions.size }
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
it "when equivalent, it is idempotent and doesn't raise" do
|
1482
|
+
expect do
|
1483
|
+
Advert.constraint :ad_category_id, parent_table_name: 'ad_categories', constraint_name: :constraint_1, parent_class_name: 'AdCategory'
|
1484
|
+
end.to_not change { Advert.index_definitions.size }
|
1485
|
+
end
|
1486
|
+
end
|
1487
|
+
end
|
1440
1488
|
end
|
1441
1489
|
end
|
@@ -37,6 +37,26 @@ RSpec.describe DeclareSchema do
|
|
37
37
|
it { is_expected.to eq("utf8mb3") }
|
38
38
|
end
|
39
39
|
end
|
40
|
+
|
41
|
+
context 'when MySQL version not known yet' do
|
42
|
+
before { described_class.remove_instance_variable('@mysql_version') rescue nil }
|
43
|
+
after { described_class.remove_instance_variable('@mysql_version') rescue nil }
|
44
|
+
|
45
|
+
context 'when set' do
|
46
|
+
let(:connection) { double("connection", select_value: "8.0.21") }
|
47
|
+
|
48
|
+
it "is lazy, so it doesn't use the database connection until read" do
|
49
|
+
expect(ActiveRecord::Base).to receive(:connection) do
|
50
|
+
@connection_called = true
|
51
|
+
connection
|
52
|
+
end
|
53
|
+
described_class.default_charset = "utf8"
|
54
|
+
expect(@connection_called).to be_falsey
|
55
|
+
described_class.default_charset
|
56
|
+
expect(@connection_called).to be_truthy
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
40
60
|
end
|
41
61
|
|
42
62
|
describe '#default_collation' do
|
@@ -81,6 +101,26 @@ RSpec.describe DeclareSchema do
|
|
81
101
|
it { is_expected.to eq("utf8mb3_general_ci") }
|
82
102
|
end
|
83
103
|
end
|
104
|
+
|
105
|
+
context 'when MySQL version not known yet' do
|
106
|
+
before { described_class.remove_instance_variable('@mysql_version') rescue nil }
|
107
|
+
after { described_class.remove_instance_variable('@mysql_version') rescue nil }
|
108
|
+
|
109
|
+
context 'when set' do
|
110
|
+
let(:connection) { double("connection", select_value: "8.0.21") }
|
111
|
+
|
112
|
+
it "is lazy, so it doesn't use the database connection until read" do
|
113
|
+
expect(ActiveRecord::Base).to receive(:connection) do
|
114
|
+
@connection_called = true
|
115
|
+
connection
|
116
|
+
end
|
117
|
+
described_class.default_collation = "utf8_general_ci"
|
118
|
+
expect(@connection_called).to be_falsey
|
119
|
+
described_class.default_collation
|
120
|
+
expect(@connection_called).to be_truthy
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
84
124
|
end
|
85
125
|
|
86
126
|
describe '#default_text_limit' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: declare_schema
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.4.0.colin.
|
4
|
+
version: 1.4.0.colin.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Invoca Development adapted from hobo_fields by Tom Locke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|