ddr-models 2.4.0.rc4 → 2.4.0.rc5
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/.travis.yml +4 -4
- data/ddr-models.gemspec +1 -1
- data/lib/ddr/index.rb +1 -2
- data/lib/ddr/index/field_attribute.rb +18 -0
- data/lib/ddr/index/filter.rb +70 -38
- data/lib/ddr/index/filters.rb +7 -20
- data/lib/ddr/index/query.rb +13 -8
- data/lib/ddr/index/query_builder.rb +122 -49
- data/lib/ddr/index/query_clause.rb +55 -41
- data/lib/ddr/index/query_params.rb +28 -12
- data/lib/ddr/index/sort_order.rb +11 -3
- data/lib/ddr/models/version.rb +1 -1
- data/spec/index/filter_spec.rb +74 -32
- data/spec/index/query_builder_spec.rb +45 -24
- data/spec/index/query_clause_spec.rb +29 -21
- data/spec/index/query_spec.rb +6 -3
- metadata +5 -12
- data/lib/ddr/index/queries.rb +0 -20
- data/lib/ddr/index/query_value.rb +0 -24
- data/spec/index/filters_spec.rb +0 -34
- data/spec/index/queries_spec.rb +0 -21
- data/spec/index/query_value_spec.rb +0 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a57bdb43e8f09d8bba57f543fa677e6f584d49e0
|
4
|
+
data.tar.gz: aaf3160fc9732099da710cff89d874701f2c9432
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbb52a96b1ea4168b8bc8a0d7cc813b425b3e407f9ce5a13d1a330a176c1684e039c3195182bf615f3199d13fc8465b3765dbc97c95bc6be47822feba9fbb7a1
|
7
|
+
data.tar.gz: d8f17c7f174c712105de7c53a6107fafb216fb6121655b9e439adeb886cf359f8c524edd06a7a9e2123e252ee0a05a2408fba4da5e2ee66762c3fc4561ce2bbc
|
data/.travis.yml
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
language: ruby
|
2
2
|
before_install:
|
3
|
+
- sudo apt-get update -qq
|
3
4
|
- sudo apt-get install libvips-dev
|
5
|
+
- gem install bundler
|
6
|
+
bundler_args: --without production
|
4
7
|
rvm:
|
5
|
-
- 2.1
|
8
|
+
- 2.1.5
|
6
9
|
script: "bundle exec rake ci"
|
7
|
-
cache:
|
8
|
-
- bundler
|
9
|
-
- apt
|
10
10
|
env:
|
11
11
|
- DDR_AUX_API_URL=http://localhost:3000/api
|
data/ddr-models.gemspec
CHANGED
@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.add_dependency "ddr-antivirus", "~> 2.1.1"
|
35
35
|
s.add_dependency "virtus", "~> 1.0.5"
|
36
36
|
|
37
|
-
s.add_development_dependency "bundler", "~> 1.
|
37
|
+
s.add_development_dependency "bundler", "~> 1.11"
|
38
38
|
s.add_development_dependency "rake"
|
39
39
|
s.add_development_dependency "sqlite3"
|
40
40
|
s.add_development_dependency "rspec-rails", "~> 3.1"
|
data/lib/ddr/index.rb
CHANGED
@@ -7,17 +7,16 @@ module Ddr
|
|
7
7
|
autoload :CSVQueryResult
|
8
8
|
autoload :DocumentBuilder
|
9
9
|
autoload :Field
|
10
|
+
autoload :FieldAttribute
|
10
11
|
autoload :Fields
|
11
12
|
autoload :Filter
|
12
13
|
autoload :Filters
|
13
14
|
autoload :LegacyLicenseFields
|
14
|
-
autoload :Queries
|
15
15
|
autoload :Query
|
16
16
|
autoload :QueryBuilder
|
17
17
|
autoload :QueryClause
|
18
18
|
autoload :QueryParams
|
19
19
|
autoload :QueryResult
|
20
|
-
autoload :QueryValue
|
21
20
|
autoload :Response
|
22
21
|
autoload :SortOrder
|
23
22
|
autoload :UniqueKeyField
|
data/lib/ddr/index/filter.rb
CHANGED
@@ -1,61 +1,93 @@
|
|
1
1
|
require "forwardable"
|
2
|
+
require "virtus"
|
2
3
|
|
3
4
|
module Ddr::Index
|
4
5
|
class Filter
|
6
|
+
include Virtus.model
|
5
7
|
|
6
|
-
|
7
|
-
extend Forwardable
|
8
|
+
attribute :clauses, Array, default: [ ]
|
8
9
|
|
9
|
-
|
10
|
+
def ==(other)
|
11
|
+
other.instance_of?(self.class) && (other.clauses == self.clauses)
|
10
12
|
end
|
11
13
|
|
12
|
-
|
14
|
+
module Api
|
15
|
+
def raw(*clauses)
|
16
|
+
self.clauses += clauses
|
17
|
+
self
|
18
|
+
end
|
13
19
|
|
14
|
-
|
15
|
-
|
16
|
-
|
20
|
+
def term(conditions)
|
21
|
+
self.clauses += conditions.map { |f, v| QueryClause.term(f, v) }
|
22
|
+
self
|
23
|
+
end
|
17
24
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
25
|
+
def where(conditions)
|
26
|
+
self.clauses += conditions.map { |f, v| QueryClause.where(f, v) }
|
27
|
+
self
|
28
|
+
end
|
23
29
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
if values.size > 1
|
28
|
-
QueryClause.or_values(field, values)
|
29
|
-
else
|
30
|
-
QueryClause.term(field, values.first)
|
31
|
-
end
|
30
|
+
def absent(field)
|
31
|
+
self.clauses << QueryClause.absent(field)
|
32
|
+
self
|
32
33
|
end
|
33
|
-
raw *clauses
|
34
|
-
end
|
35
34
|
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
def present(field)
|
36
|
+
self.clauses << QueryClause.present(field)
|
37
|
+
self
|
38
|
+
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
|
40
|
+
def negative(field, value)
|
41
|
+
self.clauses << QueryClause.negative(field, value)
|
42
|
+
self
|
43
|
+
end
|
43
44
|
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def before(field, value)
|
46
|
+
self.clauses << QueryClause.before(field, value)
|
47
|
+
self
|
48
|
+
end
|
47
49
|
|
48
|
-
|
49
|
-
|
50
|
+
def before_days(field, value)
|
51
|
+
self.clauses << QueryClause.before_days(field, value)
|
52
|
+
self
|
53
|
+
end
|
50
54
|
end
|
51
55
|
|
52
|
-
|
53
|
-
|
54
|
-
|
56
|
+
module ClassMethods
|
57
|
+
extend Forwardable
|
58
|
+
|
59
|
+
delegate Api.public_instance_methods => :new_filter
|
60
|
+
|
61
|
+
def has_content
|
62
|
+
where active_fedora_model: [ "Component", "Attachment", "Target" ]
|
63
|
+
end
|
64
|
+
|
65
|
+
def is_governed_by(object_or_id)
|
66
|
+
term is_governed_by: internal_uri(object_or_id)
|
67
|
+
end
|
68
|
+
|
69
|
+
def is_member_of_collection(object_or_id)
|
70
|
+
term is_member_of_collection: internal_uri(object_or_id)
|
71
|
+
end
|
72
|
+
|
73
|
+
private
|
74
|
+
|
75
|
+
def internal_uri(object_or_id)
|
76
|
+
if object_or_id.respond_to?(:internal_uri)
|
77
|
+
object_or_id.internal_uri
|
78
|
+
else
|
79
|
+
ActiveFedora::Base.internal_uri(object_or_id)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def new_filter
|
84
|
+
Filter.new
|
85
|
+
end
|
55
86
|
|
56
|
-
def ==(other)
|
57
|
-
other.instance_of?(self.class) && (other.clauses == self.clauses)
|
58
87
|
end
|
59
88
|
|
89
|
+
include Api
|
90
|
+
extend ClassMethods
|
91
|
+
|
60
92
|
end
|
61
93
|
end
|
data/lib/ddr/index/filters.rb
CHANGED
@@ -2,16 +2,11 @@ module Ddr::Index
|
|
2
2
|
module Filters
|
3
3
|
extend Deprecation
|
4
4
|
|
5
|
-
def self.
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
Filter.where(Fields::IS_GOVERNED_BY => internal_uri(object_or_id))
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.is_member_of_collection(object_or_id)
|
14
|
-
Filter.where(Fields::IS_MEMBER_OF_COLLECTION => internal_uri(object_or_id))
|
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)
|
15
10
|
end
|
16
11
|
|
17
12
|
private
|
@@ -20,20 +15,12 @@ module Ddr::Index
|
|
20
15
|
if name == :HAS_CONTENT
|
21
16
|
Deprecation.warn(self,
|
22
17
|
"`Ddr::Index::Filters::#{name}` is deprecated and will be removed in ddr-models 3.0." \
|
23
|
-
" Use `Ddr::Index::
|
24
|
-
has_content
|
18
|
+
" Use `Ddr::Index::Filter.has_content` instead.")
|
19
|
+
Filter.has_content
|
25
20
|
else
|
26
21
|
super
|
27
22
|
end
|
28
23
|
end
|
29
24
|
|
30
|
-
def self.internal_uri(object_or_id)
|
31
|
-
if object_or_id.respond_to?(:internal_uri)
|
32
|
-
object_or_id.internal_uri
|
33
|
-
else
|
34
|
-
ActiveFedora::Base.internal_uri(object_or_id)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
25
|
end
|
39
26
|
end
|
data/lib/ddr/index/query.rb
CHANGED
@@ -7,12 +7,13 @@ module Ddr::Index
|
|
7
7
|
extend Forwardable
|
8
8
|
|
9
9
|
attribute :q, String
|
10
|
-
attribute :fields, Array[
|
11
|
-
attribute :filters, Array[Filter],
|
12
|
-
attribute :sort, Array[String],
|
10
|
+
attribute :fields, Array[FieldAttribute], default: [ ]
|
11
|
+
attribute :filters, Array[Filter], default: [ ]
|
12
|
+
attribute :sort, Array[String], default: [ ]
|
13
13
|
attribute :rows, Integer
|
14
14
|
|
15
|
-
|
15
|
+
delegate [:count, :docs, :pids, :each_pid, :all] => :result
|
16
|
+
delegate :params => :query_params
|
16
17
|
|
17
18
|
def inspect
|
18
19
|
"#<#{self.class.name} q=#{q.inspect}, filters=#{filters.inspect}," \
|
@@ -23,10 +24,6 @@ module Ddr::Index
|
|
23
24
|
URI.encode_www_form(params)
|
24
25
|
end
|
25
26
|
|
26
|
-
def params
|
27
|
-
QueryParams.new(self).params
|
28
|
-
end
|
29
|
-
|
30
27
|
def result
|
31
28
|
QueryResult.new(self)
|
32
29
|
end
|
@@ -35,5 +32,13 @@ module Ddr::Index
|
|
35
32
|
CSVQueryResult.new(self, **opts)
|
36
33
|
end
|
37
34
|
|
35
|
+
def filter_clauses
|
36
|
+
filters.map(&:clauses).flatten
|
37
|
+
end
|
38
|
+
|
39
|
+
def query_params
|
40
|
+
QueryParams.new(self)
|
41
|
+
end
|
42
|
+
|
38
43
|
end
|
39
44
|
end
|
@@ -2,8 +2,84 @@ module Ddr::Index
|
|
2
2
|
#
|
3
3
|
# QueryBuilder - Provides a DSL for building a Query.
|
4
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
|
+
# See also: desc, order_by
|
16
|
+
#
|
17
|
+
# before [field], [date_time]
|
18
|
+
# Adds a filter selecting documents where the field has a date/time before
|
19
|
+
# (earlier than) the value.
|
20
|
+
#
|
21
|
+
# before_days [field], [int]
|
22
|
+
# Adds a filter selecting documents where the field has a date/time the
|
23
|
+
# specified number of days before today (now) or earlier.
|
24
|
+
#
|
25
|
+
# desc [field], ...
|
26
|
+
# Adds descending orderings by the fields specified.
|
27
|
+
# See also: asc, order_by
|
28
|
+
#
|
29
|
+
# id [doc_id]
|
30
|
+
# For selecting a single document by ID.
|
31
|
+
#
|
32
|
+
# filter [filter1], ...
|
33
|
+
# Adds filters to the query.
|
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
|
+
# Aliased as: fields
|
43
|
+
#
|
44
|
+
# fields [field], ...
|
45
|
+
# Alias for: field
|
46
|
+
#
|
47
|
+
# limit [int]
|
48
|
+
# Limits the number of documents returned by the query.
|
49
|
+
# Aliased as: rows
|
50
|
+
#
|
51
|
+
# negative [field], [value]
|
52
|
+
# Adds a filter selecting document where field does not have the value.
|
53
|
+
#
|
54
|
+
# order_by [{field => order, ...}], ...
|
55
|
+
# Adds ordering(s) to the query.
|
56
|
+
# Aliased as: sort
|
57
|
+
#
|
58
|
+
# present [field]
|
59
|
+
# Adds a filter selecting document where the field has any value.
|
60
|
+
#
|
61
|
+
# q [query_clause]
|
62
|
+
# Sets a query clause for the `q` parameter.
|
63
|
+
#
|
64
|
+
# raw [clause1], ...
|
65
|
+
# Adds a filter of "raw" query clauses (i.e., pre-constructed).
|
66
|
+
#
|
67
|
+
# rows [int]
|
68
|
+
# Alias for: limit
|
69
|
+
#
|
70
|
+
# sort [{field => order, ...}]
|
71
|
+
# Alias for: order_by
|
72
|
+
#
|
73
|
+
# term [{field => value, ...}]
|
74
|
+
# Adds a filter of "term" query clauses for the fields and values.
|
75
|
+
#
|
76
|
+
# where [{field => value, ...}]
|
77
|
+
# Adds a filter of "standard" query clauses.
|
78
|
+
# Values will be escaped when the filter is serialized.
|
79
|
+
# If a hash value is an array, that query clause will select documents
|
80
|
+
# where the field matches any array entry.
|
81
|
+
#
|
5
82
|
class QueryBuilder
|
6
|
-
extend Deprecation
|
7
83
|
|
8
84
|
# Builds a Query object
|
9
85
|
# @yield [builder] a new QueryBuilder instance.
|
@@ -26,86 +102,83 @@ module Ddr::Index
|
|
26
102
|
end
|
27
103
|
end
|
28
104
|
|
105
|
+
# @param pid [String]
|
106
|
+
# @return [QueryBuilder]
|
29
107
|
def id(pid)
|
30
108
|
q QueryClause.id(pid)
|
31
109
|
limit 1
|
32
110
|
end
|
33
111
|
|
112
|
+
# @param filters [Array<Filter>]
|
113
|
+
# @return [QueryBuilder]
|
34
114
|
def filter(*filters)
|
35
|
-
query.filters
|
115
|
+
query.filters += filters
|
36
116
|
self
|
37
117
|
end
|
38
118
|
alias_method :filters, :filter
|
39
119
|
|
40
|
-
|
41
|
-
|
42
|
-
end
|
43
|
-
|
44
|
-
def where(*args)
|
45
|
-
filter Filter.where(*args)
|
46
|
-
end
|
47
|
-
|
48
|
-
def absent(*args)
|
49
|
-
filter Filter.absent(*args)
|
50
|
-
end
|
51
|
-
|
52
|
-
def present(*args)
|
53
|
-
filter Filter.present(*args)
|
54
|
-
end
|
55
|
-
|
56
|
-
def negative(*args)
|
57
|
-
filter Filter.negative(*args)
|
58
|
-
end
|
59
|
-
|
60
|
-
def before(*args)
|
61
|
-
filter Filter.before(*args)
|
62
|
-
end
|
63
|
-
|
64
|
-
def before_days(*args)
|
65
|
-
filter Filter.before_days(*args)
|
66
|
-
end
|
67
|
-
|
120
|
+
# @param fields [Array<Field>]
|
121
|
+
# @return [QueryBuilder] self
|
68
122
|
def field(*fields)
|
69
|
-
query.fields
|
123
|
+
query.fields += fields
|
70
124
|
self
|
71
125
|
end
|
72
126
|
alias_method :fields, :field
|
73
127
|
|
128
|
+
# @param num [Integer]
|
129
|
+
# @return [QueryBuilder] self
|
74
130
|
def limit(num)
|
75
|
-
query.rows = num
|
131
|
+
query.rows = num.to_i
|
76
132
|
self
|
77
133
|
end
|
78
134
|
alias_method :rows, :limit
|
79
135
|
|
80
|
-
|
81
|
-
|
136
|
+
# @param orderings [Hash<Field, String>]
|
137
|
+
# @return [QueryBuilder] self
|
138
|
+
def order_by(*orderings)
|
139
|
+
unless orderings.first.is_a? Hash
|
82
140
|
Deprecation.warn(QueryBuilder, "`order_by` will require a hash of orderings in ddr-models 3.0.")
|
83
|
-
field, order =
|
141
|
+
field, order = orderings
|
84
142
|
return order_by(field => order)
|
85
143
|
end
|
86
|
-
query.sort +=
|
144
|
+
query.sort += orderings.first.map { |field, order| SortOrder.new(field: field, order: order) }
|
87
145
|
self
|
88
146
|
end
|
89
147
|
alias_method :sort, :order_by
|
90
148
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
149
|
+
# @param fields [Array<Field, Symbol, String>]
|
150
|
+
# @return [QueryBuilder] self
|
151
|
+
def asc(*fields)
|
152
|
+
query.sort += fields.map { |field| SortOrder.asc(field) }
|
153
|
+
self
|
96
154
|
end
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
order_by(field => SortOrder::DESC)
|
155
|
+
# @param fields [Array<Field, Symbol, String>]
|
156
|
+
# @return [QueryBuilder] self
|
157
|
+
def desc(*fields)
|
158
|
+
query.sort += fields.map { |field| SortOrder.desc(field) }
|
159
|
+
self
|
103
160
|
end
|
104
161
|
|
105
|
-
|
106
|
-
|
162
|
+
# @param query_clause [QueryClause, String]
|
163
|
+
# @return [QueryBuilder] self
|
164
|
+
def q(query_clause)
|
165
|
+
query.q = query_clause
|
107
166
|
self
|
108
167
|
end
|
109
168
|
|
169
|
+
private
|
170
|
+
|
171
|
+
def respond_to_missing?(name, include_all)
|
172
|
+
Filter::ClassMethods.public_instance_methods.include?(name)
|
173
|
+
end
|
174
|
+
|
175
|
+
def method_missing(name, *args, &block)
|
176
|
+
if respond_to?(name)
|
177
|
+
filter Filter.send(name, *args)
|
178
|
+
else
|
179
|
+
super
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
110
183
|
end
|
111
184
|
end
|