Module: Hecks::Ports::Query::Ordering
- Defined in:
- lib/hecks/ports/query/ordering.rb
Overview
What order an ask ANSWERS IN — the meaning of the ask, not a property
of the store that happens to hold it. Declared here once so an adapter
may satisfy it natively but never redefine it : SQLite pushes both
tiers into SQL (NullPolicy.sql_order renders field DIR, id DIR),
while Heki and Memory have no query engine and delegate straight back
to InMemory.
Two tiers, in this order : the DECLARED order_by when there is one, then IDENTITY, always. The identity tier is what makes an ask total. Without it, an ask with no order_by — or a declared order with tied keys — hands back whatever order the store happened to hold, and store order was quietly standing in for a rule while every hand-written query in the corpus stayed green : not one of them had a tie for store order to decide.
An adapter that pushes ordering down MUST push limit down with it. Re-ordering a page the store already cut would be a top-N of the wrong N — the one way this can be got quietly, expensively wrong.
Class Method Summary collapse
Class Method Details
.apply(rows, order_by, null_semantics = nil, identity:, &value_of) ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/hecks/ports/query/ordering.rb', line 27 def apply(rows, order_by, null_semantics = nil, identity:, &value_of) # STABLE, because sort_by is not : two rows whose identity ties would # otherwise swap arbitrarily, and a tier meant to REMOVE store-dependence # would be adding a coin flip of its own. rows = rows.each_with_index.sort_by { |row, index| [identity.call(row), index] }.map(&:first) return rows unless order_by QuerySpecification::Common::NullPolicy.order( rows, direction: order_by.direction, policy: null_semantics, &value_of ) end |