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.
@@ -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 @limit && total > @limit
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
- if @limit < total
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
- sql << "#{timestamp_field} >= ?" << "#{timestamp_field} <= ?"
125
- sql << "set = ?" if opts[:set]
126
- esc_values = [sql.join(" AND ")]
127
- esc_values << get_time(opts[:from]).localtime << get_time(opts[:until]).localtime #-- OAI 2.0 hack - UTC fix from record_responce
128
- esc_values << opts[:set] if opts[:set]
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
- return esc_values
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
@@ -45,6 +45,11 @@ module OAI::Provider
45
45
  raise NotImplementedError.new
46
46
  end
47
47
 
48
+ # Should return the last id of this model
49
+ def last_id(conditions)
50
+ raise NotImplementedError.new
51
+ end
52
+
48
53
  def sets
49
54
  nil
50
55
  end
@@ -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, :total
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
- xml.resumptionToken(encode_conditions, hash_of_attributes)
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
 
@@ -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
- assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
21
- assert_equal 25, doc.elements["/OAI-PMH/ListRecords"].to_a.size
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 25, doc.elements["/OAI-PMH/ListRecords"].to_a.size
45
- assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
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
@@ -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
- if token.last < @groups.size - 1
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
- assert_nil doc.elements["/OAI-PMH/ListRecords/resumptionToken"]
40
- assert_equal 100, doc.elements["/OAI-PMH/ListRecords"].to_a.size
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
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: oai_talia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.14
4
+ version: 0.0.15
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ed Summers