ddr-models 2.4.12 → 2.4.13
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.
- checksums.yaml +4 -4
- data/ddr-models.gemspec +1 -1
- data/lib/ddr/index.rb +0 -3
- data/lib/ddr/index/abstract_query_result.rb +2 -3
- data/lib/ddr/index/connection.rb +28 -9
- data/lib/ddr/index/csv_query_result.rb +31 -31
- data/lib/ddr/index/filter.rb +23 -10
- data/lib/ddr/index/query.rb +31 -5
- data/lib/ddr/index/query_builder.rb +14 -23
- data/lib/ddr/index/query_clause.rb +16 -1
- data/lib/ddr/index/query_result.rb +36 -4
- data/lib/ddr/index/response.rb +19 -2
- data/lib/ddr/models/solr_document.rb +1 -2
- data/lib/ddr/models/version.rb +1 -1
- data/spec/index/csv_query_result_spec.rb +44 -0
- data/spec/index/filter_spec.rb +53 -0
- data/spec/index/query_builder_spec.rb +25 -1
- data/spec/index/query_clause_spec.rb +10 -0
- data/spec/index/query_spec.rb +66 -23
- metadata +12 -7
- data/lib/ddr/index/csv_options.rb +0 -14
- data/lib/ddr/index/filters.rb +0 -26
- data/lib/ddr/index/solr_csv_options.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7e305b209128c60e1cf1a0231c117686f834f491
|
4
|
+
data.tar.gz: c4fa26a45ebf460c892c9e5770dc2b10f2a326db
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ddd8c567e7ec34286dc13eba223a0dedb0b0db7773196b8cecbfa179c4e1c8cc44e6794692fd50deabf9afc37e116e6a35068b2b3fc6b13d525d6425c4201b76
|
7
|
+
data.tar.gz: a8139759bcd54585aa374f987598a8cdbfc27fabacb914ea841c980e271e384b1273ddd08d40c12f7724e3d836881435f9e09e40214dee42004f9a1ceff60c9d
|
data/ddr-models.gemspec
CHANGED
@@ -33,7 +33,7 @@ Gem::Specification.new do |s|
|
|
33
33
|
s.add_dependency "cancancan", "~> 1.12"
|
34
34
|
s.add_dependency "ddr-antivirus", "~> 2.1.1"
|
35
35
|
s.add_dependency "virtus", "~> 1.0.5"
|
36
|
-
s.add_dependency "hashie", "~> 3.4.
|
36
|
+
s.add_dependency "hashie", "~> 3.4", "< 3.4.4"
|
37
37
|
|
38
38
|
s.add_development_dependency "bundler", "~> 1.11"
|
39
39
|
s.add_development_dependency "rake"
|
data/lib/ddr/index.rb
CHANGED
@@ -4,14 +4,12 @@ module Ddr
|
|
4
4
|
|
5
5
|
autoload :AbstractQueryResult
|
6
6
|
autoload :Connection
|
7
|
-
autoload :CSVOptions
|
8
7
|
autoload :CSVQueryResult
|
9
8
|
autoload :DocumentBuilder
|
10
9
|
autoload :Field
|
11
10
|
autoload :FieldAttribute
|
12
11
|
autoload :Fields
|
13
12
|
autoload :Filter
|
14
|
-
autoload :Filters
|
15
13
|
autoload :LegacyLicenseFields
|
16
14
|
autoload :Query
|
17
15
|
autoload :QueryBuilder
|
@@ -19,7 +17,6 @@ module Ddr
|
|
19
17
|
autoload :QueryParams
|
20
18
|
autoload :QueryResult
|
21
19
|
autoload :Response
|
22
|
-
autoload :SolrCSVOptions
|
23
20
|
autoload :SortOrder
|
24
21
|
autoload :UniqueKeyField
|
25
22
|
|
@@ -2,16 +2,15 @@ module Ddr::Index
|
|
2
2
|
class AbstractQueryResult
|
3
3
|
include Enumerable
|
4
4
|
|
5
|
-
attr_reader :query
|
5
|
+
attr_reader :query
|
6
6
|
delegate :params, to: :query
|
7
7
|
|
8
8
|
def initialize(query)
|
9
9
|
@query = query.dup.freeze
|
10
|
-
@conn = Connection.new
|
11
10
|
end
|
12
11
|
|
13
12
|
def count
|
14
|
-
response =
|
13
|
+
response = Connection.select(params, rows: 0)
|
15
14
|
response.num_found
|
16
15
|
end
|
17
16
|
|
data/lib/ddr/index/connection.rb
CHANGED
@@ -1,17 +1,36 @@
|
|
1
|
+
require "rsolr"
|
2
|
+
require "forwardable"
|
3
|
+
|
1
4
|
module Ddr::Index
|
2
|
-
|
5
|
+
#
|
6
|
+
# Wraps an RSolr connection
|
7
|
+
#
|
8
|
+
class Connection
|
3
9
|
|
4
|
-
|
5
|
-
|
6
|
-
end
|
10
|
+
module Methods
|
11
|
+
extend Forwardable
|
7
12
|
|
8
|
-
|
9
|
-
|
10
|
-
|
13
|
+
delegate [:get, :paginate] => :solr
|
14
|
+
|
15
|
+
def solr
|
16
|
+
RSolr.connect(ActiveFedora.solr_config)
|
17
|
+
end
|
11
18
|
|
12
|
-
|
13
|
-
|
19
|
+
def select(params, extra={})
|
20
|
+
Response.new get("select", params: params.merge(extra))
|
21
|
+
end
|
22
|
+
|
23
|
+
def page(*args)
|
24
|
+
Response.new paginate(*args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def count(params)
|
28
|
+
select(params, rows: 0).num_found
|
29
|
+
end
|
14
30
|
end
|
15
31
|
|
32
|
+
extend Methods
|
33
|
+
include Methods
|
34
|
+
|
16
35
|
end
|
17
36
|
end
|
@@ -3,65 +3,65 @@ require "csv"
|
|
3
3
|
module Ddr::Index
|
4
4
|
class CSVQueryResult < AbstractQueryResult
|
5
5
|
|
6
|
-
MAX_ROWS
|
7
|
-
|
6
|
+
MAX_ROWS = 10**8 # Just set to a really high number :)
|
7
|
+
CSV_MV_SEPARATOR = ";"
|
8
8
|
|
9
|
-
|
9
|
+
delegate :headers, :to_s, :to_csv, to: :table
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
def initialize(query, mv_sep: MV_SEP)
|
14
|
-
super(query)
|
15
|
-
@mv_sep = mv_sep
|
11
|
+
def delete_empty_columns!
|
12
|
+
table.by_col!.delete_if { |c, vals| vals.all?(&:nil?) }
|
16
13
|
end
|
17
14
|
|
18
|
-
def
|
19
|
-
|
15
|
+
def each(&block)
|
16
|
+
table.by_row!.each(&block)
|
20
17
|
end
|
21
18
|
|
22
|
-
def
|
23
|
-
|
19
|
+
def [](index_or_header)
|
20
|
+
table.by_col_or_row![index_or_header]
|
24
21
|
end
|
25
22
|
|
26
|
-
def
|
27
|
-
|
23
|
+
def table
|
24
|
+
@table ||= CSV.parse(data, csv_opts)
|
28
25
|
end
|
29
26
|
|
30
27
|
def csv_opts
|
31
|
-
|
28
|
+
{ headers: csv_headers,
|
29
|
+
return_headers: false,
|
30
|
+
write_headers: true,
|
31
|
+
}
|
32
32
|
end
|
33
33
|
|
34
34
|
def solr_csv_opts
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
35
|
+
{ "csv.mv.separator" => CSV_MV_SEPARATOR,
|
36
|
+
"csv.header" => solr_csv_header?,
|
37
|
+
"rows" => solr_csv_rows,
|
38
|
+
"wt" => "csv",
|
39
|
+
}
|
40
40
|
end
|
41
41
|
|
42
|
-
def
|
43
|
-
|
42
|
+
def query_field_headings
|
43
|
+
query.fields.map { |f| f.respond_to?(:heading) ? f.heading : f.to_s }
|
44
44
|
end
|
45
45
|
|
46
46
|
def csv_headers
|
47
|
-
|
48
|
-
:first_row
|
49
|
-
else
|
50
|
-
headers
|
51
|
-
end
|
47
|
+
query.fields.empty? ? :first_row : query_field_headings
|
52
48
|
end
|
53
49
|
|
54
|
-
def solr_csv_header
|
50
|
+
def solr_csv_header?
|
55
51
|
csv_headers == :first_row
|
56
52
|
end
|
57
53
|
|
54
|
+
def solr_csv_rows
|
55
|
+
query.rows || MAX_ROWS
|
56
|
+
end
|
57
|
+
|
58
58
|
def solr_csv_params
|
59
|
-
params.merge
|
59
|
+
params.merge(solr_csv_opts)
|
60
60
|
end
|
61
61
|
|
62
62
|
def data
|
63
|
-
raw =
|
64
|
-
raw.gsub(/\\#{
|
63
|
+
raw = Connection.get("select", params: solr_csv_params)
|
64
|
+
raw.gsub(/\\#{CSV_MV_SEPARATOR}/, CSV_MV_SEPARATOR)
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
data/lib/ddr/index/filter.rb
CHANGED
@@ -57,6 +57,16 @@ module Ddr::Index
|
|
57
57
|
self.clauses << QueryClause.before_days(field, value)
|
58
58
|
self
|
59
59
|
end
|
60
|
+
|
61
|
+
def join(**args)
|
62
|
+
self.clauses << QueryClause.join(**args)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
def regexp(field, value)
|
67
|
+
self.clauses << QueryClause.regexp(field, value)
|
68
|
+
self
|
69
|
+
end
|
60
70
|
end
|
61
71
|
|
62
72
|
module ClassMethods
|
@@ -68,16 +78,16 @@ module Ddr::Index
|
|
68
78
|
model "Component", "Attachment", "Target"
|
69
79
|
end
|
70
80
|
|
71
|
-
def is_governed_by(
|
72
|
-
term is_governed_by:
|
81
|
+
def is_governed_by(arg)
|
82
|
+
term is_governed_by: get_uri(arg)
|
73
83
|
end
|
74
84
|
|
75
|
-
def is_member_of_collection(
|
76
|
-
term is_member_of_collection:
|
85
|
+
def is_member_of_collection(arg)
|
86
|
+
term is_member_of_collection: get_uri(arg)
|
77
87
|
end
|
78
88
|
|
79
|
-
def is_part_of(
|
80
|
-
term is_part_of:
|
89
|
+
def is_part_of(arg)
|
90
|
+
term is_part_of: get_uri(arg)
|
81
91
|
end
|
82
92
|
|
83
93
|
def model(*models)
|
@@ -86,11 +96,14 @@ module Ddr::Index
|
|
86
96
|
|
87
97
|
private
|
88
98
|
|
89
|
-
def
|
90
|
-
|
91
|
-
|
99
|
+
def get_uri(arg)
|
100
|
+
case arg
|
101
|
+
when ActiveFedora::Base
|
102
|
+
arg.internal_uri
|
103
|
+
when String
|
104
|
+
arg.start_with?("info:fedora/") ? arg : "info:fedora/#{arg}"
|
92
105
|
else
|
93
|
-
ActiveFedora::Base.
|
106
|
+
raise TypeError, "Argument must be a String or ActiveFedora::Base instance: #{arg.class}"
|
94
107
|
end
|
95
108
|
end
|
96
109
|
|
data/lib/ddr/index/query.rb
CHANGED
@@ -5,6 +5,7 @@ module Ddr::Index
|
|
5
5
|
class Query
|
6
6
|
include Virtus.model
|
7
7
|
extend Forwardable
|
8
|
+
extend Deprecation
|
8
9
|
|
9
10
|
attribute :q, String
|
10
11
|
attribute :fields, Array[FieldAttribute], default: [ ]
|
@@ -12,9 +13,15 @@ module Ddr::Index
|
|
12
13
|
attribute :sort, Array[String], default: [ ]
|
13
14
|
attribute :rows, Integer
|
14
15
|
|
15
|
-
delegate [:count, :docs, :
|
16
|
+
delegate [:count, :docs, :ids, :each_id, :all] => :result
|
16
17
|
delegate :params => :query_params
|
17
18
|
|
19
|
+
def self.build(*args, &block)
|
20
|
+
new.tap do |query|
|
21
|
+
query.build(*args, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
18
25
|
def initialize(**args, &block)
|
19
26
|
super(**args)
|
20
27
|
if block_given?
|
@@ -31,12 +38,22 @@ module Ddr::Index
|
|
31
38
|
URI.encode_www_form(params)
|
32
39
|
end
|
33
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
|
+
|
34
51
|
def result
|
35
52
|
QueryResult.new(self)
|
36
53
|
end
|
37
54
|
|
38
|
-
def csv
|
39
|
-
CSVQueryResult.new(self
|
55
|
+
def csv
|
56
|
+
CSVQueryResult.new(self)
|
40
57
|
end
|
41
58
|
|
42
59
|
def filter_clauses
|
@@ -47,10 +64,19 @@ module Ddr::Index
|
|
47
64
|
QueryParams.new(self)
|
48
65
|
end
|
49
66
|
|
50
|
-
def build(&block)
|
51
|
-
QueryBuilder.new(self, &block)
|
67
|
+
def build(*args, &block)
|
68
|
+
QueryBuilder.new(self, *args, &block)
|
52
69
|
self
|
53
70
|
end
|
54
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
|
+
|
55
81
|
end
|
56
82
|
end
|
@@ -28,9 +28,6 @@ module Ddr::Index
|
|
28
28
|
#
|
29
29
|
# See also: asc, order_by
|
30
30
|
#
|
31
|
-
# id [doc_id]
|
32
|
-
# For selecting a single document by ID.
|
33
|
-
#
|
34
31
|
# filter [filter1], ...
|
35
32
|
# Adds filters to the query.
|
36
33
|
#
|
@@ -48,6 +45,12 @@ module Ddr::Index
|
|
48
45
|
# fields [field], ...
|
49
46
|
# Alias for: field
|
50
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
|
+
#
|
51
54
|
# limit [int]
|
52
55
|
# Limits the number of documents returned by the query.
|
53
56
|
#
|
@@ -74,6 +77,11 @@ module Ddr::Index
|
|
74
77
|
# raw [clause1], ...
|
75
78
|
# Adds a filter of "raw" query clauses (i.e., pre-constructed).
|
76
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
|
+
#
|
77
85
|
# rows [int]
|
78
86
|
# Alias for: limit
|
79
87
|
#
|
@@ -91,24 +99,12 @@ module Ddr::Index
|
|
91
99
|
#
|
92
100
|
class QueryBuilder
|
93
101
|
|
94
|
-
# Builds a Query object
|
95
|
-
# @yield [builder] a new QueryBuilder instance.
|
96
|
-
# @return [Query]
|
97
|
-
def self.build
|
98
|
-
Deprecation.warn(self,
|
99
|
-
"`Ddr::Index::QueryBuilder.build` is deprecated and will be removed in ddr-models 3.0." \
|
100
|
-
" Use `Ddr::Index::QueryBuilder.new` instead.")
|
101
|
-
builder = new
|
102
|
-
yield builder
|
103
|
-
builder.query
|
104
|
-
end
|
105
|
-
|
106
102
|
attr_reader :query
|
107
103
|
|
108
|
-
def initialize(
|
109
|
-
@query =
|
104
|
+
def initialize(*args, &block)
|
105
|
+
@query = args.first.is_a?(Query) ? args.shift : Query.new
|
110
106
|
if block_given?
|
111
|
-
|
107
|
+
instance_exec(*args, &block)
|
112
108
|
end
|
113
109
|
end
|
114
110
|
|
@@ -146,11 +142,6 @@ module Ddr::Index
|
|
146
142
|
# @param orderings [Hash<Field, String>]
|
147
143
|
# @return [QueryBuilder] self
|
148
144
|
def order_by(*orderings)
|
149
|
-
unless orderings.first.is_a? Hash
|
150
|
-
Deprecation.warn(QueryBuilder, "`order_by` will require a hash of orderings in ddr-models 3.0.")
|
151
|
-
field, order = orderings
|
152
|
-
return order_by(field => order)
|
153
|
-
end
|
154
145
|
query.sort += orderings.first.map { |field, order| SortOrder.new(field: field, order: order) }
|
155
146
|
self
|
156
147
|
end
|
@@ -12,6 +12,7 @@ module Ddr::Index
|
|
12
12
|
STANDARD_QUERY = "%{field}:%{value}"
|
13
13
|
NEGATIVE_QUERY = "-%{field}:%{value}"
|
14
14
|
DISJUNCTION = "{!lucene q.op=OR df=%{field}}%{value}"
|
15
|
+
REGEXP_QUERY = "%{field}:/%{value}/"
|
15
16
|
|
16
17
|
values do
|
17
18
|
attribute :field, FieldAttribute
|
@@ -29,7 +30,6 @@ module Ddr::Index
|
|
29
30
|
end
|
30
31
|
|
31
32
|
class << self
|
32
|
-
|
33
33
|
def quote(value)
|
34
34
|
# Derived from Blacklight::Solr::SearchBuilderBehavior#solr_param_quote
|
35
35
|
unless value =~ /\A[a-zA-Z0-9$_\-\^]+\z/
|
@@ -75,6 +75,16 @@ module Ddr::Index
|
|
75
75
|
new(field: field, value: value, template: DISJUNCTION)
|
76
76
|
end
|
77
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
|
+
|
78
88
|
# Builds a query clause to filter where date field value is earlier than a date/time value.
|
79
89
|
def before(field, value)
|
80
90
|
new(field: field, value: "[* TO %s]" % Ddr::Utils.solr_date(value))
|
@@ -91,6 +101,11 @@ module Ddr::Index
|
|
91
101
|
new(field: field, value: value, template: TERM_QUERY)
|
92
102
|
end
|
93
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
|
94
109
|
end
|
95
110
|
|
96
111
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
module Ddr::Index
|
2
2
|
class QueryResult < AbstractQueryResult
|
3
|
+
extend Deprecation
|
3
4
|
|
4
5
|
PAGE_SIZE = 1000
|
5
6
|
|
@@ -14,7 +15,7 @@ module Ddr::Index
|
|
14
15
|
end
|
15
16
|
|
16
17
|
def each_unpaginated(&block)
|
17
|
-
|
18
|
+
Connection.select(params).docs.each(&block)
|
18
19
|
end
|
19
20
|
|
20
21
|
def each_paginated(&block)
|
@@ -22,15 +23,31 @@ module Ddr::Index
|
|
22
23
|
end
|
23
24
|
|
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
|
25
34
|
Enumerator.new do |e|
|
26
35
|
each do |doc|
|
27
|
-
e << doc[Fields::
|
36
|
+
e << doc[Fields::ID]
|
28
37
|
end
|
29
38
|
end
|
30
39
|
end
|
31
40
|
|
32
41
|
def each_pid(&block)
|
33
|
-
|
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)
|
34
51
|
end
|
35
52
|
|
36
53
|
def docs
|
@@ -41,6 +58,21 @@ module Ddr::Index
|
|
41
58
|
end
|
42
59
|
end
|
43
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
|
+
|
44
76
|
def all
|
45
77
|
to_a
|
46
78
|
end
|
@@ -62,7 +94,7 @@ module Ddr::Index
|
|
62
94
|
def page(num)
|
63
95
|
page_params = params.dup
|
64
96
|
page_size = page_params.delete(:rows) || PAGE_SIZE
|
65
|
-
response =
|
97
|
+
response = Connection.page(num, page_size, "select", params: page_params)
|
66
98
|
response.docs
|
67
99
|
end
|
68
100
|
|
data/lib/ddr/index/response.rb
CHANGED
@@ -1,12 +1,29 @@
|
|
1
|
+
require "delegate"
|
2
|
+
|
1
3
|
module Ddr::Index
|
4
|
+
#
|
5
|
+
# Wraps an index query response
|
6
|
+
#
|
2
7
|
class Response < SimpleDelegator
|
3
8
|
|
4
9
|
def docs
|
5
|
-
|
10
|
+
response["docs"]
|
6
11
|
end
|
7
12
|
|
8
13
|
def num_found
|
9
|
-
|
14
|
+
response["numFound"].to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
def facet_counts
|
18
|
+
self["facet_counts"] || {}
|
19
|
+
end
|
20
|
+
|
21
|
+
def facet_fields
|
22
|
+
facet_counts["facet_fields"] || {}
|
23
|
+
end
|
24
|
+
|
25
|
+
def response
|
26
|
+
self["response"]
|
10
27
|
end
|
11
28
|
|
12
29
|
end
|
@@ -12,8 +12,7 @@ module Ddr::Models
|
|
12
12
|
|
13
13
|
module ClassMethods
|
14
14
|
def find(pid_or_uri)
|
15
|
-
|
16
|
-
query = Ddr::Index::QueryBuilder.build { |q| q.id(pid) }
|
15
|
+
query = Ddr::Index::Query.new { id pid_or_uri.sub(/\Ainfo:fedora\//, "") }
|
17
16
|
if doc = query.docs.first
|
18
17
|
return doc
|
19
18
|
end
|
data/lib/ddr/models/version.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
module Ddr::Index
|
2
|
+
RSpec.describe CSVQueryResult do
|
3
|
+
|
4
|
+
subject { described_class.new(query) }
|
5
|
+
|
6
|
+
before do
|
7
|
+
Item.create(title: ["Testing 1"],
|
8
|
+
identifier: ["test1"],
|
9
|
+
description: ["The process of eliminating errors."])
|
10
|
+
Item.create(title: ["Testing 2"],
|
11
|
+
identifier: ["test2"])
|
12
|
+
Item.create(title: ["Testing 3"])
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:query) {
|
16
|
+
Ddr::Index::Query.new do
|
17
|
+
fields Ddr::Index::Fields::ID
|
18
|
+
fields Ddr::Index::Fields.descmd
|
19
|
+
end
|
20
|
+
}
|
21
|
+
|
22
|
+
specify {
|
23
|
+
expect(subject["title"]).to contain_exactly("Testing 1", "Testing 2", "Testing 3")
|
24
|
+
expect(subject["identifier"]).to contain_exactly("test1", "test2", nil)
|
25
|
+
expect(subject["description"]).to contain_exactly("The process of eliminating errors.", nil, nil)
|
26
|
+
expect(subject["creator"]).to contain_exactly(nil, nil, nil)
|
27
|
+
expect(subject.headers).to include("creator")
|
28
|
+
expect(subject.to_s).to match(/creator/)
|
29
|
+
}
|
30
|
+
|
31
|
+
describe "#delete_empty_columns!" do
|
32
|
+
specify {
|
33
|
+
subject.delete_empty_columns!
|
34
|
+
expect(subject["title"]).to contain_exactly("Testing 1", "Testing 2", "Testing 3")
|
35
|
+
expect(subject["identifier"]).to contain_exactly("test1", "test2", nil)
|
36
|
+
expect(subject["description"]).to contain_exactly("The process of eliminating errors.", nil, nil)
|
37
|
+
expect(subject["creator"]).to contain_exactly(nil, nil, nil)
|
38
|
+
expect(subject.headers).to contain_exactly("pid", "title", "identifier", "description")
|
39
|
+
expect(subject.to_s).not_to match(/creator/)
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
data/spec/index/filter_spec.rb
CHANGED
@@ -37,6 +37,12 @@ module Ddr::Index
|
|
37
37
|
are_expected.to eq([QueryClause.term(:is_governed_by, "info:fedora/test:1")])
|
38
38
|
}
|
39
39
|
end
|
40
|
+
describe "with a URI" do
|
41
|
+
subject { described_class.is_governed_by("info:fedora/test:1") }
|
42
|
+
its(:clauses) {
|
43
|
+
are_expected.to eq([QueryClause.term(:is_governed_by, "info:fedora/test:1")])
|
44
|
+
}
|
45
|
+
end
|
40
46
|
end
|
41
47
|
describe ".is_member_of_collection" do
|
42
48
|
describe "with an object" do
|
@@ -51,6 +57,32 @@ module Ddr::Index
|
|
51
57
|
are_expected.to eq([QueryClause.term(:is_member_of_collection, "info:fedora/test:1")])
|
52
58
|
}
|
53
59
|
end
|
60
|
+
describe "with a URI" do
|
61
|
+
subject { described_class.is_member_of_collection("info:fedora/test:1") }
|
62
|
+
its(:clauses) {
|
63
|
+
are_expected.to eq([QueryClause.term(:is_member_of_collection, "info:fedora/test:1")])
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
describe ".is_part_of" do
|
68
|
+
describe "with an object" do
|
69
|
+
subject { described_class.is_part_of(Item.new(pid: "test:1")) }
|
70
|
+
its(:clauses) {
|
71
|
+
are_expected.to eq([QueryClause.term(:is_part_of, "info:fedora/test:1")])
|
72
|
+
}
|
73
|
+
end
|
74
|
+
describe "with an ID" do
|
75
|
+
subject { described_class.is_part_of("test:1") }
|
76
|
+
its(:clauses) {
|
77
|
+
are_expected.to eq([QueryClause.term(:is_part_of, "info:fedora/test:1")])
|
78
|
+
}
|
79
|
+
end
|
80
|
+
describe "with a URI" do
|
81
|
+
subject { described_class.is_part_of("info:fedora/test:1") }
|
82
|
+
its(:clauses) {
|
83
|
+
are_expected.to eq([QueryClause.term(:is_part_of, "info:fedora/test:1")])
|
84
|
+
}
|
85
|
+
end
|
54
86
|
end
|
55
87
|
describe ".has_content" do
|
56
88
|
subject { described_class.has_content }
|
@@ -107,6 +139,20 @@ module Ddr::Index
|
|
107
139
|
are_expected.to eq([QueryClause.before("foo", DateTime.parse("Thu, 27 Aug 2015 17:42:34 -0400"))])
|
108
140
|
}
|
109
141
|
end
|
142
|
+
describe ".join" do
|
143
|
+
subject {
|
144
|
+
described_class.join(from: :id, to: :collection_uri, where: {admin_set: "dvs"})
|
145
|
+
}
|
146
|
+
its(:clauses) {
|
147
|
+
are_expected.to eq([QueryClause.join(from: :id, to: :collection_uri, where: {admin_set: "dvs"})])
|
148
|
+
}
|
149
|
+
end
|
150
|
+
describe ".regexp" do
|
151
|
+
subject { described_class.regexp("foo", "foo/bar.*") }
|
152
|
+
its(:clauses) {
|
153
|
+
are_expected.to eq([QueryClause.regexp("foo", "foo/bar.*")])
|
154
|
+
}
|
155
|
+
end
|
110
156
|
end
|
111
157
|
|
112
158
|
describe "API methods" do
|
@@ -166,6 +212,13 @@ module Ddr::Index
|
|
166
212
|
expect(subject.clauses).to eq([QueryClause.before("foo", DateTime.parse("Thu, 27 Aug 2015 17:42:34 -0400"))])
|
167
213
|
end
|
168
214
|
end
|
215
|
+
describe "#join" do
|
216
|
+
it "adds a join query clause" do
|
217
|
+
subject.join(from: :id, to: :collection_uri, where: {admin_set: "dvs"})
|
218
|
+
expect(subject.clauses).to eq([QueryClause.join(from: :id, to: :collection_uri, where: {admin_set: "dvs"})])
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
169
222
|
end
|
170
223
|
|
171
224
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Ddr::Index
|
2
2
|
RSpec.describe QueryBuilder do
|
3
|
-
|
4
3
|
describe "DSL" do
|
5
4
|
describe "id" do
|
6
5
|
subject { described_class.new { id "test:1" } }
|
@@ -95,6 +94,22 @@ module Ddr::Index
|
|
95
94
|
subject { described_class.new { before_days "foo", 7 } }
|
96
95
|
specify { expect(subject.query.filters).to eq [Filter.before_days("foo", 7)] }
|
97
96
|
end
|
97
|
+
describe "join" do
|
98
|
+
subject {
|
99
|
+
described_class.new do
|
100
|
+
join from: :id, to: :collection_uri, where: {admin_set: "dvs"}
|
101
|
+
end
|
102
|
+
}
|
103
|
+
specify {
|
104
|
+
expect(subject.query.filters).to eq [Filter.join(from: :id, to: :collection_uri, where: {admin_set: "dvs"})]
|
105
|
+
}
|
106
|
+
end
|
107
|
+
describe "regexp" do
|
108
|
+
subject { described_class.new { regexp "foo", "foo/bar.*" } }
|
109
|
+
specify {
|
110
|
+
expect(subject.query.filters).to eq [Filter.regexp("foo", "foo/bar.*")]
|
111
|
+
}
|
112
|
+
end
|
98
113
|
end
|
99
114
|
|
100
115
|
describe "using static filters" do
|
@@ -112,5 +127,14 @@ module Ddr::Index
|
|
112
127
|
end
|
113
128
|
end
|
114
129
|
|
130
|
+
describe "passing local vars" do
|
131
|
+
let(:local_var) { double(bar: "bar") }
|
132
|
+
subject {
|
133
|
+
described_class.new(local_var) { |foo| asc foo.bar }
|
134
|
+
}
|
135
|
+
specify {
|
136
|
+
expect(subject.query.sort).to eq [SortOrder.asc("bar")]
|
137
|
+
}
|
138
|
+
end
|
115
139
|
end
|
116
140
|
end
|
@@ -52,6 +52,16 @@ module Ddr::Index
|
|
52
52
|
its(:to_s) { is_expected.to eq "{!lucene q.op=OR df=foo}\"Jungle Fever\" bar" }
|
53
53
|
end
|
54
54
|
end
|
55
|
+
describe ".join" do
|
56
|
+
subject {
|
57
|
+
described_class.join(from: :id, to: :collection_uri, where: { admin_set: "dvs"})
|
58
|
+
}
|
59
|
+
its(:to_s) { is_expected.to eq "{!join from=id to=collection_uri_ssim}admin_set_ssi:dvs" }
|
60
|
+
end
|
61
|
+
describe ".regexp" do
|
62
|
+
subject { described_class.regexp("foo", "foo/bar.*") }
|
63
|
+
its(:to_s) { is_expected.to eq "foo:/foo\\/bar.*/" }
|
64
|
+
end
|
55
65
|
end
|
56
66
|
|
57
67
|
end
|
data/spec/index/query_spec.rb
CHANGED
@@ -1,20 +1,16 @@
|
|
1
1
|
module Ddr::Index
|
2
2
|
RSpec.describe Query do
|
3
|
-
|
4
|
-
|
5
|
-
let(:
|
6
|
-
let(:foo) { Field.new("foo") }
|
7
|
-
let(:spam) { Field.new("spam") }
|
8
|
-
let(:filter) { Filter.where(spam=>"eggs") }
|
9
|
-
let(:sort_order) { SortOrder.new(field: foo, order: "asc") }
|
10
|
-
let(:fields) { [id, foo, spam] }
|
11
|
-
|
3
|
+
describe ".build" do
|
4
|
+
let(:local1) { double(value: "foo:bar") }
|
5
|
+
let(:local2) { double(value: "foo") }
|
12
6
|
subject {
|
13
|
-
described_class.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
described_class.build(local1, local2) do |l1, l2|
|
8
|
+
q l1.value
|
9
|
+
where "spam"=>"eggs"
|
10
|
+
fields :id, "foo", "spam"
|
11
|
+
asc l2.value
|
12
|
+
limit 50
|
13
|
+
end
|
18
14
|
}
|
19
15
|
|
20
16
|
its(:to_s) {
|
@@ -25,7 +21,52 @@ module Ddr::Index
|
|
25
21
|
}
|
26
22
|
end
|
27
23
|
|
28
|
-
describe "
|
24
|
+
describe "initialization" do
|
25
|
+
describe "with attributes" do
|
26
|
+
let(:id) { UniqueKeyField.instance }
|
27
|
+
let(:foo) { Field.new("foo") }
|
28
|
+
let(:spam) { Field.new("spam") }
|
29
|
+
let(:filter) { Filter.where(spam=>"eggs") }
|
30
|
+
let(:sort_order) { SortOrder.new(field: foo, order: "asc") }
|
31
|
+
let(:fields) { [id, foo, spam] }
|
32
|
+
|
33
|
+
subject {
|
34
|
+
described_class.new(q: "foo:bar",
|
35
|
+
filters: [filter],
|
36
|
+
fields: fields,
|
37
|
+
sort: sort_order,
|
38
|
+
rows: 50)
|
39
|
+
}
|
40
|
+
|
41
|
+
its(:to_s) {
|
42
|
+
is_expected.to eq "q=foo%3Abar&fq=spam%3Aeggs&fl=id%2Cfoo%2Cspam&sort=foo+asc&rows=50"
|
43
|
+
}
|
44
|
+
its(:params) {
|
45
|
+
is_expected.to eq({q: "foo:bar", fl: "id,foo,spam", fq: ["spam:eggs"], sort: "foo asc", rows: 50})
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "with a block" do
|
50
|
+
subject {
|
51
|
+
described_class.new do
|
52
|
+
q "foo:bar"
|
53
|
+
where "spam"=>"eggs"
|
54
|
+
fields :id, "foo", "spam"
|
55
|
+
asc "foo"
|
56
|
+
limit 50
|
57
|
+
end
|
58
|
+
}
|
59
|
+
|
60
|
+
its(:to_s) {
|
61
|
+
is_expected.to eq "q=foo%3Abar&fq=spam%3Aeggs&fl=id%2Cfoo%2Cspam&sort=foo+asc&rows=50"
|
62
|
+
}
|
63
|
+
its(:params) {
|
64
|
+
is_expected.to eq({q: "foo:bar", fl: "id,foo,spam", fq: ["spam:eggs"], sort: "foo asc", rows: 50})
|
65
|
+
}
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "equality" do
|
29
70
|
subject {
|
30
71
|
described_class.new do
|
31
72
|
q "foo:bar"
|
@@ -35,14 +76,16 @@ module Ddr::Index
|
|
35
76
|
limit 50
|
36
77
|
end
|
37
78
|
}
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
79
|
+
let(:other) do
|
80
|
+
described_class.new do
|
81
|
+
q "foo:bar"
|
82
|
+
where "spam"=>"eggs"
|
83
|
+
fields :id, "foo", "spam"
|
84
|
+
asc "foo"
|
85
|
+
limit 50
|
86
|
+
end
|
87
|
+
end
|
88
|
+
it { is_expected.to eq other }
|
45
89
|
end
|
46
|
-
|
47
90
|
end
|
48
91
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddr-models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.4.
|
4
|
+
version: 2.4.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jim Coble
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-09-
|
12
|
+
date: 2016-09-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -227,14 +227,20 @@ dependencies:
|
|
227
227
|
requirements:
|
228
228
|
- - "~>"
|
229
229
|
- !ruby/object:Gem::Version
|
230
|
-
version: 3.4
|
230
|
+
version: '3.4'
|
231
|
+
- - "<"
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: 3.4.4
|
231
234
|
type: :runtime
|
232
235
|
prerelease: false
|
233
236
|
version_requirements: !ruby/object:Gem::Requirement
|
234
237
|
requirements:
|
235
238
|
- - "~>"
|
236
239
|
- !ruby/object:Gem::Version
|
237
|
-
version: 3.4
|
240
|
+
version: '3.4'
|
241
|
+
- - "<"
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: 3.4.4
|
238
244
|
- !ruby/object:Gem::Dependency
|
239
245
|
name: bundler
|
240
246
|
requirement: !ruby/object:Gem::Requirement
|
@@ -473,14 +479,12 @@ files:
|
|
473
479
|
- lib/ddr/index.rb
|
474
480
|
- lib/ddr/index/abstract_query_result.rb
|
475
481
|
- lib/ddr/index/connection.rb
|
476
|
-
- lib/ddr/index/csv_options.rb
|
477
482
|
- lib/ddr/index/csv_query_result.rb
|
478
483
|
- lib/ddr/index/document_builder.rb
|
479
484
|
- lib/ddr/index/field.rb
|
480
485
|
- lib/ddr/index/field_attribute.rb
|
481
486
|
- lib/ddr/index/fields.rb
|
482
487
|
- lib/ddr/index/filter.rb
|
483
|
-
- lib/ddr/index/filters.rb
|
484
488
|
- lib/ddr/index/legacy_license_fields.rb
|
485
489
|
- lib/ddr/index/query.rb
|
486
490
|
- lib/ddr/index/query_builder.rb
|
@@ -488,7 +492,6 @@ files:
|
|
488
492
|
- lib/ddr/index/query_params.rb
|
489
493
|
- lib/ddr/index/query_result.rb
|
490
494
|
- lib/ddr/index/response.rb
|
491
|
-
- lib/ddr/index/solr_csv_options.rb
|
492
495
|
- lib/ddr/index/sort_order.rb
|
493
496
|
- lib/ddr/index/unique_key_field.rb
|
494
497
|
- lib/ddr/jobs.rb
|
@@ -647,6 +650,7 @@ files:
|
|
647
650
|
- spec/fixtures/sample.pdf
|
648
651
|
- spec/fixtures/target.png
|
649
652
|
- spec/helpers/models_helper_spec.rb
|
653
|
+
- spec/index/csv_query_result_spec.rb
|
650
654
|
- spec/index/fields_spec.rb
|
651
655
|
- spec/index/filter_spec.rb
|
652
656
|
- spec/index/query_builder_spec.rb
|
@@ -823,6 +827,7 @@ test_files:
|
|
823
827
|
- spec/fixtures/sample.pdf
|
824
828
|
- spec/fixtures/target.png
|
825
829
|
- spec/helpers/models_helper_spec.rb
|
830
|
+
- spec/index/csv_query_result_spec.rb
|
826
831
|
- spec/index/fields_spec.rb
|
827
832
|
- spec/index/filter_spec.rb
|
828
833
|
- spec/index/query_builder_spec.rb
|
@@ -1,14 +0,0 @@
|
|
1
|
-
require "csv"
|
2
|
-
require "hashie"
|
3
|
-
|
4
|
-
module Ddr::Index
|
5
|
-
class CSVOptions < Hashie::Dash
|
6
|
-
|
7
|
-
property :headers, default: CSV::DEFAULT_OPTIONS[:headers]
|
8
|
-
property :return_headers, default: true
|
9
|
-
property :write_headers, default: true
|
10
|
-
property :col_sep, default: CSV::DEFAULT_OPTIONS[:col_sep]
|
11
|
-
property :quote_char, default: CSV::DEFAULT_OPTIONS[:quote_char]
|
12
|
-
|
13
|
-
end
|
14
|
-
end
|
data/lib/ddr/index/filters.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
module Ddr::Index
|
2
|
-
module Filters
|
3
|
-
extend Deprecation
|
4
|
-
|
5
|
-
def self.is_governed_by(pid)
|
6
|
-
Deprecation.warn(self,
|
7
|
-
"`Ddr::Index:Filters.is_governed_by` is deprecated and will be removed in ddr-models 3.0." \
|
8
|
-
" Use `Ddr::Index::Filter.is_governed_by` instead.")
|
9
|
-
Filter.is_governed_by(pid)
|
10
|
-
end
|
11
|
-
|
12
|
-
private
|
13
|
-
|
14
|
-
def self.const_missing(name)
|
15
|
-
if name == :HAS_CONTENT
|
16
|
-
Deprecation.warn(self,
|
17
|
-
"`Ddr::Index::Filters::#{name}` is deprecated and will be removed in ddr-models 3.0." \
|
18
|
-
" Use `Ddr::Index::Filter.has_content` instead.")
|
19
|
-
Filter.has_content
|
20
|
-
else
|
21
|
-
super
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
end
|
26
|
-
end
|
@@ -1,18 +0,0 @@
|
|
1
|
-
require "hashie"
|
2
|
-
|
3
|
-
module Ddr::Index
|
4
|
-
class SolrCSVOptions < Hashie::Trash
|
5
|
-
|
6
|
-
property "csv.header", from: :header, default: false
|
7
|
-
property "csv.separator", from: :col_sep, default: ","
|
8
|
-
property "csv.encapsulator", from: :quote_char, default: '"'
|
9
|
-
property "csv.mv.separator", from: :mv_sep, default: ","
|
10
|
-
property :wt, default: "csv"
|
11
|
-
property :rows
|
12
|
-
|
13
|
-
def params
|
14
|
-
to_h.reject { |k, v| v.nil? }
|
15
|
-
end
|
16
|
-
|
17
|
-
end
|
18
|
-
end
|