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
fieldswithcolumnsand remove alias. -
#fields ⇒ Object
(also: #columns)
readonly
TODO: replace
fieldswithcolumnsand remove alias. -
#name ⇒ Object
readonly
TODO: replace
fieldswithcolumnsand remove alias. -
#table ⇒ Object
readonly
TODO: replace
fieldswithcolumnsand remove alias. -
#unique ⇒ Object
readonly
TODO: replace
fieldswithcolumnsand remove alias. -
#where ⇒ Object
readonly
TODO: replace
fieldswithcolumnsand 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.
- .index_name(columns) ⇒ Object
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) || self.class.index_name(@fields) @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 |
.index_name(columns) ⇒ Object
63 64 65 |
# File 'lib/declare_schema/model/index_definition.rb', line 63 def index_name(columns) "on_#{Array(columns).join("_and_")}" end |
Instance Method Details
#<=>(rhs) ⇒ Object
127 128 129 |
# File 'lib/declare_schema/model/index_definition.rb', line 127 def <=>(rhs) to_key <=> rhs.to_key end |
#equivalent?(rhs) ⇒ Boolean
131 132 133 |
# File 'lib/declare_schema/model/index_definition.rb', line 131 def equivalent?(rhs) settings == rhs.settings end |
#hash ⇒ Object
123 124 125 |
# File 'lib/declare_schema/model/index_definition.rb', line 123 def hash to_key.hash end |
#primary_key? ⇒ Boolean
92 93 94 |
# File 'lib/declare_schema/model/index_definition.rb', line 92 def primary_key? name == PRIMARY_KEY_NAME end |
#settings ⇒ Object
119 120 121 |
# File 'lib/declare_schema/model/index_definition.rb', line 119 def settings @settings ||= [table, fields, unique].map(&:to_s) end |
#to_add_primary_key_statement(new_table_name, existing_primary_key) ⇒ Object
109 110 111 112 113 |
# File 'lib/declare_schema/model/index_definition.rb', line 109 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
96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/declare_schema/model/index_definition.rb', line 96 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
115 116 117 |
# File 'lib/declare_schema/model/index_definition.rb', line 115 def to_key @key ||= [table, fields, name, unique, where].map(&:to_s) end |
#with_name(new_name) ⇒ Object
135 136 137 |
# File 'lib/declare_schema/model/index_definition.rb', line 135 def with_name(new_name) self.class.new(@model, @fields, table_name: @table_name, index_name: @index_name, unique: @unique, name: new_name) end |