Class: Gitlab::Graphql::Pagination::ClickHouseConnection
- Inherits:
-
GraphQL::Pagination::Connection
- Object
- GraphQL::Pagination::Connection
- Gitlab::Graphql::Pagination::ClickHouseConnection
- Includes:
- Utils::StrongMemoize
- Defined in:
- lib/gitlab/graphql/pagination/click_house_connection.rb
Overview
rubocop: disable CodeReuse/ActiveRecord – requires AR methods to build the keyset pagination conditions
Direct Known Subclasses
Constant Summary collapse
- TIME_PATTERN =
Timestamps are stored with 6 digit microseconds precision in both PG and in CH (our schema)
"%Y-%m-%d %H:%M:%S.%6N"
Instance Method Summary collapse
- #cursor_for(item) ⇒ Object
- #decoded_cursor(cursor) ⇒ Object
- #has_next_page ⇒ Object
-
#has_previous_page ⇒ Object
rubocop: disable Naming/PredicateName – methods required by PageInfo relay.dev/graphql/connections.htm#sec-undefined.PageInfo.Fields.
-
#nodes ⇒ Object
rubocop: enable Naming/PredicateName.
Instance Method Details
#cursor_for(item) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/gitlab/graphql/pagination/click_house_connection.rb', line 52 def cursor_for(item) raw_cursor = @items.manager.ast.orders.each_with_object({}) do |order, hash| expression_name = order.expr.name value = item[expression_name] raise "Cursor value for '#{expression_name}' is missing" if value.nil? hash[expression_name] = case when value.is_a?(Date) value.to_fs(:db) when value.is_a?(Time) # In ClickHouse we store timestamps in UTC value.utc.strftime(TIME_PATTERN) when value.is_a?(Numeric) || value.is_a?(String) value else raise 'Unsupported type in the cursor: only Time, \ Numeric, and String types are supported' end end encode(Gitlab::Json.dump(raw_cursor)) end |
#decoded_cursor(cursor) ⇒ Object
75 76 77 78 79 |
# File 'lib/gitlab/graphql/pagination/click_house_connection.rb', line 75 def decoded_cursor(cursor) Gitlab::Json.parse(decode(cursor)) rescue JSON::ParserError raise Gitlab::Graphql::Errors::ArgumentError, 'Invalid cursor given' end |
#has_next_page ⇒ Object
36 37 38 39 40 41 42 43 44 |
# File 'lib/gitlab/graphql/pagination/click_house_connection.rb', line 36 def has_next_page if before true elsif first limited_nodes.size > limit_value else false end end |
#has_previous_page ⇒ Object
rubocop: disable Naming/PredicateName – methods required by PageInfo relay.dev/graphql/connections.htm#sec-undefined.PageInfo.Fields
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
# File 'lib/gitlab/graphql/pagination/click_house_connection.rb', line 15 def has_previous_page if after # If `after` is specified, that points to a specific record, # even if it's the first one. Since we're asking for `after`, # then the specific record we're pointing to is in the # previous page true elsif last limited_nodes !!@has_previous_page_cache else # Key thing to remember. When `before` is specified (and no `last`), # the spec says return _all_ edges minus anything after the `before`. # Which means the returned list starts at the very first record. # Then the max_page kicks in, and returns the first max_page items. # Because of this, `has_previous_page` will be false false end end |
#nodes ⇒ Object
rubocop: enable Naming/PredicateName
48 49 50 |
# File 'lib/gitlab/graphql/pagination/click_house_connection.rb', line 48 def nodes limited_nodes.take(limit_value) end |