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
- TABLE_NAME =
Name of the table in the database to store things in.
'sqlitecache'
Instance Attribute Summary (collapse)
-
- (Object) busy_retries
Number of times to retry, if database is locked [integer, default 100].
-
- (Object) count_hits
Enable/disable cache hit counting [boolean].
Instance Method Summary (collapse)
-
- (Object) do_cached(key, &block)
Perform a block if key isn't already cached.
-
- (Object) fetch(key)
Fetch something from the cache, based on a key string.
-
- (SqliteCache) initialize(path)
constructor
Create a new SQLiteCache.
-
- (Object) purge
Delete everything in the cache.
-
- (Object) size
Return the number of items in the cache.
-
- (Object) store(key, value)
Store a key and value in the cache.
Constructor Details
- (SqliteCache) initialize(path)
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
- (Object) busy_retries
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 |
- (Object) count_hits
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
- (Object) do_cached(key, &block)
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 |
- (Object) fetch(key)
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 |
- (Object) purge
Delete everything in the cache.
48 49 50 |
# File 'lib/sqlite_cache.rb', line 48 def purge @db.execute( "DELETE FROM #{TABLE_NAME};" ) end |
- (Object) size
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 |
- (Object) store(key, value)
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 |