Class: Moneta::Adapters::ActiveRecord

Inherits:
Object
  • Object
show all
Includes:
Defaults
Defined in:
lib/moneta/adapters/activerecord.rb

Overview

ActiveRecord as key/value stores

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Defaults

#[], #[]=, #close, #decrement, #features, #fetch, included, #supports?

Methods included from OptionSupport

#expires, #prefix, #raw, #with

Constructor Details

#initialize(options = {}) ⇒ ActiveRecord

Returns a new instance of ActiveRecord.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :table (String) — default: 'moneta'

    Table name

  • :connection (Hash)

    ActiveRecord connection configuration



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/moneta/adapters/activerecord.rb', line 20

def initialize(options = {})
  table = options[:table] || 'moneta'
  @table = self.class.tables[table] ||=
    begin
      c = Class.new(::ActiveRecord::Base)
      c.table_name = table
      c.primary_key = :k
      c
    end

  if options[:connection]
    begin
      @table.establish_connection(options[:connection])
    rescue
      tries ||= 0
      (tries += 1) < 3 ? retry : raise
    end
  end

  unless @table.table_exists?
    @table.connection.create_table(@table.table_name, :id => false) do |t|
      # Do not use binary columns (Issue #17)
      t.string :k, :null => false
      t.string :v
    end
    @table.connection.add_index(@table.table_name, :k, :unique => true)
  end
end

Instance Attribute Details

#tableObject (readonly)



11
12
13
# File 'lib/moneta/adapters/activerecord.rb', line 11

def table
  @table
end

Class Method Details

.tablesObject



13
14
15
# File 'lib/moneta/adapters/activerecord.rb', line 13

def self.tables
  @tables ||= {}
end

Instance Method Details

#clear(options = {}) ⇒ void

This method returns an undefined value.

Clear all keys in this store

Parameters:

  • options (Hash) (defaults to: {})


112
113
114
115
# File 'lib/moneta/adapters/activerecord.rb', line 112

def clear(options = {})
  @table.delete_all
  self
end

#create(key, value, options = {}) ⇒ Boolean

Note:

Not every Moneta store implements this method, a NotImplementedError is raised if it is not supported.

Atomically sets a key to value if it’s not set.

Parameters:

  • key (Object)
  • value (Object)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :expires (Integer)

    Update expiration time (See Expires)

  • :raw (Boolean)

    Raw access without value transformation (See Transformer)

  • :prefix (String)

    Prefix key (See Transformer)

Returns:

  • (Boolean)

    key was set



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/moneta/adapters/activerecord.rb', line 99

def create(key, value, options = {})
  record = @table.new
  record.k = key
  record.v = value
  record.save
  true
rescue
  # FIXME: This catches too many errors
  # it should only catch a not-unique-exception
  false
end

#delete(key, options = {}) ⇒ Object

Delete the key from the store and return the current value

Parameters:

  • key (Object)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :raw (Boolean)

    Raw access without value transformation (See Transformer)

  • :prefix (String)

    Prefix key (See Transformer)

  • Other (Object)

    options as defined by the adapters or middleware

Returns:

  • (Object)

    current value



72
73
74
75
76
77
# File 'lib/moneta/adapters/activerecord.rb', line 72

def delete(key, options = {})
  if record = @table.where(:k => key).first
    record.destroy
    record.v
  end
end

#increment(key, amount = 1, options = {}) ⇒ Object

Note:

Not every Moneta store implements this method, a NotImplementedError is raised if it is not supported.

Atomically increment integer value with key

This method also accepts negative amounts.

Parameters:

  • key (Object)
  • amount (Integer) (defaults to: 1)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :prefix (String)

    Prefix key (See Transformer)

  • Other (Object)

    options as defined by the adapters or middleware

Returns:

  • (Object)

    value from store



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/moneta/adapters/activerecord.rb', line 80

def increment(key, amount = 1, options = {})
  @table.transaction do
    if record = @table.where(:k => key).lock.first
      value = Utils.to_int(record.v) + amount
      record.v = value.to_s
      record.save
      value
    elsif create(key, amount.to_s, options)
      amount
    else
      raise 'Concurrent modification'
    end
  end
rescue
  tries ||= 0
  (tries += 1) < 10 ? retry : raise
end

#key?(key, options = {}) ⇒ Boolean

Exists the value with key

Parameters:

  • key (Object)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :expires (Integer)

    Update expiration time (See Expires)

  • :prefix (String)

    Prefix key (See Transformer)

  • Other (Object)

    options as defined by the adapters or middleware

Returns:

  • (Boolean)


50
51
52
# File 'lib/moneta/adapters/activerecord.rb', line 50

def key?(key, options = {})
  !@table.where(:k => key).empty?
end

#load(key, options = {}) ⇒ Object

Fetch value with key. Return nil if the key doesn’t exist

Parameters:

  • key (Object)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :expires (Integer)

    Update expiration time (See Expires)

  • :raw (Boolean)

    Raw access without value transformation (See Transformer)

  • :prefix (String)

    Prefix key (See Transformer)

  • Other (Object)

    options as defined by the adapters or middleware

Returns:

  • (Object)

    value



55
56
57
58
# File 'lib/moneta/adapters/activerecord.rb', line 55

def load(key, options = {})
  record = @table.select(:v).where(:k => key).first
  record && record.v
end

#store(key, value, options = {}) ⇒ Object

Store value with key

Parameters:

  • key (Object)
  • value (Object)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • :expires (Integer)

    Set expiration time (See Expires)

  • :raw (Boolean)

    Raw access without value transformation (See Transformer)

  • :prefix (String)

    Prefix key (See Transformer)

  • Other (Object)

    options as defined by the adapters or middleware

Returns:

  • value



61
62
63
64
65
66
67
68
69
# File 'lib/moneta/adapters/activerecord.rb', line 61

def store(key, value, options = {})
  record = @table.select(:k).where(:k => key).first_or_initialize
  record.v = value
  record.save
  value
rescue
  tries ||= 0
  (tries += 1) < 10 ? retry : raise
end