Class: Hayfork::Binding

Inherits:
Struct
  • Object
show all
Defined in:
lib/hayfork/binding.rb

Constant Summary collapse

SPECIAL_CASTS =
{
  "character varying" => "varchar",
  "tsvector" => "varchar"
}.freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#columnObject

Returns the value of attribute column

Returns:

  • (Object)

    the current value of column



2
3
4
# File 'lib/hayfork/binding.rb', line 2

def column
  @column
end

#raw_valueObject

Returns the value of attribute raw_value

Returns:

  • (Object)

    the current value of raw_value



2
3
4
# File 'lib/hayfork/binding.rb', line 2

def raw_value
  @raw_value
end

#statementObject

Returns the value of attribute statement

Returns:

  • (Object)

    the current value of statement



2
3
4
# File 'lib/hayfork/binding.rb', line 2

def statement
  @statement
end

Instance Method Details

#column_nameObject Also known as: key



9
10
11
# File 'lib/hayfork/binding.rb', line 9

def column_name
  column.name
end

#quoted_valueObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/hayfork/binding.rb', line 14

def quoted_value
  case raw_value
  when Arel::Attributes::Attribute
    value_column = raw_value.relation.send(:type_caster).send(:types).columns_hash[raw_value.name.to_s]
    fail Hayfork::ColumnNotFoundError, "'#{raw_value.name}' is not a column on '#{raw_value.relation.name}'" unless value_column

    value = "#{raw_value.relation.name}.#{raw_value.name}"

    unless column.sql_type == value_column.sql_type
      type = SPECIAL_CASTS.fetch(column.sql_type, column.sql_type)
      value = "#{value}::#{type}"
    end

    if statement.unnest? && [Hayfork::SEARCH_VECTOR, Hayfork::TEXT].member?(column.name)
      value = "unnest(string_to_array(#{value}, E'\\n'))"
    end

    if column.type == :tsvector

      # Postgres does not handle hyphens well.
      #
      # Notice how, in the following example, the way it breaks up
      # those words throws off the index (Jesus is the fifth word
      # not the third or fourth). This prevents you from constructing
      # an exact-phrase query for a hyphenated word:
      #
      #   > select to_tsvector('hayfork', 'thou long-expected jesus');
      #   { 'expect':4 'jesus':5 'long':3 'long-expect':2 'thou':1 }
      #
      #
      # We'll coerce Postgres into treating hyphenated words as two words.

      value = "setweight(to_tsvector('#{statement.dictionary}', replace(#{value}, '-', ' ')), '#{statement.weight}')"
    end

    value

  when Arel::Nodes::Node
    raw_value.to_sql

  else
    type = SPECIAL_CASTS.fetch(column.sql_type, column.sql_type)
    "#{statement.haystack.connection.quote(raw_value)}::#{type}"

  end
end

#to_sqlObject Also known as: to_s



4
5
6
# File 'lib/hayfork/binding.rb', line 4

def to_sql
  "#{quoted_value} \"#{column.name}\""
end