Class: OAI::Provider::ResumptionToken

Inherits:
Object
  • Object
show all
Defined in:
lib/oai/provider/resumption_token.rb

Overview

OAI::Provider::ResumptionToken

The ResumptionToken class forms the basis of paging query results. It provides several helper methods for dealing with resumption tokens.

OAI-PMH spec does not specify anything about resumptionToken format, they can be purely opaque tokens.

Our implementation however encodes everything needed to construct the next page inside the resumption token.

The ‘last’ component: offset or ID/pk to resume from

The ‘#last` component is an offset or ID to resume from. In the case of it being an ID to resume from, this assumes that ID’s are sortable and results are returned in ID order, so that the ‘last’ ID can be used as the place to resume from.

Originally it was assumed that #last was always an integer, but since existing implementations (like ActiveRecordWrapper) used it as an ID, and identifiers and primary keys are not always integers (can be UUID etc), we have expanded to allow any string value.

However, for backwards compatibility #last always returns an integer (sometimes 0 if actual last component is not an integer), and #last_str returns the full string version. Trying to change #last itself to be string broke a lot of existing code in this gem in mysterious ways.

Also beware that in some cases the value 0/“0” seems to be a special value used to signify some special case. A lot of “code archeology” going on here after significant period of no maintenance to this gem.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options, expiration = nil, total = nil) ⇒ ResumptionToken

Returns a new instance of ResumptionToken.



68
69
70
71
72
73
74
75
76
# File 'lib/oai/provider/resumption_token.rb', line 68

def initialize(options, expiration = nil, total = nil)
  @prefix = options[:metadata_prefix]
  @set = options[:set]
  self.last = options[:last]
  @from = options[:from] if options[:from]
  @until = options[:until] if options[:until]
  @expiration = expiration if expiration
  @total = total if total
end

Instance Attribute Details

#expirationObject (readonly)

Returns the value of attribute expiration.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def expiration
  @expiration
end

#fromObject (readonly)

Returns the value of attribute from.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def from
  @from
end

#lastObject

Returns the value of attribute last.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def last
  @last
end

#last_strObject (readonly)

Returns the value of attribute last_str.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def last_str
  @last_str
end

#prefixObject (readonly)

Returns the value of attribute prefix.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def prefix
  @prefix
end

#setObject (readonly)

Returns the value of attribute set.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def set
  @set
end

#totalObject (readonly)

Returns the value of attribute total.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def total
  @total
end

#untilObject (readonly)

Returns the value of attribute until.



36
37
38
# File 'lib/oai/provider/resumption_token.rb', line 36

def until
  @until
end

Class Method Details

.extract_format(token_string) ⇒ Object

extracts the metadata prefix from a token string



64
65
66
# File 'lib/oai/provider/resumption_token.rb', line 64

def self.extract_format(token_string)
  return token_string.split('.')[0]
end

.parse(token_string, expiration = nil, total = nil) ⇒ Object

parses a token string and returns a ResumptionToken



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/oai/provider/resumption_token.rb', line 39

def self.parse(token_string, expiration = nil, total = nil)
  begin
    options = {}
    matches = /(.+):([^ :]+)$/.match(token_string)
    options[:last] = matches.captures[1]

    parts = matches.captures[0].split('.')
    options[:metadata_prefix] = parts.shift
    parts.each do |part|
      case part
      when /^s/
        options[:set] = part.sub(/^s\(/, '').sub(/\)$/, '')
      when /^f/
        options[:from] = Time.parse(part.sub(/^f\(/, '').sub(/\)$/, '')).localtime
      when /^u/
        options[:until] = Time.parse(part.sub(/^u\(/, '').sub(/\)$/, '')).localtime
      end
    end
    self.new(options, expiration, total)
  rescue => err
    raise OAI::ResumptionTokenException.new
  end
end

Instance Method Details

#==(other) ⇒ Object



84
85
86
87
88
# File 'lib/oai/provider/resumption_token.rb', line 84

def ==(other)
  prefix == other.prefix and set == other.set and from == other.from and
    self.until == other.until and last == other.last and
    expiration == other.expiration and total == other.total
end

#next(last) ⇒ Object

convenience method for setting the offset of the next set of results



79
80
81
82
# File 'lib/oai/provider/resumption_token.rb', line 79

def next(last)
  self.last = last
  self
end

#to_conditions_hashObject

return a hash containing just the model selection parameters



98
99
100
101
102
103
104
# File 'lib/oai/provider/resumption_token.rb', line 98

def to_conditions_hash
  conditions = {:metadata_prefix => self.prefix }
  conditions[:set] = self.set if self.set
  conditions[:from] = self.from if self.from
  conditions[:until] = self.until if self.until
  conditions
end

#to_sObject

return the a string representation of the token minus the offset/ID

Q: Why does it eliminate the offset/id “last” on the end? Doesn’t fully

represent state without it, which is confusing. Not sure, but
other code seems to rely on it, tests break if not.


111
112
113
# File 'lib/oai/provider/resumption_token.rb', line 111

def to_s
  encode_conditions.gsub(/:\w+?$/, '')
end

#to_xmlObject

output an xml resumption token



91
92
93
94
95
# File 'lib/oai/provider/resumption_token.rb', line 91

def to_xml
  xml = Builder::XmlMarkup.new
  xml.resumptionToken(encode_conditions, hash_of_attributes)
  xml.target!
end