declare_schema 0.4.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf6d8bf1670910eeadc3f7ed08860af6630f1b5edc271a0740fe8bb94e7f5c71
4
- data.tar.gz: 4d058e02cb6b269f6b66fa20f8ac661ecdb7f8b31547cf43e65e27c869221902
3
+ metadata.gz: c0c13793a5b263a2f1134ee19168a42ceb57c472cf8fb656b8e86fcdd9500b79
4
+ data.tar.gz: ee92620b0a091538958957205ba940d97cd9f67bc606751cb52a8ae44370e541
5
5
  SHA512:
6
- metadata.gz: d95d741db5f9279cfe39f7bd972581708a0ccae7e2d9d209318282a9980d2980e3611592ba08b6b53136e23b92ac4aaa51e2a66187002de04bf818c29715820f
7
- data.tar.gz: 93c203bb2ff2255f014d76a3069d1530d97f9603293738844e2faf6f2c9cb6fb95dcc2aa9ad505df15c8e1e14567e076a5e2901b7b4847f804ce3dd85dc5b313
6
+ metadata.gz: 3bc0e18dd1b3a998640cc2e983c86182e19b855d8ce42b3f7233b3471a7849d0dc28fa2653d110b42d0544c513267f8066386496b1469085bb507541c068b87a
7
+ data.tar.gz: 34b9e31862291b85becf7eeb908c4ef1da5b29178b1ab387b35c6678680299cd921fa65b49e0ba89604518a66515092d3e7d6c38678267301c9399b4572d372e
@@ -0,0 +1,14 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: bundler
4
+ directory: "/"
5
+ schedule:
6
+ interval: weekly
7
+ day: friday
8
+ time: "22:00"
9
+ timezone: PST8PDT
10
+ open-pull-requests-limit: 99
11
+ versioning-strategy: lockfile-only
12
+ commit-message:
13
+ prefix: No-Jira
14
+ include: scope
@@ -0,0 +1,44 @@
1
+ ---
2
+ on: [push]
3
+
4
+ name: DeclareSchema Build
5
+
6
+ jobs:
7
+ build:
8
+ name: DeclareSchema Build
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby: [ 2.4.5, 2.5.8, 2.6.5, 2.7.1 ]
13
+ gemfile: [ gemfiles/rails_4.gemfile, gemfiles/rails_5.gemfile, gemfiles/rails_6.gemfile ]
14
+ exclude:
15
+ - { gemfile: gemfiles/rails_4.gemfile, ruby: 2.7.1 }
16
+ - { gemfile: gemfiles/rails_5.gemfile, ruby: 2.4.5 }
17
+ - { gemfile: gemfiles/rails_6.gemfile, ruby: 2.4.5 }
18
+ env:
19
+ BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
20
+ steps:
21
+ - name: Checkout Branch
22
+ id: checkout_branch
23
+ uses: actions/checkout@v2
24
+ - name: Setup Ruby
25
+ id: setup_ruby
26
+ uses: ruby/setup-ruby@v1
27
+ with:
28
+ bundler: 1.17.3
29
+ ruby-version: ${{matrix.ruby}}
30
+ - name: Remove Bundler 2
31
+ id: remove_bundler_2
32
+ if: ${{ matrix.ruby >= '2.6.5' }}
33
+ run: |
34
+ rm -f /opt/hostedtoolcache/Ruby/2.*/x64/lib/ruby/gems/2.*/specifications/default/bundler-2.*.gemspec
35
+ gem install bundler:1.17.3 --force --default
36
+ gem install bundler -v 1.17.3
37
+ - name: Appraisals
38
+ id: appraisals
39
+ run: |
40
+ bundle install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle} --gemfile=${{ matrix.gemfile }}
41
+ git config --global user.email "dummy@example.com"
42
+ git config --global user.name "dummy"
43
+ bundle exec rake test:prepare_testapp[force]
44
+ bundle exec rake test:all < test_responses.txt
data/.gitignore CHANGED
@@ -12,3 +12,4 @@
12
12
 
13
13
  # appraisal
14
14
  gemfiles/*.lock
15
+ .idea
@@ -4,6 +4,22 @@ 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
+ ## [0.6.0] - 2020-12-23
8
+ ### Added
9
+ - Fields may now be declared with `:bigint` type which is identical to `:integer, limit 8`
10
+ - FieldSpec#initialize interface now includes `position` keyword argument and `**options` hash.
11
+
12
+ ### Fixed
13
+ - Fixed cycle in which FieldSpec#initialize was calling `model.field_specs`
14
+
15
+ ### Changed
16
+ - Changed ci support from Travis to Github Workflow
17
+
18
+ ## [0.5.0] - 2020-12-21
19
+ ### Added
20
+ - Added support for configuring the character set and collation for MySQL databases
21
+ at the global, table, and field level
22
+
7
23
  ## [0.4.2] - 2020-12-05
8
24
  ### Fixed
9
25
  - Generalize the fix below to sqlite || Rails 4.
@@ -15,7 +31,7 @@ Note: this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0
15
31
  ## [0.4.0] - 2020-11-20
16
32
  ### Added
17
33
  - Fields may be declared with `serialize: true` (any value with a valid `.to_yaml` stored as YAML),
18
- or `serialize: <serializeable-class>`, where `<serializeable-class>`
34
+ or `serialize: <serializeable-class>`, where `<serializeable-class>`
19
35
  may be `Array` (`Array` stored as YAML) or `Hash` (`Hash` stored as YAML) or `JSON` (any value with a valid `.to_json`, stored as JSON)
20
36
  or any custom serializable class.
21
37
  This invokes `ActiveSupport`'s `serialize` macro for that field, passing the serializable class, if given.
@@ -68,6 +84,8 @@ using the appropriate Rails configuration attributes.
68
84
  ### Added
69
85
  - Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
70
86
 
87
+ [0.6.0]: https://github.com/Invoca/declare_schema/compare/v0.5.0...v0.6.0
88
+ [0.5.0]: https://github.com/Invoca/declare_schema/compare/v0.4.2...v0.5.0
71
89
  [0.4.2]: https://github.com/Invoca/declare_schema/compare/v0.4.1...v0.4.2
72
90
  [0.4.1]: https://github.com/Invoca/declare_schema/compare/v0.4.0...v0.4.1
73
91
  [0.4.0]: https://github.com/Invoca/declare_schema/compare/v0.3.1...v0.4.0
data/Gemfile CHANGED
@@ -14,6 +14,7 @@ gem 'bundler', '< 2'
14
14
  gem "climate_control", '~> 0.2'
15
15
  gem 'pry'
16
16
  gem 'pry-byebug'
17
+ gem 'mysql2'
17
18
  gem 'rails', '~> 5.2', '>= 5.2.4.3'
18
19
  gem 'responders'
19
20
  gem 'rspec'
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- declare_schema (0.4.2)
4
+ declare_schema (0.6.0)
5
5
  rails (>= 4.2)
6
6
 
7
7
  GEM
@@ -85,6 +85,7 @@ GEM
85
85
  mini_portile2 (2.4.0)
86
86
  minitest (5.14.2)
87
87
  msgpack (1.3.3)
88
+ mysql2 (0.5.3)
88
89
  nio4r (2.5.4)
89
90
  nokogiri (1.10.10)
90
91
  mini_portile2 (~> 2.4.0)
@@ -187,6 +188,7 @@ DEPENDENCIES
187
188
  climate_control (~> 0.2)
188
189
  declare_schema!
189
190
  listen
191
+ mysql2
190
192
  pry
191
193
  pry-byebug
192
194
  rails (~> 5.2, >= 5.2.4.3)
data/README.md CHANGED
@@ -70,6 +70,72 @@ DeclareSchema::Migration::Migrator.before_generating_migration do
70
70
  end
71
71
  ```
72
72
 
73
+ ## Declaring Character Set and Collation
74
+ _Note: This feature currently only works for MySQL database configurations._
75
+
76
+ MySQL originally supported UTF-8 in the range of 1-3 bytes (`mb3` or "multi-byte 3")
77
+ which covered the full set of Unicode code points at the time: U+0000 - U+FFFF.
78
+ But later, Unicode was extended beyond U+FFFF to make room for emojis, and with that
79
+ UTF-8 require 1-4 bytes (`mb4` or "multi-byte 4"). With this addition, there has
80
+ come a need to dynamically define the character set and collation for individual
81
+ tables and columns in the database. With `declare_schema` this can be configured
82
+ at three separate levels
83
+
84
+ ### Global Configuration
85
+ The character set and collation for all tables and fields can be set at the global level
86
+ using the `Generators::DeclareSchema::Migrator.default_charset=` and
87
+ `Generators::DeclareSchema::Migrator.default_collation=` configuration methods.
88
+
89
+ For example, adding the following to your `config/initializers` directory will
90
+ turn all tables into `utf8mb4` supporting tables:
91
+
92
+ **declare_schema.rb**
93
+ ```ruby
94
+ # frozen_string_literal: true
95
+
96
+ Generators::DeclareSchema::Migration::Migrator.default_charset = "utf8mb4"
97
+ Generators::DeclareSchema::Migration::Migrator.default_collation = "utf8mb4_general"
98
+ ```
99
+
100
+ ### Table Configuration
101
+ In order to configure a table's default character set and collation, the `charset` and
102
+ `collation` arguments can be added to the `fields` block.
103
+
104
+ For example, if you have a comments model that needs `utf8mb4` support, it would look
105
+ like the following:
106
+
107
+ **app/models/comment.rb**
108
+ ```ruby
109
+ # frozen_string_literal: true
110
+
111
+ class Comment < ActiveRecord::Base
112
+ fields charset: "utf8mb4", collation: "utf8mb4_general" do
113
+ subject :string, limit: 255
114
+ content :text, limit: 0xffff_ffff
115
+ end
116
+ end
117
+ ```
118
+
119
+ ### Field Configuration
120
+ If you're looking to only change the character set and collation for a single field
121
+ in the table, simply set the `charset` and `collation` configuration options on the
122
+ field definition itself.
123
+
124
+ For example, if you only want to support `utf8mb4` for the content of a comment, it would
125
+ look like the following:
126
+
127
+ **app/models/comment.rb**
128
+ ```ruby
129
+ # frozen_string_literal: true
130
+
131
+ class Comment < ActiveRecord::Base
132
+ fields do
133
+ subject :string, limit: 255
134
+ context :text, limit: 0xffff_ffff, charset: "utf8mb4", collation: "utf8mb4_general"
135
+ end
136
+ end
137
+ ```
138
+
73
139
  ## Installing
74
140
 
75
141
  Install the `DeclareSchema` gem directly:
@@ -7,6 +7,7 @@ gem "bundler", "< 2"
7
7
  gem "climate_control", "~> 0.2"
8
8
  gem "pry"
9
9
  gem "pry-byebug"
10
+ gem "mysql2"
10
11
  gem "rails", "~> 4.2"
11
12
  gem "responders"
12
13
  gem "rspec"
@@ -7,6 +7,7 @@ gem "bundler", "< 2"
7
7
  gem "climate_control", "~> 0.2"
8
8
  gem "pry"
9
9
  gem "pry-byebug"
10
+ gem "mysql2"
10
11
  gem "rails", "~> 5.2"
11
12
  gem "responders"
12
13
  gem "rspec"
@@ -7,6 +7,7 @@ gem "bundler", "< 2"
7
7
  gem "climate_control", "~> 0.2"
8
8
  gem "pry"
9
9
  gem "pry-byebug"
10
+ gem "mysql2"
10
11
  gem "rails", "~> 6.0"
11
12
  gem "responders"
12
13
  gem "rspec"
@@ -41,5 +41,6 @@ require 'declare_schema/model'
41
41
  require 'declare_schema/model/field_spec'
42
42
  require 'declare_schema/model/index_definition'
43
43
  require 'declare_schema/model/foreign_key_definition'
44
+ require 'declare_schema/model/table_options_definition'
44
45
 
45
46
  require 'declare_schema/railtie' if defined?(Rails)
@@ -6,12 +6,13 @@ require 'declare_schema/field_declaration_dsl'
6
6
 
7
7
  module DeclareSchema
8
8
  module FieldsDsl
9
- def fields(&block)
9
+ def fields(table_options = {}, &block)
10
10
  # Any model that calls 'fields' gets DeclareSchema::Model behavior
11
11
  DeclareSchema::Model.mix_in(self)
12
12
 
13
13
  # @include_in_migration = false #||= options.fetch(:include_in_migration, true); options.delete(:include_in_migration)
14
14
  @include_in_migration = true
15
+ @table_options = table_options
15
16
 
16
17
  if block
17
18
  dsl = DeclareSchema::FieldDeclarationDsl.new(self, null: false)
@@ -30,6 +30,10 @@ module DeclareSchema
30
30
  inheriting_cattr_reader ignore_indexes: []
31
31
  inheriting_cattr_reader constraint_specs: []
32
32
 
33
+ # table_options holds optional configuration for the create_table statement
34
+ # supported options include :charset and :collation
35
+ inheriting_cattr_reader table_options: HashWithIndifferentAccess.new
36
+
33
37
  # eval avoids the ruby 1.9.2 "super from singleton method ..." error
34
38
 
35
39
  eval %(
@@ -84,7 +88,7 @@ module DeclareSchema
84
88
  add_formatting_for_field(name, type)
85
89
  add_validations_for_field(name, type, args, options)
86
90
  add_index_for_field(name, args, options)
87
- field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, options)
91
+ field_specs[name] = ::DeclareSchema::Model::FieldSpec.new(self, name, type, position: field_specs.size, **options)
88
92
  attr_order << name unless attr_order.include?(name)
89
93
  end
90
94
 
@@ -33,7 +33,8 @@ module DeclareSchema
33
33
 
34
34
  attr_reader :model, :name, :type, :position, :options
35
35
 
36
- def initialize(model, name, type, options = {})
36
+ def initialize(model, name, type, position: 0, **options)
37
+ # TODO: TECH-5116
37
38
  # Invoca change - searching for the primary key was causing an additional database read on every model load. Assume
38
39
  # "id" which works for invoca.
39
40
  # raise ArgumentError, "you cannot provide a field spec for the primary key" if name == model.primary_key
@@ -43,9 +44,8 @@ module DeclareSchema
43
44
  @name = name.to_sym
44
45
  type.is_a?(Symbol) or raise ArgumentError, "type must be a Symbol; got #{type.inspect}"
45
46
  @type = type
46
- position_option = options.delete(:position)
47
+ @position = position
47
48
  @options = options
48
-
49
49
  case type
50
50
  when :text
51
51
  @options[:default] and raise "default may not be given for :text field #{model}##{@name}"
@@ -54,8 +54,15 @@ module DeclareSchema
54
54
  end
55
55
  when :string
56
56
  @options[:limit] or raise "limit must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
57
+ when :bigint
58
+ @type = :integer
59
+ @options = options.merge(limit: 8)
60
+ end
61
+
62
+ unless type.in?([:text, :string])
63
+ @options[:collation] and raise "collation may only given for :string and :text fields"
64
+ @options[:charset] and raise "charset may only given for :string and :text fields"
57
65
  end
58
- @position = position_option || model.field_specs.length
59
66
  end
60
67
 
61
68
  TYPE_SYNONYMS = { timestamp: :datetime }.freeze
@@ -102,6 +109,18 @@ module DeclareSchema
102
109
  @options[:default]
103
110
  end
104
111
 
112
+ def collation
113
+ if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
114
+ (@options[:collation] || model.table_options[:collation] || Generators::DeclareSchema::Migration::Migrator.default_collation).to_s
115
+ end
116
+ end
117
+
118
+ def charset
119
+ if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
120
+ (@options[:charset] || model.table_options[:charset] || Generators::DeclareSchema::Migration::Migrator.default_charset).to_s
121
+ end
122
+ end
123
+
105
124
  def same_type?(col_spec)
106
125
  type = sql_type
107
126
  normalized_type = TYPE_SYNONYMS[type] || type
@@ -109,36 +128,77 @@ module DeclareSchema
109
128
  normalized_type == normalized_col_spec_type
110
129
  end
111
130
 
112
- def different_to?(col_spec)
113
- !same_type?(col_spec) ||
114
- begin
115
- native_type = native_types[type]
116
- check_attributes = [:null, :default]
117
- check_attributes += [:precision, :scale] if sql_type == :decimal && !col_spec.is_a?(SQLITE_COLUMN_CLASS) # remove when rails fixes https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2872
118
- check_attributes -= [:default] if sql_type == :text && col_spec.class.name =~ /mysql/i
119
- check_attributes << :limit if sql_type.in?([:string, :binary, :varbinary, :integer, :enum]) ||
120
- (sql_type == :text && self.class.mysql_text_limits?)
121
- check_attributes.any? do |k|
122
- if k == :default
123
- case Rails::VERSION::MAJOR
124
- when 4
125
- col_spec.type_cast_from_database(col_spec.default) != col_spec.type_cast_from_database(default)
126
- else
127
- cast_type = ActiveRecord::Base.connection.lookup_cast_type_from_column(col_spec) or raise "cast_type not found for #{col_spec.inspect}"
128
- cast_type.deserialize(col_spec.default) != cast_type.deserialize(default)
129
- end
130
- else
131
- col_value = col_spec.send(k)
132
- if col_value.nil? && native_type
133
- col_value = native_type[k]
134
- end
135
- col_value != send(k)
136
- end
131
+ def different_to?(table_name, col_spec)
132
+ !same_as(table_name, col_spec)
133
+ end
134
+
135
+ def same_as(table_name, col_spec)
136
+ same_type?(col_spec) &&
137
+ same_attributes?(col_spec) &&
138
+ (!type.in?([:text, :string]) || same_charset_and_collation?(table_name, col_spec))
139
+ end
140
+
141
+ private
142
+
143
+ def same_attributes?(col_spec)
144
+ native_type = native_types[type]
145
+ check_attributes = [:null, :default]
146
+ check_attributes += [:precision, :scale] if sql_type == :decimal && !col_spec.is_a?(SQLITE_COLUMN_CLASS) # remove when rails fixes https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/2872
147
+ check_attributes -= [:default] if sql_type == :text && col_spec.class.name =~ /mysql/i
148
+ check_attributes << :limit if sql_type.in?([:string, :binary, :varbinary, :integer, :enum]) ||
149
+ (sql_type == :text && self.class.mysql_text_limits?)
150
+ check_attributes.all? do |k|
151
+ if k == :default
152
+ case Rails::VERSION::MAJOR
153
+ when 4
154
+ col_spec.type_cast_from_database(col_spec.default) == col_spec.type_cast_from_database(default)
155
+ else
156
+ cast_type = ActiveRecord::Base.connection.lookup_cast_type_from_column(col_spec) or raise "cast_type not found for #{col_spec.inspect}"
157
+ cast_type.deserialize(col_spec.default) == cast_type.deserialize(default)
137
158
  end
159
+ else
160
+ col_value = col_spec.send(k)
161
+ if col_value.nil? && native_type
162
+ col_value = native_type[k]
163
+ end
164
+ col_value == send(k)
138
165
  end
166
+ end
139
167
  end
140
168
 
141
- private
169
+ def same_charset_and_collation?(table_name, col_spec)
170
+ current_collation_and_charset = collation_and_charset_for_column(table_name, col_spec)
171
+
172
+ collation == current_collation_and_charset[:collation] &&
173
+ charset == current_collation_and_charset[:charset]
174
+ end
175
+
176
+ def collation_and_charset_for_column(table_name, col_spec)
177
+ column_name = col_spec.name
178
+ connection = ActiveRecord::Base.connection
179
+
180
+ if connection.class.name.match?(/mysql/i)
181
+ database_name = connection.current_database
182
+
183
+ defaults = connection.select_one(<<~EOS)
184
+ SELECT C.character_set_name, C.collation_name
185
+ FROM information_schema.`COLUMNS` C
186
+ WHERE C.table_schema = '#{connection.quote_string(database_name)}' AND
187
+ C.table_name = '#{connection.quote_string(table_name)}' AND
188
+ C.column_name = '#{connection.quote_string(column_name)}';
189
+ EOS
190
+
191
+ defaults["character_set_name"] or raise "character_set_name missing from #{defaults.inspect}"
192
+ defaults["collation_name"] or raise "collation_name missing from #{defaults.inspect}"
193
+
194
+ {
195
+ charset: defaults["character_set_name"],
196
+ collation: defaults["collation_name"]
197
+ }
198
+ else
199
+ {}
200
+ end
201
+ end
142
202
 
143
203
  def native_type?(type)
144
204
  type.to_sym != :primary_key && native_types.has_key?(type)
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DeclareSchema
4
+ module Model
5
+ class TableOptionsDefinition
6
+ include Comparable
7
+
8
+ TABLE_OPTIONS_TO_SQL_MAPPINGS = {
9
+ charset: 'CHARACTER SET',
10
+ collation: 'COLLATE'
11
+ }.freeze
12
+
13
+ class << self
14
+ def for_model(model, old_table_name = nil)
15
+ table_name = old_table_name || model.table_name
16
+ table_options = if model.connection.class.name.match?(/mysql/i)
17
+ mysql_table_options(model.connection, table_name)
18
+ else
19
+ {}
20
+ end
21
+
22
+ new(table_name, table_options)
23
+ end
24
+
25
+ private
26
+
27
+ def mysql_table_options(connection, table_name)
28
+ database = connection.current_database
29
+ defaults = connection.select_one(<<~EOS)
30
+ SELECT CCSA.character_set_name, CCSA.collation_name
31
+ FROM information_schema.`TABLES` T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
32
+ WHERE CCSA.collation_name = T.table_collation AND
33
+ T.table_schema = '#{connection.quote_string(database)}' AND
34
+ T.table_name = '#{connection.quote_string(table_name)}';
35
+ EOS
36
+
37
+ defaults["character_set_name"] or raise "character_set_name missing from #{defaults.inspect}"
38
+ defaults["collation_name"] or raise "collation_name missing from #{defaults.inspect}"
39
+
40
+ {
41
+ charset: defaults["character_set_name"],
42
+ collation: defaults["collation_name"]
43
+ }
44
+ end
45
+ end
46
+
47
+ attr_reader :table_name, :table_options
48
+
49
+ def initialize(table_name, table_options = {})
50
+ @table_name = table_name
51
+ @table_options = table_options
52
+ end
53
+
54
+ def to_key
55
+ @key ||= [table_name, table_options].map(&:to_s)
56
+ end
57
+
58
+ def settings
59
+ @settings ||= table_options.map { |name, value| "#{TABLE_OPTIONS_TO_SQL_MAPPINGS[name]} #{value}" if value }.compact.join(" ")
60
+ end
61
+
62
+ def hash
63
+ to_key.hash
64
+ end
65
+
66
+ def <=>(rhs)
67
+ to_key <=> rhs.to_key
68
+ end
69
+
70
+ def equivalent?(rhs)
71
+ settings == rhs.settings
72
+ end
73
+
74
+ alias eql? ==
75
+ alias to_s settings
76
+
77
+ def alter_table_statement
78
+ statement = "ALTER TABLE #{ActiveRecord::Base.connection.quote_table_name(table_name)} #{to_s};"
79
+ "execute #{statement.inspect}"
80
+ end
81
+ end
82
+ end
83
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DeclareSchema
4
- VERSION = "0.4.2"
4
+ VERSION = "0.6.0"
5
5
  end
@@ -23,6 +23,10 @@ module Generators
23
23
  end
24
24
  end
25
25
 
26
+ def table_options
27
+ {}
28
+ end
29
+
26
30
  def table_name
27
31
  join_table
28
32
  end
@@ -33,11 +37,9 @@ module Generators
33
37
 
34
38
  def field_specs
35
39
  i = 0
36
- foreign_keys.reduce({}) do |h, v|
37
- # some trickery to avoid an infinite loop when FieldSpec#initialize tries to call model.field_specs
38
- h[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: i, null: false)
40
+ foreign_keys.each_with_object({}) do |v, result|
41
+ result[v] = ::DeclareSchema::Model::FieldSpec.new(self, v, :integer, position: i, null: false)
39
42
  i += 1
40
- h
41
43
  end
42
44
  end
43
45
 
@@ -69,13 +71,19 @@ module Generators
69
71
  class Migrator
70
72
  class Error < RuntimeError; end
71
73
 
72
- @ignore_models = []
73
- @ignore_tables = []
74
+ DEFAULT_CHARSET = :utf8mb4
75
+ DEFAULT_COLLATION = :utf8mb4_general
76
+
77
+ @ignore_models = []
78
+ @ignore_tables = []
74
79
  @before_generating_migration_callback = nil
75
- @active_record_class = ActiveRecord::Base
80
+ @active_record_class = ActiveRecord::Base
81
+ @default_charset = DEFAULT_CHARSET
82
+ @default_collation = DEFAULT_COLLATION
76
83
 
77
84
  class << self
78
- attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints, :active_record_class
85
+ attr_accessor :ignore_models, :ignore_tables, :disable_indexing, :disable_constraints,
86
+ :active_record_class, :default_charset, :default_collation
79
87
  attr_reader :before_generating_migration_callback
80
88
 
81
89
  def active_record_class
@@ -292,52 +300,76 @@ module Generators
292
300
  "drop_table :#{t}"
293
301
  end * "\n"
294
302
 
295
- changes = []
296
- undo_changes = []
297
- index_changes = []
298
- undo_index_changes = []
299
- fk_changes = []
300
- undo_fk_changes = []
303
+ changes = []
304
+ undo_changes = []
305
+ index_changes = []
306
+ undo_index_changes = []
307
+ fk_changes = []
308
+ undo_fk_changes = []
309
+ table_options_changes = []
310
+ undo_table_options_changes = []
311
+
301
312
  to_change.each do |t|
302
313
  model = models_by_table_name[t]
303
314
  table = to_rename.key(t) || model.table_name
304
315
  if table.in?(db_tables)
305
- change, undo, index_change, undo_index, fk_change, undo_fk = change_table(model, table)
316
+ change, undo, index_change, undo_index, fk_change, undo_fk, table_options_change, undo_table_options_change = change_table(model, table)
306
317
  changes << change
307
318
  undo_changes << undo
308
319
  index_changes << index_change
309
320
  undo_index_changes << undo_index
310
321
  fk_changes << fk_change
311
322
  undo_fk_changes << undo_fk
323
+ table_options_changes << table_options_change
324
+ undo_table_options_changes << undo_table_options_change
312
325
  end
313
326
  end
314
327
 
315
- up = [renames, drops, creates, changes, index_changes, fk_changes].flatten.reject(&:blank?) * "\n\n"
316
- down = [undo_changes, undo_renames, undo_drops, undo_creates, undo_index_changes, undo_fk_changes].flatten.reject(&:blank?) * "\n\n"
328
+ up = [renames, drops, creates, changes, index_changes, fk_changes, table_options_changes].flatten.reject(&:blank?) * "\n\n"
329
+ down = [undo_changes, undo_renames, undo_drops, undo_creates, undo_index_changes, undo_fk_changes, undo_table_options_changes].flatten.reject(&:blank?) * "\n\n"
317
330
 
318
331
  [up, down]
319
332
  end
320
333
 
321
334
  def create_table(model)
322
- longest_field_name = model.field_specs.values.map { |f| f.sql_type.to_s.length }.max
323
- disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
324
- primary_key_option =
325
- if model.primary_key.blank? || disable_auto_increment
326
- ", id: false"
327
- elsif model.primary_key == "id"
328
- ", id: :bigint"
329
- else
330
- ", primary_key: :#{model.primary_key}"
335
+ longest_field_name = model.field_specs.values.map { |f| f.sql_type.to_s.length }.max
336
+ disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
337
+ table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
338
+ field_definitions = [
339
+ disable_auto_increment ? "t.integer :id, limit: 8, auto_increment: false, primary_key: true" : nil,
340
+ *(model.field_specs.values.sort_by(&:position).map { |f| create_field(f, longest_field_name) })
341
+ ].compact
342
+
343
+ <<~EOS.strip
344
+ create_table :#{model.table_name}, #{create_table_options(model, disable_auto_increment)} do |t|
345
+ #{field_definitions.join("\n")}
331
346
  end
332
- (["create_table :#{model.table_name}#{primary_key_option} do |t|"] +
333
- [(disable_auto_increment ? " t.integer :id, limit: 8, auto_increment: false, primary_key: true" : nil)] +
334
- model.field_specs.values.sort_by(&:position).map { |f| create_field(f, longest_field_name) } +
335
- ["end"] + (if Migrator.disable_indexing
336
- []
337
- else
338
- create_indexes(model) +
339
- create_constraints(model)
340
- end)).compact * "\n"
347
+
348
+ #{table_options_definition.alter_table_statement unless ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)}
349
+ #{create_indexes(model).join("\n") unless Migrator.disable_indexing}
350
+ #{create_constraints(model).join("\n") unless Migrator.disable_indexing}
351
+ EOS
352
+ end
353
+
354
+ def create_table_options(model, disable_auto_increment)
355
+ if model.primary_key.blank? || disable_auto_increment
356
+ "id: false"
357
+ elsif model.primary_key == "id"
358
+ "id: :bigint"
359
+ else
360
+ "primary_key: :#{model.primary_key}"
361
+ end
362
+ end
363
+
364
+ def table_options_for_model(model)
365
+ if ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
366
+ {}
367
+ else
368
+ {
369
+ charset: model.table_options[:charset] || Migrator.default_charset,
370
+ collation: model.table_options[:collation] || Migrator.default_collation
371
+ }
372
+ end
341
373
  end
342
374
 
343
375
  def create_indexes(model)
@@ -351,7 +383,7 @@ module Generators
351
383
  def create_field(field_spec, field_name_width)
352
384
  options = fk_field_options(field_spec.model, field_spec.name).merge(field_spec.sql_options)
353
385
  args = [field_spec.name.inspect] + format_options(options, field_spec.sql_type)
354
- format(" t.%-*s %s", field_name_width, field_spec.sql_type, args.join(', '))
386
+ format("t.%-*s %s", field_name_width, field_spec.sql_type, args.join(', '))
355
387
  end
356
388
 
357
389
  def change_table(model, current_table_name)
@@ -413,15 +445,17 @@ module Generators
413
445
  col_name = old_names[c] || c
414
446
  col = db_columns[col_name]
415
447
  spec = model.field_specs[c]
416
- if spec.different_to?(col) # TODO: TECH-4814 DRY this up to a diff function that returns the differences. It's different if it has differences. -Colin
448
+ if spec.different_to?(current_table_name, col) # TODO: TECH-4814 DRY this up to a diff function that returns the differences. It's different if it has differences. -Colin
417
449
  change_spec = fk_field_options(model, c)
418
450
  change_spec[:limit] ||= spec.limit if (spec.sql_type != :text ||
419
451
  ::DeclareSchema::Model::FieldSpec.mysql_text_limits?) &&
420
452
  (spec.limit || col.limit)
421
- change_spec[:precision] = spec.precision unless spec.precision.nil?
422
- change_spec[:scale] = spec.scale unless spec.scale.nil?
423
- change_spec[:null] = spec.null unless spec.null && col.null
424
- change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
453
+ change_spec[:precision] = spec.precision unless spec.precision.nil?
454
+ change_spec[:scale] = spec.scale unless spec.scale.nil?
455
+ change_spec[:null] = spec.null unless spec.null && col.null
456
+ change_spec[:default] = spec.default unless spec.default.nil? && col.default.nil?
457
+ change_spec[:collation] = spec.collation unless spec.collation.nil?
458
+ change_spec[:charset] = spec.charset unless spec.charset.nil?
425
459
 
426
460
  changes << "change_column :#{new_table_name}, :#{c}, " +
427
461
  ([":#{spec.sql_type}"] + format_options(change_spec, spec.sql_type, changing: true)).join(", ")
@@ -436,13 +470,20 @@ module Generators
436
470
  else
437
471
  change_foreign_key_constraints(model, current_table_name)
438
472
  end
473
+ table_options_changes, undo_table_options_changes = if ActiveRecord::Base.connection.class.name.match?(/mysql/i)
474
+ change_table_options(model, current_table_name)
475
+ else
476
+ [[], []]
477
+ end
439
478
 
440
479
  [(renames + adds + removes + changes) * "\n",
441
480
  (undo_renames + undo_adds + undo_removes + undo_changes) * "\n",
442
481
  index_changes * "\n",
443
482
  undo_index_changes * "\n",
444
483
  fk_changes * "\n",
445
- undo_fk_changes * "\n"]
484
+ undo_fk_changes * "\n",
485
+ table_options_changes * "\n",
486
+ undo_table_options_changes * "\n"]
446
487
  end
447
488
 
448
489
  def change_indexes(model, old_table_name)
@@ -552,6 +593,20 @@ module Generators
552
593
  end
553
594
  end
554
595
 
596
+ def change_table_options(model, current_table_name)
597
+ old_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.for_model(model, current_table_name)
598
+ new_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
599
+
600
+ if old_options_definition.equivalent?(new_options_definition)
601
+ [[], []]
602
+ else
603
+ [
604
+ [new_options_definition.alter_table_statement],
605
+ [old_options_definition.alter_table_statement]
606
+ ]
607
+ end
608
+ end
609
+
555
610
  def revert_table(table)
556
611
  res = StringIO.new
557
612
  schema_dumper_klass = case Rails::VERSION::MAJOR
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe 'DeclareSchema Model FieldSpec' do
4
+ before do
5
+ load File.expand_path('prepare_testapp.rb', __dir__)
6
+ end
7
+
8
+ context 'There are no model columns to change' do
9
+ it '#different_to should return false for int8 == int8' do
10
+ subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :integer, limit: 8, null: false, position: 0)
11
+
12
+ case Rails::VERSION::MAJOR
13
+ when 4
14
+ cast_type = ActiveRecord::Type::Integer.new(limit: 8)
15
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "integer(8)", false)
16
+ else
17
+ sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "integer(8)", type: :integer, limit: 8)
18
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
19
+ end
20
+
21
+ expect(subject.different_to?(subject.name, col)).to eq(false)
22
+ end
23
+
24
+ it '#different_to should return false for bigint == bigint' do
25
+ subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :bigint, null: false, position: 0)
26
+
27
+ case Rails::VERSION::MAJOR
28
+ when 4
29
+ cast_type = ActiveRecord::Type::BigInteger.new(limit: 8)
30
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "bigint(20)", false)
31
+ else
32
+ sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "bigint(20)", type: :integer, limit: 8)
33
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
34
+ end
35
+
36
+ expect(subject.different_to?(subject.name, col)).to eq(false)
37
+ end
38
+
39
+ it '#different_to should return false for int8 == bigint' do
40
+ subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :integer, limit: 8, null: false, position: 0)
41
+
42
+ case Rails::VERSION::MAJOR
43
+ when 4
44
+ cast_type = ActiveRecord::Type::BigInteger.new(limit: 8)
45
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "bigint(20)", false)
46
+ else
47
+ sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "bigint(20)", type: :integer, limit: 8)
48
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
49
+ end
50
+
51
+ expect(subject.different_to?(subject.name, col)).to eq(false)
52
+ end
53
+
54
+ it '#different_to should return false for bigint == int8' do
55
+ subject = DeclareSchema::Model::FieldSpec.new(Object, :price, :bigint, null: false, position: 0)
56
+
57
+ case Rails::VERSION::MAJOR
58
+ when 4
59
+ cast_type = ActiveRecord::Type::Integer.new(limit: 8)
60
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, cast_type, "integer(8)", false)
61
+ else
62
+ sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(sql_type: "integer(8)", type: :integer, limit: 8)
63
+ col = ActiveRecord::ConnectionAdapters::Column.new("price", nil, sql_type_metadata, false, "adverts")
64
+ end
65
+
66
+ expect(subject.different_to?(subject.name, col)).to eq(false)
67
+ end
68
+ end
69
+ end
@@ -27,15 +27,28 @@ RSpec.describe 'DeclareSchema Migration Generator' do
27
27
  end
28
28
  EOS
29
29
 
30
- expect_test_definition_to_eq('alpha/beta', <<~EOS)
31
- require 'test_helper'
32
-
33
- class Alpha::BetaTest < ActiveSupport::TestCase
34
- # test "the truth" do
35
- # assert true
36
- # end
37
- end
38
- EOS
30
+ case Rails::VERSION::MAJOR
31
+ when 4, 5
32
+ expect_test_definition_to_eq('alpha/beta', <<~EOS)
33
+ require 'test_helper'
34
+
35
+ class Alpha::BetaTest < ActiveSupport::TestCase
36
+ # test "the truth" do
37
+ # assert true
38
+ # end
39
+ end
40
+ EOS
41
+ else
42
+ expect_test_definition_to_eq('alpha/beta', <<~EOS)
43
+ require "test_helper"
44
+
45
+ class Alpha::BetaTest < ActiveSupport::TestCase
46
+ # test "the truth" do
47
+ # assert true
48
+ # end
49
+ end
50
+ EOS
51
+ end
39
52
 
40
53
  case Rails::VERSION::MAJOR
41
54
  when 4
@@ -1093,4 +1093,29 @@ RSpec.describe 'DeclareSchema Migration Generator' do
1093
1093
  expect(base_class).to eq("(Rails::VERSION::MAJOR >= 5 ? ActiveRecord::Migration[4.2] : ActiveRecord::Migration)")
1094
1094
  end
1095
1095
  end
1096
+
1097
+ context 'Does not generate migrations' do
1098
+ it 'for aliased fields bigint -> integer limit 8' do
1099
+ if Rails::VERSION::MAJOR >= 5 || !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/)
1100
+ class Advert < active_record_base_class.constantize
1101
+ fields do
1102
+ price :bigint
1103
+ end
1104
+ end
1105
+
1106
+ generate_migrations '-n', '-m'
1107
+
1108
+ migrations = Dir.glob('db/migrate/*declare_schema_migration*.rb')
1109
+ expect(migrations.size).to eq(1), migrations.inspect
1110
+
1111
+ class Advert < active_record_base_class.constantize
1112
+ fields do
1113
+ price :integer, limit: 8
1114
+ end
1115
+ end
1116
+
1117
+ expect { generate_migrations '-n', '-g' }.to output("Database and models match -- nothing to change\n").to_stdout
1118
+ end
1119
+ end
1120
+ end
1096
1121
  end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_record/connection_adapters/mysql2_adapter'
4
+ require_relative '../../../../lib/declare_schema/model/table_options_definition'
5
+
6
+ RSpec.describe DeclareSchema::Model::TableOptionsDefinition do
7
+ before do
8
+ load File.expand_path('../prepare_testapp.rb', __dir__)
9
+
10
+ class TableOptionsDefinitionTestModel < ActiveRecord::Base
11
+ fields do
12
+ name :string, limit: 127, index: true
13
+ end
14
+ end
15
+ end
16
+
17
+ let(:model_class) { TableOptionsDefinitionTestModel }
18
+
19
+ context 'instance methods' do
20
+ let(:table_options) { { charset: "utf8", collation: "utf8_general"} }
21
+ let(:model) { described_class.new('table_options_definition_test_models', table_options) }
22
+
23
+ describe '#to_key' do
24
+ subject { model.to_key }
25
+ it { should eq(["table_options_definition_test_models", "{:charset=>\"utf8\", :collation=>\"utf8_general\"}"]) }
26
+ end
27
+
28
+ describe '#settings' do
29
+ subject { model.settings }
30
+ it { should eq("CHARACTER SET utf8 COLLATE utf8_general") }
31
+ end
32
+
33
+ describe '#hash' do
34
+ subject { model.hash }
35
+ it { should eq(["table_options_definition_test_models", "{:charset=>\"utf8\", :collation=>\"utf8_general\"}"].hash) }
36
+ end
37
+
38
+ describe '#to_s' do
39
+ subject { model.to_s }
40
+ it { should eq("CHARACTER SET utf8 COLLATE utf8_general") }
41
+ end
42
+
43
+ describe '#alter_table_statement' do
44
+ subject { model.alter_table_statement }
45
+ it { should eq('execute "ALTER TABLE \"table_options_definition_test_models\" CHARACTER SET utf8 COLLATE utf8_general;"') }
46
+ end
47
+ end
48
+
49
+
50
+ context 'class << self' do
51
+ describe '#for_model' do
52
+ context 'when using a SQLite connection' do
53
+ subject { described_class.for_model(model_class) }
54
+ it { should eq(described_class.new(model_class.table_name, {})) }
55
+ end
56
+ # TODO: Convert these tests to run against a MySQL database so that we can
57
+ # perform them without mocking out so much
58
+ context 'when using a MySQL connection' do
59
+ before do
60
+ double(ActiveRecord::ConnectionAdapters::Mysql2Adapter).tap do |stub_connection|
61
+ expect(stub_connection).to receive(:class).and_return(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
62
+ expect(stub_connection).to receive(:current_database).and_return('test_database')
63
+ expect(stub_connection).to receive(:quote_string).with('test_database').and_return('test_database')
64
+ expect(stub_connection).to receive(:quote_string).with(model_class.table_name).and_return(model_class.table_name)
65
+ expect(stub_connection).to(
66
+ receive(:select_one).with(<<~EOS)
67
+ SELECT CCSA.character_set_name, CCSA.collation_name
68
+ FROM information_schema.`TABLES` T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA
69
+ WHERE CCSA.collation_name = T.table_collation AND
70
+ T.table_schema = 'test_database' AND
71
+ T.table_name = '#{model_class.table_name}';
72
+ EOS
73
+ .and_return({ "character_set_name" => "utf8", "collation_name" => "utf8_general" })
74
+ )
75
+ allow(model_class).to receive(:connection).and_return(stub_connection)
76
+ end
77
+ end
78
+
79
+ subject { described_class.for_model(model_class) }
80
+ it { should eq(described_class.new(model_class.table_name, { charset: "utf8", collation: "utf8_general" })) }
81
+ end
82
+ end
83
+ end
84
+ end
@@ -43,6 +43,34 @@ module Generators
43
43
  end
44
44
  end
45
45
 
46
+ describe '#default_charset' do
47
+ subject { described_class.default_charset }
48
+
49
+ context 'when not explicitly set' do
50
+ it { should eq(:utf8mb4) }
51
+ end
52
+
53
+ context 'when explicitly set' do
54
+ before { described_class.default_charset = :utf8 }
55
+ after { described_class.default_charset = described_class::DEFAULT_CHARSET }
56
+ it { should eq(:utf8) }
57
+ end
58
+ end
59
+
60
+ describe '#default_collation' do
61
+ subject { described_class.default_collation }
62
+
63
+ context 'when not explicitly set' do
64
+ it { should eq(:utf8mb4_general) }
65
+ end
66
+
67
+ context 'when explicitly set' do
68
+ before { described_class.default_collation = :utf8mb4_general_ci }
69
+ after { described_class.default_collation = described_class::DEFAULT_COLLATION }
70
+ it { should eq(:utf8mb4_general_ci) }
71
+ end
72
+ end
73
+
46
74
  describe 'load_rails_models' do
47
75
  before do
48
76
  expect(Rails.application).to receive(:eager_load!)
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: 0.4.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Invoca Development adapted from hobo_fields by Tom Locke
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-12-05 00:00:00.000000000 Z
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -32,13 +32,13 @@ executables:
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
- - ".dependabot/config.yml"
35
+ - ".github/dependabot.yml"
36
+ - ".github/workflows/declare_schema_build.yml"
36
37
  - ".github/workflows/gem_release.yml"
37
38
  - ".gitignore"
38
39
  - ".rspec"
39
40
  - ".rubocop.yml"
40
41
  - ".ruby-version"
41
- - ".travis.yml"
42
42
  - Appraisals
43
43
  - CHANGELOG.md
44
44
  - Gemfile
@@ -61,6 +61,7 @@ files:
61
61
  - lib/declare_schema/model/field_spec.rb
62
62
  - lib/declare_schema/model/foreign_key_definition.rb
63
63
  - lib/declare_schema/model/index_definition.rb
64
+ - lib/declare_schema/model/table_options_definition.rb
64
65
  - lib/declare_schema/railtie.rb
65
66
  - lib/declare_schema/version.rb
66
67
  - lib/generators/declare_schema/migration/USAGE
@@ -74,10 +75,12 @@ files:
74
75
  - lib/generators/declare_schema/support/thor_shell.rb
75
76
  - spec/lib/declare_schema/api_spec.rb
76
77
  - spec/lib/declare_schema/field_declaration_dsl_spec.rb
78
+ - spec/lib/declare_schema/field_spec_spec.rb
77
79
  - spec/lib/declare_schema/generator_spec.rb
78
80
  - spec/lib/declare_schema/interactive_primary_key_spec.rb
79
81
  - spec/lib/declare_schema/migration_generator_spec.rb
80
82
  - spec/lib/declare_schema/model/index_definition_spec.rb
83
+ - spec/lib/declare_schema/model/table_options_definition_spec.rb
81
84
  - spec/lib/declare_schema/prepare_testapp.rb
82
85
  - spec/lib/generators/declare_schema/migration/migrator_spec.rb
83
86
  - spec/spec_helper.rb
@@ -87,7 +90,7 @@ homepage: https://github.com/Invoca/declare_schema
87
90
  licenses: []
88
91
  metadata:
89
92
  allowed_push_host: https://rubygems.org
90
- post_install_message:
93
+ post_install_message:
91
94
  rdoc_options: []
92
95
  require_paths:
93
96
  - lib
@@ -103,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
106
  version: 1.3.6
104
107
  requirements: []
105
108
  rubygems_version: 3.0.3
106
- signing_key:
109
+ signing_key:
107
110
  specification_version: 4
108
111
  summary: Database migration generator for Rails
109
112
  test_files: []
@@ -1,10 +0,0 @@
1
- ---
2
- version: 1
3
- update_configs:
4
- - package_manager: "ruby:bundler"
5
- directory: "/"
6
- update_schedule: "weekly"
7
- version_requirement_updates: "off"
8
- commit_message:
9
- prefix: "No-Jira"
10
- include_scope: true
@@ -1,37 +0,0 @@
1
- ---
2
- dist: trusty
3
- os: linux
4
- language: ruby
5
- cache: bundler
6
- rvm:
7
- - 2.4.5
8
- - 2.5.8
9
- - 2.6.5
10
- - 2.7.1
11
- - ruby-head
12
- gemfile:
13
- - gemfiles/rails_4.gemfile
14
- - gemfiles/rails_5.gemfile
15
- - gemfiles/rails_6.gemfile
16
- jobs:
17
- fast_finish: false
18
- exclude:
19
- - gemfile: gemfiles/rails_4.gemfile
20
- rvm: 2.7.1
21
- - gemfile: gemfiles/rails_5.gemfile
22
- rvm: 2.4.5
23
- - gemfile: gemfiles/rails_6.gemfile
24
- rvm: 2.4.5
25
- allow_failures:
26
- - rvm: ruby-head
27
- before_install:
28
- - rm -f /home/travis/.rvm/rubies/ruby-2.*/lib/ruby/gems/2.*/specifications/default/bundler-2.*.gemspec
29
- - echo y | rvm @global do gem install bundler -v 1.17.3 --force --default
30
- - gem install bundler -v 1.17.3 --force --default
31
- - gem install bundler -v 1.17.3
32
- install:
33
- - bundle --version
34
- - bundle install --jobs=3 --retry=3 --path=${BUNDLE_PATH:-vendor/bundle}
35
- script:
36
- - bundle exec rake test:prepare_testapp[force]
37
- - bundle exec rake test:all < test_responses.txt