Class: SqliteCache
- Inherits:
-
Object
- Object
- SqliteCache
- Defined in:
- lib/sqlite_cache.rb
Overview
Lightweight, persistent cache, to store keys and their values in an SQLite database.
Constant Summary collapse
- TABLE_NAME =
Name of the table in the database to store things in.
'sqlitecache'
Instance Attribute Summary collapse
-
#busy_retries ⇒ Object
Number of times to retry, if database is locked [integer, default 100].
-
#count_hits ⇒ Object
Enable/disable cache hit counting [boolean].
Instance Method Summary collapse
-
#do_cached(key, &block) ⇒ Object
Perform a block if key isn’t already cached.
-
#fetch(key) ⇒ Object
Fetch something from the cache, based on a key string.
-
#initialize(path) ⇒ SqliteCache
constructor
Create a new SQLiteCache.
-
#purge ⇒ Object
Delete everything in the cache.
-
#size ⇒ Object
Return the number of items in the cache.
-
#store(key, value) ⇒ Object
Store a key and value in the cache.
Constructor Details
#initialize(path) ⇒ SqliteCache
Create a new SQLiteCache. Where path is the full path to the SQLite database file to use.
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 |
# File 'lib/sqlite_cache.rb', line 20 def initialize( path ) @db = SQLite3::Database.new( path ) @count_hits = false @busy_retries = 100 # Wait up to 10 seconds to access locked database @db.busy_handler do |resource,retries| sleep 0.1 retries<@busy_retries end # Create the table, if it doesn't exist if @db.table_info(TABLE_NAME).empty? @db.execute( %Q{ CREATE TABLE #{TABLE_NAME} ( id INTEGER PRIMARY KEY AUTOINCREMENT, key TEXT, value TEXT, hits INTEGER DEFAULT 0, created_at INTEGER, updated_at INTEGER ); } ) @db.execute( %Q{ CREATE UNIQUE INDEX key_index ON #{TABLE_NAME} (key) } ) end end |
Instance Attribute Details
#busy_retries ⇒ Object
Number of times to retry, if database is locked [integer, default 100]
14 15 16 |
# File 'lib/sqlite_cache.rb', line 14 def busy_retries @busy_retries end |
#count_hits ⇒ Object
Enable/disable cache hit counting [boolean]
11 12 13 |
# File 'lib/sqlite_cache.rb', line 11 def count_hits @count_hits end |
Instance Method Details
#do_cached(key, &block) ⇒ Object
Perform a block if key isn’t already cached.
103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/sqlite_cache.rb', line 103 def do_cached( key, &block ) # have a look in the cache value = fetch( key ) # Cache HIT? return value unless value.nil? # Cache MISS : execute the block value = block.call( key ) # Store value in the cache return store( key, value ) end |
#fetch(key) ⇒ Object
Fetch something from the cache, based on a key string.
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
# File 'lib/sqlite_cache.rb', line 58 def fetch( key ) key = key.to_s.strip unless key.nil? raise "Invalid key" if key.nil? or key == '' id,value,hits = @db.get_first_row( "SELECT id,value,hits "+ "FROM #{TABLE_NAME} "+ "WHERE key=?", key.to_s.strip ) # Return nil if there is cache MISS. return nil if value.nil? # Increment the number of hits if @count_hits @db.execute( "UPDATE #{TABLE_NAME} SET hits=?, updated_at=? WHERE id=?", hits.to_i+1, Time.now.to_i, id ) end # Otherwise if there is a HIT, parse the YAML into an object return YAML::load(value) end |
#purge ⇒ Object
Delete everything in the cache.
48 49 50 |
# File 'lib/sqlite_cache.rb', line 48 def purge @db.execute( "DELETE FROM #{TABLE_NAME};" ) end |
#size ⇒ Object
Return the number of items in the cache.
53 54 55 |
# File 'lib/sqlite_cache.rb', line 53 def size @db.get_first_value( "SELECT COUNT(*) FROM #{TABLE_NAME};" ).to_i end |
#store(key, value) ⇒ Object
Store a key and value in the cache.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/sqlite_cache.rb', line 85 def store( key, value ) key = key.to_s.strip unless key.nil? raise "Invalid key" if key.nil? or key == '' @db.execute( %Q{ INSERT INTO #{TABLE_NAME} (key,value,created_at) VALUES (?,?,?) }, key, value.to_yaml, Time.now.to_i ) return value end |