ddr-core 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +12 -0
  3. data/README.md +27 -0
  4. data/Rakefile +30 -0
  5. data/app/assets/config/ddr_core_manifest.js +0 -0
  6. data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
  7. data/app/controllers/users/sessions_controller.rb +15 -0
  8. data/app/models/concerns/ddr/captionable.rb +25 -0
  9. data/app/models/concerns/ddr/describable.rb +108 -0
  10. data/app/models/concerns/ddr/governable.rb +25 -0
  11. data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
  12. data/app/models/concerns/ddr/has_attachments.rb +10 -0
  13. data/app/models/concerns/ddr/has_children.rb +10 -0
  14. data/app/models/concerns/ddr/has_content.rb +132 -0
  15. data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
  16. data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
  17. data/app/models/concerns/ddr/has_multires_image.rb +14 -0
  18. data/app/models/concerns/ddr/has_parent.rb +18 -0
  19. data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
  20. data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
  21. data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
  22. data/app/models/concerns/ddr/streamable.rb +25 -0
  23. data/app/models/ddr/admin_set.rb +28 -0
  24. data/app/models/ddr/attachment.rb +14 -0
  25. data/app/models/ddr/collection.rb +28 -0
  26. data/app/models/ddr/component.rb +31 -0
  27. data/app/models/ddr/contact.rb +23 -0
  28. data/app/models/ddr/digest.rb +8 -0
  29. data/app/models/ddr/file.rb +40 -0
  30. data/app/models/ddr/item.rb +36 -0
  31. data/app/models/ddr/language.rb +31 -0
  32. data/app/models/ddr/media_type.rb +22 -0
  33. data/app/models/ddr/resource.rb +94 -0
  34. data/app/models/ddr/rights_statement.rb +25 -0
  35. data/app/models/ddr/target.rb +17 -0
  36. data/config/initializers/devise.rb +262 -0
  37. data/config/locales/ddr-core.en.yml +85 -0
  38. data/config/routes.rb +3 -0
  39. data/db/migrate/20141104181418_create_users.rb +34 -0
  40. data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
  41. data/lib/ddr-core.rb +1 -0
  42. data/lib/ddr/auth.rb +80 -0
  43. data/lib/ddr/auth/ability.rb +18 -0
  44. data/lib/ddr/auth/ability_definitions.rb +26 -0
  45. data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
  46. data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
  47. data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
  48. data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
  49. data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
  50. data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
  51. data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
  52. data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
  53. data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
  54. data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
  55. data/lib/ddr/auth/ability_factory.rb +10 -0
  56. data/lib/ddr/auth/abstract_ability.rb +48 -0
  57. data/lib/ddr/auth/affiliation.rb +14 -0
  58. data/lib/ddr/auth/affiliation_groups.rb +20 -0
  59. data/lib/ddr/auth/anonymous_ability.rb +7 -0
  60. data/lib/ddr/auth/auth_context.rb +109 -0
  61. data/lib/ddr/auth/auth_context_factory.rb +13 -0
  62. data/lib/ddr/auth/detached_auth_context.rb +19 -0
  63. data/lib/ddr/auth/dynamic_groups.rb +13 -0
  64. data/lib/ddr/auth/effective_permissions.rb +12 -0
  65. data/lib/ddr/auth/effective_roles.rb +9 -0
  66. data/lib/ddr/auth/failure_app.rb +16 -0
  67. data/lib/ddr/auth/group.rb +40 -0
  68. data/lib/ddr/auth/grouper_gateway.rb +70 -0
  69. data/lib/ddr/auth/groups.rb +32 -0
  70. data/lib/ddr/auth/ldap_gateway.rb +74 -0
  71. data/lib/ddr/auth/permissions.rb +18 -0
  72. data/lib/ddr/auth/remote_groups.rb +14 -0
  73. data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
  74. data/lib/ddr/auth/roles.rb +28 -0
  75. data/lib/ddr/auth/roles/role.rb +121 -0
  76. data/lib/ddr/auth/roles/role_type.rb +23 -0
  77. data/lib/ddr/auth/roles/role_types.rb +52 -0
  78. data/lib/ddr/auth/superuser_ability.rb +7 -0
  79. data/lib/ddr/auth/test_helpers.rb +22 -0
  80. data/lib/ddr/auth/user.rb +54 -0
  81. data/lib/ddr/auth/web_auth_context.rb +29 -0
  82. data/lib/ddr/core.rb +110 -0
  83. data/lib/ddr/core/engine.rb +8 -0
  84. data/lib/ddr/core/version.rb +5 -0
  85. data/lib/ddr/error.rb +16 -0
  86. data/lib/ddr/files.rb +13 -0
  87. data/lib/ddr/fits.rb +189 -0
  88. data/lib/ddr/index.rb +29 -0
  89. data/lib/ddr/index/abstract_query_result.rb +22 -0
  90. data/lib/ddr/index/connection.rb +38 -0
  91. data/lib/ddr/index/csv_query_result.rb +84 -0
  92. data/lib/ddr/index/document_builder.rb +9 -0
  93. data/lib/ddr/index/field.rb +35 -0
  94. data/lib/ddr/index/field_attribute.rb +22 -0
  95. data/lib/ddr/index/fields.rb +154 -0
  96. data/lib/ddr/index/filter.rb +139 -0
  97. data/lib/ddr/index/query.rb +82 -0
  98. data/lib/ddr/index/query_builder.rb +185 -0
  99. data/lib/ddr/index/query_clause.rb +112 -0
  100. data/lib/ddr/index/query_params.rb +40 -0
  101. data/lib/ddr/index/query_result.rb +102 -0
  102. data/lib/ddr/index/response.rb +30 -0
  103. data/lib/ddr/index/sort_order.rb +28 -0
  104. data/lib/ddr/index/unique_key_field.rb +12 -0
  105. data/lib/ddr/managers.rb +9 -0
  106. data/lib/ddr/managers/manager.rb +13 -0
  107. data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
  108. data/lib/ddr/structure.rb +188 -0
  109. data/lib/ddr/structures/agent.rb +49 -0
  110. data/lib/ddr/structures/component_type_term.rb +29 -0
  111. data/lib/ddr/structures/div.rb +64 -0
  112. data/lib/ddr/structures/f_locat.rb +54 -0
  113. data/lib/ddr/structures/file.rb +52 -0
  114. data/lib/ddr/structures/file_grp.rb +35 -0
  115. data/lib/ddr/structures/file_sec.rb +22 -0
  116. data/lib/ddr/structures/fptr.rb +31 -0
  117. data/lib/ddr/structures/mets_hdr.rb +37 -0
  118. data/lib/ddr/structures/mptr.rb +49 -0
  119. data/lib/ddr/structures/struct_map.rb +40 -0
  120. data/lib/ddr/utils.rb +185 -0
  121. data/lib/ddr/vocab.rb +22 -0
  122. data/lib/ddr/vocab/asset.rb +51 -0
  123. data/lib/ddr/vocab/contact.rb +9 -0
  124. data/lib/ddr/vocab/display.rb +9 -0
  125. data/lib/ddr/vocab/duke_terms.rb +13 -0
  126. data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
  127. data/lib/ddr/vocab/roles.rb +25 -0
  128. data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
  129. data/lib/ddr/vocab/vocabulary.rb +37 -0
  130. data/lib/ddr/workflow.rb +8 -0
  131. data/lib/tasks/ddr/core_tasks.rake +4 -0
  132. metadata +428 -0
@@ -0,0 +1,82 @@
1
+ require "virtus"
2
+ require "forwardable"
3
+
4
+ module Ddr::Index
5
+ class Query
6
+ include Virtus.model
7
+ extend Forwardable
8
+ extend Deprecation
9
+
10
+ attribute :q, String, default: '*:*'
11
+ attribute :fields, Array[FieldAttribute], default: [ ]
12
+ attribute :filters, Array[Filter], default: [ ]
13
+ attribute :sort, Array[String], default: [ ]
14
+ attribute :rows, Integer
15
+
16
+ delegate [:count, :docs, :ids, :each_id, :all] => :result
17
+ delegate :params => :query_params
18
+
19
+ def self.build(*args, &block)
20
+ new.tap do |query|
21
+ query.build(*args, &block)
22
+ end
23
+ end
24
+
25
+ def initialize(**args, &block)
26
+ super(**args)
27
+ if block_given?
28
+ build(&block)
29
+ end
30
+ end
31
+
32
+ def inspect
33
+ "#<#{self.class.name} q=#{q.inspect}, filters=#{filters.inspect}," \
34
+ " sort=#{sort.inspect}, rows=#{rows.inspect}, fields=#{fields.inspect}>"
35
+ end
36
+
37
+ def to_s
38
+ URI.encode_www_form(params)
39
+ end
40
+
41
+ def pids
42
+ Deprecation.warn(QueryResult, "`pids` is deprecated; use `ids` instead.")
43
+ ids
44
+ end
45
+
46
+ def each_pid(&block)
47
+ Deprecation.warn(QueryResult, "`each_pid` is deprecated; use `each_id` instead.")
48
+ each_id(&block)
49
+ end
50
+
51
+ def result
52
+ QueryResult.new(self)
53
+ end
54
+
55
+ def csv
56
+ CSVQueryResult.new(self)
57
+ end
58
+
59
+ def filter_clauses
60
+ filters.map(&:clauses).flatten
61
+ end
62
+
63
+ def query_params
64
+ QueryParams.new(self)
65
+ end
66
+
67
+ def build(*args, &block)
68
+ QueryBuilder.new(self, *args, &block)
69
+ self
70
+ end
71
+
72
+ def ==(other)
73
+ other.instance_of?(self.class) &&
74
+ other.q == self.q &&
75
+ other.fields == self.fields &&
76
+ other.filters == self.filters &&
77
+ other.rows == self.rows &&
78
+ other.sort == self.sort
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,185 @@
1
+ module Ddr::Index
2
+ #
3
+ # QueryBuilder - Provides a DSL for building a Query.
4
+ #
5
+ # Note: Where a method receives a [field] parameter, the parameter value is
6
+ # coerced to a Field instance. See FieldAttribute#coerce for details.
7
+ #
8
+ # *** DSL METHODS ***
9
+ #
10
+ # absent [field]
11
+ # Adds a filter selecting documents where the field is not present (no values).
12
+ #
13
+ # asc [field], ...
14
+ # Adds ascending orderings by the fields specified.
15
+ #
16
+ # See also: desc, order_by
17
+ #
18
+ # before [field], [date_time]
19
+ # Adds a filter selecting documents where the field has a date/time before
20
+ # (earlier than) the value.
21
+ #
22
+ # before_days [field], [int]
23
+ # Adds a filter selecting documents where the field has a date/time the
24
+ # specified number of days before today (now) or earlier.
25
+ #
26
+ # desc [field], ...
27
+ # Adds descending orderings by the fields specified.
28
+ #
29
+ # See also: asc, order_by
30
+ #
31
+ # filter [filter1], ...
32
+ # Adds filters to the query.
33
+ #
34
+ # Aliased as: filters
35
+ #
36
+ # filters [filter], ...
37
+ # Alias for: filter
38
+ #
39
+ # field [field1], ...
40
+ # Adds fields to result documents.
41
+ # Note that all fields are returned when none is specified.
42
+ #
43
+ # Aliased as: fields
44
+ #
45
+ # fields [field], ...
46
+ # Alias for: field
47
+ #
48
+ # id [doc_id]
49
+ # For selecting a single document by ID.
50
+ #
51
+ # join [from: {field1}, to: {field2}, where: {condition}]
52
+ # Adds a Solr join clause (see https://wiki.apache.org/solr/Join)
53
+ #
54
+ # limit [int]
55
+ # Limits the number of documents returned by the query.
56
+ #
57
+ # Aliased as: rows
58
+ #
59
+ # model [model_name], ...
60
+ # Adds a filter selecting document where ActiveFedora model equals value
61
+ # or one of the values.
62
+ #
63
+ # negative [field], [value]
64
+ # Adds a filter selecting document where field does not have the value.
65
+ #
66
+ # order_by [{field => order, ...}], ...
67
+ # Adds ordering(s) to the query.
68
+ #
69
+ # Aliased as: sort
70
+ #
71
+ # present [field]
72
+ # Adds a filter selecting document where the field has any value.
73
+ #
74
+ # q [query_clause]
75
+ # Sets a query clause for the `q` parameter.
76
+ #
77
+ # raw [clause1], ...
78
+ # Adds a filter of "raw" query clauses (i.e., pre-constructed).
79
+ #
80
+ # regexp [field], [regexp]
81
+ # Adds a filter selecting documents where the field has a value
82
+ # matching the regular expression.
83
+ # Slashes (/) in the regexp will be escaped as required by Solr.
84
+ #
85
+ # rows [int]
86
+ # Alias for: limit
87
+ #
88
+ # sort [{field => order, ...}]
89
+ # Alias for: order_by
90
+ #
91
+ # term [{field => value, ...}]
92
+ # Adds a filter of "term" query clauses for the fields and values.
93
+ #
94
+ # where [{field => value, ...}]
95
+ # Adds a filter of "standard" query clauses.
96
+ # Values will be escaped when the filter is serialized.
97
+ # If a hash value is an array, that query clause will select documents
98
+ # where the field matches any array entry.
99
+ #
100
+ class QueryBuilder
101
+
102
+ attr_reader :query
103
+
104
+ def initialize(*args, &block)
105
+ @query = args.first.is_a?(Query) ? args.shift : Query.new
106
+ if block_given?
107
+ instance_exec(*args, &block)
108
+ end
109
+ end
110
+
111
+ # @param pid [String]
112
+ # @return [QueryBuilder]
113
+ def id(pid)
114
+ q QueryClause.id(pid)
115
+ limit 1
116
+ end
117
+
118
+ # @param filters [Array<Filter>]
119
+ # @return [QueryBuilder]
120
+ def filter(*filters)
121
+ query.filters += filters
122
+ self
123
+ end
124
+ alias_method :filters, :filter
125
+
126
+ # @param fields [Array<Field>]
127
+ # @return [QueryBuilder] self
128
+ def field(*fields)
129
+ query.fields += fields.flatten.map { |f| FieldAttribute.coerce(f) }
130
+ self
131
+ end
132
+ alias_method :fields, :field
133
+
134
+ # @param num [Integer]
135
+ # @return [QueryBuilder] self
136
+ def limit(num)
137
+ query.rows = num.to_i
138
+ self
139
+ end
140
+ alias_method :rows, :limit
141
+
142
+ # @param orderings [Hash<Field, String>]
143
+ # @return [QueryBuilder] self
144
+ def order_by(*orderings)
145
+ query.sort += orderings.first.map { |field, order| SortOrder.new(field: field, order: order) }
146
+ self
147
+ end
148
+ alias_method :sort, :order_by
149
+
150
+ # @param fields [Array<Field, Symbol, String>]
151
+ # @return [QueryBuilder] self
152
+ def asc(*fields)
153
+ query.sort += fields.map { |field| SortOrder.asc(field) }
154
+ self
155
+ end
156
+ # @param fields [Array<Field, Symbol, String>]
157
+ # @return [QueryBuilder] self
158
+ def desc(*fields)
159
+ query.sort += fields.map { |field| SortOrder.desc(field) }
160
+ self
161
+ end
162
+
163
+ # @param query_clause [QueryClause, String]
164
+ # @return [QueryBuilder] self
165
+ def q(query_clause)
166
+ query.q = query_clause
167
+ self
168
+ end
169
+
170
+ private
171
+
172
+ def respond_to_missing?(name, include_all)
173
+ Filter::ClassMethods.public_instance_methods.include?(name)
174
+ end
175
+
176
+ def method_missing(name, *args, &block)
177
+ if respond_to?(name)
178
+ filter Filter.send(name, *args)
179
+ else
180
+ super
181
+ end
182
+ end
183
+
184
+ end
185
+ end
@@ -0,0 +1,112 @@
1
+ require "virtus"
2
+
3
+ module Ddr::Index
4
+ class QueryClause
5
+ include Virtus.value_object
6
+
7
+ ANY_FIELD = Field.new('*').freeze
8
+ ANY_VALUE = "[* TO *]"
9
+ QUOTE = '"'
10
+
11
+ TERM_QUERY = "{!term f=%{field}}%{value}"
12
+ STANDARD_QUERY = "%{field}:%{value}"
13
+ NEGATIVE_QUERY = "-%{field}:%{value}"
14
+ DISJUNCTION = "{!lucene q.op=OR df=%{field}}%{value}"
15
+ REGEXP_QUERY = "%{field}:/%{value}/"
16
+
17
+ values do
18
+ attribute :field, FieldAttribute
19
+ attribute :value, String
20
+ attribute :quote_value, Boolean, default: false
21
+ attribute :template, String, default: STANDARD_QUERY
22
+ end
23
+
24
+ def to_s
25
+ template % { field: field, value: quote_value ? quote(value) : value }
26
+ end
27
+
28
+ def quote(value)
29
+ self.class.quote(value)
30
+ end
31
+
32
+ class << self
33
+ def quote(value)
34
+ # Derived from Blacklight::Solr::SearchBuilderBehavior#solr_param_quote
35
+ unless value =~ /\A[a-zA-Z0-9$_\-\^]+\z/
36
+ QUOTE + value.gsub("'", "\\\\\'").gsub('"', "\\\\\"") + QUOTE
37
+ else
38
+ value
39
+ end
40
+ end
41
+
42
+ # Builds a query clause to retrieve the index document by unique key.
43
+ def unique_key(value)
44
+ term(UniqueKeyField.instance, value)
45
+ end
46
+ alias_method :id, :unique_key
47
+
48
+ def where(field, value)
49
+ values = Array(value)
50
+ if values.size > 1
51
+ disjunction(field, values)
52
+ else
53
+ new(field: field, value: values.first, quote_value: true)
54
+ end
55
+ end
56
+
57
+ # Builds a query clause to filter where field does not have the given value.
58
+ def negative(field, value)
59
+ new(field: field, value: value, template: NEGATIVE_QUERY, quote_value: true)
60
+ end
61
+
62
+ # Builds a query clause to filter where field is present (i.e, has any value)
63
+ def present(field)
64
+ new(field: field, value: ANY_VALUE)
65
+ end
66
+
67
+ # Builds a query clause to filter where field is NOT present (no values)
68
+ def absent(field)
69
+ new(field: field, value: ANY_VALUE, template: NEGATIVE_QUERY)
70
+ end
71
+
72
+ # Builds a query clause to filter where field contains at least one of a set of values.
73
+ def disjunction(field, values)
74
+ value = values.map { |v| quote(v) }.join(" ")
75
+ new(field: field, value: value, template: DISJUNCTION)
76
+ end
77
+
78
+ # Builds a Solr join clause
79
+ # @see https://wiki.apache.org/solr/Join
80
+ def join(from:, to:, where:)
81
+ field, value = where.to_a.first
82
+ from_field = FieldAttribute.coerce(from)
83
+ to_field = FieldAttribute.coerce(to)
84
+ template = "{!join from=#{from_field} to=#{to_field}}%{field}:%{value}"
85
+ new(field: field, value: value, template: template, quote_value: true)
86
+ end
87
+
88
+ # Builds a query clause to filter where date field value is earlier than a date/time value.
89
+ def before(field, value)
90
+ new(field: field, value: "[* TO %s]" % Ddr::Utils.solr_date(value))
91
+ end
92
+ alias_method :before_date_time, :before
93
+
94
+ # Builds a query clause to filter where date field value is earlier than a number of days before now.
95
+ def before_days(field, value)
96
+ new(field: field, value: "[* TO NOW-%iDAYS]" % value)
97
+ end
98
+
99
+ # Builds a "term query" clause to filter where field contains value.
100
+ def term(field, value)
101
+ new(field: field, value: value, template: TERM_QUERY)
102
+ end
103
+
104
+ # Builds a regular expression query clause
105
+ def regexp(field, value)
106
+ val = value.gsub(/\//, "\\/")
107
+ new(field: field, value: val, template: REGEXP_QUERY)
108
+ end
109
+ end
110
+
111
+ end
112
+ end
@@ -0,0 +1,40 @@
1
+ module Ddr::Index
2
+ class QueryParams
3
+
4
+ attr_reader :query
5
+
6
+ def initialize(query)
7
+ @query = query
8
+ end
9
+
10
+ def params
11
+ { q: q_param,
12
+ fq: filter_queries,
13
+ fl: fields,
14
+ sort: sort,
15
+ rows: rows,
16
+ }.select { |k, v| v.present? }
17
+ end
18
+
19
+ def q_param
20
+ query.q.to_s
21
+ end
22
+
23
+ def filter_queries
24
+ query.filter_clauses.map(&:to_s)
25
+ end
26
+
27
+ def fields
28
+ query.fields.join(",")
29
+ end
30
+
31
+ def sort
32
+ query.sort.join(",")
33
+ end
34
+
35
+ def rows
36
+ query.rows
37
+ end
38
+
39
+ end
40
+ end
@@ -0,0 +1,102 @@
1
+ module Ddr::Index
2
+ class QueryResult < AbstractQueryResult
3
+ extend Deprecation
4
+
5
+ PAGE_SIZE = 1000
6
+
7
+ delegate :csv, to: :query
8
+
9
+ def each(&block)
10
+ if params[:rows]
11
+ each_unpaginated(&block)
12
+ else
13
+ each_paginated(&block)
14
+ end
15
+ end
16
+
17
+ def each_unpaginated(&block)
18
+ Connection.select(params).docs.each(&block)
19
+ end
20
+
21
+ def each_paginated(&block)
22
+ pages.each { |pg| pg.each(&block) }
23
+ end
24
+
25
+ def pids
26
+ Deprecation.warn(QueryResult,
27
+ "`pids` is deprecated; use `ids` instead." \
28
+ " (called from #{caller.first})"
29
+ )
30
+ ids
31
+ end
32
+
33
+ def ids
34
+ Enumerator.new do |e|
35
+ each do |doc|
36
+ e << doc[Fields::ID]
37
+ end
38
+ end
39
+ end
40
+
41
+ def each_pid(&block)
42
+ Deprecation.warn(QueryResult,
43
+ "`each_pid` is deprecated; use `each_id` instead." \
44
+ " (called from #{caller.first})"
45
+ )
46
+ each_id(&block)
47
+ end
48
+
49
+ def each_id(&block)
50
+ ids.each(&block)
51
+ end
52
+
53
+ def docs
54
+ Enumerator.new do |e|
55
+ each do |doc|
56
+ e << DocumentBuilder.build(doc)
57
+ end
58
+ end
59
+ end
60
+
61
+ def objects
62
+ Enumerator.new do |e|
63
+ each_id do |id|
64
+ e << ActiveFedora::Base.find(id)
65
+ end
66
+ end
67
+ end
68
+
69
+ def facet_fields
70
+ response = Connection.select(params, rows: 0)
71
+ response.facet_fields.each_with_object({}) do |(field, values), memo|
72
+ memo[field] = Hash[*values]
73
+ end
74
+ end
75
+
76
+ def all
77
+ to_a
78
+ end
79
+
80
+ def pages
81
+ num = 1
82
+ Enumerator.new do |e|
83
+ loop do
84
+ pg = page(num)
85
+ e << pg
86
+ unless pg.has_next?
87
+ break
88
+ end
89
+ num += 1
90
+ end
91
+ end
92
+ end
93
+
94
+ def page(num)
95
+ page_params = params.dup
96
+ page_size = page_params.delete(:rows) || PAGE_SIZE
97
+ response = Connection.page(num, page_size, "select", params: page_params)
98
+ response.docs
99
+ end
100
+
101
+ end
102
+ end