sqlitecache 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +56 -0
- data/NEWS +2 -0
- data/README +37 -0
- data/Rakefile +90 -0
- data/lib/sqlite_cache.rb +118 -0
- metadata +67 -0
data/COPYING
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
SqliteCache is copyrighted free software by Nicholas J Humfrey <njh@aelius.com>.
|
2
|
+
You can redistribute it and/or modify it under either the terms of the GPL
|
3
|
+
version 2 (see the file GPL), or the conditions below:
|
4
|
+
|
5
|
+
1. You may make and give away verbatim copies of the source form of the
|
6
|
+
software without restriction, provided that you duplicate all of the
|
7
|
+
original copyright notices and associated disclaimers.
|
8
|
+
|
9
|
+
2. You may modify your copy of the software in any way, provided that
|
10
|
+
you do at least ONE of the following:
|
11
|
+
|
12
|
+
a) place your modifications in the Public Domain or otherwise
|
13
|
+
make them Freely Available, such as by posting said
|
14
|
+
modifications to Usenet or an equivalent medium, or by allowing
|
15
|
+
the author to include your modifications in the software.
|
16
|
+
|
17
|
+
b) use the modified software only within your corporation or
|
18
|
+
organization.
|
19
|
+
|
20
|
+
c) give non-standard binaries non-standard names, with
|
21
|
+
instructions on where to get the original software distribution.
|
22
|
+
|
23
|
+
d) make other distribution arrangements with the author.
|
24
|
+
|
25
|
+
3. You may distribute the software in object code or binary form,
|
26
|
+
provided that you do at least ONE of the following:
|
27
|
+
|
28
|
+
a) distribute the binaries and library files of the software,
|
29
|
+
together with instructions (in the manual page or equivalent)
|
30
|
+
on where to get the original distribution.
|
31
|
+
|
32
|
+
b) accompany the distribution with the machine-readable source of
|
33
|
+
the software.
|
34
|
+
|
35
|
+
c) give non-standard binaries non-standard names, with
|
36
|
+
instructions on where to get the original software distribution.
|
37
|
+
|
38
|
+
d) make other distribution arrangements with the author.
|
39
|
+
|
40
|
+
4. You may modify and include the part of the software into any other
|
41
|
+
software (possibly commercial). But some files in the distribution
|
42
|
+
are not written by the author, so that they are not under these terms.
|
43
|
+
|
44
|
+
For the list of those files and their copying conditions, see the
|
45
|
+
file LEGAL.
|
46
|
+
|
47
|
+
5. The scripts and library files supplied as input to or produced as
|
48
|
+
output from the software do not automatically fall under the
|
49
|
+
copyright of the software, but belong to whomever generated them,
|
50
|
+
and may be sold commercially, and may be aggregated with this
|
51
|
+
software.
|
52
|
+
|
53
|
+
6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
54
|
+
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
55
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
56
|
+
PURPOSE.
|
data/README
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
== SQLiteCache
|
2
|
+
|
3
|
+
SQLiteCache is a gem to allow you cache slow operations in ruby code.
|
4
|
+
It provides a simple API to make it easy to add caching to your ruby code.
|
5
|
+
|
6
|
+
RubyForge Project Page http://rubyforge.org/projects/sqlitecache/
|
7
|
+
|
8
|
+
== Installing
|
9
|
+
|
10
|
+
You may get the latest stable version from Rubyforge. Source gems are also available.
|
11
|
+
|
12
|
+
$ gem install sqlitecache
|
13
|
+
|
14
|
+
=== Loading sqlitecache gem itself
|
15
|
+
|
16
|
+
You have installed the gem already, yeah?
|
17
|
+
|
18
|
+
require 'rubygems'
|
19
|
+
require 'sqlitecache'
|
20
|
+
|
21
|
+
== Example
|
22
|
+
|
23
|
+
cache = SqliteCache('my_cache.db')
|
24
|
+
result = cache.do_cached('key') do
|
25
|
+
my_intensive_operation
|
26
|
+
end
|
27
|
+
|
28
|
+
== Resources
|
29
|
+
|
30
|
+
Documentation: http://sqlitecache.rubyforge.org/
|
31
|
+
|
32
|
+
== Contact
|
33
|
+
|
34
|
+
Author:: Nicholas J Humfrey
|
35
|
+
Email:: njh@aelius.com
|
36
|
+
Home Page:: http://www.aelius.com/njh/
|
37
|
+
License:: Distributes under the same terms as Ruby
|
data/Rakefile
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/gempackagetask'
|
5
|
+
require 'rake/rdoctask'
|
6
|
+
require 'rake/testtask'
|
7
|
+
|
8
|
+
NAME = "sqlitecache"
|
9
|
+
VERS = "0.0.1"
|
10
|
+
CLEAN.include ['pkg', 'rdoc']
|
11
|
+
|
12
|
+
Gem::manage_gems
|
13
|
+
|
14
|
+
spec = Gem::Specification.new do |s|
|
15
|
+
s.name = NAME
|
16
|
+
s.version = VERS
|
17
|
+
s.author = "Nicholas J Humfrey"
|
18
|
+
s.email = "njh@aelius.com"
|
19
|
+
s.homepage = "http://sqlitecache.rubyforge.org"
|
20
|
+
s.platform = Gem::Platform::RUBY
|
21
|
+
s.summary = "SQLite Cache is a gem to allow you cache slow queries in ruby code."
|
22
|
+
s.rubyforge_project = "sqlitecache"
|
23
|
+
s.description = "The SQLite Cache gem allows you cache slow queries in ruby code. It provides a simple API to make it easy to add caching to your ruby code."
|
24
|
+
s.files = FileList["Rakefile", "lib/sqlite_cache.rb", "examples/*"]
|
25
|
+
s.require_path = "lib"
|
26
|
+
|
27
|
+
# rdoc
|
28
|
+
s.has_rdoc = true
|
29
|
+
s.extra_rdoc_files = ["README", "NEWS", "COPYING"]
|
30
|
+
|
31
|
+
# Dependencies
|
32
|
+
s.add_dependency "rake"
|
33
|
+
end
|
34
|
+
|
35
|
+
desc "Default: package up the gem."
|
36
|
+
task :default => :package
|
37
|
+
|
38
|
+
task :build_package => [:repackage]
|
39
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
40
|
+
pkg.need_zip = false
|
41
|
+
pkg.need_tar = true
|
42
|
+
pkg.gem_spec = spec
|
43
|
+
end
|
44
|
+
|
45
|
+
desc "Run :package and install the resulting .gem"
|
46
|
+
task :install => :package do
|
47
|
+
sh %{sudo gem install --local pkg/#{NAME}-#{VERS}.gem}
|
48
|
+
end
|
49
|
+
|
50
|
+
desc "Run :clean and uninstall the .gem"
|
51
|
+
task :uninstall => :clean do
|
52
|
+
sh %{sudo gem uninstall #{NAME}}
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
|
57
|
+
## Testing
|
58
|
+
desc "Run all the specification tests"
|
59
|
+
Rake::TestTask.new(:spec) do |t|
|
60
|
+
t.warning = true
|
61
|
+
t.verbose = true
|
62
|
+
t.pattern = 'spec/*_spec.rb'
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Check the syntax of all ruby files"
|
66
|
+
task :check_syntax do
|
67
|
+
`find . -name "*.rb" |xargs -n1 ruby -c |grep -v "Syntax OK"`
|
68
|
+
puts "* Done"
|
69
|
+
end
|
70
|
+
|
71
|
+
desc "Create rspec report as HTML"
|
72
|
+
task :rspec_html do
|
73
|
+
sh %{spec -f html spec/sqlite_cache_spec.rb > rspec_results.html}
|
74
|
+
end
|
75
|
+
|
76
|
+
## Documentation
|
77
|
+
desc "Generate documentation for the library"
|
78
|
+
Rake::RDocTask.new("rdoc") { |rdoc|
|
79
|
+
rdoc.rdoc_dir = 'rdoc'
|
80
|
+
rdoc.title = "sqlitecache Documentation"
|
81
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
82
|
+
rdoc.main = "README"
|
83
|
+
rdoc.rdoc_files.include("README", "NEWS", "COPYING", "lib/sqlite_cache.rb")
|
84
|
+
}
|
85
|
+
|
86
|
+
desc "Upload rdoc to rubyforge"
|
87
|
+
task :upload_rdoc => [:rdoc] do
|
88
|
+
sh %{/usr/bin/scp -r -p rdoc/* sqlitecache.rubyforge.org:/var/www/gforge-projects/sqlitecache}
|
89
|
+
end
|
90
|
+
|
data/lib/sqlite_cache.rb
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'sqlite3'
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
|
8
|
+
## Lightweight, persistent cache, to store keys and their values in an SQLite database.
|
9
|
+
class SqliteCache
|
10
|
+
## Enable/disable cache hit counting [boolean]
|
11
|
+
attr_accessor :count_hits
|
12
|
+
|
13
|
+
## Number of times to retry, if database is locked [integer, default 100]
|
14
|
+
attr_accessor :busy_retries
|
15
|
+
|
16
|
+
## Name of the table in the database to store things in.
|
17
|
+
TABLE_NAME = 'sqlitecache'
|
18
|
+
|
19
|
+
## Create a new SQLiteCache. Where <tt>path</tt> is the full path to the SQLite database file to use.
|
20
|
+
def initialize( path )
|
21
|
+
@db = SQLite3::Database.new( path )
|
22
|
+
@count_hits = false
|
23
|
+
@busy_retries = 100
|
24
|
+
|
25
|
+
# Wait up to 10 seconds to access locked database
|
26
|
+
@db.busy_handler do |resource,retries|
|
27
|
+
sleep 0.1
|
28
|
+
retries<@busy_retries
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create the table, if it doesn't exist
|
32
|
+
if @db.table_info(TABLE_NAME).empty?
|
33
|
+
@db.execute( %Q{
|
34
|
+
CREATE TABLE #{TABLE_NAME} (
|
35
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
36
|
+
key TEXT,
|
37
|
+
value TEXT,
|
38
|
+
hits INTEGER DEFAULT 0,
|
39
|
+
created_at INTEGER,
|
40
|
+
updated_at INTEGER
|
41
|
+
);
|
42
|
+
} )
|
43
|
+
@db.execute( %Q{ CREATE UNIQUE INDEX key_index ON #{TABLE_NAME} (key) } )
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
## Delete everything in the cache.
|
48
|
+
def purge
|
49
|
+
@db.execute( "DELETE FROM #{TABLE_NAME};" )
|
50
|
+
end
|
51
|
+
|
52
|
+
## Return the number of items in the cache.
|
53
|
+
def size
|
54
|
+
@db.get_first_value( "SELECT COUNT(*) FROM #{TABLE_NAME};" ).to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
## Fetch something from the cache, based on a key string.
|
58
|
+
def fetch( key )
|
59
|
+
key = key.to_s.strip unless key.nil?
|
60
|
+
raise "Invalid key" if key.nil? or key == ''
|
61
|
+
|
62
|
+
id,value,hits = @db.get_first_row(
|
63
|
+
"SELECT id,value,hits "+
|
64
|
+
"FROM #{TABLE_NAME} "+
|
65
|
+
"WHERE key=?",
|
66
|
+
key.to_s.strip
|
67
|
+
)
|
68
|
+
|
69
|
+
# Return nil if there is cache MISS.
|
70
|
+
return nil if value.nil?
|
71
|
+
|
72
|
+
# Increment the number of hits
|
73
|
+
if @count_hits
|
74
|
+
@db.execute(
|
75
|
+
"UPDATE #{TABLE_NAME} SET hits=?, updated_at=? WHERE id=?",
|
76
|
+
hits.to_i+1, Time.now.to_i, id
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Otherwise if there is a HIT, parse the YAML into an object
|
81
|
+
return YAML::load(value)
|
82
|
+
end
|
83
|
+
|
84
|
+
## Store a key and value in the cache.
|
85
|
+
def store( key, value )
|
86
|
+
key = key.to_s.strip unless key.nil?
|
87
|
+
raise "Invalid key" if key.nil? or key == ''
|
88
|
+
|
89
|
+
@db.execute( %Q{
|
90
|
+
INSERT INTO #{TABLE_NAME}
|
91
|
+
(key,value,created_at)
|
92
|
+
VALUES (?,?,?)
|
93
|
+
},
|
94
|
+
key,
|
95
|
+
value.to_yaml,
|
96
|
+
Time.now.to_i
|
97
|
+
)
|
98
|
+
|
99
|
+
return value
|
100
|
+
end
|
101
|
+
|
102
|
+
## Perform a block if key isn't already cached.
|
103
|
+
def do_cached( key, &block )
|
104
|
+
|
105
|
+
# have a look in the cache
|
106
|
+
value = fetch( key )
|
107
|
+
|
108
|
+
# Cache HIT?
|
109
|
+
return value unless value.nil?
|
110
|
+
|
111
|
+
# Cache MISS : execute the block
|
112
|
+
value = block.call( key )
|
113
|
+
|
114
|
+
# Store value in the cache
|
115
|
+
return store( key, value )
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
metadata
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sqlitecache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nicholas J Humfrey
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2008-10-30 00:00:00 +00:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rake
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: "0"
|
23
|
+
version:
|
24
|
+
description: The SQLite Cache gem allows you cache slow queries in ruby code. It provides a simple API to make it easy to add caching to your ruby code.
|
25
|
+
email: njh@aelius.com
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
- NEWS
|
33
|
+
- COPYING
|
34
|
+
files:
|
35
|
+
- Rakefile
|
36
|
+
- lib/sqlite_cache.rb
|
37
|
+
- README
|
38
|
+
- NEWS
|
39
|
+
- COPYING
|
40
|
+
has_rdoc: true
|
41
|
+
homepage: http://sqlitecache.rubyforge.org
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
|
45
|
+
require_paths:
|
46
|
+
- lib
|
47
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: "0"
|
52
|
+
version:
|
53
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: "0"
|
58
|
+
version:
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
rubyforge_project: sqlitecache
|
62
|
+
rubygems_version: 1.1.1
|
63
|
+
signing_key:
|
64
|
+
specification_version: 2
|
65
|
+
summary: SQLite Cache is a gem to allow you cache slow queries in ruby code.
|
66
|
+
test_files: []
|
67
|
+
|