Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

The great rewrite has begun (Rails 3 coming soon!)

  • Loading branch information...
commit 9f2c9546723f40a917928a68e56683ee934b88c0 1 parent 4fb7de4
@winton authored
View
2  README.md
@@ -95,7 +95,7 @@ To keep insertions fast, there are no indexes on your archive table by default.
If you are querying your archive a lot, you will want to add indexes:
<pre>
-class Article < ActiveRecord::Base
+class Article &lt; ActiveRecord::Base
acts_as_archive :indexes => [ :id, :created_at, :deleted_at ]
end
</pre>
View
126 lib/acts_as_archive.rb
@@ -2,30 +2,38 @@
ActsAsArchive::Gems.require(:lib)
+require 'also_migrate'
+require 'mover'
+
$:.unshift File.dirname(__FILE__) + '/acts_as_archive'
require 'version'
-module ActsAsArchive
+class ActsAsArchive
- def self.migrate_from_acts_as_paranoid(klass)
- if respond_to?(:acts_as_archive?) && acts_as_archive?
- time = Benchmark.measure do
- if column_names.include?('deleted_at')
- if table_exists? && archive_table_exists?
- condition = "deleted_at IS NOT NULL"
- if self.count_by_sql("SELECT COUNT(*) FROM #{table_name} WHERE #{condition}") > 0
- self.move_to(
- Archive,
- :conditions => condition,
- :migrate => true
- )
- end
- end
+ class <<self
+ attr_accessor :configuration
+
+ def find(from)
+ (@configuration || []).select do |hash|
+ if from[0].is_a?(::String)
+ from.include?(hash[:from].table_name)
+ else
+ from.include?(hash[:from])
+ end
+ end
+ end
+
+ def move(config, where, merge_options={})
+ config[:to].each do |to|
+ options = config[:options].dup.merge(merge_options)
+ if options[:conditions]
+ options[:conditions] += " AND #{where}"
+ elsif where
+ options[:conditions] = where
end
+ config[:from].move_to(to, options)
end
- $stdout.puts "-- ActsAsArchive.update(#{models.join(', ')})"
- $stdout.puts " -> #{"%.4fs" % time.real}"
end
end
@@ -35,36 +43,92 @@ def self.included(base)
end
module ActMethods
- def acts_as_archive(options={})
+ def acts_as_archive(*args)
+ return if ActsAsArchive.find(self)
+
+ options = args.last.is_a?(::Hash) ? args.pop : {}
+ options[:copy] = true
+ options[:magic] = 'deleted_at' if options[:magic].nil?
+ options[:add] = [[ options[:magic], :datetime ]]
+ options[:ignore] = options[:magic]
+ options[:timestamps] = false if options[:timestamps].nil?
+
+ if args.empty?
+ class_eval <<-EVAL
+ class Archive < ActiveRecord::Base
+ set_table_name "archived_#{self.table_name}"
+ end
+ EVAL
+ args << self::Archive
+ end
+
+ args.each do |klass|
+ klass.class_eval <<-EVAL
+ record_timestamps = #{options[:timestamps].inspect}
+ acts_as_archive(
+ #{self},
+ :magic => nil,
+ :migrate => false,
+ :timestamps => true,
+ :subtract => #{options[:magic] ? options[:magic].inspect : 'nil'}
+ )
+ EVAL
+ unless options[:migrate] == false
+ self.also_migrate klass.table_name, options
+ end
+ end
+
+ ActsAsArchive.configuration ||= []
+ ActsAsArchive.configuration << {
+ :from => self,
+ :to => args,
+ :options => options
+ }
end
end
end
- module AbstractAdapter
+ module DatabaseStatements
def self.included(base)
unless base.included_modules.include?(InstanceMethods)
- base.send :extend, ClassMethods
+ base.send :include, InstanceMethods
base.class_eval do
- class <<self
- unless method_defined?(:delete_sql_without_archive)
- alias_method :delete_sql_without_archive, :delete_sql
- alias_method :delete_sql, :delete_sql_with_archive
- end
+ unless method_defined?(:delete_sql_without_archive)
+ alias_method :delete_sql_without_archive, :delete_sql
+ alias_method :delete_sql, :delete_sql_with_archive
end
end
end
end
-
- module ClassMethods
+
+ module InstanceMethods
def delete_sql_with_archive(sql, name = nil)
+ from, where = /DELETE FROM (.+)/i.match(sql)[1].split(/\s+WHERE\s+/i, 2)
+ from = from.gsub(/`/, '').split(/\s*,\s*/)
+
+ ActsAsArchive.find(from).each do |config|
+ ActsAsArchive.move(config, where)
+ end
+
delete_sql_without_archive(sql, name)
end
- end
-
- module InstanceMethods
+
+ def migrate_from_acts_as_paranoid
+ time = Benchmark.measure do
+ ActsAsArchive.find(self).each do |config|
+ ActsAsArchive.move(
+ config,
+ "#{config[:options][:magic]} IS NOT NULL",
+ :migrate => true
+ )
+ end
+ end
+ $stdout.puts "-- #{self.class}.migrate_from_acts_as_paranoid"
+ $stdout.puts " -> #{"%.4fs" % time.real}"
+ end
end
end
end
ActiveRecord::Base.send(:include, ActsAsArchive::Base)
-ActiveRecord::ConnectionAdapters::AbstractAdapter.send(:include, ActsAsArchive::AbstractAdapter)
+ActiveRecord::ConnectionAdapters::DatabaseStatements.send(:include, ActsAsArchive::DatabaseStatements)
View
8 lib/acts_as_archive/gems.rb
@@ -2,19 +2,21 @@
require 'rubygems'
- module ActsAsArchive
+ class ActsAsArchive
class Gems
VERSIONS = {
:active_wrapper => '=0.3.4',
+ :also_migrate => '0.2.1',
+ :mover => '0.3.3',
:rake => '=0.8.7',
:rspec => '=1.3.1'
}
TYPES = {
- :gemspec => [],
+ :gemspec => [ :also_migrate, :mover ],
:gemspec_dev => [ :active_wrapper, :rspec ],
- :lib => [],
+ :lib => [ :also_migrate, :mover ],
:rake => [ :rake, :rspec ],
:spec => [ :active_wrapper, :rspec ],
:spec_rake => [ :active_wrapper ]
View
2  lib/acts_as_archive/version.rb
@@ -1,3 +1,3 @@
-module ActsAsArchive
+class ActsAsArchive
VERSION = "0.2.5" unless defined?(::ActsAsArchive::VERSION)
end
View
4 spec/Rakefile
@@ -1,5 +1,5 @@
-require File.expand_path(File.dirname(__FILE__) + '/../lib/gem_template/gems')
-GemTemplate::Gems.require(:spec_rake)
+require File.expand_path(File.dirname(__FILE__) + '/../lib/acts_as_archive/gems')
+ActsAsArchive::Gems.require(:spec_rake)
require 'active_wrapper/tasks'
View
9 spec/acts_as_archive_spec.rb
@@ -0,0 +1,9 @@
+require 'spec_helper'
+
+describe ActsAsArchive do
+ it "should" do
+ [ 1, 0, 1 ].each { |v| $db.migrate(v) }
+ a = Article.create
+ a.destroy
+ end
+end
View
2  spec/config/database.yml.example
@@ -1,6 +1,6 @@
test:
adapter: mysql
- database: gem_template
+ database: acts_as_archive
username: root
password:
host: localhost
View
11 spec/db/migrate/001_articles.rb
@@ -0,0 +1,11 @@
+class Articles < ActiveRecord::Migration
+ def self.up
+ create_table :articles do |t|
+ t.string :blah
+ end
+ end
+
+ def self.down
+ drop_table :articles
+ end
+end
View
3  spec/fixtures/article.rb
@@ -0,0 +1,3 @@
+class Article < ActiveRecord::Base
+ acts_as_archive
+end
View
1  spec/spec_helper.rb
@@ -6,6 +6,7 @@
require 'active_wrapper'
require "#{$root}/lib/acts_as_archive"
+require "#{$root}/spec/fixtures/article"
require 'pp'
Spec::Runner.configure do |config|
Please sign in to comment.
Something went wrong with that request. Please try again.