Permalink
Browse files

General refactoring and cleanup

  • Loading branch information...
1 parent 10a5a54 commit 76bb4a31f27eb6a375d462d952a3c339455c5c51 @brasten committed Aug 16, 2011
View
@@ -1,4 +1,6 @@
.rvmrc
.rspec
.idea
-pkg
+pkg
+.bundle
+coverage
View
@@ -2,5 +2,7 @@ source :rubygems
group :development do
gem "rspec", ">= 2.6"
+ gem "simplecov", "0.4.2"
gem "activerecord", "~> 3.0.0"
+ gem "sqlite3-ruby"
end
View
@@ -23,6 +23,12 @@ GEM
rspec-expectations (2.6.0)
diff-lcs (~> 1.1.2)
rspec-mocks (2.6.0)
+ simplecov (0.4.2)
+ simplecov-html (~> 0.4.4)
+ simplecov-html (0.4.5)
+ sqlite3 (1.3.4)
+ sqlite3-ruby (1.3.3)
+ sqlite3 (>= 1.3.3)
tzinfo (0.3.29)
PLATFORMS
@@ -31,3 +37,5 @@ PLATFORMS
DEPENDENCIES
activerecord (~> 3.0.0)
rspec (>= 2.6)
+ simplecov (= 0.4.2)
+ sqlite3-ruby
@@ -1,3 +1,4 @@
+require 'active_record'
require 'active_record/connection_adapters/abstract/connection_pool'
module ActiveShard
@@ -15,7 +16,7 @@ class ConnectionHandler < ::ActiveRecord::ConnectionAdapters::ConnectionHandler
#
# @param [Array<ShardDefinition>] shard_definitions
# @param [Hash] options
- # @option options [ShardLookupHandler] :shard_lookup
+ # @option options [ShardLookupHandler, #lookup_active_shard] :shard_lookup
#
def initialize( shard_definitions, options={} )
@shard_lookup = options[ :shard_lookup ]
@@ -28,26 +29,26 @@ def initialize( shard_definitions, options={} )
def initialize_shard_definitions( definitions )
definitions.each do |definition|
- schema_pools[ definition.schema.to_sym ] ||= SchemaConnectionPool.new(
- ::ActiveRecord::Base::ConnectionSpecification.new( definition.connection_spec, definition.adapter_method )
- )
+ schema_pools[ definition.schema.to_sym ] ||= new_schema_pool( definition )
- connection_pools[ connection_pool_id( definition.schema, definition.name ) ] =
- ::ActiveRecord::ConnectionAdapters::ConnectionPool.new(
- ::ActiveRecord::Base::ConnectionSpecification.new( definition.connection_spec, definition.adapter_method )
- )
+ connection_pools[ connection_pool_id( definition.schema, definition.name ) ] = new_connection_pool( definition )
end
end
+ # I want to put this in here, but it seems to cause problems that I haven't yet tracked down. [BLS]
+ #
#def establish_connection( *args )
# raise NoMethodError, "Sharded models do not support establish_connection"
#end
# Retrieve connection pool for class
#
+ # @param [#schema_name] klass An object which responds to #schema_name
+ # @return [ConnectionPool,SchemaConnectionPool] connection pool
+ #
def retrieve_connection_pool( klass )
- schema_name = klass.schema_name
+ schema_name = ( sn = klass.schema_name ).nil? ? nil : sn.to_sym
active_shard_name = shard_lookup.lookup_active_shard( schema_name )
@@ -60,6 +61,30 @@ def retrieve_connection_pool( klass )
attr_reader :schema_pools
+ def new_schema_pool( definition )
+ schema_pool_class.new(
+ connection_specification_class.new( definition.connection_spec, definition.adapter_method )
+ )
+ end
+
+ def new_connection_pool( definition )
+ connection_pool_class.new(
+ connection_specification_class.new( definition.connection_spec, definition.adapter_method )
+ )
+ end
+
+ def connection_pool_class
+ ::ActiveRecord::ConnectionAdapters::ConnectionPool
+ end
+
+ def schema_pool_class
+ SchemaConnectionPool
+ end
+
+ def connection_specification_class
+ ::ActiveRecord::Base::ConnectionSpecification
+ end
+
def connection_pool_id( schema_name, shard_name )
"#{schema_name.to_s}+#{shard_name.to_s}".to_sym
end
@@ -0,0 +1,30 @@
+module ActiveShard
+ module ActiveRecord
+ class PoolFactory
+
+ attr_accessor :connection_pool_class
+ attr_accessor :schema_pool_class
+
+ # Initializes a new PoolFactory
+ #
+ # @param [Hash] options
+ # @option options [Class] connection_pool_class
+ # @option options [Class] schema_pool_class
+ #
+ def initialize( options={} )
+ @connection_pool_class = options[:connection_pool_class]
+ @schema_pool_class = options[:schema_pool_class]
+ end
+
+
+ def create_connection_pool( definition )
+
+ end
+
+ def create_schema_pool( definition )
+
+ end
+
+ end
+ end
+end
@@ -4,19 +4,19 @@ module ActiveShard
module ActiveRecord
class SchemaConnectionAdapter
- delegate :columns, :verify, :verify!, :run_callbacks, :quote_table_name, :quote_value, :quote, :to => :adapter
+ delegate :columns, :verify, :verify!, :run_callbacks, :quote_table_name, :quote_value, :quote, :to => :target
- def initialize( adapter )
- @adapter = adapter
+ def initialize( target )
+ @target = target
end
def method_missing( sym, *args, &block )
raise ::ActiveShard::NoActiveShardError
end
private
- def adapter
- @adapter
+ def target
+ @target
end
end
end
@@ -6,11 +6,12 @@ module ActiveShard
# than nesting.
#
+ # Base exception for all ActiveShard errors
+ #
class ActiveShardError < StandardError; end
class DefinitionError < ActiveShardError; end
class NameNotUniqueError < DefinitionError; end
-
class NoActiveShardError < ActiveShardError; end
end
@@ -52,6 +52,9 @@ def push( active_shards )
# Remove the last scope from the stack
#
+ # FIXME: Symbols (for AnySchema) may not roll back properly if multiple
+ # the same symbol is on the stack several times
+ #
def pop( pop_until=nil )
if pop_until.nil?
scope_crumbs.pop
@@ -17,7 +17,7 @@ class ScopeManager
# scope instances
#
def initialize( options={} )
- @scope_class = options[:scope_class] if options[:scope_class]
+ self.scope_class = options[:scope_class] if options[:scope_class]
end
# @see ActiveShard::Scope#push
@@ -15,9 +15,31 @@ class << self
# @return [Hash] hash of environments and lists of Definitions
#
def from_yaml_file( file_name )
- definitions = {}
+ from_yaml( File.open( file_name ).read() )
+ end
+
+ # Returns a hash with environments as the hash keys and
+ # a list of ShardDefinitions as the hash values
+ #
+ # @param [String] yaml YAML string to parse
+ #
+ # @return [Hash] hash of environments and lists of Definitions
+ #
+ def from_yaml( yaml )
+ hash = YAML.load( ERB.new( yaml ).result )
- hash = YAML.load( ERB.new( File.open( file_name ).read() ).result )
+ from_hash( hash )
+ end
+
+ # Returns a hash with environments as the hash keys and
+ # a list of ShardDefinitions as the hash values
+ #
+ # @param [Hash] hash raw hash in YAML-format
+ #
+ # @return [Hash] hash of environments and lists of Definitions
+ #
+ def from_hash( hash )
+ definitions = {}
hash.each_pair do |environment, schemas|
schemas.each_pair do |schema, shards|
@@ -1,28 +1,26 @@
module ActiveShard
- # Handles current and schema shard resolution using the current
- # scope and
+ # Handles current shard resolution using the provided scope
+ #
class ShardLookupHandler
# Initializes a shard lookup handler
#
# @param [Hash] options
# @option options [Scope,ScopeManager] :scope
- # @option options [Config] :config
- # scope instances
#
def initialize( options={} )
@scope = options[:scope]
- @config = options[:config]
end
+ # Returns the active shard for the provided schema, or nil if none.
+ #
+ # @param [Symbol] schema_name
+ # @return [Symbol, nil] shard name if any
+ #
def lookup_active_shard( schema_name )
@scope.active_shard_for_schema( schema_name )
end
- def lookup_schema_shard( schema_name )
- @config.schema_shard_name_by_schema( schema_name )
- end
-
end
end
@@ -0,0 +1,89 @@
+require 'spec_helper'
+require 'active_shard/active_record/connection_handler'
+
+module ActiveShard::ActiveRecord
+
+ describe ConnectionHandler do
+ let :shard_definitions do
+ yaml = <<-EOY
+test:
+ schema_one:
+ shard_one:
+ adapter: sqlite3
+ database: spec/output/shard_one.db
+ shard_two:
+ adapter: sqlite3
+ database: spec/output/shard_two.db
+ schema_two:
+ shard_three:
+ adapter: sqlite3
+ database: spec/output/shard_three.db
+ shard_four:
+ adapter: sqlite3
+ database: spec/output/shard_four.db
+ shard_five:
+ adapter: sqlite3
+ database: spec/output/shard_five.db
+ schema_three:
+ shard_six:
+ adapter: sqlite3
+ database: spec/output/shard_six.db
+ shard_seven:
+ adapter: sqlite3
+ database: spec/output/shard_seven.db
+EOY
+ ActiveShard::ShardDefinition.from_yaml( yaml )[:test]
+ end
+
+ describe "#retrieve_connection_pool" do
+ context "with schema/shards" do
+ let :lookup_handler do
+ handler = mock(:handler)
+ handler.stub!(:lookup_active_shard).and_return(nil)
+ handler
+ end
+
+ let :handler do
+ ConnectionHandler.new( shard_definitions, :shard_lookup => lookup_handler )
+ end
+
+ context "with active shards :schema_one => :shard_two, :schema_two => :shard_four" do
+ let :lookup_handler do
+ handler = mock(:handler)
+ handler.stub!(:lookup_active_shard).with(:schema_one).and_return(:shard_two)
+ handler.stub!(:lookup_active_shard).with(:schema_two).and_return(:shard_four)
+ handler.stub!(:lookup_active_shard).with(:schema_three).and_return(nil)
+ handler
+ end
+
+ it "should return connection_pool for shard_two when klass.schema_name == :schema_one" do
+ pool = handler.retrieve_connection_pool( mock(:klass, :schema_name => :schema_one) )
+ pool.spec.config[:adapter].should == 'sqlite3'
+ pool.spec.config[:database].should == 'spec/output/shard_two.db'
+ pool.should be_instance_of( ::ActiveRecord::ConnectionAdapters::ConnectionPool )
+ end
+
+ it "should return connection_pool for shard_four when klass.schema_name == :schema_two" do
+ pool = handler.retrieve_connection_pool( mock(:klass, :schema_name => :schema_two) )
+ pool.spec.config[:adapter].should == 'sqlite3'
+ pool.spec.config[:database].should == 'spec/output/shard_four.db'
+ pool.should be_instance_of( ::ActiveRecord::ConnectionAdapters::ConnectionPool )
+ end
+
+ it "should return schema_connection_pool for shard_six when klass.schema_name == :schema_three" do
+ pool = handler.retrieve_connection_pool( mock(:klass, :schema_name => :schema_three) )
+ pool.spec.config[:adapter].should == 'sqlite3'
+ pool.spec.config[:database].should == 'spec/output/shard_six.db'
+ pool.should be_instance_of( ::ActiveShard::ActiveRecord::SchemaConnectionPool )
+ end
+ end
+
+
+ end
+
+ end
+
+
+ end
+
+end
@@ -0,0 +1,12 @@
+require 'spec_helper'
+require 'active_shard/active_record/schema_connection_pool'
+
+module ActiveShard::ActiveRecord
+
+ describe SchemaConnectionPool do
+
+
+
+ end
+
+end
Oops, something went wrong.

0 comments on commit 76bb4a3

Please sign in to comment.