Permalink
Browse files

First commit: partially working, partially tested

  • Loading branch information...
0 parents commit cc6c0c11701bab83bede31ea6ec939d8747a0a3f @winton winton committed Apr 22, 2009
@@ -0,0 +1,6 @@
+.DS_Store
+*.gem
+tmp
+
+spec/fixtures/database.yml
+spec/fixtures/*.log
@@ -0,0 +1,4 @@
+Version 0.1.0
+-------------
+
+*
@@ -0,0 +1,18 @@
+Copyright (c) 2009 Winton Welsh
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,23 @@
+GemTemplate
+===========
+
+A gem template for new projects.
+
+Setup
+-----
+
+<pre>
+git clone git://github.com/winton/acts_as_archive.git my_project
+cd my_project
+rm -Rf .git
+git init
+git remote add origin git@github.com:winton/my_project.git
+</pre>
+
+Rename these files/folders:
+
+<pre>
+ls **/acts_as_archive*
+</pre>
+
+Do a project-wide find/replace on <code>acts_as_archive</code>.
@@ -0,0 +1,39 @@
+require 'rake'
+
+GEM_NAME = 'acts_as_archive'
+task :default => "#{GEM_NAME}.gemspec"
+
+file "#{GEM_NAME}.gemspec" => FileList[ '{lib,spec}/**', 'Rakefile' ] do |f|
+ # Read spec file and split out manifest section
+ spec = File.read(f.name)
+ parts = spec.split(" # = MANIFEST =\n")
+ fail 'bad spec' if parts.length != 3
+ # Determine file list from git ls-files
+ files = `git ls-files`.
+ split("\n").
+ sort.
+ reject{ |file| file =~ /^\./ }.
+ reject { |file| file =~ /^doc/ }.
+ map{ |file| " #{file}" }.
+ join("\n")
+ # Piece file back together and write
+ parts[1] = " s.files = %w[\n#{files}\n ]\n"
+ spec = parts.join(" # = MANIFEST =\n")
+ File.open(f.name, 'w') { |io| io.write(spec) }
+ puts "Updated #{f.name}"
+end
+
+# Install the gem
+task :install do
+ `sudo gem uninstall #{GEM_NAME} -x`
+ `gem build #{GEM_NAME}.gemspec`
+ `sudo gem install #{GEM_NAME}*.gem`
+ `rm #{GEM_NAME}*.gem`
+end
+
+# rake spec
+desc "Run specs"
+Spec::Rake::SpecTask.new do |t|
+ t.spec_opts = ["--format", "specdoc", "--colour"]
+ t.spec_files = FileList["spec/**/*_spec.rb"]
+end
@@ -0,0 +1,17 @@
+Gem::Specification.new do |s|
+ s.name = 'acts_as_archive'
+ s.version = '0.1.0'
+ s.date = '2009-04-21'
+
+ s.summary = "Moves your deleted records to a different table"
+ s.description = "Moves your deleted records to a different table"
+
+ s.author = 'Winton Welsh'
+ s.email = 'mail@wintoni.us'
+ s.homepage = 'http://github.com/winton/'
+
+ s.has_rdoc = false
+
+ # = MANIFEST =
+ # = MANIFEST =
+end
@@ -0,0 +1 @@
+require File.dirname(__FILE__) + "/rails/init"
@@ -0,0 +1,19 @@
+require File.dirname(__FILE__) + "/acts_as_archive/activerecord/base/destroy"
+require File.dirname(__FILE__) + "/acts_as_archive/activerecord/base/find"
+require File.dirname(__FILE__) + "/acts_as_archive/activerecord/base/migrate"
+require File.dirname(__FILE__) + "/acts_as_archive/activerecord/migration"
+
+module ActsAsArchive
+ def self.included(base)
+ base.extend ActMethods
+ end
+
+ module ActMethods
+ def acts_as_archive
+ include ActiveRecord::Base::Destroy
+ include ActiveRecord::Base::Find
+ include ActiveRecord::Base::Migrate
+ self.create_archive_table unless $TESTING
+ end
+ end
+end
@@ -0,0 +1,58 @@
+module ActsAsArchive
+ module ActiveRecord
+ module Base
+ module Destroy
+
+ def self.included(base)
+ unless base.included_modules.include?(InstanceMethods)
+ base.class_eval do
+ alias_method :destroy_without_callbacks!, :destroy_without_callbacks
+ class <<self
+ alias_method :delete_all!, :delete_all
+ end
+ end
+ base.send :extend, ClassMethods
+ base.send :include, InstanceMethods
+ end
+ end
+
+ module ClassMethods
+ def copy_to_archive_sql(conditions)
+ %{
+ INSERT INTO archived_#{table_name} (#{column_names.join(', ')}, deleted_at)
+ SELECT #{column_names.join(', ')}, '#{Time.now.to_s(:db)}'
+ FROM #{table_name}
+ WHERE #{conditions}
+ }
+ end
+
+ def delete_all(conditions = nil)
+ sql = copy_to_archive_sql(conditions)
+ connection.execute(sql)
+ end
+ end
+
+ module InstanceMethods
+ def destroy_without_callbacks
+ unless new_record?
+ sql = copy_to_archive_sql("#{self.class.primary_key} = #{id}")
+ connection.execute(sql)
+ end
+ freeze
+ end
+
+ def destroy!
+ transaction { destroy_with_callbacks! }
+ end
+
+ def destroy_with_callbacks!
+ return false if callback(:before_destroy) == false
+ result = destroy_without_callbacks!
+ callback(:after_destroy)
+ result
+ end
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,21 @@
+module ActsAsArchive
+ module ActiveRecord
+ module Base
+ module Find
+
+ def self.included(base)
+ unless base.included_modules.include?(InstanceMethods)
+ base.send :extend, ClassMethods
+ base.send :include, InstanceMethods
+ end
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,34 @@
+module ActsAsArchive
+ module ActiveRecord
+ module Base
+ module Migrate
+
+ def self.included(base)
+ unless base.included_modules.include?(InstanceMethods)
+ base.send :extend, ClassMethods
+ base.send :include, InstanceMethods
+ end
+ end
+
+ module ClassMethods
+ def create_archive_table
+ unless connection.table_exists?("archived_#{table_name}")
+ connection.execute("
+ CREATE TABLE archived_#{table_name}
+ AS SELECT * from #{table_name}
+ WHERE false;
+ ")
+ end
+ columns = connection.columns("archived_#{table_name}").collect(&:name)
+ unless columns.include?('deleted_at')
+ connection.add_column("archived_#{table_name}", 'deleted_at', :datetime)
+ end
+ end
+ end
+
+ module InstanceMethods
+ end
+ end
+ end
+ end
+end
@@ -0,0 +1,19 @@
+module ActsAsArchive
+ module ActiveRecord
+ module Migration
+
+ def self.included(base)
+ unless base.included_modules.include?(InstanceMethods)
+ base.send :extend, ClassMethods
+ base.send :include, InstanceMethods
+ end
+ end
+
+ module ClassMethods
+ end
+
+ module InstanceMethods
+ end
+ end
+ end
+end
@@ -0,0 +1,2 @@
+require File.expand_path(File.dirname(__FILE__) + "/../lib/acts_as_archive")
+ActiveRecord::Base.send(:include, ActsAsArchive)
@@ -0,0 +1,11 @@
+require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
+
+describe ActsAsArchive::ActiveRecord::Base::Destroy do
+
+ before(:each) do
+ establish_test_db
+ end
+
+ it "" do
+ end
+end
@@ -0,0 +1,11 @@
+require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
+
+describe ActsAsArchive::ActiveRecord::Base::Destroy do
+
+ before(:each) do
+ establish_test_db
+ end
+
+ it "" do
+ end
+end
@@ -0,0 +1,32 @@
+require File.expand_path(File.dirname(__FILE__) + "/../../../spec_helper")
+
+describe ActsAsArchive::ActiveRecord::Base::Migrate do
+
+ before(:all) do
+ establish_test_db
+ @connection = Article.connection
+ end
+
+ describe 'create_archive_table' do
+
+ before(:all) do
+ Article.create_archive_table
+ @article_columns = @connection.columns("articles").collect(&:name)
+ @archive_columns = @connection.columns("archived_articles").collect(&:name)
+ end
+
+ it "should create an archive table" do
+ @connection.table_exists?("archived_articles").should == true
+ end
+
+ it "should create an archive table with the same structure as the original table" do
+ @article_columns.each do |col|
+ @archive_columns.include?(col).should == true
+ end
+ end
+
+ it "should add a deleted_at column to the archive table" do
+ (@archive_columns - @article_columns).should == [ 'deleted_at' ]
+ end
+ end
+end
@@ -0,0 +1,3 @@
+class Article < ActiveRecord::Base
+ acts_as_archive
+end
@@ -0,0 +1,6 @@
+test:
+ adapter: mysql
+ database: acts_as_archive
+ username: root
+ password:
+ host: localhost
@@ -0,0 +1 @@
+--color
Oops, something went wrong.

0 comments on commit cc6c0c1

Please sign in to comment.