oai_talia 0.0.14 → 0.0.15
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/oai/provider/model/activerecord_caching_wrapper.rb +1 -1
- data/lib/oai/provider/model/activerecord_wrapper.rb +28 -17
- data/lib/oai/provider/model.rb +5 -0
- data/lib/oai/provider/response.rb +1 -1
- data/lib/oai/provider/resumption_token.rb +20 -4
- data/test/activerecord_provider/database/oaipmhtest +0 -0
- data/test/activerecord_provider/tc_simple_paging_provider.rb +9 -4
- data/test/provider/models.rb +3 -6
- data/test/provider/tc_functional_tokens.rb +4 -3
- data/test/provider/tc_resumption_tokens.rb +17 -4
- metadata +1 -1
@@ -65,7 +65,7 @@ module OAI::Provider
|
|
65
65
|
total = model.count(:id, :conditions => conditions)
|
66
66
|
if @limit && total > @limit
|
67
67
|
select_partial(
|
68
|
-
ResumptionToken.new(options.merge({:last => 0})))
|
68
|
+
ResumptionToken.new(last_id(conditions), options.merge({:last => 0}), nil, total))
|
69
69
|
else
|
70
70
|
model.find(:all, :conditions => conditions)
|
71
71
|
end
|
@@ -34,6 +34,12 @@ module OAI::Provider
|
|
34
34
|
model.find(:first,
|
35
35
|
:order => "#{timestamp_field} desc").send(timestamp_field)
|
36
36
|
end
|
37
|
+
|
38
|
+
def last_id(conditions)
|
39
|
+
model.find(:first, :conditions => conditions,
|
40
|
+
:order => "#{timestamp_field} desc").id
|
41
|
+
end
|
42
|
+
|
37
43
|
# A model class is expected to provide a method Model.sets that
|
38
44
|
# returns all the sets the model supports. See the
|
39
45
|
# activerecord_provider tests for an example.
|
@@ -46,8 +52,8 @@ module OAI::Provider
|
|
46
52
|
conditions = sql_conditions(options)
|
47
53
|
if :all == selector
|
48
54
|
total = model.count(:id, :conditions => conditions)
|
49
|
-
if
|
50
|
-
select_partial(ResumptionToken.new(options.merge({:last => 0})))
|
55
|
+
if(@limit && total > @limit)
|
56
|
+
select_partial(ResumptionToken.new(last_id(conditions), options.merge({:last => 0}), nil, total))
|
51
57
|
else
|
52
58
|
model.find(:all, :conditions => conditions)
|
53
59
|
end
|
@@ -78,13 +84,7 @@ module OAI::Provider
|
|
78
84
|
token = ResumptionToken.parse(token_string)
|
79
85
|
total = model.count(:id, :conditions => token_conditions(token))
|
80
86
|
|
81
|
-
|
82
|
-
select_partial(token)
|
83
|
-
else # end of result set
|
84
|
-
model.find(:all,
|
85
|
-
:conditions => token_conditions(token),
|
86
|
-
:limit => @limit, :order => "#{model.primary_key} asc")
|
87
|
-
end
|
87
|
+
select_partial(token)
|
88
88
|
end
|
89
89
|
|
90
90
|
# select a subset of the result set, and return it with a
|
@@ -96,7 +96,6 @@ module OAI::Provider
|
|
96
96
|
:order => "#{model.primary_key} asc")
|
97
97
|
raise OAI::ResumptionTokenException.new unless records
|
98
98
|
offset = records.last.send(model.primary_key.to_sym)
|
99
|
-
|
100
99
|
PartialResult.new(records, token.next(offset))
|
101
100
|
end
|
102
101
|
|
@@ -121,17 +120,29 @@ module OAI::Provider
|
|
121
120
|
# build a sql conditions statement from an OAI options hash
|
122
121
|
def sql_conditions(opts)
|
123
122
|
sql = []
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
123
|
+
values = []
|
124
|
+
|
125
|
+
if(opts[:set])
|
126
|
+
sql << "set = ?"
|
127
|
+
values << opts[:set]
|
128
|
+
end
|
129
|
+
|
130
|
+
if(opts[:from])
|
131
|
+
sql << "#{timestamp_field} >= ?"
|
132
|
+
values << get_time(opts[:from])
|
133
|
+
end
|
134
|
+
|
135
|
+
if(opts[:until])
|
136
|
+
sql << "#{timestamp_field} <= ?"
|
137
|
+
values << get_time(opts[:until])
|
138
|
+
end
|
129
139
|
|
130
|
-
|
140
|
+
values.unshift(sql.join(' AND '))
|
131
141
|
end
|
132
142
|
|
143
|
+
#-- OAI 2.0 hack - UTC fix from record_responce
|
133
144
|
def get_time(time)
|
134
|
-
time.kind_of?(Time) ? time : Time.parse(time)
|
145
|
+
(time.kind_of?(Time) ? time : Time.parse(time)).localtime
|
135
146
|
end
|
136
147
|
|
137
148
|
end
|
data/lib/oai/provider/model.rb
CHANGED
@@ -142,7 +142,7 @@ module OAI
|
|
142
142
|
def internalize(hash = {})
|
143
143
|
internal = {}
|
144
144
|
hash.keys.each do |key|
|
145
|
-
internal[key.to_s.gsub(/([A-Z])/, '_\1').downcase.intern] = hash[key].dup
|
145
|
+
internal[key.to_s.gsub(/([A-Z])/, '_\1').downcase.intern] = hash[key].nil? ? nil : hash[key].dup
|
146
146
|
end
|
147
147
|
|
148
148
|
# Convert date formated strings into internal time values
|
@@ -9,7 +9,8 @@ module OAI::Provider
|
|
9
9
|
# provides several helper methods for dealing with resumption tokens.
|
10
10
|
#
|
11
11
|
class ResumptionToken
|
12
|
-
attr_reader :prefix, :set, :from, :until, :last, :expiration, :
|
12
|
+
attr_reader :prefix, :set, :from, :until, :last, :expiration, :last_id
|
13
|
+
attr_accessor :total
|
13
14
|
|
14
15
|
# parses a token string and returns a ResumptionToken
|
15
16
|
def self.parse(token_string)
|
@@ -17,6 +18,8 @@ module OAI::Provider
|
|
17
18
|
options = {}
|
18
19
|
matches = /(.+):(\d+)$/.match(token_string)
|
19
20
|
options[:last] = matches.captures[1].to_i
|
21
|
+
last_id = nil
|
22
|
+
total = nil
|
20
23
|
|
21
24
|
parts = matches.captures[0].split('.')
|
22
25
|
options[:metadata_prefix] = parts.shift
|
@@ -28,9 +31,13 @@ module OAI::Provider
|
|
28
31
|
options[:from] = Time.parse(part.sub(/^f\(/, '').sub(/\)$/, ''))
|
29
32
|
when /^u/
|
30
33
|
options[:until] = Time.parse(part.sub(/^u\(/, '').sub(/\)$/, ''))
|
34
|
+
when /^l/
|
35
|
+
last_id = part.sub(/^l\(/, '').sub(/\)$/, '')
|
36
|
+
when /^t/
|
37
|
+
total = part.sub(/^t\(/, '').sub(/\)$/, '')
|
31
38
|
end
|
32
39
|
end
|
33
|
-
self.new(options)
|
40
|
+
self.new(last_id, options, nil, total)
|
34
41
|
rescue => err
|
35
42
|
raise ResumptionTokenException.new
|
36
43
|
end
|
@@ -41,7 +48,7 @@ module OAI::Provider
|
|
41
48
|
return token_string.split('.')[0]
|
42
49
|
end
|
43
50
|
|
44
|
-
def initialize(options, expiration = nil, total = nil)
|
51
|
+
def initialize(last_id, options, expiration = nil, total = nil)
|
45
52
|
@prefix = options[:metadata_prefix]
|
46
53
|
@set = options[:set]
|
47
54
|
@last = options[:last]
|
@@ -49,6 +56,7 @@ module OAI::Provider
|
|
49
56
|
@until = options[:until] if options[:until]
|
50
57
|
@expiration = expiration if expiration
|
51
58
|
@total = total if total
|
59
|
+
@last_id = last_id
|
52
60
|
end
|
53
61
|
|
54
62
|
# convenience method for setting the offset of the next set of results
|
@@ -66,7 +74,13 @@ module OAI::Provider
|
|
66
74
|
# output an xml resumption token
|
67
75
|
def to_xml
|
68
76
|
xml = Builder::XmlMarkup.new
|
69
|
-
|
77
|
+
token_content = if(last_id.to_s == last.to_s)
|
78
|
+
[] # Empty token required on last page of results
|
79
|
+
else
|
80
|
+
[encode_conditions, hash_of_attributes]
|
81
|
+
end
|
82
|
+
|
83
|
+
xml.resumptionToken(*token_content)
|
70
84
|
xml.target!
|
71
85
|
end
|
72
86
|
|
@@ -91,6 +105,8 @@ module OAI::Provider
|
|
91
105
|
encoded_token << ".s(#{set})" if set
|
92
106
|
encoded_token << ".f(#{self.from.utc.xmlschema})" if self.from
|
93
107
|
encoded_token << ".u(#{self.until.utc.xmlschema})" if self.until
|
108
|
+
encoded_token << ".t(#{self.total})" if(self.total)
|
109
|
+
encoded_token << ".l(#{last_id})"
|
94
110
|
encoded_token << ":#{last}"
|
95
111
|
end
|
96
112
|
|
Binary file
|
@@ -8,17 +8,21 @@ class SimpleResumptionProviderTest < Test::Unit::TestCase
|
|
8
8
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
9
9
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
10
10
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
11
|
+
assert_not_nil token
|
11
12
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
12
13
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
13
14
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
15
|
+
assert_not_nil token
|
14
16
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
15
17
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
16
18
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
17
19
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
20
|
+
assert_not_nil token
|
18
21
|
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
19
22
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
20
|
-
|
21
|
-
|
23
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
24
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
25
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
22
26
|
end
|
23
27
|
|
24
28
|
def test_from_and_until
|
@@ -41,8 +45,9 @@ class SimpleResumptionProviderTest < Test::Unit::TestCase
|
|
41
45
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
42
46
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
43
47
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
44
|
-
assert_equal
|
45
|
-
|
48
|
+
assert_equal 26, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
49
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
50
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
46
51
|
end
|
47
52
|
|
48
53
|
def setup
|
data/test/provider/models.rb
CHANGED
@@ -64,12 +64,9 @@ class TestModel < OAI::Provider::Model
|
|
64
64
|
raise OAI::ResumptionTokenException.new unless @limit
|
65
65
|
begin
|
66
66
|
token = ResumptionToken.parse(opts[:resumption_token])
|
67
|
+
token.total = @groups.size
|
67
68
|
|
68
|
-
|
69
|
-
PartialResult.new(@groups[token.last], token.next(token.last + 1))
|
70
|
-
else
|
71
|
-
@groups[token.last]
|
72
|
-
end
|
69
|
+
PartialResult.new(@groups[token.last], token.next(token.last + 1))
|
73
70
|
rescue
|
74
71
|
raise OAI::ResumptionTokenException.new
|
75
72
|
end
|
@@ -88,7 +85,7 @@ class TestModel < OAI::Provider::Model
|
|
88
85
|
if @limit && records.size > @limit
|
89
86
|
@groups = generate_chunks(records, @limit)
|
90
87
|
return PartialResult.new(@groups[0],
|
91
|
-
ResumptionToken.new(opts.merge({:last => 1})))
|
88
|
+
ResumptionToken.new(@groups.size, opts.merge({:last => 1}), nil, records.size))
|
92
89
|
end
|
93
90
|
return records
|
94
91
|
end
|
@@ -34,10 +34,11 @@ class ResumptionTokenFunctionalTest < Test::Unit::TestCase
|
|
34
34
|
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
35
35
|
assert_equal 101, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
36
36
|
token = doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
37
|
-
|
37
|
+
|
38
38
|
doc = Document.new(@provider.list_records(:resumption_token => token))
|
39
|
-
|
40
|
-
|
39
|
+
assert_not_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
|
40
|
+
assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"].text
|
41
|
+
assert_equal 101, doc.elements["/OAI-PMH/ListRecords"].to_a.size
|
41
42
|
end
|
42
43
|
|
43
44
|
end
|
@@ -5,17 +5,24 @@ class ResumptionTokenTest < Test::Unit::TestCase
|
|
5
5
|
include OAI::Provider
|
6
6
|
|
7
7
|
def setup
|
8
|
-
@token = ResumptionToken.new(
|
8
|
+
@token = ResumptionToken.new(2, {
|
9
9
|
:from => Time.utc(2005,"jan",1,17,0,0),
|
10
10
|
:until => Time.utc(2005,"jan",31,17,0,0),
|
11
11
|
:set => "A",
|
12
12
|
:metadata_prefix => "oai_dc",
|
13
|
-
:last => 1
|
13
|
+
:last => 1 }
|
14
|
+
)
|
15
|
+
@last_token = ResumptionToken.new(1, {
|
16
|
+
:from => Time.utc(2005,"jan",1,17,0,0),
|
17
|
+
:until => Time.utc(2005,"jan",31,17,0,0),
|
18
|
+
:set => "A",
|
19
|
+
:metadata_prefix => "oai_dc",
|
20
|
+
:last => 1 }
|
14
21
|
)
|
15
22
|
end
|
16
23
|
|
17
24
|
def test_resumption_token_options_encoding
|
18
|
-
assert_equal "oai_dc.s(A).f(2005-01-01T17:00:00Z).u(2005-01-31T17:00:00Z)",
|
25
|
+
assert_equal "oai_dc.s(A).f(2005-01-01T17:00:00Z).u(2005-01-31T17:00:00Z).l(2)",
|
19
26
|
@token.to_s
|
20
27
|
end
|
21
28
|
|
@@ -33,7 +40,7 @@ class ResumptionTokenTest < Test::Unit::TestCase
|
|
33
40
|
|
34
41
|
def test_resumption_token_parsing
|
35
42
|
new_token = ResumptionToken.parse(
|
36
|
-
"oai_dc.s(A).f(2005-01-01T17:00:00Z).u(2005-01-31T17:00:00Z):1"
|
43
|
+
"oai_dc.s(A).f(2005-01-01T17:00:00Z).u(2005-01-31T17:00:00Z).l(2):1"
|
37
44
|
)
|
38
45
|
assert_equal @token, new_token
|
39
46
|
end
|
@@ -43,4 +50,10 @@ class ResumptionTokenTest < Test::Unit::TestCase
|
|
43
50
|
assert_equal "#{@token.to_s}:#{@token.last}", doc.elements['/resumptionToken'].text
|
44
51
|
end
|
45
52
|
|
53
|
+
def test_last_resumption_token_to_xml
|
54
|
+
doc = REXML::Document.new(@last_token.to_xml)
|
55
|
+
assert_not_nil doc.elements['/resumptionToken']
|
56
|
+
assert_nil doc.elements['/resumptionToken'].text
|
57
|
+
end
|
58
|
+
|
46
59
|
end
|