Class: DeclareSchema::Model::IndexDefinition
- Inherits:
-
Object
- Object
- DeclareSchema::Model::IndexDefinition
- Includes:
- Comparable
- Defined in:
- lib/declare_schema/model/index_definition.rb
Defined Under Namespace
Classes: IndexNameTooLongError
Constant Summary collapse
- PRIMARY_KEY_NAME =
"PRIMARY"- MYSQL_INDEX_NAME_MAX_LENGTH =
64
Instance Attribute Summary collapse
-
#explicit_name ⇒ Object
readonly
TODO: replace ‘fields` with `columns` and remove alias.
-
#fields ⇒ Object
(also: #columns)
readonly
TODO: replace ‘fields` with `columns` and remove alias.
-
#name ⇒ Object
readonly
TODO: replace ‘fields` with `columns` and remove alias.
-
#table ⇒ Object
readonly
TODO: replace ‘fields` with `columns` and remove alias.
-
#unique ⇒ Object
readonly
TODO: replace ‘fields` with `columns` and remove alias.
-
#where ⇒ Object
readonly
TODO: replace ‘fields` with `columns` and remove alias.
Class Method Summary collapse
-
.for_model(model, old_table_name = nil) ⇒ Object
extract IndexSpecs from an existing table always includes the PRIMARY KEY index.
Instance Method Summary collapse
- #<=>(rhs) ⇒ Object
- #equivalent?(rhs) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(model, fields, options = {}) ⇒ IndexDefinition
constructor
A new instance of IndexDefinition.
- #primary_key? ⇒ Boolean
- #settings ⇒ Object
- #to_add_primary_key_statement(new_table_name, existing_primary_key) ⇒ Object
- #to_add_statement(new_table_name, existing_primary_key = nil) ⇒ Object
- #to_key ⇒ Object
- #with_name(new_name) ⇒ Object
Constructor Details
#initialize(model, fields, options = {}) ⇒ IndexDefinition
Returns a new instance of IndexDefinition.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/declare_schema/model/index_definition.rb', line 17 def initialize(model, fields, = {}) @model = model @table = .delete(:table_name) || model.table_name @fields = Array.wrap(fields).map(&:to_s) @explicit_name = [:name] unless .delete(:allow_equivalent) @name = .delete(:name) || model.connection.index_name(table, column: @fields).gsub(/index.*_on_/, 'on_') @unique = .delete(:unique) || name == PRIMARY_KEY_NAME || false if @name.length > MYSQL_INDEX_NAME_MAX_LENGTH raise IndexNameTooLongError, "Index '#{@name}' exceeds MySQL limit of #{MYSQL_INDEX_NAME_MAX_LENGTH} characters. Give it a shorter name." end if (where = [:where]) @where = where.start_with?('(') ? where : "(#{where})" end end |
Instance Attribute Details
#explicit_name ⇒ Object (readonly)
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def explicit_name @explicit_name end |
#fields ⇒ Object (readonly) Also known as: columns
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def fields @fields end |
#name ⇒ Object (readonly)
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def name @name end |
#table ⇒ Object (readonly)
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def table @table end |
#unique ⇒ Object (readonly)
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def unique @unique end |
#where ⇒ Object (readonly)
TODO: replace ‘fields` with `columns` and remove alias. -Colin
9 10 11 |
# File 'lib/declare_schema/model/index_definition.rb', line 9 def where @where end |
Class Method Details
.for_model(model, old_table_name = nil) ⇒ Object
extract IndexSpecs from an existing table always includes the PRIMARY KEY index
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/declare_schema/model/index_definition.rb', line 37 def for_model(model, old_table_name = nil) t = old_table_name || model.table_name primary_key_columns = Array(model.connection.primary_key(t)).presence || sqlite_compound_primary_key(model, t) or raise "could not find primary key for table #{t} in #{model.connection.columns(t).inspect}" primary_key_found = false index_definitions = model.connection.indexes(t).map do |i| model.ignore_indexes.include?(i.name) and next if i.name == PRIMARY_KEY_NAME i.columns == primary_key_columns && i.unique or raise "primary key on #{t} was not unique on #{primary_key_columns} (was unique=#{i.unique} on #{i.columns})" primary_key_found = true elsif i.columns == primary_key_columns && i.unique # skip this primary key index since we'll create it below, with PRIMARY_KEY_NAME next end new(model, i.columns, name: i.name, unique: i.unique, where: i.where, table_name: old_table_name) end.compact if !primary_key_found index_definitions << new(model, primary_key_columns, name: PRIMARY_KEY_NAME, unique: true, where: nil, table_name: old_table_name) end index_definitions end |
Instance Method Details
#<=>(rhs) ⇒ Object
123 124 125 |
# File 'lib/declare_schema/model/index_definition.rb', line 123 def <=>(rhs) to_key <=> rhs.to_key end |
#equivalent?(rhs) ⇒ Boolean
127 128 129 |
# File 'lib/declare_schema/model/index_definition.rb', line 127 def equivalent?(rhs) settings == rhs.settings end |
#hash ⇒ Object
119 120 121 |
# File 'lib/declare_schema/model/index_definition.rb', line 119 def hash to_key.hash end |
#primary_key? ⇒ Boolean
88 89 90 |
# File 'lib/declare_schema/model/index_definition.rb', line 88 def primary_key? name == PRIMARY_KEY_NAME end |
#settings ⇒ Object
115 116 117 |
# File 'lib/declare_schema/model/index_definition.rb', line 115 def settings @settings ||= [table, fields, unique].map(&:to_s) end |
#to_add_primary_key_statement(new_table_name, existing_primary_key) ⇒ Object
105 106 107 108 109 |
# File 'lib/declare_schema/model/index_definition.rb', line 105 def to_add_primary_key_statement(new_table_name, existing_primary_key) drop = "DROP PRIMARY KEY, " if existing_primary_key statement = "ALTER TABLE #{new_table_name} #{drop}ADD PRIMARY KEY (#{fields.join(', ')})" "execute #{statement.inspect}" end |
#to_add_statement(new_table_name, existing_primary_key = nil) ⇒ Object
92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/declare_schema/model/index_definition.rb', line 92 def to_add_statement(new_table_name, existing_primary_key = nil) if primary_key? && !ActiveRecord::Base.connection.class.name.match?(/SQLite3Adapter/) to_add_primary_key_statement(new_table_name, existing_primary_key) else # Note: + below keeps that interpolated string from being frozen, so we can << into it. r = +"add_index #{new_table_name.to_sym.inspect}, #{fields.map(&:to_sym).inspect}" r << ", unique: true" if unique r << ", where: '#{where}'" if where.present? r << ", name: '#{name}'" r end end |
#to_key ⇒ Object
111 112 113 |
# File 'lib/declare_schema/model/index_definition.rb', line 111 def to_key @key ||= [table, fields, name, unique, where].map(&:to_s) end |
#with_name(new_name) ⇒ Object
131 132 133 |
# File 'lib/declare_schema/model/index_definition.rb', line 131 def with_name(new_name) self.class.new(@model, @fields, table_name: @table_name, index_name: @index_name, unique: @unique, name: new_name) end |