declare_schema 1.3.2.rp.1 → 1.3.3.colin.1
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 +6 -1
- data/Gemfile.lock +1 -1
- data/README.md +3 -0
- data/lib/declare_schema/model/field_spec.rb +2 -0
- data/lib/declare_schema/model/table_options_definition.rb +11 -1
- data/lib/declare_schema/version.rb +1 -1
- data/lib/declare_schema.rb +34 -2
- data/spec/lib/declare_schema/field_spec_spec.rb +22 -2
- data/spec/lib/declare_schema/model/table_options_definition_spec.rb +26 -6
- data/spec/lib/declare_schema_spec.rb +62 -8
- data/spec/lib/generators/declare_schema/migration/migrator_spec.rb +3 -1
- data/spec/spec_helper.rb +4 -3
- 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: 2cc1b63a3d66a299428ec32493d79aa3ef2a3953a663c66c661887f28dffe96e
|
4
|
+
data.tar.gz: 6712668fe9c41feb156cd0127ceacf57802bbb17c633da408038a0f5b8067509
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad29f584d6b7bd42b6e5b547578b8a0004a5602376e015117b811e726c8d62d2b69bb97a1af32af1635788e6b18a9cfbbc89e185ee496fac3e35567246c9185d
|
7
|
+
data.tar.gz: 14fc6510af10b9158919f23d8125f9d15cd2c4b34b5cb81ee990332fa924a82f52ca41e08c514be2157539900a10ea19238f0be49ec9fe8ec9c5fb404b0e2b3d
|
data/CHANGELOG.md
CHANGED
@@ -4,7 +4,12 @@ Inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|
4
4
|
|
5
5
|
Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
6
6
|
|
7
|
-
## [1.3.
|
7
|
+
## [1.3.3] - Unreleased
|
8
|
+
### Fixed
|
9
|
+
- Fix a MySQL 8 bug where MySQL 8+ renames charset 'utf8' to 'utf8mb3' and collation 'utf8_general_ci' to
|
10
|
+
'utf8mb3_unicode_ci'.
|
11
|
+
|
12
|
+
## [1.3.2] - 2024-01-12
|
8
13
|
### Fixed
|
9
14
|
- Fix bug in migrator when table option definitions differ
|
10
15
|
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -213,6 +213,9 @@ turn all tables into `utf8mb4` supporting tables:
|
|
213
213
|
DeclareSchema.default_charset = "utf8mb4"
|
214
214
|
DeclareSchema.default_collation = "utf8mb4_bin"
|
215
215
|
```
|
216
|
+
Note: MySQL 8+ aliases charset 'utf8' to 'utf8mb3', and 'utf8_general_ci' to 'utf8mb3_unicode_ci',
|
217
|
+
so when running on MySQL 8+, those aliases will be applied by `DeclareSchema`.
|
218
|
+
|
216
219
|
#### db:migrate Command
|
217
220
|
`declare_schema` can run the migration once it is generated, if the `--migrate` option is passed.
|
218
221
|
If not, it will display the command to run later. By default this command is
|
@@ -107,7 +107,9 @@ module DeclareSchema
|
|
107
107
|
if @type.in?([:text, :string])
|
108
108
|
if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
|
109
109
|
@options[:charset] ||= model._table_options&.[](:charset) || ::DeclareSchema.default_charset
|
110
|
+
@options[:charset] = DeclareSchema.normalize_charset(@options[:charset])
|
110
111
|
@options[:collation] ||= model._table_options&.[](:collation) || ::DeclareSchema.default_collation
|
112
|
+
@options[:collation] = DeclareSchema.normalize_collation(@options[:collation])
|
111
113
|
else
|
112
114
|
@options.delete(:charset)
|
113
115
|
@options.delete(:collation)
|
@@ -50,7 +50,17 @@ module DeclareSchema
|
|
50
50
|
|
51
51
|
def initialize(table_name, **table_options)
|
52
52
|
@table_name = table_name
|
53
|
-
@table_options = table_options
|
53
|
+
@table_options = table_options.each_with_object({}) do |(k, v),result|
|
54
|
+
result[k] =
|
55
|
+
case k
|
56
|
+
when :charset
|
57
|
+
DeclareSchema.normalize_charset(v)
|
58
|
+
when :collation
|
59
|
+
DeclareSchema.normalize_collation(v)
|
60
|
+
else
|
61
|
+
v
|
62
|
+
end
|
63
|
+
end
|
54
64
|
end
|
55
65
|
|
56
66
|
def to_key
|
data/lib/declare_schema.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
require 'active_support'
|
4
4
|
require 'active_support/all'
|
5
5
|
require_relative 'declare_schema/version'
|
6
|
+
require 'rubygems/version'
|
6
7
|
|
7
8
|
ActiveSupport::Dependencies.autoload_paths |= [__dir__]
|
8
9
|
|
@@ -21,6 +22,8 @@ module DeclareSchema
|
|
21
22
|
text: String
|
22
23
|
}.freeze
|
23
24
|
|
25
|
+
SEMVER_8 = Gem::Version.new('8.0.0').freeze
|
26
|
+
|
24
27
|
@default_charset = "utf8mb4"
|
25
28
|
@default_collation = "utf8mb4_bin"
|
26
29
|
@default_text_limit = 0xffff_ffff
|
@@ -32,6 +35,7 @@ module DeclareSchema
|
|
32
35
|
@max_index_and_constraint_name_length = 64 # limit for MySQL
|
33
36
|
|
34
37
|
class << self
|
38
|
+
attr_writer :mysql_version
|
35
39
|
attr_reader :default_charset, :default_collation, :default_text_limit, :default_string_limit, :default_null,
|
36
40
|
:default_generate_foreign_keys, :default_generate_indexing, :db_migrate_command,
|
37
41
|
:max_index_and_constraint_name_length
|
@@ -47,14 +51,42 @@ module DeclareSchema
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
54
|
+
def mysql_version
|
55
|
+
if defined?(@mysql_version)
|
56
|
+
@mysql_version
|
57
|
+
else
|
58
|
+
@mysql_version =
|
59
|
+
if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
|
60
|
+
version_string = ActiveRecord::Base.connection.select_value('SELECT VERSION()')
|
61
|
+
Gem::Version.new(version_string)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def normalize_charset(charset)
|
67
|
+
if mysql_version && mysql_version >= SEMVER_8 && charset == 'utf8'
|
68
|
+
'utf8mb3'
|
69
|
+
else
|
70
|
+
charset
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def normalize_collation(collation)
|
75
|
+
if mysql_version && mysql_version >= SEMVER_8
|
76
|
+
collation.sub(/\Autf8_/, 'utf8mb3_')
|
77
|
+
else
|
78
|
+
collation
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
50
82
|
def default_charset=(charset)
|
51
83
|
charset.is_a?(String) or raise ArgumentError, "charset must be a string (got #{charset.inspect})"
|
52
|
-
@default_charset = charset
|
84
|
+
@default_charset = normalize_charset(charset)
|
53
85
|
end
|
54
86
|
|
55
87
|
def default_collation=(collation)
|
56
88
|
collation.is_a?(String) or raise ArgumentError, "collation must be a string (got #{collation.inspect})"
|
57
|
-
@default_collation = collation
|
89
|
+
@default_collation = normalize_collation(collation)
|
58
90
|
end
|
59
91
|
|
60
92
|
def default_text_limit=(text_limit)
|
@@ -5,6 +5,11 @@ begin
|
|
5
5
|
rescue LoadError
|
6
6
|
end
|
7
7
|
|
8
|
+
begin
|
9
|
+
require 'sqlite3'
|
10
|
+
rescue LoadError
|
11
|
+
end
|
12
|
+
|
8
13
|
RSpec.describe DeclareSchema::Model::FieldSpec do
|
9
14
|
let(:model) { double('model', _table_options: {}, _declared_primary_key: 'id') }
|
10
15
|
let(:col_spec) { double('col_spec', type: :string) }
|
@@ -58,8 +63,23 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
58
63
|
end
|
59
64
|
end
|
60
65
|
|
61
|
-
|
62
|
-
|
66
|
+
if defined?(Mysql2)
|
67
|
+
context 'when running on MySQL 8.0' do
|
68
|
+
around do |spec|
|
69
|
+
DeclareSchema.mysql_version = '8.0.21'
|
70
|
+
spec.run
|
71
|
+
ensure
|
72
|
+
DeclareSchema.remove_instance_variable('@mysql_version') rescue nil
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'normalizes charset and collation' do
|
76
|
+
subject = described_class.new(model, :title, :string, limit: 100, null: true, charset: 'utf8', collation: 'utf8_general', position: 0)
|
77
|
+
|
78
|
+
expect(subject.schema_attributes(col_spec)).to eq(type: :string, limit: 100, null: true, charset: 'utf8mb3', collation: 'utf8mb3_general')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'raises error when default_string_limit option is nil when not explicitly set in field spec' do
|
63
83
|
expect(::DeclareSchema).to receive(:default_string_limit) { nil }
|
64
84
|
expect do
|
65
85
|
described_class.new(model, :title, :string, null: true, charset: 'utf8mb4', position: 0)
|
@@ -9,6 +9,8 @@ require_relative '../../../../lib/declare_schema/model/table_options_definition'
|
|
9
9
|
|
10
10
|
RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
11
11
|
let(:model_class) { TableOptionsDefinitionTestModel }
|
12
|
+
let(:charset) { DeclareSchema.normalize_charset('utf8') }
|
13
|
+
let(:collation) { DeclareSchema.normalize_collation('utf8_general') } # adapt so that tests will pass on MySQL 5.7 or 8+
|
12
14
|
|
13
15
|
context 'Using declare_schema' do
|
14
16
|
before do
|
@@ -27,27 +29,45 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
|
27
29
|
|
28
30
|
describe '#to_key' do
|
29
31
|
subject { model.to_key }
|
30
|
-
it {
|
32
|
+
it { is_expected.to eq(['table_options_definition_test_models', "{:charset=>#{charset.inspect}, :collation=>#{collation.inspect}}"]) }
|
31
33
|
end
|
32
34
|
|
33
35
|
describe '#settings' do
|
34
36
|
subject { model.settings }
|
35
|
-
it {
|
37
|
+
it { is_expected.to eq("CHARACTER SET #{charset} COLLATE #{collation}") }
|
38
|
+
|
39
|
+
if defined?(Mysql2)
|
40
|
+
context 'when running in MySQL 8' do
|
41
|
+
around do |spec|
|
42
|
+
DeclareSchema.mysql_version = Gem::Version.new('8.0.21')
|
43
|
+
spec.run
|
44
|
+
ensure
|
45
|
+
DeclareSchema.remove_instance_variable('@mysql_version') rescue nil
|
46
|
+
end
|
47
|
+
|
48
|
+
it { is_expected.to eq("CHARACTER SET utf8mb3 COLLATE utf8mb3_general") }
|
49
|
+
|
50
|
+
context 'when _ci collation' do
|
51
|
+
let(:table_options) { { charset: "utf8", collation: "utf8_general_ci"} }
|
52
|
+
it { is_expected.to eq("CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci") }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
58
|
describe '#hash' do
|
39
59
|
subject { model.hash }
|
40
|
-
it {
|
60
|
+
it { is_expected.to eq(['table_options_definition_test_models', "{:charset=>#{charset.inspect}, :collation=>#{collation.inspect}}"].hash) }
|
41
61
|
end
|
42
62
|
|
43
63
|
describe '#to_s' do
|
44
64
|
subject { model.to_s }
|
45
|
-
it {
|
65
|
+
it { is_expected.to eq("CHARACTER SET #{charset} COLLATE #{collation}") }
|
46
66
|
end
|
47
67
|
|
48
68
|
describe '#alter_table_statement' do
|
49
69
|
subject { model.alter_table_statement }
|
50
|
-
it {
|
70
|
+
it { is_expected.to match(/execute "ALTER TABLE .*table_options_definition_test_models.* CHARACTER SET #{charset} COLLATE #{collation}"/) }
|
51
71
|
end
|
52
72
|
end
|
53
73
|
|
@@ -67,7 +87,7 @@ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
|
|
67
87
|
generate_migrations '-n', '-m'
|
68
88
|
end
|
69
89
|
|
70
|
-
it {
|
90
|
+
it { is_expected.to eq(described_class.new(model_class.table_name, **options)) }
|
71
91
|
end
|
72
92
|
end
|
73
93
|
end
|
@@ -8,10 +8,34 @@ RSpec.describe DeclareSchema do
|
|
8
8
|
it { is_expected.to eq("utf8mb4") }
|
9
9
|
end
|
10
10
|
|
11
|
-
context 'when
|
12
|
-
|
13
|
-
|
14
|
-
|
11
|
+
context 'when running on MySQL 5.7' do
|
12
|
+
around do |spec|
|
13
|
+
described_class.mysql_version = Gem::Version.new('5.7.48')
|
14
|
+
spec.run
|
15
|
+
ensure
|
16
|
+
described_class.remove_instance_variable('@mysql_version') rescue nil
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when explicitly set' do
|
20
|
+
before { described_class.default_charset = "utf8" }
|
21
|
+
after { described_class.default_charset = "utf8mb4" }
|
22
|
+
it { is_expected.to eq("utf8") }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'when running on MySQL 8.0' do
|
27
|
+
around do |spec|
|
28
|
+
described_class.mysql_version = Gem::Version.new('8.0.21')
|
29
|
+
spec.run
|
30
|
+
ensure
|
31
|
+
described_class.remove_instance_variable('@mysql_version') rescue nil
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when explicitly set' do
|
35
|
+
before { described_class.default_charset = "utf8" }
|
36
|
+
after { described_class.default_charset = "utf8mb4" }
|
37
|
+
it { is_expected.to eq("utf8mb3") }
|
38
|
+
end
|
15
39
|
end
|
16
40
|
end
|
17
41
|
|
@@ -22,10 +46,40 @@ RSpec.describe DeclareSchema do
|
|
22
46
|
it { is_expected.to eq("utf8mb4_bin") }
|
23
47
|
end
|
24
48
|
|
25
|
-
context 'when
|
26
|
-
|
27
|
-
|
28
|
-
|
49
|
+
context 'when running on MySQL 5.7' do
|
50
|
+
around do |spec|
|
51
|
+
described_class.mysql_version = Gem::Version.new('5.7.48')
|
52
|
+
spec.run
|
53
|
+
ensure
|
54
|
+
described_class.remove_instance_variable('@mysql_version')
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'when explicitly set' do
|
58
|
+
before { described_class.default_collation = "utf8_general_ci" }
|
59
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
60
|
+
it { is_expected.to eq("utf8_general_ci") }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'when running on MySQL 8.0' do
|
65
|
+
around do |spec|
|
66
|
+
described_class.mysql_version = Gem::Version.new('8.0.21')
|
67
|
+
spec.run
|
68
|
+
ensure
|
69
|
+
described_class.remove_instance_variable('@mysql_version')
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'when explicitly set without _ci' do
|
73
|
+
before { described_class.default_collation = "utf8_general" }
|
74
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
75
|
+
it { is_expected.to eq("utf8mb3_general") }
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when explicitly set with _ci' do
|
79
|
+
before { described_class.default_collation = "utf8_general_ci" }
|
80
|
+
after { described_class.default_collation = "utf8mb4_bin" }
|
81
|
+
it { is_expected.to eq("utf8mb3_general_ci") }
|
82
|
+
end
|
29
83
|
end
|
30
84
|
end
|
31
85
|
|
@@ -12,6 +12,8 @@ module Generators
|
|
12
12
|
module Migration
|
13
13
|
RSpec.describe Migrator do
|
14
14
|
subject { described_class.new }
|
15
|
+
let(:charset) { ::DeclareSchema.normalize_charset('utf8') }
|
16
|
+
let(:collation) { ::DeclareSchema.normalize_collation('utf8_general') } # adapt so that tests will pass on MySQL 5.7 or 8+
|
15
17
|
|
16
18
|
describe '#before_generating_migration' do
|
17
19
|
it 'requires a block be passed' do
|
@@ -29,7 +31,7 @@ module Generators
|
|
29
31
|
context 'when explicitly set' do
|
30
32
|
before { described_class.default_charset = "utf8" }
|
31
33
|
after { described_class.default_charset = "utf8mb4" }
|
32
|
-
it { should eq(
|
34
|
+
it { should eq(charset) }
|
33
35
|
end
|
34
36
|
|
35
37
|
it 'should output deprecation warning' do
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'declare_schema'
|
5
|
+
require 'climate_control'
|
6
|
+
require 'pry'
|
6
7
|
|
7
8
|
require_relative "./support/acceptance_spec_helpers"
|
8
9
|
|
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.3.
|
4
|
+
version: 1.3.3.colin.1
|
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-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|