Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

initial checkin, couple basic tests

  • Loading branch information...
commit 1ce78660a659aa74706097380cd641125052740b 0 parents
Andrew Grim authored
2  .gitignore
@@ -0,0 +1,2 @@
+test/debug.log
+sti_splitter.*
1  README
@@ -0,0 +1 @@
+# TODO
11 Rakefile
@@ -0,0 +1,11 @@
+require 'rake/testtask'
+
+desc 'Default: run unit tests.'
+task :default => :test
+
+desc 'Test the plugin.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
2  init.rb
@@ -0,0 +1,2 @@
+require 'single_table_inheritance_splitter'
+
32 lib/single_table_inheritance_splitter.rb
@@ -0,0 +1,32 @@
+class SingleTableInheritanceSplitter
+ attr_accessor :source, :destinations
+
+ DISALLOWED_COLUMN_NAMES = %w(id type)
+
+ def initialize(source)
+ self.source = source
+
+ all_types = source.find(:all, :select => 'DISTINCT type').map {|t| t.attributes['type']}
+ self.destinations = {}
+ all_types.each do |type|
+ self.destinations[type] = type.tableize
+ end
+ end
+
+ # Process records from the source table into the destination tables
+ def cleave!
+ destinations.each do |source_type, destination_table_name|
+ # "insert into games(uploaded_by_id, title) select uploaded_by_id, title from games where id=-1;"
+ ActiveRecord::Base.connection.insert <<-SQL
+ INSERT INTO #{destination_table_name}(#{column_names}) SELECT #{column_names} FROM #{source.table_name} AS source_table WHERE source_table.type = '#{source_type}'
+ SQL
+ end
+ end
+
+ def column_names
+ names = self.source.column_names
+
+ names.delete_if { |name| DISALLOWED_COLUMN_NAMES.include?(name) }
+ names.join(', ')
+ end
+end
3  test/database.yml
@@ -0,0 +1,3 @@
+sqlite3:
+ :adapter: sqlite3
+ :dbfile: sti_splitter.sqlite3.db
17 test/models.rb
@@ -0,0 +1,17 @@
+class HighScore < ActiveRecord::Base
+ def self.create!(options = {})
+ type = options.delete(:type)
+ record = super
+ record.update_attribute(:type, type) if type
+ record
+ end
+end
+
+class LifetimeHighScore < ActiveRecord::Base
+end
+
+class DailyHighScore < ActiveRecord::Base
+end
+
+class WeeklyHighScore < ActiveRecord::Base
+end
21 test/schema.rb
@@ -0,0 +1,21 @@
+ActiveRecord::Schema.define(:version => 0) do
+ create_table :high_scores, :force => true do |t|
+ t.string :type
+ t.date :date
+ t.integer :user_id, :value, :statistic_id
+ end
+
+ create_table :daily_high_scores, :force => true do |t|
+ t.date :date
+ t.integer :user_id, :value, :statistic_id
+ end
+
+ create_table :weekly_high_scores, :force => true do |t|
+ t.date :date
+ t.integer :user_id, :value, :statistic_id
+ end
+
+ create_table :lifetime_high_scores, :force => true do |t|
+ t.integer :user_id, :value, :statistic_id
+ end
+end
26 test/single_table_inheritance_splitter_test.rb
@@ -0,0 +1,26 @@
+require File.join(File.dirname(__FILE__), 'test_helper')
+
+class SingleTableInheritanceSplitterTest < Test::Unit::TestCase
+ def setup
+ end
+
+ def test_splitter_knows_what_the_table_will_be_split_into
+ HighScore.create!(:type => 'DailyHighScore')
+ HighScore.create!(:type => 'WeeklyHighScore')
+
+ splitter = SingleTableInheritanceSplitter.new(HighScore)
+ assert_equal HighScore, splitter.source
+ assert_equal({'DailyHighScore' => 'daily_high_scores', 'WeeklyHighScore' => 'weekly_high_scores'}, splitter.destinations)
+ end
+
+ def test_split_moves_data_to_correct_tables
+ daily = HighScore.create!(:type => 'DailyHighScore', :value => 2)
+ weekly = HighScore.create!(:type => 'WeeklyHighScore', :value => 3)
+
+ splitter = SingleTableInheritanceSplitter.new(HighScore)
+ splitter.cleave!
+
+ assert_equal [2], DailyHighScore.find(:all).map(&:value)
+ assert_equal [3], WeeklyHighScore.find(:all).map(&:value)
+ end
+end
33 test/test_helper.rb
@@ -0,0 +1,33 @@
+$:.unshift(File.dirname(__FILE__) + '/../lib')
+
+require 'test/unit'
+require 'rubygems'
+require 'active_support'
+require 'active_record'
+require 'active_record/fixtures'
+require 'action_controller'
+
+require 'ruby-debug'
+Debugger.settings[:autoeval] = true
+Debugger.start
+
+config = YAML::load(IO.read(File.dirname(__FILE__) + '/database.yml'))
+ActiveRecord::Base.logger = Logger.new(File.dirname(__FILE__) + '/debug.log')
+ActiveRecord::Base.establish_connection(config[ENV['DB'] || 'sqlite3'])
+
+load(File.join(File.dirname(__FILE__), 'schema.rb'))
+
+require 'models'
+require File.join(File.dirname(__FILE__), '../init')
+
+
+def assert_same_elements(a1, a2, msg = nil)
+ [:select, :inject, :size].each do |m|
+ [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
+ end
+
+ assert a1h = a1.inject({}) { |h,e| h[e] = a1.select { |i| i == e }.size; h }
+ assert a2h = a2.inject({}) { |h,e| h[e] = a2.select { |i| i == e }.size; h }
+
+ assert_equal(a1h, a2h, msg)
+end
Please sign in to comment.
Something went wrong with that request. Please try again.