Class: RDBr::Query::Relational

Inherits:
Object
  • Object
show all
Includes:
Lookup, TypeSupport
Defined in:
lib/rdbr/query/relational.rb

Direct Known Subclasses

Mysql, Postgresql, Sqlite

Defined Under Namespace

Classes: GroupRequest, Request

Constant Summary collapse

DEFAULT_PAGE_SIZE =
25

Constants included from TypeSupport

TypeSupport::FILTER_OPERATORS, TypeSupport::INTEGER_TYPES, TypeSupport::TYPE_GROUPS

Instance Method Summary collapse

Methods included from Lookup

#lookup

Methods included from TypeSupport

#filter_operators, #groupable_column?, #sortable_column?

Constructor Details

#initialize(connection:, catalog:, max_results: 100) ⇒ Relational

Returns a new instance of Relational.



11
12
13
14
15
# File 'lib/rdbr/query/relational.rb', line 11

def initialize(connection:, catalog:, max_results: 100)
  @connection = connection
  @catalog = catalog
  @max_results = positive_integer(max_results, 'maximum result limit')
end

Instance Method Details

#build_page(request, rows, total_count) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/rdbr/query/relational.rb', line 33

def build_page(request, rows, total_count)
  Page.build(
    namespace: request.namespace.name,
    relation: request.relation.name,
    columns: request.relation.columns.map(&:name),
    rows: rows.first(request.page_size),
    page: request.page_number,
    per_page: request.page_size,
    has_next: page_has_next?(request, rows, total_count),
    total_count: total_count
  )
end

#group(namespace:, relation:, column:, **options) ⇒ Object

Raises:



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/rdbr/query/relational.rb', line 67

def group(namespace:, relation:, column:, **options)
  ,  = find_relation(namespace, relation)
   = .column(column)
  raise InvalidQueryError, "Unknown group column: #{column}" unless 
  raise InvalidQueryError, "Unsupported group column: #{column}" unless groupable_column?()

  page_number = positive_integer(options.fetch(:page, 1), 'page')
  requested_size = positive_integer(options.fetch(:per_page, DEFAULT_PAGE_SIZE), 'page size')
  page_size = [ requested_size, max_results ].min
  request = GroupRequest.new(
    namespace: , relation: , column: ,
    page_number: page_number, page_size: page_size,
    filters: options.fetch(:filters, {}), search: options[:search]
  )
  rows = connection.select_all(group_sql(request))
  Page.build(
    namespace: .name, relation: .name,
    columns: [ 'value', 'count' ], rows: rows.first(page_size), page: page_number,
    per_page: page_size, has_next: rows.length > page_size
  )
end

#page(namespace:, relation:, **options) ⇒ Object



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/rdbr/query/relational.rb', line 17

def page(namespace:, relation:, **options)
  ,  = find_relation(namespace, relation)
  request = Request.new(
    namespace: ,
    relation: ,
    page_number: positive_integer(options.fetch(:page, 1), 'page'),
    page_size: [ positive_integer(options.fetch(:per_page, DEFAULT_PAGE_SIZE), 'page size'), max_results ].min,
    sort: options[:sort],
    filters: options.fetch(:filters, {}),
    search: options[:search]
  )
  total_count = count_rows(request) if options[:include_total]
  rows = connection.select_all(select_sql(request))
  build_page(request, rows, total_count)
end

#page_has_next?(request, rows, total_count) ⇒ Boolean

Returns:

  • (Boolean)


46
47
48
49
50
# File 'lib/rdbr/query/relational.rb', line 46

def page_has_next?(request, rows, total_count)
  return rows.length > request.page_size unless total_count

  request.page_number * request.page_size < total_count
end

#record(namespace:, relation:, key:) ⇒ Object

Raises:



54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rdbr/query/relational.rb', line 54

def record(namespace:, relation:, key:)
  _namespace,  = find_relation(namespace, relation)
  primary_key = .primary_key
  raise InvalidQueryError, 'This relation has no primary key' unless primary_key

  normalized_key = key.to_h.transform_keys(&:to_s)
  unless normalized_key.keys.sort == primary_key.columns.sort
    raise InvalidQueryError, 'Record key must contain every primary-key column'
  end

  page(namespace: namespace, relation: relation, per_page: 1, filters: normalized_key).rows.first
end