comboy-cached_record 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/History.txt ADDED
@@ -0,0 +1,4 @@
1
+ == 1.0.0 / 2008-11-22
2
+
3
+ * 1 major enhancement
4
+ * Birthday!
data/Manifest.txt ADDED
@@ -0,0 +1,22 @@
1
+ History.txt
2
+ Manifest.txt
3
+ README.txt
4
+ Rakefile
5
+ bin/cached_record
6
+ lib/cached_record.rb
7
+ spec/cached_record_spec.rb
8
+ spec/spec_helper.rb
9
+ tasks/ann.rake
10
+ tasks/bones.rake
11
+ tasks/gem.rake
12
+ tasks/git.rake
13
+ tasks/manifest.rake
14
+ tasks/notes.rake
15
+ tasks/post_load.rake
16
+ tasks/rdoc.rake
17
+ tasks/rubyforge.rake
18
+ tasks/setup.rb
19
+ tasks/spec.rake
20
+ tasks/svn.rake
21
+ tasks/test.rake
22
+ test/test_cached_record.rb
data/README.txt ADDED
@@ -0,0 +1,58 @@
1
+ cached_record
2
+ by Kacper Cieśla (comboy)
3
+ FIXME (url)
4
+
5
+ == DESCRIPTION:
6
+
7
+ caching for activerecord using memcached
8
+
9
+ == FEATURES/PROBLEMS:
10
+
11
+ * I
12
+ * am (features)
13
+ * so
14
+ * lazy (problems)
15
+
16
+ == SYNOPSIS:
17
+
18
+ require 'cached_record'
19
+
20
+ class User < CachedRecord::Base
21
+
22
+ # normal AR class here
23
+
24
+ end
25
+
26
+ == REQUIREMENTS:
27
+
28
+ * active_record
29
+ * memcache
30
+
31
+ == INSTALL:
32
+
33
+ sudo gem install cached_record
34
+
35
+ == LICENSE:
36
+
37
+ (The MIT License)
38
+
39
+ Copyright (c) 2008 Kacper Cieśla
40
+
41
+ Permission is hereby granted, free of charge, to any person obtaining
42
+ a copy of this software and associated documentation files (the
43
+ 'Software'), to deal in the Software without restriction, including
44
+ without limitation the rights to use, copy, modify, merge, publish,
45
+ distribute, sublicense, and/or sell copies of the Software, and to
46
+ permit persons to whom the Software is furnished to do so, subject to
47
+ the following conditions:
48
+
49
+ The above copyright notice and this permission notice shall be
50
+ included in all copies or substantial portions of the Software.
51
+
52
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
53
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
54
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
55
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
56
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
57
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
58
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ # Look in the tasks/setup.rb file for the various options that can be
2
+ # configured in this Rakefile. The .rake files in the tasks directory
3
+ # are where the options are used.
4
+
5
+ load 'tasks/setup.rb'
6
+
7
+ ensure_in_path 'lib'
8
+ require 'cached_record'
9
+
10
+ task :default => 'spec:run'
11
+
12
+ PROJ.name = 'cached_record'
13
+ PROJ.authors = 'Kacper Cieśla (comboy)'
14
+ PROJ.email = 'kacper.ciesla@gmail.com'
15
+ PROJ.url = 'FIXME (project homepage)'
16
+ PROJ.rubyforge.name = 'cached_record'
17
+
18
+ PROJ.spec.opts << '--color'
19
+
20
+
21
+ namespace :test do
22
+ desc 'Prepare data for testing'
23
+ task :prepare do
24
+ require 'test/environment'
25
+ CachedRecord::TestEnvironment.setup_db
26
+ end
27
+ end
28
+
29
+ # EOF
@@ -0,0 +1,60 @@
1
+ # $Id$
2
+
3
+ require 'rubygems'
4
+ require 'activerecord'
5
+ require 'memcache'
6
+
7
+ # Equivalent to a header guard in C/C++
8
+ # Used to prevent the class/module from being loaded more than once
9
+ unless defined? CachedRecord
10
+
11
+ module CachedRecord
12
+
13
+ # :stopdoc:
14
+ VERSION = '0.0.1'
15
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
16
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
17
+ # :startdoc:
18
+
19
+ # Returns the version string for the library.
20
+ #
21
+ def self.version
22
+ VERSION
23
+ end
24
+
25
+ # Returns the library path for the module. If any arguments are given,
26
+ # they will be joined to the end of the libray path using
27
+ # <tt>File.join</tt>.
28
+ #
29
+ def self.libpath( *args )
30
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
31
+ end
32
+
33
+ # Returns the lpath for the module. If any arguments are given,
34
+ # they will be joined to the end of the path using
35
+ # <tt>File.join</tt>.
36
+ #
37
+ def self.path( *args )
38
+ args.empty? ? PATH : ::File.join(PATH, *args)
39
+ end
40
+
41
+ # Utility method used to rquire all files ending in .rb that lie in the
42
+ # directory below this file that has the same name as the filename passed
43
+ # in. Optionally, a specific _directory_ name can be passed in such that
44
+ # the _filename_ does not have to be equivalent to the directory.
45
+ #
46
+ def self.require_all_libs_relative_to( fname, dir = nil )
47
+ dir ||= ::File.basename(fname, '.*')
48
+ search_me = ::File.expand_path(
49
+ ::File.join(::File.dirname(fname), dir, '**', '*.rb'))
50
+
51
+ Dir.glob(search_me).sort.each {|rb| require rb}
52
+ end
53
+
54
+ end # module CachedRecord
55
+
56
+ CachedRecord.require_all_libs_relative_to __FILE__
57
+
58
+ end # unless defined?
59
+
60
+ # EOF
@@ -0,0 +1,39 @@
1
+ module CachedRecord
2
+ class Base < ::ActiveRecord::Base
3
+
4
+ class << self
5
+
6
+ def find_one(id,options)
7
+ return super unless options.empty?
8
+ key = "#{self.table_name}::#{id}"
9
+ if value = cache_store.get(key)
10
+ else
11
+ value = super
12
+ cache_store.set(key,value)
13
+ end
14
+ return value
15
+ end
16
+
17
+ def cache_store
18
+ @cache_store ||= ::CachedRecord.cache_store
19
+ end
20
+
21
+ end
22
+
23
+ def save(run_validations = true)
24
+ self.class.cache_store.set "#{self.class.table_name}::#{id}", nil
25
+ super
26
+ end
27
+
28
+ self.abstract_class = true
29
+ end
30
+
31
+ def self.cache_store
32
+ @cache_store ||= ::CACHE
33
+ end
34
+
35
+ def self.cache_store=(cache)
36
+ @cache_store = cache
37
+ end
38
+
39
+ end
data/tasks/ann.rake ADDED
@@ -0,0 +1,81 @@
1
+ # $Id$
2
+
3
+ begin
4
+ require 'bones/smtp_tls'
5
+ rescue LoadError
6
+ require 'net/smtp'
7
+ end
8
+ require 'time'
9
+
10
+ namespace :ann do
11
+
12
+ # A prerequisites task that all other tasks depend upon
13
+ task :prereqs
14
+
15
+ file PROJ.ann.file do
16
+ ann = PROJ.ann
17
+ puts "Generating #{ann.file}"
18
+ File.open(ann.file,'w') do |fd|
19
+ fd.puts("#{PROJ.name} version #{PROJ.version}")
20
+ fd.puts(" by #{Array(PROJ.authors).first}") if PROJ.authors
21
+ fd.puts(" #{PROJ.url}") if PROJ.url.valid?
22
+ fd.puts(" (the \"#{PROJ.release_name}\" release)") if PROJ.release_name
23
+ fd.puts
24
+ fd.puts("== DESCRIPTION")
25
+ fd.puts
26
+ fd.puts(PROJ.description)
27
+ fd.puts
28
+ fd.puts(PROJ.changes.sub(%r/^.*$/, '== CHANGES'))
29
+ fd.puts
30
+ ann.paragraphs.each do |p|
31
+ fd.puts "== #{p.upcase}"
32
+ fd.puts
33
+ fd.puts paragraphs_of(PROJ.readme_file, p).join("\n\n")
34
+ fd.puts
35
+ end
36
+ fd.puts ann.text if ann.text
37
+ end
38
+ end
39
+
40
+ desc "Create an announcement file"
41
+ task :announcement => ['ann:prereqs', PROJ.ann.file]
42
+
43
+ desc "Send an email announcement"
44
+ task :email => ['ann:prereqs', PROJ.ann.file] do
45
+ ann = PROJ.ann
46
+ from = ann.email[:from] || PROJ.email
47
+ to = Array(ann.email[:to])
48
+
49
+ ### build a mail header for RFC 822
50
+ rfc822msg = "From: #{from}\n"
51
+ rfc822msg << "To: #{to.join(',')}\n"
52
+ rfc822msg << "Subject: [ANN] #{PROJ.name} #{PROJ.version}"
53
+ rfc822msg << " (#{PROJ.release_name})" if PROJ.release_name
54
+ rfc822msg << "\n"
55
+ rfc822msg << "Date: #{Time.new.rfc822}\n"
56
+ rfc822msg << "Message-Id: "
57
+ rfc822msg << "<#{"%.8f" % Time.now.to_f}@#{ann.email[:domain]}>\n\n"
58
+ rfc822msg << File.read(ann.file)
59
+
60
+ params = [:server, :port, :domain, :acct, :passwd, :authtype].map do |key|
61
+ ann.email[key]
62
+ end
63
+
64
+ params[3] = PROJ.email if params[3].nil?
65
+
66
+ if params[4].nil?
67
+ STDOUT.write "Please enter your e-mail password (#{params[3]}): "
68
+ params[4] = STDIN.gets.chomp
69
+ end
70
+
71
+ ### send email
72
+ Net::SMTP.start(*params) {|smtp| smtp.sendmail(rfc822msg, from, to)}
73
+ end
74
+ end # namespace :ann
75
+
76
+ desc 'Alias to ann:announcement'
77
+ task :ann => 'ann:announcement'
78
+
79
+ CLOBBER << PROJ.ann.file
80
+
81
+ # EOF
data/tasks/bones.rake ADDED
@@ -0,0 +1,21 @@
1
+ # $Id$
2
+
3
+ if HAVE_BONES
4
+
5
+ namespace :bones do
6
+
7
+ desc 'Show the PROJ open struct'
8
+ task :debug do |t|
9
+ atr = if t.application.top_level_tasks.length == 2
10
+ t.application.top_level_tasks.pop
11
+ end
12
+
13
+ if atr then Bones::Debug.show_attr(PROJ, atr)
14
+ else Bones::Debug.show PROJ end
15
+ end
16
+
17
+ end # namespace :bones
18
+
19
+ end # HAVE_BONES
20
+
21
+ # EOF
data/tasks/gem.rake ADDED
@@ -0,0 +1,126 @@
1
+ # $Id$
2
+
3
+ require 'rake/gempackagetask'
4
+
5
+ namespace :gem do
6
+
7
+ PROJ.gem._spec = Gem::Specification.new do |s|
8
+ s.name = PROJ.name
9
+ s.version = PROJ.version
10
+ s.summary = PROJ.summary
11
+ s.authors = Array(PROJ.authors)
12
+ s.email = PROJ.email
13
+ s.homepage = Array(PROJ.url).first
14
+ s.rubyforge_project = PROJ.rubyforge.name
15
+
16
+ s.description = PROJ.description
17
+
18
+ PROJ.gem.dependencies.each do |dep|
19
+ s.add_dependency(*dep)
20
+ end
21
+
22
+ s.files = PROJ.gem.files
23
+ s.executables = PROJ.gem.executables.map {|fn| File.basename(fn)}
24
+ s.extensions = PROJ.gem.files.grep %r/extconf\.rb$/
25
+
26
+ s.bindir = 'bin'
27
+ dirs = Dir["{#{PROJ.libs.join(',')}}"]
28
+ s.require_paths = dirs unless dirs.empty?
29
+
30
+ incl = Regexp.new(PROJ.rdoc.include.join('|'))
31
+ excl = PROJ.rdoc.exclude.dup.concat %w[\.rb$ ^(\.\/|\/)?ext]
32
+ excl = Regexp.new(excl.join('|'))
33
+ rdoc_files = PROJ.gem.files.find_all do |fn|
34
+ case fn
35
+ when excl; false
36
+ when incl; true
37
+ else false end
38
+ end
39
+ s.rdoc_options = PROJ.rdoc.opts + ['--main', PROJ.rdoc.main]
40
+ s.extra_rdoc_files = rdoc_files
41
+ s.has_rdoc = true
42
+
43
+ if test ?f, PROJ.test.file
44
+ s.test_file = PROJ.test.file
45
+ else
46
+ s.test_files = PROJ.test.files.to_a
47
+ end
48
+
49
+ # Do any extra stuff the user wants
50
+ PROJ.gem.extras.each do |msg, val|
51
+ case val
52
+ when Proc
53
+ val.call(s.send(msg))
54
+ else
55
+ s.send "#{msg}=", val
56
+ end
57
+ end
58
+ end # Gem::Specification.new
59
+
60
+ # A prerequisites task that all other tasks depend upon
61
+ task :prereqs
62
+
63
+ desc 'Show information about the gem'
64
+ task :debug => 'gem:prereqs' do
65
+ puts PROJ.gem._spec.to_ruby
66
+ end
67
+
68
+ pkg = Rake::PackageTask.new(PROJ.name, PROJ.version) do |pkg|
69
+ pkg.need_tar = PROJ.gem.need_tar
70
+ pkg.need_zip = PROJ.gem.need_zip
71
+ pkg.package_files += PROJ.gem._spec.files
72
+ end
73
+ Rake::Task['gem:package'].instance_variable_set(:@full_comment, nil)
74
+
75
+ gem_file = if PROJ.gem._spec.platform == Gem::Platform::RUBY
76
+ "#{pkg.package_name}.gem"
77
+ else
78
+ "#{pkg.package_name}-#{PROJ.gem._spec.platform}.gem"
79
+ end
80
+
81
+ desc "Build the gem file #{gem_file}"
82
+ task :package => ['gem:prereqs', "#{pkg.package_dir}/#{gem_file}"]
83
+
84
+ file "#{pkg.package_dir}/#{gem_file}" => [pkg.package_dir] + PROJ.gem._spec.files do
85
+ when_writing("Creating GEM") {
86
+ Gem::Builder.new(PROJ.gem._spec).build
87
+ verbose(true) {
88
+ mv gem_file, "#{pkg.package_dir}/#{gem_file}"
89
+ }
90
+ }
91
+ end
92
+
93
+ desc 'Install the gem'
94
+ task :install => [:clobber, 'gem:package'] do
95
+ sh "#{SUDO} #{GEM} install --local pkg/#{PROJ.gem._spec.full_name}"
96
+
97
+ # use this version of the command for rubygems > 1.0.0
98
+ #sh "#{SUDO} #{GEM} install --no-update-sources pkg/#{PROJ.gem._spec.full_name}"
99
+ end
100
+
101
+ desc 'Uninstall the gem'
102
+ task :uninstall do
103
+ installed_list = Gem.source_index.find_name(PROJ.name)
104
+ if installed_list and installed_list.collect { |s| s.version.to_s}.include?(PROJ.version) then
105
+ sh "#{SUDO} #{GEM} uninstall --version '#{PROJ.version}' --ignore-dependencies --executables #{PROJ.name}"
106
+ end
107
+ end
108
+
109
+ desc 'Reinstall the gem'
110
+ task :reinstall => [:uninstall, :install]
111
+
112
+ desc 'Cleanup the gem'
113
+ task :cleanup do
114
+ sh "#{SUDO} #{GEM} cleanup #{PROJ.gem._spec.name}"
115
+ end
116
+
117
+ end # namespace :gem
118
+
119
+ desc 'Alias to gem:package'
120
+ task :gem => 'gem:package'
121
+
122
+ task :clobber => 'gem:clobber_package'
123
+
124
+ remove_desc_for_task %w(gem:clobber_package)
125
+
126
+ # EOF