64 lines
1.6 KiB
Ruby
64 lines
1.6 KiB
Ruby
|
require 'active_record'
|
||
|
|
||
|
class Carto::VisualizationQueryOrderer
|
||
|
|
||
|
DEFAULT_ORDER_DIRECTION = 'asc'.freeze
|
||
|
SUPPORTED_OFFDATABASE_ORDERS = %w(size mapviews likes estimated_row_count).freeze
|
||
|
VISUALIZATION_TABLE_ORDERS = %w(name updated_at privacy).freeze
|
||
|
|
||
|
DEPENDENT_VISUALIZATIONS_ORDER_CLAUSE = "coalesce(dependent_visualization_count, 0)".freeze
|
||
|
FAVORITED_ORDER_CLAUSE = "(likes.actor IS NOT NULL)".freeze
|
||
|
|
||
|
def initialize(query)
|
||
|
@query = query
|
||
|
end
|
||
|
|
||
|
def order(order, direction = "")
|
||
|
return @query unless order
|
||
|
|
||
|
prepare_order_params(order, direction)
|
||
|
|
||
|
if offdatabase_orders.empty?
|
||
|
@query.order(database_orders)
|
||
|
else
|
||
|
Carto::OffdatabaseQueryAdapter.new(@query, offdatabase_orders)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
private
|
||
|
|
||
|
def prepare_order_params(order_string, direction_string)
|
||
|
directions = direction_string.split(',')
|
||
|
orders = order_string.split(',')
|
||
|
|
||
|
@order_hash = orders.zip(directions).map { |order, direction|
|
||
|
order = custom_order_clause(order)
|
||
|
direction ||= directions[0] || DEFAULT_ORDER_DIRECTION
|
||
|
[order, direction]
|
||
|
}.to_h
|
||
|
end
|
||
|
|
||
|
def custom_order_clause(order)
|
||
|
case order
|
||
|
when 'favorited'
|
||
|
FAVORITED_ORDER_CLAUSE
|
||
|
when 'dependent_visualizations'
|
||
|
DEPENDENT_VISUALIZATIONS_ORDER_CLAUSE
|
||
|
when *VISUALIZATION_TABLE_ORDERS
|
||
|
"visualizations.#{order}"
|
||
|
else
|
||
|
order
|
||
|
end
|
||
|
end
|
||
|
|
||
|
def database_orders
|
||
|
db_order_hash = @order_hash.except(*SUPPORTED_OFFDATABASE_ORDERS)
|
||
|
db_order_hash.map { |key, value| "#{key} #{value}" }.join(",")
|
||
|
end
|
||
|
|
||
|
def offdatabase_orders
|
||
|
@order_hash.slice(*SUPPORTED_OFFDATABASE_ORDERS)
|
||
|
end
|
||
|
|
||
|
end
|