class Moneta::Adapters::Sqlite

Sqlite3 backend @api public

Public Class Methods

new(options = {}) click to toggle source

@param [Hash] options @option options [String] :file Database file @option options [String] :table (‘moneta’) Table name @option options [Integer] :busy_timeout (1000) Sqlite timeout if database is busy @option options [::Sqlite3::Database] :backend Use existing backend instance @option options [String, Symbol] :journal_mode Set the journal mode for the connection

Calls superclass method Moneta::Adapter::new
# File lib/moneta/adapters/sqlite.rb, line 24
      def initialize(options = {})
        super

        backend.busy_timeout(config.busy_timeout)
        backend.execute("create table if not exists #{config.table} (k blob not null primary key, v blob)")

        if journal_mode = config.journal_mode
          backend.journal_mode = journal_mode.to_s
        end

        @stmts =
          [@exists = backend.prepare("select exists(select 1 from #{config.table} where k = ?)"),
           @select = backend.prepare("select v from #{config.table} where k = ?"),
           @replace = backend.prepare("replace into #{config.table} values (?, ?)"),
           @delete = backend.prepare("delete from #{config.table} where k = ?"),
           @clear = backend.prepare("delete from #{config.table}"),
           @create = backend.prepare("insert into #{config.table} values (?, ?)"),
           @keys = backend.prepare("select k from #{config.table}"),
           @count = backend.prepare("select count(*) from #{config.table}")]

        version = backend.execute("select sqlite_version()").first.first
        if @can_upsert = ::Gem::Version.new(version) >= ::Gem::Version.new('3.24.0')
          @stmts << (@increment = backend.prepare <<-SQL)
            insert into #{config.table} values (?, ?)
            on conflict (k)
            do update set v = cast(cast(v as integer) + ? as blob)
            where v = '0' or v = X'30' or cast(v as integer) != 0
          SQL
        end
      end

Public Instance Methods

clear(options = {}) click to toggle source

(see Proxy#clear)

# File lib/moneta/adapters/sqlite.rb, line 89
def clear(options = {})
  @clear.execute!
  self
end
close() click to toggle source

(see Proxy#close)

# File lib/moneta/adapters/sqlite.rb, line 106
def close
  @stmts.each { |s| s.close }
  backend.close
  nil
end
create(key, value, options = {}) click to toggle source

(see Default#create)

# File lib/moneta/adapters/sqlite.rb, line 95
def create(key, value, options = {})
  @create.execute!(key, value)
  true
rescue SQLite3::ConstraintException
  # If you know a better way to detect whether an insert-ignore
  # suceeded, please tell me.
  @create.reset!
  false
end
delete(key, options = {}) click to toggle source

(see Proxy#delete)

# File lib/moneta/adapters/sqlite.rb, line 73
def delete(key, options = {})
  value = load(key, options)
  @delete.execute!(key)
  value
end
each_key() { |first| ... } click to toggle source

(see Proxy#each_key)

# File lib/moneta/adapters/sqlite.rb, line 164
def each_key
  return enum_for(:each_key) { @count.execute!.first.first } unless block_given?
  @keys.execute!.each do |row|
    yield row.first
  end
  self
end
fetch_values(*keys, **options) { |key| ... } click to toggle source

(see Proxy#fetch_values)

# File lib/moneta/adapters/sqlite.rb, line 125
def fetch_values(*keys, **options)
  return values_at(*keys, **options) unless block_given?
  hash = Hash[slice(*keys, **options)]
  keys.map do |key|
    if hash.key?(key)
      hash[key]
    else
      yield key
    end
  end
end
increment(key, amount = 1, options = {}) click to toggle source

(see Proxy#increment)

Calls superclass method Moneta::IncrementSupport#increment
# File lib/moneta/adapters/sqlite.rb, line 80
def increment(key, amount = 1, options = {})
  backend.transaction(:exclusive) { return super } unless @can_upsert
  backend.transaction do
    @increment.execute!(key, amount.to_s, amount)
    return Integer(load(key))
  end
end
key?(key, options = {}) click to toggle source

(see Proxy#key?)

# File lib/moneta/adapters/sqlite.rb, line 56
def key?(key, options = {})
  @exists.execute!(key).first.first.to_i == 1
end
load(key, options = {}) click to toggle source

(see Proxy#load)

# File lib/moneta/adapters/sqlite.rb, line 61
def load(key, options = {})
  rows = @select.execute!(key)
  rows.empty? ? nil : rows.first.first
end
merge!(pairs, options = {}) { |key, existing, new_value| ... } click to toggle source

(see Proxy#merge!)

# File lib/moneta/adapters/sqlite.rb, line 138
def merge!(pairs, options = {})
  transaction = backend.transaction if block_given?

  if block_given?
    existing = Hash[slice(*pairs.map { |k, _| k }.to_a)]
    pairs = pairs.map do |key, new_value|
      new_value = yield(key, existing[key], new_value) if existing.key?(key)
      [key, new_value]
    end.to_a
  else
    pairs = pairs.to_a
  end

  unless pairs.empty?
    query = "replace into #{config.table} (k, v) values" + (['(?, ?)'] * pairs.length).join(',')
    backend.query(query, pairs.flatten).close
  end
rescue
  backend.rollback if transaction
  raise
else
  backend.commit if transaction
  self
end
slice(*keys, **options) click to toggle source

(see Proxy#slice)

# File lib/moneta/adapters/sqlite.rb, line 113
def slice(*keys, **options)
  query = "select k, v from #{config.table} where k in (#{(['?'] * keys.length).join(',')})"
  backend.execute(query, keys)
end
store(key, value, options = {}) click to toggle source

(see Proxy#store)

# File lib/moneta/adapters/sqlite.rb, line 67
def store(key, value, options = {})
  @replace.execute!(key, value)
  value
end
values_at(*keys, **options) click to toggle source

(see Proxy#values_at)

# File lib/moneta/adapters/sqlite.rb, line 119
def values_at(*keys, **options)
  hash = Hash[slice(*keys, **options)]
  keys.map { |key| hash[key] }
end