lib/graphql/relay/relation_connection.rb in graphql-relay-0.8.1 vs lib/graphql/relay/relation_connection.rb in graphql-relay-0.9.0

- old
+ new

@@ -1,20 +1,13 @@ module GraphQL module Relay class RelationConnection < BaseConnection - DEFAULT_ORDER = "id" - def cursor_from_node(item) - order_value = item.public_send(order_name) - cursor_parts = [order, order_value] - Base64.strict_encode64(cursor_parts.join(CURSOR_SEPARATOR)) + offset = starting_offset + paged_nodes_array.index(item) + 1 + Base64.strict_encode64(offset.to_s) end - def order - @order ||= (super || DEFAULT_ORDER) - end - def has_next_page !!(first && sliced_nodes.limit(first + 1).count > first) end # Used by `pageInfo` @@ -24,77 +17,64 @@ private # apply first / last limit results def paged_nodes - @paged_nodes = begin + @paged_nodes ||= begin items = sliced_nodes - limit = [first, last, max_page_size].compact.min - first && items = items.first(limit) - last && items.count > last && items = items.last(limit) - items + items.limit(limit) end end # Apply cursors to edges def sliced_nodes @sliced_nodes ||= begin items = object + items.offset(starting_offset) + end + end - if order - items = items.order(items.table[order_name].public_send(order_direction)) - end + def offset_from_cursor(cursor) + Base64.decode64(cursor).to_i + end - if after - _o, order_value = slice_from_cursor(after) - direction_marker = order_direction == :asc ? ">" : "<" - where_condition = create_order_condition(table_name, order_name, order_value, direction_marker) - items = items.where(where_condition) - end - + def starting_offset + @initial_offset ||= begin if before - _o, order_value = slice_from_cursor(before) - direction_marker = order_direction == :asc ? "<" : ">" - where_condition = create_order_condition(table_name, order_name, order_value, direction_marker) - items = items.where(where_condition) + [previous_offset, 0].max + else + previous_offset end - - items end end - def slice_from_cursor(cursor) - decoded = Base64.decode64(cursor) - order, order_value = decoded.split(CURSOR_SEPARATOR) + # Offset from the previous selection, if there was one + # Otherwise, zero + def previous_offset + @previous_offset ||= if after + offset_from_cursor(after) + elsif before + offset_from_cursor(before) - last - 1 + else + 0 + end end - # Remove possible direction marker: - def order_name - @order_name ||= order.sub(/^-/, '') - end - - # Check for direction marker - def order_direction - @order_direction ||= order.start_with?("-") ? :desc : :asc - end - - def table_name - @table_name ||= object.table.table_name - end - - # When creating the where constraint, cast the value to correct column data type so - # active record can send it in correct format to db - def create_order_condition(table, column, value, direction_marker) - table_name = ActiveRecord::Base.connection.quote_table_name(table) - name = ActiveRecord::Base.connection.quote_column_name(column) - if ActiveRecord::VERSION::MAJOR == 5 - casted_value = object.table.able_to_type_cast? ? object.table.type_cast_for_database(column, value) : value - elsif ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR >= 2 - casted_value = object.table.engine.columns_hash[column].cast_type.type_cast_from_user(value) + def limit + @limit ||= if first + [first, max_page_size].compact.min else - casted_value = object.table.engine.columns_hash[column].type_cast(value) + last_limit = if previous_offset <= 0 + previous_offset + last + else + last + end + [last_limit, max_page_size].compact.min end - ["#{table_name}.#{name} #{direction_marker} ?", casted_value] + end + + def paged_nodes_array + @paged_nodes_array ||= paged_nodes.to_a end end if defined?(ActiveRecord)