Module: ActiveRecord::ConnectionAdapters::Constraints::Sql

Included in:
Postgresql
Defined in:
lib/activerecord_constraints.rb

Overview

Generallized SQL constraint code.

Instance Method Summary collapse

Instance Method Details

#check_str(column_name, options, column_constraint) ⇒ Object

Utility routine to produce the string for a CHECK constraint. The alternatives here are: (the first two are named, the last two are unnamed) 1) :check => “constraint_name”, :expr => “check expression” 2) :check => true, :name => “constraint_name”,

:expr => "check expression"

3) :check => true, :expr => “check expression” 4) :check => “check expression”



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/activerecord_constraints.rb', line 148

def check_str(column_name, options, column_constraint)
  ActiveRecord::Base.logger.debug("IN: Constraints#check_str")
  return "" unless has_constraint(options, :check)
  
  # Have to dance a little bit here...
  if options[:check] == true
    expr = options[:expr]
    name = options[:name]
  elsif options.has_key?(:expr)
    expr = options[:expr]
    name = options[:check]
  else
    expr = options[:check]
    name = nil
  end
  constraint_name = name_str({ :name => name, :check => true }, :check)
  # column string is not part of CHECK constraints
  constraint_name + " CHECK ( #{expr} )"
end

#column_to_str(column) ⇒ Object

Utility routine to return the column or the array of columns as a string.



209
210
211
212
213
214
215
216
# File 'lib/activerecord_constraints.rb', line 209

def column_to_str(column)
  ActiveRecord::Base.logger.debug("IN: Constraints#column_to_str")
  if column.is_a? Array
    column.map { |c| "\"#{c.to_s}\""}.join(", ")
  else
    "\"#{column.to_s}\""
  end
end

#deferrable_str(options) ⇒ Object

Creates the DEFERRABLE string



103
104
105
106
107
108
109
110
# File 'lib/activerecord_constraints.rb', line 103

def deferrable_str(options)
  if options.has_key?(:deferrable)
    ((options[:deferrable] == false) ? " NOT" : "") +
      " DEFERRABLE"
  else
    ""
  end
end

#has_constraint(options, constraint_type) ⇒ Object

Utility routine to return true if the options has the indicated constraint type.



74
75
76
77
# File 'lib/activerecord_constraints.rb', line 74

def has_constraint(options, constraint_type)
  options.has_key?(constraint_type) &&
    options[constraint_type] != false
end

#initially_str(options) ⇒ Object

Creates the INITIALLY string



113
114
115
116
117
118
119
# File 'lib/activerecord_constraints.rb', line 113

def initially_str(options)
  if options.has_key?(:initially)
    ref_str << " INITIALLY #{to_db_string(options[:initially])}"
  else
    ""
  end
end

#name_str(options, constraint_type) ⇒ Object

Utility routine to produce the named part of a named constraint: passed the full set of options along with the type of the constraint, e.g. :unique.



82
83
84
85
86
87
88
89
# File 'lib/activerecord_constraints.rb', line 82

def name_str(options, constraint_type)
  if options[constraint_type] == true
    n = options[:name]
  else
    n = options[constraint_type]
  end
  n.blank? ? "" : " CONSTRAINT #{n}"
end

#reference_str(column_name, options, column_constraint) ⇒ Object

Utility routine to produce the string for a FOREIGN KEY constraint. Like a UNIQUE constraint, the optional name of the constraint can either the string assigned to the :reference option or a separate :name option.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/activerecord_constraints.rb', line 181

def reference_str(column_name, options, column_constraint)
  ActiveRecord::Base.logger.debug("IN: Constraints#reference_str")
  return "" unless has_constraint(options, :reference)
  constraint_name = name_str(options, :reference)
  column_spec = table_str(column_name, column_constraint,
                          "FOREIGN KEY ")
  local_options = { }
  if md = /(.*)_id$/.match(column_name.to_s)
    local_options[:table_name] = md[1].pluralize
    local_options[:foreign_key] = "id"
  end
  local_options.merge!(options)
  ref_column_str = column_to_str(local_options[:foreign_key])
  ref_str = " REFERENCES #{local_options[:table_name]} (#{ref_column_str})"
  
  if local_options.has_key?(:delete)
    ref_str << " ON DELETE #{to_db_string(local_options[:delete])}"
  end
  
  if local_options.has_key?(:update)
    ref_str << " ON UPDATE #{to_db_string(local_options[:update])}"
  end
  
  constraint_name + column_spec + ref_str
end

#suffix_str(options) ⇒ Object

Creates the suffix options deferrable and initially



122
123
124
# File 'lib/activerecord_constraints.rb', line 122

def suffix_str(options)
  deferrable_str(options) + initially_str(options)
end

#table_str(column_name, column_constraint, prefix_string = "") ⇒ Object

Utility routine to produce the additional string needed in a table constraint that is not needed in a column constraint. Passed the column name (which may be an array of names), the column_constraint flag, and the an optional prefix string.



95
96
97
98
99
100
# File 'lib/activerecord_constraints.rb', line 95

def table_str(column_name, column_constraint, prefix_string = "")
  # No space is needed around the parens but it looks nicer with
  # spaces.
  column_constraint ? "" :
    " #{prefix_string}( #{column_to_str(column_name)} )"
end

#to_db_string(f) ⇒ Object

Simple function to convert symbols and strings to what SQL wants.

:no_action

goes to “NO ACTION”

:cascade

goes to “CASCADE”

etc



173
174
175
# File 'lib/activerecord_constraints.rb', line 173

def to_db_string(f)
  f.to_s.upcase.gsub(/_/, ' ')
end

#unique_str(column_name, options, column_constraint) ⇒ Object

Utility routine to produce the string for the UNIQUE constraint. For a column constraint, the syntax may be either :unique => "constraint_name" or it can be :unique => true followed by an optional :name => "constraint_name". If constraint_name is a symbol, it is simply converted to a string.



132
133
134
135
136
137
138
# File 'lib/activerecord_constraints.rb', line 132

def unique_str(column_name, options, column_constraint)
  ActiveRecord::Base.logger.debug("IN: Constraints#unique_str")
  return "" unless has_constraint(options, :unique)
  constraint_name = name_str(options, :unique)
  column_spec = table_str(column_name, column_constraint)
  constraint_name + " UNIQUE" + column_spec
end