declare_schema 1.3.2 → 1.3.3.colin.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- 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,6 +4,11 @@ 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.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
|
+
|
7
12
|
## [1.3.2] - 2024-01-12
|
8
13
|
### Fixed
|
9
14
|
- Fix bug in migrator when table option definitions differ
|
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
|