schema_plus 1.8.9 → 2.0.0.pre1
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/.gitignore +4 -4
- data/.travis.yml +1 -47
- data/CHANGELOG.md +0 -35
- data/README.md +73 -107
- data/Rakefile +7 -10
- data/TODO.md +51 -0
- data/gemfiles/Gemfile.base +2 -0
- data/lib/schema_column_plus.rb +7 -0
- data/lib/{schema_plus → schema_column_plus}/active_record/connection_adapters/column.rb +13 -11
- data/lib/schema_column_plus/middleware/model.rb +22 -0
- data/lib/schema_db_default.rb +13 -0
- data/lib/{schema_plus → schema_db_default}/active_record/attribute.rb +4 -4
- data/lib/schema_db_default/db_default.rb +17 -0
- data/lib/schema_db_default/middleware.rb +30 -0
- data/lib/schema_default_expr.rb +32 -0
- data/lib/schema_default_expr/active_record/connection_adapters/mysql_adapter.rb +17 -0
- data/lib/schema_default_expr/active_record/connection_adapters/postgresql_adapter.rb +18 -0
- data/lib/schema_default_expr/active_record/connection_adapters/sqlite3_adapter.rb +35 -0
- data/lib/schema_default_expr/middleware.rb +54 -0
- data/lib/schema_pg_enums.rb +6 -0
- data/lib/schema_pg_enums/active_record.rb +69 -0
- data/lib/schema_pg_enums/middleware.rb +23 -0
- data/lib/schema_plus.rb +17 -45
- data/lib/schema_plus/active_record/base.rb +6 -23
- data/lib/schema_plus/active_record/connection_adapters/abstract_adapter.rb +80 -181
- data/lib/schema_plus/active_record/connection_adapters/foreign_key_definition.rb +78 -99
- data/lib/schema_plus/active_record/connection_adapters/mysql_adapter.rb +34 -114
- data/lib/schema_plus/active_record/connection_adapters/postgresql_adapter.rb +16 -370
- data/lib/schema_plus/active_record/connection_adapters/schema_statements.rb +1 -67
- data/lib/schema_plus/active_record/connection_adapters/sqlite3_adapter.rb +18 -112
- data/lib/schema_plus/active_record/connection_adapters/table_definition.rb +14 -116
- data/lib/schema_plus/active_record/migration/command_recorder.rb +8 -59
- data/lib/schema_plus/middleware/dumper.rb +94 -0
- data/lib/schema_plus/middleware/migration.rb +167 -0
- data/lib/schema_plus/middleware/model.rb +17 -0
- data/lib/schema_plus/version.rb +1 -1
- data/lib/schema_plus_tables.rb +15 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/abstract_adapter.rb +20 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/mysql_adapter.rb +25 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/postgresql_adapter.rb +13 -0
- data/lib/schema_plus_tables/active_record/connection_adapters/sqlite3_adapter.rb +12 -0
- data/lib/schema_views.rb +16 -0
- data/lib/schema_views/active_record/connection_adapters/abstract_adapter.rb +41 -0
- data/lib/schema_views/active_record/connection_adapters/mysql_adapter.rb +30 -0
- data/lib/schema_views/active_record/connection_adapters/postgresql_adapter.rb +31 -0
- data/lib/schema_views/active_record/connection_adapters/sqlite3_adapter.rb +18 -0
- data/lib/schema_views/middleware.rb +47 -0
- data/schema_dev.yml +1 -31
- data/schema_plus.gemspec +11 -9
- data/spec/foreign_key_definition_spec.rb +7 -7
- data/spec/foreign_key_spec.rb +63 -48
- data/spec/migration_spec.rb +58 -203
- data/spec/named_schemas_spec.rb +5 -88
- data/spec/{column_spec.rb → schema_column_plus/column_spec.rb} +26 -48
- data/spec/schema_db_default/column_spec.rb +58 -0
- data/spec/{column_default_spec.rb → schema_default_expr/column_default_spec.rb} +1 -2
- data/spec/schema_default_expr/schema_dumper_spec.rb +116 -0
- data/spec/schema_dumper_spec.rb +22 -327
- data/spec/{enum_spec.rb → schema_pg_enums/enum_spec.rb} +1 -1
- data/spec/schema_pg_enums/schema_dumper_spec.rb +37 -0
- data/spec/schema_views/named_schemas_spec.rb +97 -0
- data/spec/{views_spec.rb → schema_views/views_spec.rb} +1 -1
- data/spec/spec_helper.rb +2 -1
- data/spec/support/matchers/reference.rb +11 -12
- metadata +104 -57
- data/gemfiles/rails-3.2/Gemfile.base +0 -3
- data/gemfiles/rails-3.2/Gemfile.mysql +0 -10
- data/gemfiles/rails-3.2/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-3.2/Gemfile.postgresql +0 -10
- data/gemfiles/rails-3.2/Gemfile.sqlite3 +0 -10
- data/gemfiles/rails-4.0/Gemfile.base +0 -3
- data/gemfiles/rails-4.0/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-4.0/Gemfile.postgresql +0 -10
- data/gemfiles/rails-4.0/Gemfile.sqlite3 +0 -10
- data/gemfiles/rails-4.1/Gemfile.base +0 -3
- data/gemfiles/rails-4.1/Gemfile.mysql2 +0 -10
- data/gemfiles/rails-4.1/Gemfile.postgresql +0 -10
- data/gemfiles/rails-4.1/Gemfile.sqlite3 +0 -10
- data/lib/schema_plus/active_record/column_options_handler.rb +0 -117
- data/lib/schema_plus/active_record/connection_adapters/index_definition.rb +0 -70
- data/lib/schema_plus/active_record/db_default.rb +0 -19
- data/lib/schema_plus/active_record/foreign_keys.rb +0 -137
- data/lib/schema_plus/active_record/schema_dumper.rb +0 -171
- data/lib/schema_plus/railtie.rb +0 -20
- data/spec/index_definition_spec.rb +0 -211
- data/spec/index_spec.rb +0 -249
@@ -1,117 +0,0 @@
|
|
1
|
-
module SchemaPlus::ActiveRecord
|
2
|
-
module ColumnOptionsHandler
|
3
|
-
def schema_plus_normalize_column_options(options)
|
4
|
-
# replace some shortcuts with full versions
|
5
|
-
[:index, :_index].each do |key|
|
6
|
-
case options[key]
|
7
|
-
when true then options[key] = {}
|
8
|
-
when :unique then options[key] = { :unique => true }
|
9
|
-
when Hash
|
10
|
-
if options[key][:length].is_a? Hash
|
11
|
-
normalize = if "#{::ActiveRecord::VERSION::MAJOR}.#{::ActiveRecord::VERSION::MINOR}".to_r >= "4.2".to_r
|
12
|
-
:stringify_keys!
|
13
|
-
else
|
14
|
-
:symbolize_keys!
|
15
|
-
end
|
16
|
-
options[key][:length].send normalize
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def schema_plus_handle_column_options(table_name, column_name, column_options, opts = {}) #:nodoc:
|
23
|
-
config = opts[:config] || SchemaPlus.config
|
24
|
-
fk_args = get_fk_args(table_name, column_name, column_options, config)
|
25
|
-
|
26
|
-
# remove existing fk and auto-generated index in case of change to existing column
|
27
|
-
if fk_args # includes :none for explicitly off
|
28
|
-
remove_foreign_key_if_exists(table_name, column_name)
|
29
|
-
remove_auto_index_if_exists(table_name, column_name)
|
30
|
-
end
|
31
|
-
|
32
|
-
fk_args = nil if fk_args == :none
|
33
|
-
|
34
|
-
# create index if requested explicity or implicitly due to auto_index
|
35
|
-
index = column_options[:index]
|
36
|
-
index = column_options[:_index] if column_options.include? :_index
|
37
|
-
if index.nil? and fk_args && config.foreign_keys.auto_index?
|
38
|
-
index = { :name => auto_index_name(table_name, column_name) }
|
39
|
-
end
|
40
|
-
column_index(table_name, column_name, index) if index
|
41
|
-
|
42
|
-
if fk_args
|
43
|
-
references = fk_args.delete(:references)
|
44
|
-
add_foreign_key(table_name, column_name, references.first, references.last, fk_args)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
protected
|
49
|
-
|
50
|
-
def get_fk_args(table_name, column_name, column_options = {}, config = {}) #:nodoc:
|
51
|
-
|
52
|
-
args = nil
|
53
|
-
column_name = column_name.to_s
|
54
|
-
|
55
|
-
if column_options.has_key?(:foreign_key)
|
56
|
-
args = column_options[:foreign_key]
|
57
|
-
args = args.dup if args.is_a?(Hash)
|
58
|
-
return :none unless args
|
59
|
-
args = {} if args == true
|
60
|
-
return :none if args.has_key?(:references) and not args[:references]
|
61
|
-
end
|
62
|
-
|
63
|
-
|
64
|
-
if column_options.has_key?(:references)
|
65
|
-
references = column_options[:references]
|
66
|
-
return :none unless references
|
67
|
-
args = (args || {}).reverse_merge(:references => references)
|
68
|
-
end
|
69
|
-
|
70
|
-
args ||= {} if config.foreign_keys.auto_create? and column_name =~ /_id$/
|
71
|
-
|
72
|
-
return nil if args.nil?
|
73
|
-
|
74
|
-
args[:references] ||= table_name if column_name == 'parent_id'
|
75
|
-
|
76
|
-
args[:references] ||= begin
|
77
|
-
table_name = column_name.sub(/_id$/, '')
|
78
|
-
table_name = table_name.pluralize if ActiveRecord::Base.pluralize_table_names
|
79
|
-
table_name
|
80
|
-
end
|
81
|
-
|
82
|
-
args[:references] = [args[:references], :id] unless args[:references].is_a? Array
|
83
|
-
|
84
|
-
[:on_update, :on_delete, :deferrable].each do |shortcut|
|
85
|
-
args[shortcut] ||= column_options[shortcut] if column_options.has_key? shortcut
|
86
|
-
end
|
87
|
-
|
88
|
-
args[:on_update] ||= config.foreign_keys.on_update
|
89
|
-
args[:on_delete] ||= config.foreign_keys.on_delete
|
90
|
-
|
91
|
-
args
|
92
|
-
end
|
93
|
-
|
94
|
-
def remove_foreign_key_if_exists(table_name, column_name) #:nodoc:
|
95
|
-
foreign_keys = ActiveRecord::Base.connection.foreign_keys(table_name.to_s) rescue [] # no fks if table_name doesn't exist
|
96
|
-
fk = foreign_keys.detect { |fk| fk.table_name == table_name.to_s && fk.column_names == Array(column_name).collect(&:to_s) }
|
97
|
-
remove_foreign_key(table_name, fk.column_names, fk.references_table_name, fk.references_column_names) if fk
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
def column_index(table_name, column_name, options) #:nodoc:
|
102
|
-
options = options.dup
|
103
|
-
column_name = [column_name] + Array.wrap(options.delete(:with)).compact
|
104
|
-
add_index(table_name, column_name, options)
|
105
|
-
end
|
106
|
-
|
107
|
-
def remove_auto_index_if_exists(table_name, column_name)
|
108
|
-
name = auto_index_name(table_name, column_name)
|
109
|
-
remove_index(table_name, :name => name, :column => column_name, :if_exists => true)
|
110
|
-
end
|
111
|
-
|
112
|
-
def auto_index_name(table_name, column_name)
|
113
|
-
ConnectionAdapters::ForeignKeyDefinition.auto_index_name(table_name, column_name)
|
114
|
-
end
|
115
|
-
|
116
|
-
end
|
117
|
-
end
|
@@ -1,70 +0,0 @@
|
|
1
|
-
module SchemaPlus
|
2
|
-
module ActiveRecord
|
3
|
-
module ConnectionAdapters
|
4
|
-
#
|
5
|
-
# SchemaPlus extends the IndexDefinition object to return information
|
6
|
-
# about partial indexes and case sensitivity (i.e. Postgresql
|
7
|
-
# support).
|
8
|
-
module IndexDefinition
|
9
|
-
def self.included(base) #:nodoc:
|
10
|
-
base.alias_method_chain :initialize, :schema_plus
|
11
|
-
end
|
12
|
-
|
13
|
-
attr_accessor :conditions
|
14
|
-
attr_reader :expression
|
15
|
-
attr_reader :kind
|
16
|
-
attr_reader :operator_classes
|
17
|
-
|
18
|
-
def case_sensitive?
|
19
|
-
@case_sensitive
|
20
|
-
end
|
21
|
-
|
22
|
-
def initialize_with_schema_plus(*args) #:nodoc:
|
23
|
-
# same args as add_index(table_name, column_names, options)
|
24
|
-
if args.length == 3 and Hash === args.last
|
25
|
-
table_name, column_names, options = args + [{}]
|
26
|
-
initialize_without_schema_plus(table_name, options[:name], options[:unique], column_names, options[:length], options[:orders])
|
27
|
-
@conditions = options[:conditions]
|
28
|
-
@expression = options[:expression]
|
29
|
-
@kind = options[:kind]
|
30
|
-
@case_sensitive = options.include?(:case_sensitive) ? options[:case_sensitive] : true
|
31
|
-
@operator_classes = options[:operator_classes] || {}
|
32
|
-
else # backwards compatibility
|
33
|
-
initialize_without_schema_plus(*args)
|
34
|
-
@case_sensitive = true
|
35
|
-
@operator_classes = {}
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# returns the options as a hash suitable for add_index
|
40
|
-
def opts #:nodoc:
|
41
|
-
opts = {}
|
42
|
-
opts[:name] = name unless name.nil?
|
43
|
-
opts[:unique] = unique unless unique.nil?
|
44
|
-
opts[:length] = lengths unless lengths.nil?
|
45
|
-
opts[:conditions] = conditions unless conditions.nil?
|
46
|
-
opts[:expression] = expression unless expression.nil?
|
47
|
-
opts[:kind] = kind unless kind.nil?
|
48
|
-
opts[:case_sensitive] = case_sensitive? unless @case_sensitive.nil?
|
49
|
-
opts[:operator_classes] = @operator_classes unless @operator_classes.nil?
|
50
|
-
opts
|
51
|
-
end
|
52
|
-
|
53
|
-
# tests if the corresponding indexes would be the same
|
54
|
-
def ==(other)
|
55
|
-
return false if other.nil?
|
56
|
-
return false unless self.name == other.name
|
57
|
-
return false unless Array.wrap(self.columns).collect(&:to_s).sort == Array.wrap(other.columns).collect(&:to_s).sort
|
58
|
-
return false unless !!self.unique == !!other.unique
|
59
|
-
return false unless Array.wrap(self.lengths).compact.sort == Array.wrap(other.lengths).compact.sort
|
60
|
-
return false unless self.conditions == other.conditions
|
61
|
-
return false unless self.expression == other.expression
|
62
|
-
return false unless self.kind == other.kind
|
63
|
-
return false unless self.operator_classes == other.operator_classes
|
64
|
-
return false unless !!self.case_sensitive? == !!other.case_sensitive?
|
65
|
-
true
|
66
|
-
end
|
67
|
-
end
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'singleton'
|
2
|
-
|
3
|
-
module SchemaPlus
|
4
|
-
module ActiveRecord
|
5
|
-
class DbDefault
|
6
|
-
include Singleton
|
7
|
-
def to_s
|
8
|
-
'DEFAULT'
|
9
|
-
end
|
10
|
-
def id
|
11
|
-
self
|
12
|
-
end
|
13
|
-
def quoted_id
|
14
|
-
self
|
15
|
-
end
|
16
|
-
end
|
17
|
-
DB_DEFAULT = DbDefault.instance
|
18
|
-
end
|
19
|
-
end
|
@@ -1,137 +0,0 @@
|
|
1
|
-
module SchemaPlus::ActiveRecord
|
2
|
-
module ForeignKeys
|
3
|
-
include SchemaPlus::ActiveRecord::ColumnOptionsHandler
|
4
|
-
|
5
|
-
# Enhances ActiveRecord::ConnectionAdapters::AbstractAdapter#add_column to support indexes and foreign keys, with automatic creation
|
6
|
-
#
|
7
|
-
# == Indexes
|
8
|
-
#
|
9
|
-
# The <tt>:index</tt> option takes a hash of parameters to pass to ActiveRecord::Migration.add_index. Thus
|
10
|
-
#
|
11
|
-
# add_column('books', 'isbn', :string, :index => {:name => "ISBN-index", :unique => true })
|
12
|
-
#
|
13
|
-
# is equivalent to:
|
14
|
-
#
|
15
|
-
# add_column('books', 'isbn', :string)
|
16
|
-
# add_index('books', ['isbn'], :name => "ISBN-index", :unique => true)
|
17
|
-
#
|
18
|
-
#
|
19
|
-
# In order to support multi-column indexes, an special parameter <tt>:with</tt> may be specified, which takes another column name or an array of column names to include in the index. Thus
|
20
|
-
#
|
21
|
-
# add_column('contacts', 'phone_number', :string, :index => { :with => [:country_code, :area_code], :unique => true })
|
22
|
-
#
|
23
|
-
# is equivalent to:
|
24
|
-
#
|
25
|
-
# add_column('contacts', 'phone_number', :string)
|
26
|
-
# add_index('contacts', ['phone_number', 'country_code', 'area_code'], :unique => true)
|
27
|
-
#
|
28
|
-
#
|
29
|
-
# Some convenient shorthands are available:
|
30
|
-
#
|
31
|
-
# add_column('books', 'isbn', :index => true) # adds index with no extra options
|
32
|
-
# add_column('books', 'isbn', :index => :unique) # adds index with :unique => true
|
33
|
-
#
|
34
|
-
# == Foreign Key Constraints
|
35
|
-
#
|
36
|
-
# The +:foreign_key+ option controls creation of foreign key
|
37
|
-
# constraints. Specifying +true+ or an empty hash defines a foreign
|
38
|
-
# key with default values. In particular, the foreign table name
|
39
|
-
# defaults to the column name, with trailing +_id+ removed, pluralized;
|
40
|
-
# And the foreign column name defaults to +:id+
|
41
|
-
#
|
42
|
-
# add_column('widgets', 'color', :integer, :foreign_key => true)
|
43
|
-
#
|
44
|
-
# is equivalent to
|
45
|
-
#
|
46
|
-
# add_column('widgets', 'color_id', :integer)
|
47
|
-
# add_foreign_key('widgets', 'color_id', 'colors', 'id')
|
48
|
-
#
|
49
|
-
# As a special case, if the column is named 'parent_id', SchemaPlus
|
50
|
-
# assumes it's a self reference, for a record that acts as a node of
|
51
|
-
# a tree. Thus, these are equivalent:
|
52
|
-
#
|
53
|
-
# add_column('sections', 'parent_id', :integer, :foreign_key => true)
|
54
|
-
#
|
55
|
-
# is equivalent to
|
56
|
-
#
|
57
|
-
# add_column('sections', 'parent_id', :integer)
|
58
|
-
# add_foreign_key('sections', 'parent_id', 'sections', 'id')
|
59
|
-
#
|
60
|
-
# A different foreign table name can be specified using
|
61
|
-
# <tt>:foreign_key => { :references => table_name }</tt>, and
|
62
|
-
# a different column name can also be specified using <tt>:foreign_key => { :references => [table_name,column_name] }</tt>
|
63
|
-
#
|
64
|
-
# Additional options +:on_update+ and +:on_delete+ can be specified,
|
65
|
-
# with values as described at ConnectionAdapters::ForeignKeyDefinition. For example:
|
66
|
-
#
|
67
|
-
# add_column('comments', 'post', :integer, :references => 'posts', :on_delete => :cascade)
|
68
|
-
#
|
69
|
-
# Global default values for +:on_update+ and +:on_delete+ can be
|
70
|
-
# specified in SchemaPlus.steup via, e.g., <tt>config.foreign_keys.on_update = :cascade</tt>
|
71
|
-
#
|
72
|
-
# The constraint will have an automatic default name, but you can
|
73
|
-
# specify a constraint name using <tt>:foreign_key => { :name => "my_name" }</tt>
|
74
|
-
#
|
75
|
-
# == Automatic Foreign Key Constraints
|
76
|
-
#
|
77
|
-
# SchemaPlus supports the convention of naming foreign key columns
|
78
|
-
# with a suffix of +_id+. That is, if you define a column suffixed
|
79
|
-
# with +_id+, SchemaPlus assumes that you want a foreign key constraint
|
80
|
-
# with default paramters. Thus, these two are equivalent:
|
81
|
-
#
|
82
|
-
# add_column('posts', 'author_id', :integer)
|
83
|
-
# add_column('posts', 'author_id', :integer, :foreign_key => true)
|
84
|
-
#
|
85
|
-
# If you don't want a foreign key constraint to be created, specify
|
86
|
-
# <tt>:foreign_key => false</tt>.
|
87
|
-
# To disable automatic foreign key constraint creation globally, set
|
88
|
-
# <tt>config.foreign_keys.auto_create = false</tt> in
|
89
|
-
# SchemaPlus.steup.
|
90
|
-
#
|
91
|
-
# == Shortcut options
|
92
|
-
#
|
93
|
-
# As a shortcut (and for backwards compatibility), the options
|
94
|
-
# +:references+, +:on_update+, and +:on_delete+ can provided to
|
95
|
-
# +add_column+ directly instead of within a +:foreign_key+ hash.
|
96
|
-
#
|
97
|
-
# The presence of option +:references+ implies the foreign
|
98
|
-
# key should be created, while <tt>:references => nil</tt> is a
|
99
|
-
# shortcut for <tt>:foreign_key => false</tt>
|
100
|
-
#
|
101
|
-
# == Automatic Foreign Key Indexes
|
102
|
-
#
|
103
|
-
# Since efficient use of foreign key constraints requires that the
|
104
|
-
# referencing column be indexed, SchemaPlus will automatically create
|
105
|
-
# an index for the column if it created a foreign key. Thus
|
106
|
-
#
|
107
|
-
# add_column('widgets', 'color', :integer, :references => 'colors')
|
108
|
-
#
|
109
|
-
# is equivalent to:
|
110
|
-
#
|
111
|
-
# add_column('widgets', 'color', :integer, :references => 'colors', :index => true)
|
112
|
-
#
|
113
|
-
# If you want to pass options to the index, you can explcitly pass
|
114
|
-
# index options, such as <tt>:index => :unique</tt>.
|
115
|
-
#
|
116
|
-
# If you don't want an index to be created, specify
|
117
|
-
# <tt>:index => nil</tt>.
|
118
|
-
# To disable automatic foreign key index creation globally, set
|
119
|
-
# <tt>config.foreign_keys.auto_index = false</tt> in
|
120
|
-
# SchemaPlus.steup. (*Note*: If you're using MySQL, it will
|
121
|
-
# automatically create an index for foreign keys if you don't.)
|
122
|
-
#
|
123
|
-
def add_column(table_name, column_name, type, options = {})
|
124
|
-
schema_plus_normalize_column_options(options)
|
125
|
-
super
|
126
|
-
schema_plus_handle_column_options(table_name, column_name, options)
|
127
|
-
end
|
128
|
-
|
129
|
-
# Enhances ActiveRecord::Migration#change_column to support indexes and foreign keys same as add_column.
|
130
|
-
def change_column(table_name, column_name, type, options = {})
|
131
|
-
schema_plus_normalize_column_options(options)
|
132
|
-
super
|
133
|
-
schema_plus_handle_column_options(table_name, column_name, options)
|
134
|
-
end
|
135
|
-
|
136
|
-
end
|
137
|
-
end
|