ddr-core 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE.txt +12 -0
- data/README.md +27 -0
- data/Rakefile +30 -0
- data/app/assets/config/ddr_core_manifest.js +0 -0
- data/app/controllers/users/omniauth_callbacks_controller.rb +11 -0
- data/app/controllers/users/sessions_controller.rb +15 -0
- data/app/models/concerns/ddr/captionable.rb +25 -0
- data/app/models/concerns/ddr/describable.rb +108 -0
- data/app/models/concerns/ddr/governable.rb +25 -0
- data/app/models/concerns/ddr/has_admin_metadata.rb +141 -0
- data/app/models/concerns/ddr/has_attachments.rb +10 -0
- data/app/models/concerns/ddr/has_children.rb +10 -0
- data/app/models/concerns/ddr/has_content.rb +132 -0
- data/app/models/concerns/ddr/has_extracted_text.rb +10 -0
- data/app/models/concerns/ddr/has_intermediate_file.rb +25 -0
- data/app/models/concerns/ddr/has_multires_image.rb +14 -0
- data/app/models/concerns/ddr/has_parent.rb +18 -0
- data/app/models/concerns/ddr/has_struct_metadata.rb +21 -0
- data/app/models/concerns/ddr/has_thumbnail.rb +33 -0
- data/app/models/concerns/ddr/solr_document_behavior.rb +429 -0
- data/app/models/concerns/ddr/streamable.rb +25 -0
- data/app/models/ddr/admin_set.rb +28 -0
- data/app/models/ddr/attachment.rb +14 -0
- data/app/models/ddr/collection.rb +28 -0
- data/app/models/ddr/component.rb +31 -0
- data/app/models/ddr/contact.rb +23 -0
- data/app/models/ddr/digest.rb +8 -0
- data/app/models/ddr/file.rb +40 -0
- data/app/models/ddr/item.rb +36 -0
- data/app/models/ddr/language.rb +31 -0
- data/app/models/ddr/media_type.rb +22 -0
- data/app/models/ddr/resource.rb +94 -0
- data/app/models/ddr/rights_statement.rb +25 -0
- data/app/models/ddr/target.rb +17 -0
- data/config/initializers/devise.rb +262 -0
- data/config/locales/ddr-core.en.yml +85 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20141104181418_create_users.rb +34 -0
- data/db/migrate/20141107124012_add_columns_to_user.rb +46 -0
- data/lib/ddr-core.rb +1 -0
- data/lib/ddr/auth.rb +80 -0
- data/lib/ddr/auth/ability.rb +18 -0
- data/lib/ddr/auth/ability_definitions.rb +26 -0
- data/lib/ddr/auth/ability_definitions/admin_set_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_definitions/alias_ability_definitions.rb +23 -0
- data/lib/ddr/auth/ability_definitions/attachment_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/collection_ability_definitions.rb +28 -0
- data/lib/ddr/auth/ability_definitions/component_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/item_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/lock_ability_definitions.rb +13 -0
- data/lib/ddr/auth/ability_definitions/publication_ability_definitions.rb +16 -0
- data/lib/ddr/auth/ability_definitions/role_based_ability_definitions.rb +39 -0
- data/lib/ddr/auth/ability_definitions/superuser_ability_definitions.rb +9 -0
- data/lib/ddr/auth/ability_factory.rb +10 -0
- data/lib/ddr/auth/abstract_ability.rb +48 -0
- data/lib/ddr/auth/affiliation.rb +14 -0
- data/lib/ddr/auth/affiliation_groups.rb +20 -0
- data/lib/ddr/auth/anonymous_ability.rb +7 -0
- data/lib/ddr/auth/auth_context.rb +109 -0
- data/lib/ddr/auth/auth_context_factory.rb +13 -0
- data/lib/ddr/auth/detached_auth_context.rb +19 -0
- data/lib/ddr/auth/dynamic_groups.rb +13 -0
- data/lib/ddr/auth/effective_permissions.rb +12 -0
- data/lib/ddr/auth/effective_roles.rb +9 -0
- data/lib/ddr/auth/failure_app.rb +16 -0
- data/lib/ddr/auth/group.rb +40 -0
- data/lib/ddr/auth/grouper_gateway.rb +70 -0
- data/lib/ddr/auth/groups.rb +32 -0
- data/lib/ddr/auth/ldap_gateway.rb +74 -0
- data/lib/ddr/auth/permissions.rb +18 -0
- data/lib/ddr/auth/remote_groups.rb +14 -0
- data/lib/ddr/auth/role_based_access_controls_enforcement.rb +56 -0
- data/lib/ddr/auth/roles.rb +28 -0
- data/lib/ddr/auth/roles/role.rb +121 -0
- data/lib/ddr/auth/roles/role_type.rb +23 -0
- data/lib/ddr/auth/roles/role_types.rb +52 -0
- data/lib/ddr/auth/superuser_ability.rb +7 -0
- data/lib/ddr/auth/test_helpers.rb +22 -0
- data/lib/ddr/auth/user.rb +54 -0
- data/lib/ddr/auth/web_auth_context.rb +29 -0
- data/lib/ddr/core.rb +110 -0
- data/lib/ddr/core/engine.rb +8 -0
- data/lib/ddr/core/version.rb +5 -0
- data/lib/ddr/error.rb +16 -0
- data/lib/ddr/files.rb +13 -0
- data/lib/ddr/fits.rb +189 -0
- data/lib/ddr/index.rb +29 -0
- data/lib/ddr/index/abstract_query_result.rb +22 -0
- data/lib/ddr/index/connection.rb +38 -0
- data/lib/ddr/index/csv_query_result.rb +84 -0
- data/lib/ddr/index/document_builder.rb +9 -0
- data/lib/ddr/index/field.rb +35 -0
- data/lib/ddr/index/field_attribute.rb +22 -0
- data/lib/ddr/index/fields.rb +154 -0
- data/lib/ddr/index/filter.rb +139 -0
- data/lib/ddr/index/query.rb +82 -0
- data/lib/ddr/index/query_builder.rb +185 -0
- data/lib/ddr/index/query_clause.rb +112 -0
- data/lib/ddr/index/query_params.rb +40 -0
- data/lib/ddr/index/query_result.rb +102 -0
- data/lib/ddr/index/response.rb +30 -0
- data/lib/ddr/index/sort_order.rb +28 -0
- data/lib/ddr/index/unique_key_field.rb +12 -0
- data/lib/ddr/managers.rb +9 -0
- data/lib/ddr/managers/manager.rb +13 -0
- data/lib/ddr/managers/technical_metadata_manager.rb +141 -0
- data/lib/ddr/structure.rb +188 -0
- data/lib/ddr/structures/agent.rb +49 -0
- data/lib/ddr/structures/component_type_term.rb +29 -0
- data/lib/ddr/structures/div.rb +64 -0
- data/lib/ddr/structures/f_locat.rb +54 -0
- data/lib/ddr/structures/file.rb +52 -0
- data/lib/ddr/structures/file_grp.rb +35 -0
- data/lib/ddr/structures/file_sec.rb +22 -0
- data/lib/ddr/structures/fptr.rb +31 -0
- data/lib/ddr/structures/mets_hdr.rb +37 -0
- data/lib/ddr/structures/mptr.rb +49 -0
- data/lib/ddr/structures/struct_map.rb +40 -0
- data/lib/ddr/utils.rb +185 -0
- data/lib/ddr/vocab.rb +22 -0
- data/lib/ddr/vocab/asset.rb +51 -0
- data/lib/ddr/vocab/contact.rb +9 -0
- data/lib/ddr/vocab/display.rb +9 -0
- data/lib/ddr/vocab/duke_terms.rb +13 -0
- data/lib/ddr/vocab/rdf_vocabulary_parser.rb +43 -0
- data/lib/ddr/vocab/roles.rb +25 -0
- data/lib/ddr/vocab/sources/duketerms.rdf +870 -0
- data/lib/ddr/vocab/vocabulary.rb +37 -0
- data/lib/ddr/workflow.rb +8 -0
- data/lib/tasks/ddr/core_tasks.rake +4 -0
- 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
|