Module: CouchRest::Model::Rotation::ClassMethods

Defined in:
lib/couchrest/model/rotation.rb

Instance Method Summary collapse

Instance Method Details

#create_database!(name = nil) ⇒ Object

create a new empty database.



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/couchrest/model/rotation.rb', line 134

def create_database!(name=nil)
  db = if name
    self.server.database!(db_name_with_prefix(name))
  else
    self.database!
  end
  create_rotation_filter(db)
  if self.respond_to?(:design_doc, true)
    design_doc.sync!(db)
    # or maybe this?:
    #self.design_docs.each do |design|
    #  design.migrate(to_db)
    #end
  end
  return db
end

#rotate_database(base_name, options = {}) ⇒ Object

Set up database rotation.

base_name – the name of the db before the rotation number is appended.

options – one of:

  • :every – frequency of rotation

  • :expiration_field - what field to use to determine if a

    document is expired.
    
  • :timestamp_field - alternately, what field to use for the

    document timestamp.
    
  • :timeout – used to expire documents with only a timestamp

    field (in minutes)
    


61
62
63
64
65
66
67
68
69
70
# File 'lib/couchrest/model/rotation.rb', line 61

def rotate_database(base_name, options={})
  @rotation_base_name = base_name
  @rotation_every = (options.delete(:every) || 30.days).to_i
  @expiration_field = options.delete(:expiration_field)
  @timestamp_field = options.delete(:timestamp_field)
  @timeout = options.delete(:timeout)
  if options.any?
    raise ArgumentError.new('Could not understand options %s' % options.keys)
  end
end

#rotate_database_now(options = {}) ⇒ Object

Check to see if dbs should be rotated. The :window argument specifies how far in advance we should create the new database (default 1.day).

This method relies on the assumption that it is called at least once within each @rotation_every period.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/couchrest/model/rotation.rb', line 80

def rotate_database_now(options={})
  window = options[:window] || 1.day

  now = Time.now.utc
  current_name = rotated_database_name(now)
  current_count = now.to_i/@rotation_every

  next_time = window.from_now.utc
  next_name = rotated_database_name(next_time)
  next_count = current_count+1

  prev_name = current_name.sub(/(\d+)$/) {|i| i.to_i-1}
  replication_started = false
  old_name = prev_name.sub(/(\d+)$/) {|i| i.to_i-1} # even older than prev_name
  trailing_edge_time = window.ago.utc

  if !database_exists?(current_name)
    # we should have created the current db earlier, but if somehow
    # it is missing we must make sure it exists.
    create_new_rotated_database(:from => prev_name, :to => current_name)
    replication_started = true
  end

  if next_time.to_i/@rotation_every >= next_count && !database_exists?(next_name)
    # time to create the next db in advance of actually needing it.
    create_new_rotated_database(:from => current_name, :to => next_name)
  end

  if trailing_edge_time.to_i/@rotation_every == current_count
    # delete old dbs, but only after window time has past since the last rotation
    if !replication_started && database_exists?(prev_name)
      # delete previous, but only if we didn't just start replicating from it
      self.server.database(db_name_with_prefix(prev_name)).delete!
    end
    if database_exists?(old_name)
      # there are some edge cases, when rotate_database_now is run
      # infrequently, that an older db might be left around.
      self.server.database(db_name_with_prefix(old_name)).delete!
    end
  end
end

#rotated_database_name(time = nil) ⇒ Object



122
123
124
125
126
127
128
129
# File 'lib/couchrest/model/rotation.rb', line 122

def rotated_database_name(time=nil)
  unless @rotation_base_name && @rotation_every
    raise ArgumentError.new('missing @rotation_base_name or @rotation_every')
  end
  time ||= Time.now.utc
  units = time.to_i / @rotation_every.to_i
  "#{@rotation_base_name}_#{units}"
end