Class: Rotulus::Column

Inherits:
Object
  • Object
show all
Defined in:
lib/rotulus/column.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, name, direction: :asc, nullable: nil, nulls: nil, distinct: nil) ⇒ Column

Creates a Column object representing a table column in the “ORDER BY” expression.

Parameters:

  • model (Class)

    the ActiveRecord model class name where this column belongs

  • name (String)

    the column name. Columns from joined tables are prefixed with the joined table’s name/alias (e.g. some_table.column).

  • direction (Symbol) (defaults to: :asc)

    the sort direction, :asc or :desc. Default: :asc.

  • nullable (Boolean) (defaults to: nil)

    whether a null value is expected for this column in the result. Note that for queries with table JOINs, a column could have a null value even if the column doesn’t allow nulls in its table so :nullable might need to be set to true for such cases. Default: true if :nullable option value is nil and the column is defined as nullable in its table otherwise, false.

  • nulls (Symbol) (defaults to: nil)

    null values sorting, :first for NULLS FIRST and :last for NULLS LAST. Applicable only if column is nullable.

  • distinct (Boolean) (defaults to: nil)

    whether the column value is expected to be unique in the result. Note that for queries with table JOINs, multiple rows could have the same column value even if the column has a unique index defined in its table so :distinct might need to be set to false for such cases. Default: true if :distinct option value is nil and the column is the PK of its table otherwise, false.



26
27
28
29
30
31
32
33
34
35
# File 'lib/rotulus/column.rb', line 26

def initialize(model, name, direction: :asc, nullable: nil, nulls: nil, distinct: nil)
  @model = model
  @name = name.to_s
  validate_name!

  @direction = sort_direction(direction)
  @distinct = uniqueness(distinct)
  @nullable = nullability(nullable)
  @nulls = nulls_order(nulls)
end

Instance Attribute Details

#directionObject (readonly)

Returns the value of attribute direction.



3
4
5
# File 'lib/rotulus/column.rb', line 3

def direction
  @direction
end

#modelObject (readonly)

Returns the value of attribute model.



3
4
5
# File 'lib/rotulus/column.rb', line 3

def model
  @model
end

#nameObject (readonly)

Returns the value of attribute name.



3
4
5
# File 'lib/rotulus/column.rb', line 3

def name
  @name
end

#nullsObject (readonly)

Returns the value of attribute nulls.



3
4
5
# File 'lib/rotulus/column.rb', line 3

def nulls
  @nulls
end

Class Method Details

.select_alias(name) ⇒ Object



41
42
43
# File 'lib/rotulus/column.rb', line 41

def self.select_alias(name)
  "cursor___#{name.to_s.gsub('.', '__')}"
end

.select_alias_to_name(select_alias) ⇒ Object



37
38
39
# File 'lib/rotulus/column.rb', line 37

def self.select_alias_to_name(select_alias)
  select_alias.gsub('cursor___', '').gsub('__', '.')
end

Instance Method Details

#as_leftmost!Object

Mark the column as the ‘leftmost’ column in the ‘ORDER BY’ SQL (column with highest sort priority)



46
47
48
49
50
# File 'lib/rotulus/column.rb', line 46

def as_leftmost!
  @leftmost = true

  self
end

#asc?Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/rotulus/column.rb', line 56

def asc?
  direction == :asc
end

#desc?Boolean

Returns:

  • (Boolean)


60
61
62
# File 'lib/rotulus/column.rb', line 60

def desc?
  !asc?
end

#distinct?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/rotulus/column.rb', line 64

def distinct?
  @distinct
end

#leftmost?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/rotulus/column.rb', line 52

def leftmost?
  @leftmost
end

#nullable?Boolean

Returns:

  • (Boolean)


68
69
70
# File 'lib/rotulus/column.rb', line 68

def nullable?
  @nullable
end

#nulls_first?Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/rotulus/column.rb', line 72

def nulls_first?
  nulls == :first
end

#nulls_last?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/rotulus/column.rb', line 76

def nulls_last?
  nulls == :last
end

#order_sqlObject



113
114
115
116
117
# File 'lib/rotulus/column.rb', line 113

def order_sql
  return Rotulus.db.order_sql(prefixed_name, direction) unless nullable?

  Rotulus.db.nullable_order_sql(prefixed_name, direction, nulls)
end

#prefixed_nameObject



84
85
86
87
88
89
90
# File 'lib/rotulus/column.rb', line 84

def prefixed_name
  @prefixed_name ||= if !name_has_prefix?
                       "#{model.table_name}.#{name}"
                     else
                       name
                     end
end

#reversed_order_sqlObject



107
108
109
110
111
# File 'lib/rotulus/column.rb', line 107

def reversed_order_sql
  return Rotulus.db.reversed_order_sql(prefixed_name, direction) unless nullable?

  Rotulus.db.reversed_nullable_order_sql(prefixed_name, direction, nulls)
end

#select_aliasObject



92
93
94
# File 'lib/rotulus/column.rb', line 92

def select_alias
  self.class.select_alias(prefixed_name)
end

#select_sqlObject



119
120
121
# File 'lib/rotulus/column.rb', line 119

def select_sql
  "#{prefixed_name} as #{select_alias}"
end

#to_hObject



96
97
98
99
100
101
102
103
104
105
# File 'lib/rotulus/column.rb', line 96

def to_h
  h = {
    direction: direction,
    nullable: nullable?,
    distinct: distinct?
  }
  h[:nulls] = nulls if nullable?

  { prefixed_name => h }
end

#unprefixed_nameObject



80
81
82
# File 'lib/rotulus/column.rb', line 80

def unprefixed_name
  @unprefixed_name ||= name.split('.').last
end