Class: Ultrasphinx::Fields
- Includes:
- Singleton, Associations
- Defined in:
- lib/ultrasphinx/fields.rb
Overview
This is a special singleton configuration class that stores the index field configurations. Rather than using a magic hash and including relevant behavior in Ultrasphinx::Configure and Ultrasphinx::Search, we unify it here.
Constant Summary collapse
- TYPE_MAP =
{ 'string' => 'text', 'text' => 'text', 'integer' => 'integer', 'date' => 'date', 'datetime' => 'date', 'timestamp' => 'date', 'float' => 'float', 'boolean' => 'bool' }
Instance Attribute Summary collapse
-
#classes ⇒ Object
Returns the value of attribute classes.
-
#types ⇒ Object
Returns the value of attribute types.
Instance Method Summary collapse
- #cast(source_string, field) ⇒ Object
- #configure(configuration) ⇒ Object
- #extract_field_alias!(entry, klass) ⇒ Object
- #extract_table_alias!(entry, klass) ⇒ Object
- #groups ⇒ Object
-
#initialize ⇒ Fields
constructor
A new instance of Fields.
- #install_duplicate_fields!(entry, klass) ⇒ Object
- #null(field) ⇒ Object
- #save_and_verify_type(field, new_type, string_sortable, klass, msg = nil) ⇒ Object
Methods included from Associations
#get_association, #get_association_model
Constructor Details
Instance Attribute Details
#classes ⇒ Object
Returns the value of attribute classes.
25 26 27 |
# File 'lib/ultrasphinx/fields.rb', line 25 def classes @classes end |
#types ⇒ Object
Returns the value of attribute types.
25 26 27 |
# File 'lib/ultrasphinx/fields.rb', line 25 def types @types end |
Instance Method Details
#cast(source_string, field) ⇒ Object
72 73 74 75 76 77 78 79 80 |
# File 'lib/ultrasphinx/fields.rb', line 72 def cast(source_string, field) if types[field] == "date" "UNIX_TIMESTAMP(#{source_string})" elsif types[field] == "integer" source_string # "CAST(#{source_string} AS UNSIGNED)" else source_string end + " AS #{field}" end |
#configure(configuration) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/ultrasphinx/fields.rb', line 99 def configure(configuration) configuration.each do |model, | klass = model.constantize save_and_verify_type('class_id', 'integer', nil, klass) save_and_verify_type('class', 'string', nil, klass) begin # Fields are from the model ['fields'] = ['fields'].to_a.map do |entry| extract_table_alias!(entry, klass) extract_field_alias!(entry, klass) unless klass.columns_hash[entry['field']] # XXX I think this is here for migrations Ultrasphinx.say "warning: field #{entry['field']} is not present in #{model}" else save_and_verify_type(entry['as'], klass.columns_hash[entry['field']].type, nil, klass) install_duplicate_fields!(entry, klass) end end # Joins are whatever they are in the target ['include'].to_a.each do |entry| extract_table_alias!(entry, klass) extract_field_alias!(entry, klass) association_model = get_association_model(klass, entry) save_and_verify_type(entry['as'] || entry['field'], association_model.columns_hash[entry['field']].type, nil, klass) install_duplicate_fields!(entry, klass) end # Regular concats are CHAR, group_concats are BLOB and need to be cast to CHAR ['concatenate'].to_a.each do |entry| extract_table_alias!(entry, klass) save_and_verify_type(entry['as'], 'text', nil, klass) install_duplicate_fields!(entry, klass) end rescue ActiveRecord::StatementInvalid Ultrasphinx.say "warning: model #{model} does not exist in the database yet" end end self end |
#extract_field_alias!(entry, klass) ⇒ Object
170 171 172 173 174 |
# File 'lib/ultrasphinx/fields.rb', line 170 def extract_field_alias!(entry, klass) unless entry['as'] entry['as'] = entry['field'] end end |
#extract_table_alias!(entry, klass) ⇒ Object
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/ultrasphinx/fields.rb', line 177 def extract_table_alias!(entry, klass) unless entry['table_alias'] entry['table_alias'] = if entry['field'] and entry['field'].include? "." and entry['association_sql'] # This field is referenced by a table alias in association_sql table_alias, entry['field'] = entry['field'].split(".") table_alias elsif get_association(klass, entry) # Refers to the association get_association(klass, entry).name elsif entry['association_sql'] # Refers to the association_sql class's table entry['class_name'].constantize.table_name else # Refers to this class klass.table_name end end end |
#groups ⇒ Object
34 35 36 37 38 |
# File 'lib/ultrasphinx/fields.rb', line 34 def groups @groups.compact.sort_by do |string| string[/= (.*)/, 1] end end |
#install_duplicate_fields!(entry, klass) ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/ultrasphinx/fields.rb', line 150 def install_duplicate_fields!(entry, klass) if entry['facet'] # Source must be a string save_and_verify_type(entry['as'], 'text', nil, klass, "#{klass}##{entry['as']}: 'facet' option is only valid for text fields; numeric fields are enabled by default") # Install facet column save_and_verify_type("#{entry['as']}_facet", 'integer', nil, klass) end if entry['sortable'] # Source must be a string save_and_verify_type(entry['as'], 'text', nil, klass, "#{klass}##{entry['as']}: 'sortable' option is only valid for text columns; numeric fields are enabled by default") # Install sortable column save_and_verify_type("#{entry['as']}_sortable", 'text', true, klass) end entry end |
#null(field) ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
# File 'lib/ultrasphinx/fields.rb', line 83 def null(field) case types[field] when 'text' "''" when 'integer', 'float', 'bool' "0" when 'date' "18000" # Midnight on 1/1/1970 when nil raise "Field #{field} is missing" else raise "Field #{field} does not have a valid type #{types[field]}." end + " AS #{field}" end |
#save_and_verify_type(field, new_type, string_sortable, klass, msg = nil) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/ultrasphinx/fields.rb', line 41 def save_and_verify_type(field, new_type, string_sortable, klass, msg = nil) # Smoosh fields together based on their name in the Sphinx query schema field, new_type = field.to_s, TYPE_MAP[new_type.to_s] if types[field] # Existing field name; verify its type msg ||= "Column type mismatch for #{field.inspect}; was already #{types[field].inspect}, but is now #{new_type.inspect}." raise ConfigurationError, msg unless types[field] == new_type classes[field] = (classes[field] + [klass]).uniq else # New field types[field] = new_type classes[field] = [klass] @groups << case new_type when 'integer' "sql_attr_uint = #{field}" when 'float' "sql_attr_float = #{field}" when 'bool' "sql_attr_bool = #{field}" when 'date' "sql_attr_timestamp = #{field}" when 'text' "sql_attr_str2ordinal = #{field}" if string_sortable end end end |