declare_schema 0.7.1 → 0.8.0.pre.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 -0
- data/Gemfile.lock +1 -1
- data/lib/declare_schema/model/column.rb +11 -20
- data/lib/declare_schema/model/field_spec.rb +14 -15
- data/lib/declare_schema/version.rb +1 -1
- data/lib/generators/declare_schema/migration/migration_generator.rb +1 -1
- data/lib/generators/declare_schema/migration/migrator.rb +3 -3
- data/spec/lib/declare_schema/field_spec_spec.rb +2 -2
- data/spec/lib/declare_schema/model/column_spec.rb +5 -24
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63c52c12c292be619b08901eb088c9957e8bfbc9708d087faa9d418704524175
|
4
|
+
data.tar.gz: 5a12e3d6cc67914e6b8c8739c17d89e2ea7886212f2abd90bd372f57fab808af
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e33ae65cdfcb5fc56c24b4d62804ba28c77b29efc0a7659b45660c953f6310ae90b8b42a8d51f9f5331592e511ec33d56ff0f7b691dcb7aa8f299a5f7d523f22
|
7
|
+
data.tar.gz: 688ca01165e655ab6ff309f82ba336530bb44d695ac90de049cabc730850c7059c8789ef95bafbc02059b6329b4212d0e2ab726034b9c71d814a51fdaca02501
|
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
|
+
## [0.8.0] - UNRELEASED
|
8
|
+
### Removed
|
9
|
+
- Removed `sql_type` that was confusing because it was actually the same as `type` (ex: :string) and not
|
10
|
+
in fact the SQL type (ex: ``varchar(255)'`).
|
11
|
+
|
7
12
|
## [0.7.1] - 2021-02-17
|
8
13
|
### Fixed
|
9
14
|
- Exclude unknown options from FieldSpec#sql_options and #schema_attributes.
|
@@ -125,6 +130,7 @@ using the appropriate Rails configuration attributes.
|
|
125
130
|
### Added
|
126
131
|
- Initial version from https://github.com/Invoca/hobo_fields v4.1.0.
|
127
132
|
|
133
|
+
[0.8.0]: https://github.com/Invoca/declare_schema/compare/v0.7.1...v0.8.0
|
128
134
|
[0.7.1]: https://github.com/Invoca/declare_schema/compare/v0.7.0...v0.7.1
|
129
135
|
[0.7.0]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.7.0
|
130
136
|
[0.6.4]: https://github.com/Invoca/declare_schema/compare/v0.6.3...v0.6.4
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module DeclareSchema
|
4
|
-
class
|
4
|
+
class UnknownTypeError < RuntimeError; end
|
5
5
|
|
6
6
|
module Model
|
7
7
|
# This class is a wrapper for the ActiveRecord::...::Column class
|
8
8
|
class Column
|
9
9
|
class << self
|
10
10
|
def native_type?(type)
|
11
|
-
type != :primary_key && native_types
|
11
|
+
type != :primary_key && native_types[type]
|
12
12
|
end
|
13
13
|
|
14
14
|
# MySQL example:
|
@@ -48,27 +48,17 @@ module DeclareSchema
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
def
|
52
|
-
|
53
|
-
type
|
54
|
-
else
|
55
|
-
if (field_class = DeclareSchema.to_class(type))
|
56
|
-
field_class::COLUMN_TYPE
|
57
|
-
end or raise UnknownSqlTypeError, "#{type.inspect} for type #{type.inspect}"
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def deserialize_default_value(column, sql_type, default_value)
|
62
|
-
sql_type or raise ArgumentError, "must pass sql_type; got #{sql_type.inspect}"
|
51
|
+
def deserialize_default_value(column, type, default_value)
|
52
|
+
type or raise ArgumentError, "must pass type; got #{type.inspect}"
|
63
53
|
|
64
54
|
case Rails::VERSION::MAJOR
|
65
55
|
when 4
|
66
56
|
# TODO: Delete this Rails 4 support ASAP! This could be wrong, since it's using the type of the old column...which
|
67
|
-
# might be getting migrated to a new type. We should be using just
|
57
|
+
# might be getting migrated to a new type. We should be using just type as below. -Colin
|
68
58
|
column.type_cast_from_database(default_value)
|
69
59
|
else
|
70
|
-
cast_type = ActiveRecord::Base.connection.send(:lookup_cast_type,
|
71
|
-
raise "cast_type not found for #{
|
60
|
+
cast_type = ActiveRecord::Base.connection.send(:lookup_cast_type, type) or
|
61
|
+
raise "cast_type not found for #{type}"
|
72
62
|
cast_type.deserialize(default_value)
|
73
63
|
end
|
74
64
|
end
|
@@ -103,13 +93,14 @@ module DeclareSchema
|
|
103
93
|
end
|
104
94
|
end
|
105
95
|
|
106
|
-
attr_reader :
|
96
|
+
attr_reader :type
|
107
97
|
|
108
98
|
def initialize(model, current_table_name, column)
|
109
99
|
@model = model or raise ArgumentError, "must pass model"
|
110
100
|
@current_table_name = current_table_name or raise ArgumentError, "must pass current_table_name"
|
111
101
|
@column = column or raise ArgumentError, "must pass column"
|
112
|
-
@
|
102
|
+
@type = @column.type
|
103
|
+
self.class.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect}"
|
113
104
|
end
|
114
105
|
|
115
106
|
SCHEMA_KEYS = [:type, :limit, :precision, :scale, :null, :default].freeze
|
@@ -120,7 +111,7 @@ module DeclareSchema
|
|
120
111
|
value =
|
121
112
|
case key
|
122
113
|
when :default
|
123
|
-
self.class.deserialize_default_value(@column, @
|
114
|
+
self.class.deserialize_default_value(@column, @type, @column.default)
|
124
115
|
else
|
125
116
|
col_value = @column.send(key)
|
126
117
|
if col_value.nil? && (native_type = self.class.native_types[@column.type])
|
@@ -33,7 +33,7 @@ module DeclareSchema
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
attr_reader :model, :name, :type, :
|
36
|
+
attr_reader :model, :name, :type, :position, :options, :sql_options
|
37
37
|
|
38
38
|
TYPE_SYNONYMS = { timestamp: :datetime }.freeze # TODO: drop this synonym. -Colin
|
39
39
|
|
@@ -62,13 +62,13 @@ module DeclareSchema
|
|
62
62
|
|
63
63
|
@options.has_key?(:null) or @options[:null] = false
|
64
64
|
|
65
|
-
case type
|
65
|
+
case @type
|
66
66
|
when :text
|
67
67
|
if self.class.mysql_text_limits?
|
68
68
|
@options[:default].nil? or raise MysqlTextMayNotHaveDefault, "when using MySQL, non-nil default may not be given for :text field #{model}##{@name}"
|
69
69
|
@options[:limit] = self.class.round_up_mysql_text_limit(@options[:limit] || MYSQL_LONGTEXT_LIMIT)
|
70
70
|
else
|
71
|
-
@options
|
71
|
+
@options.delete(:limit)
|
72
72
|
end
|
73
73
|
when :string
|
74
74
|
@options[:limit] or raise "limit: must be given for :string field #{model}##{@name}: #{@options.inspect}; do you want `limit: 255`?"
|
@@ -77,24 +77,23 @@ module DeclareSchema
|
|
77
77
|
@options[:limit] = 8
|
78
78
|
end
|
79
79
|
|
80
|
-
|
81
|
-
@sql_type = @options.delete(:sql_type) || Column.sql_type(@type)
|
80
|
+
Column.native_type?(@type) or raise UnknownTypeError, "#{@type.inspect}"
|
82
81
|
|
83
|
-
if @
|
84
|
-
@options[:limit] ||= Column.native_types[@
|
82
|
+
if @type.in?([:string, :text, :binary, :varbinary, :integer, :enum])
|
83
|
+
@options[:limit] ||= Column.native_types[@type][:limit]
|
85
84
|
else
|
86
|
-
@
|
85
|
+
@type != :decimal && @options.has_key?(:limit) and warn("unsupported limit: for SQL type #{@type} in field #{model}##{@name}")
|
87
86
|
@options.delete(:limit)
|
88
87
|
end
|
89
88
|
|
90
|
-
if @
|
89
|
+
if @type == :decimal
|
91
90
|
@options[:precision] or warn("precision: required for :decimal type in field #{model}##{@name}")
|
92
91
|
@options[:scale] or warn("scale: required for :decimal type in field #{model}##{@name}")
|
93
92
|
else
|
94
|
-
if @
|
95
|
-
@options.has_key?(:precision) and warn("precision: only allowed for :decimal type or :datetime for SQL type #{@
|
93
|
+
if @type != :datetime
|
94
|
+
@options.has_key?(:precision) and warn("precision: only allowed for :decimal type or :datetime for SQL type #{@type} in field #{model}##{@name}")
|
96
95
|
end
|
97
|
-
@options.has_key?(:scale) and warn("scale: only allowed for :decimal type for SQL type #{@
|
96
|
+
@options.has_key?(:scale) and warn("scale: only allowed for :decimal type for SQL type #{@type} in field #{model}##{@name}")
|
98
97
|
end
|
99
98
|
|
100
99
|
if @type.in?([:text, :string])
|
@@ -106,8 +105,8 @@ module DeclareSchema
|
|
106
105
|
@options.delete(:collation)
|
107
106
|
end
|
108
107
|
else
|
109
|
-
@options[:charset] and warn("charset may only given for :string and :text fields for SQL type #{@
|
110
|
-
@options[:collation] and warne("collation may only given for :string and :text fields for SQL type #{@
|
108
|
+
@options[:charset] and warn("charset may only given for :string and :text fields for SQL type #{@type} in field #{model}##{@name}")
|
109
|
+
@options[:collation] and warne("collation may only given for :string and :text fields for SQL type #{@type} in field #{model}##{@name}")
|
111
110
|
end
|
112
111
|
|
113
112
|
@options = Hash[@options.sort_by { |k, _v| OPTION_INDEXES[k] || 9999 }]
|
@@ -120,7 +119,7 @@ module DeclareSchema
|
|
120
119
|
# omits keys with nil values
|
121
120
|
def schema_attributes(col_spec)
|
122
121
|
@sql_options.merge(type: @type).tap do |attrs|
|
123
|
-
attrs[:default] = Column.deserialize_default_value(col_spec, @
|
122
|
+
attrs[:default] = Column.deserialize_default_value(col_spec, @type, attrs[:default])
|
124
123
|
end.compact
|
125
124
|
end
|
126
125
|
end
|
@@ -328,7 +328,7 @@ module Generators
|
|
328
328
|
end
|
329
329
|
|
330
330
|
def create_table(model)
|
331
|
-
longest_field_name = model.field_specs.values.map { |f| f.
|
331
|
+
longest_field_name = model.field_specs.values.map { |f| f.type.to_s.length }.max
|
332
332
|
disable_auto_increment = model.respond_to?(:disable_auto_increment) && model.disable_auto_increment
|
333
333
|
table_options_definition = ::DeclareSchema::Model::TableOptionsDefinition.new(model.table_name, table_options_for_model(model))
|
334
334
|
field_definitions = [
|
@@ -379,7 +379,7 @@ module Generators
|
|
379
379
|
def create_field(field_spec, field_name_width)
|
380
380
|
options = field_spec.sql_options.merge(fk_field_options(field_spec.model, field_spec.name))
|
381
381
|
args = [field_spec.name.inspect] + format_options(options.compact)
|
382
|
-
format("t.%-*s %s", field_name_width, field_spec.
|
382
|
+
format("t.%-*s %s", field_name_width, field_spec.type, args.join(', '))
|
383
383
|
end
|
384
384
|
|
385
385
|
def change_table(model, current_table_name)
|
@@ -417,7 +417,7 @@ module Generators
|
|
417
417
|
args =
|
418
418
|
if (spec = model.field_specs[c])
|
419
419
|
options = spec.sql_options.merge(fk_field_options(model, c))
|
420
|
-
[":#{spec.
|
420
|
+
[":#{spec.type}", *format_options(options.compact)]
|
421
421
|
else
|
422
422
|
[":integer"]
|
423
423
|
end
|
@@ -7,7 +7,7 @@ end
|
|
7
7
|
|
8
8
|
RSpec.describe DeclareSchema::Model::FieldSpec do
|
9
9
|
let(:model) { double('model', table_options: {}) }
|
10
|
-
let(:col_spec) { double('col_spec',
|
10
|
+
let(:col_spec) { double('col_spec', type: :string) }
|
11
11
|
|
12
12
|
before do
|
13
13
|
load File.expand_path('prepare_testapp.rb', __dir__)
|
@@ -127,7 +127,7 @@ RSpec.describe DeclareSchema::Model::FieldSpec do
|
|
127
127
|
end
|
128
128
|
|
129
129
|
describe 'default:' do
|
130
|
-
let(:col_spec) { double('col_spec',
|
130
|
+
let(:col_spec) { double('col_spec', type: :integer) }
|
131
131
|
|
132
132
|
it 'typecasts default value' do
|
133
133
|
allow(col_spec).to receive(:type_cast_from_database) { |default| Integer(default) }
|
@@ -59,26 +59,6 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
|
-
describe '.sql_type' do
|
63
|
-
it 'returns the sql type for :string' do
|
64
|
-
expect(described_class.sql_type(:string)).to eq(:string)
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'returns the sql type for :integer' do
|
68
|
-
expect(described_class.sql_type(:integer)).to match(:integer)
|
69
|
-
end
|
70
|
-
|
71
|
-
it 'returns the sql type for :datetime' do
|
72
|
-
expect(described_class.sql_type(:datetime)).to eq(:datetime)
|
73
|
-
end
|
74
|
-
|
75
|
-
it 'raises UnknownSqlType' do
|
76
|
-
expect do
|
77
|
-
described_class.sql_type(:email)
|
78
|
-
end.to raise_exception(::DeclareSchema::UnknownSqlTypeError, /:email for type :email/)
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
62
|
describe '.deserialize_default_value' do
|
83
63
|
require 'rails'
|
84
64
|
|
@@ -109,10 +89,11 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
109
89
|
end
|
110
90
|
end
|
111
91
|
let(:model) { ColumnTestModel }
|
92
|
+
let(:type) { :integer }
|
112
93
|
let(:current_table_name) { model.table_name }
|
113
94
|
let(:column) { double("ActiveRecord Column",
|
114
95
|
name: 'count',
|
115
|
-
type:
|
96
|
+
type: type,
|
116
97
|
limit: nil,
|
117
98
|
precision: nil,
|
118
99
|
scale: nil,
|
@@ -122,9 +103,9 @@ RSpec.describe DeclareSchema::Model::Column do
|
|
122
103
|
sql_type_metadata: {}) }
|
123
104
|
subject { described_class.new(model, current_table_name, column) }
|
124
105
|
|
125
|
-
describe '#
|
126
|
-
it 'returns
|
127
|
-
expect(subject.
|
106
|
+
describe '#type' do
|
107
|
+
it 'returns type' do
|
108
|
+
expect(subject.type).to eq(type)
|
128
109
|
end
|
129
110
|
end
|
130
111
|
|