Class: DeclareSchema::Model::IndexSpec
- Inherits:
-
Object
- Object
- DeclareSchema::Model::IndexSpec
- Includes:
- Comparable
- Defined in:
- lib/declare_schema/model/index_spec.rb
Defined Under Namespace
Classes: IndexNameTooLongError
Constant Summary collapse
- PRIMARY_KEY_NAME =
"PRIMARY_KEY"- MYSQL_INDEX_NAME_MAX_LENGTH =
64
Instance Attribute Summary collapse
-
#explicit_name ⇒ Object
readonly
Returns the value of attribute explicit_name.
-
#fields ⇒ Object
readonly
Returns the value of attribute fields.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#table ⇒ Object
readonly
Returns the value of attribute table.
-
#unique ⇒ Object
readonly
Returns the value of attribute unique.
-
#where ⇒ Object
readonly
Returns the value of attribute where.
Class Method Summary collapse
-
.for_model(model, old_table_name = nil) ⇒ Object
extract IndexSpecs from an existing table.
Instance Method Summary collapse
- #<=>(rhs) ⇒ Object
- #equivalent?(rhs) ⇒ Boolean
- #hash ⇒ Object
-
#initialize(model, fields, options = {}) ⇒ IndexSpec
constructor
A new instance of IndexSpec.
- #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 = {}) ⇒ IndexSpec
Returns a new instance of IndexSpec.
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/declare_schema/model/index_spec.rb', line 15 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)
Returns the value of attribute explicit_name.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def explicit_name @explicit_name end |
#fields ⇒ Object (readonly)
Returns the value of attribute fields.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def fields @fields end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def name @name end |
#table ⇒ Object (readonly)
Returns the value of attribute table.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def table @table end |
#unique ⇒ Object (readonly)
Returns the value of attribute unique.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def unique @unique end |
#where ⇒ Object (readonly)
Returns the value of attribute where.
8 9 10 |
# File 'lib/declare_schema/model/index_spec.rb', line 8 def where @where end |
Class Method Details
.for_model(model, old_table_name = nil) ⇒ Object
extract IndexSpecs from an existing table
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
# File 'lib/declare_schema/model/index_spec.rb', line 34 def for_model(model, old_table_name = nil) t = old_table_name || model.table_name connection = model.connection.dup # TODO: Change below to use prepend class << connection # defeat Rails code that skips the primary keys by changing their name to PRIMARY_KEY_NAME def each_hash(result) super do |hash| if hash[:Key_name] == "PRIMARY" hash[:Key_name] = PRIMARY_KEY_NAME end yield hash end end end connection.indexes(t).map do |i| new(model, i.columns, name: i.name, unique: i.unique, where: i.where, table_name: old_table_name) unless model.ignore_indexes.include?(i.name) end.compact end |
Instance Method Details
#<=>(rhs) ⇒ Object
88 89 90 |
# File 'lib/declare_schema/model/index_spec.rb', line 88 def <=>(rhs) to_key <=> rhs.to_key end |
#equivalent?(rhs) ⇒ Boolean
92 93 94 |
# File 'lib/declare_schema/model/index_spec.rb', line 92 def equivalent?(rhs) settings == rhs.settings end |
#hash ⇒ Object
84 85 86 |
# File 'lib/declare_schema/model/index_spec.rb', line 84 def hash to_key.hash end |
#primary_key? ⇒ Boolean
54 55 56 |
# File 'lib/declare_schema/model/index_spec.rb', line 54 def primary_key? name == PRIMARY_KEY_NAME end |
#settings ⇒ Object
80 81 82 |
# File 'lib/declare_schema/model/index_spec.rb', line 80 def settings @settings ||= [table, fields, unique].map(&:to_s) end |
#to_add_primary_key_statement(new_table_name, existing_primary_key) ⇒ Object
70 71 72 73 74 |
# File 'lib/declare_schema/model/index_spec.rb', line 70 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
58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/declare_schema/model/index_spec.rb', line 58 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 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
76 77 78 |
# File 'lib/declare_schema/model/index_spec.rb', line 76 def to_key @key ||= [table, fields, name, unique, where].map(&:to_s) end |
#with_name(new_name) ⇒ Object
96 97 98 |
# File 'lib/declare_schema/model/index_spec.rb', line 96 def with_name(new_name) self.class.new(@model, @fields, table_name: @table_name, index_name: @index_name, unique: @unique, name: new_name) end |