<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>lib/data_fabric/ar20.rb</filename>
    </added>
    <added>
      <filename>lib/data_fabric/ar22.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -1,5 +1,9 @@
 DataFabric changelog
 
+v1.2.0 - 2008-12-25
+
+- Now supports ActiveRecord 2.2.
+
 v1.1.0 - 2008-11-22
 
 - Cache connections so we don't have to reconnect constantly. (Justin Balthrop, Geni)</diff>
      <filename>CHANGELOG</filename>
    </modified>
    <modified>
      <diff>@@ -56,6 +56,8 @@ example/test/functional/accounts_controller_test.rb
 example/test/integration/account_figments_test.rb
 example/test/test_helper.rb
 init.rb
+lib/data_fabric/ar20.rb
+lib/data_fabric/ar22.rb
 lib/data_fabric/version.rb
 lib/data_fabric.rb
 Manifest
@@ -68,4 +70,8 @@ test/database_test.rb
 test/shard_test.rb
 test/test_helper.rb
 test/thread_test.rb
+test/vr_austin_master.db
+test/vr_austin_slave.db
+test/vr_dallas_master.db
+test/vr_dallas_slave.db
 TESTING.rdoc</diff>
      <filename>Manifest</filename>
    </modified>
    <modified>
      <diff>@@ -62,7 +62,7 @@ ActionController around_filter based on the user as follows:
 == Warnings
 
 * Sharded models should never be placed in the session store or you will get &quot;Shard not set&quot; errors when the session is persisted.
-* ActiveRecord's allow_concurrency = true is NOT supported in this version of data_fabric.
+* DataFabric does not support running with ActiveRecord's allow_concurrency = true in AR 2.0 and 2.1.  allow_concurrency is gone in AR 2.2.
 
 == Testing and Bug Reports
 </diff>
      <filename>README.rdoc</filename>
    </modified>
    <modified>
      <diff>@@ -1,8 +1,6 @@
 require 'rubygems'
 require 'echoe'
 
-#gem 'rails', '=2.0.2'
-
 require File.dirname(__FILE__) &lt;&lt; &quot;/lib/data_fabric/version&quot;
 
 Echoe.new 'data_fabric' do |p|
@@ -10,16 +8,23 @@ Echoe.new 'data_fabric' do |p|
   p.author = &quot;Mike Perham&quot;
   p.email  = 'mperham@gmail.com'
   p.project = 'fiveruns'
-  p.summary = 'Sharding and replication support for ActiveRecord 2.0 and 2.1'
+  p.summary = 'Sharding and replication support for ActiveRecord 2.x'
   p.url = &quot;http://github.com/fiveruns/data_fabric&quot;
-#  p.dependencies = ['activerecord &gt;=2.0.2']
   p.development_dependencies = []
   p.rubygems_version = nil
   p.include_rakefile = true
+  p.test_pattern = 'test/*_test.rb'
 end
 
 task :test =&gt; [:pretest]
 
+desc &quot;Test all versions of ActiveRecord installed locally&quot;
+task :test_all do
+  Gem.source_index.search(Gem::Dependency.new('activerecord', '&gt;=2.0')).each do |spec|
+    puts `rake test AR_VERSION=#{spec.version}`
+  end
+end
+
 task :pretest do
   setup(false)
 end
@@ -28,10 +33,6 @@ task :create_db do
   setup(true)
 end
 
-task :changelog do
-  `git log | grep -v git-svn-id &gt; History.txt`
-end
-
 def load_database_yml
   filename = &quot;test/database.yml&quot;
   if !File.exist?(filename)</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -45,7 +45,13 @@ module DataFabric
   def self.init
     logger = ActiveRecord::Base.logger unless logger
     log { &quot;Loading data_fabric #{DataFabric::Version::STRING} with ActiveRecord #{ActiveRecord::VERSION::STRING}&quot; }
-    ActiveRecord::Base.send(:include, self)
+
+    if ActiveRecord::VERSION::STRING &lt; '2.2.0'
+      require 'data_fabric/ar20'
+    else
+      require 'data_fabric/ar22'
+    end
+    ActiveRecord::Base.send(:include, DataFabric::Extensions)
   end
   
   def self.activate_shard(shards, &amp;block)
@@ -89,11 +95,6 @@ module DataFabric
     Thread.current[:shards] and Thread.current[:shards][group.to_s]
   end
 
-  def self.included(model)
-    # Wire up ActiveRecord::Base
-    model.extend ClassMethods
-  end
-
   def self.ensure_setup
     Thread.current[:shards] = {} unless Thread.current[:shards]
   end
@@ -102,130 +103,4 @@ module DataFabric
     logger &amp;&amp; logger.add(level, &amp;block)
   end
 
-  # Class methods injected into ActiveRecord::Base
-  module ClassMethods
-    def data_fabric(options)
-      proxy = DataFabric::ConnectionProxy.new(self, options)
-      ActiveRecord::Base.active_connections[name] = proxy
-      
-      raise ArgumentError, &quot;data_fabric does not support ActiveRecord's allow_concurrency = true&quot; if allow_concurrency
-      DataFabric.log { &quot;Creating data_fabric proxy for class #{name}&quot; }
-    end
-  end
-  
-  class StringProxy
-    def initialize(&amp;block)
-      @proc = block
-    end
-    def to_s
-      @proc.call
-    end
-  end
-
-  class ConnectionProxy
-    def initialize(model_class, options)
-      @model_class = model_class      
-      @replicated  = options[:replicated]
-      @shard_group = options[:shard_by]
-      @prefix      = options[:prefix]
-      @role        = 'slave' if @replicated
-
-      @model_class.send :include, ActiveRecordConnectionMethods if @replicated
-    end
-    
-    delegate :insert, :update, :delete, :create_table, :rename_table, :drop_table, :add_column, :remove_column, 
-      :change_column, :change_column_default, :rename_column, :add_index, :remove_index, :initialize_schema_information,
-      :dump_schema_information, :execute, :execute_ignore_duplicate, :to =&gt; :master
-    
-    def cache(&amp;block)
-      connection.cache(&amp;block)
-    end
-
-    def transaction(start_db_transaction = true, &amp;block)
-      with_master { connection.transaction(start_db_transaction, &amp;block) }
-    end
-
-    def method_missing(method, *args, &amp;block)
-      DataFabric.log(Logger::DEBUG) { &quot;Calling #{method} on #{connection}&quot; }
-      connection.send(method, *args, &amp;block)
-    end
-    
-    def connection_name
-      connection_name_builder.join('_')
-    end
-    
-    def disconnect!
-      if connected?
-        connection.disconnect! 
-        cached_connections[connection_name] = nil
-      end
-    end
-    
-    def verify!(arg)
-      connection.verify!(arg) if connected?
-    end
-    
-    def with_master
-      # Allow nesting of with_master.
-      old_role = @role
-      set_role('master')
-      yield
-    ensure
-      set_role(old_role)
-    end
-
-  private
-
-    def cached_connections
-      @cached_connections ||= {}
-    end
-
-    def connection_name_builder
-      @connection_name_builder ||= begin
-        clauses = []
-        clauses &lt;&lt; @prefix if @prefix
-        clauses &lt;&lt; @shard_group if @shard_group
-        clauses &lt;&lt; StringProxy.new { DataFabric.active_shard(@shard_group) } if @shard_group
-        clauses &lt;&lt; RAILS_ENV
-        clauses &lt;&lt; StringProxy.new { @role } if @replicated
-        clauses
-      end
-    end
-    
-    def connection
-      name = connection_name
-      if not connected?
-        config = ActiveRecord::Base.configurations[name]
-        raise ArgumentError, &quot;Unknown database config: #{name}, have #{ActiveRecord::Base.configurations.inspect}&quot; unless config
-        DataFabric.log { &quot;Connecting to #{name}&quot; }
-        @model_class.establish_connection(config)
-        cached_connections[name] = @model_class.connection
-        @model_class.active_connections[@model_class.name] = self
-      end
-      cached_connections[name].verify!(3600)
-      cached_connections[name]
-    end
-
-    def connected?
-      DataFabric.shard_active_for?(@shard_group) and cached_connections[connection_name]
-    end
-
-    def set_role(role)
-      @role = role if @replicated
-    end
-    
-    def master
-      with_master { return connection }
-    end
-  end
-
-  module ActiveRecordConnectionMethods
-    def self.included(base)
-      base.alias_method_chain :reload, :master
-    end
-
-    def reload_with_master(*args, &amp;block)
-      connection.with_master { reload_without_master }
-    end
-  end
 end</diff>
      <filename>lib/data_fabric.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,5 @@
 module DataFabric
 	module Version
-		STRING = &quot;1.1.0&quot;
+		STRING = &quot;1.2.0&quot;
 	end
 end</diff>
      <filename>lib/data_fabric/version.rb</filename>
    </modified>
    <modified>
      <diff>@@ -36,7 +36,7 @@ end
 
 class RawConnection
   def method_missing(name, *args)
-      puts &quot;#{self.class.name} missing '#{name}': #{args.inspect}&quot;
+    puts &quot;#{self.class.name} missing '#{name}': #{args.inspect}&quot;
   end
 end
 
@@ -96,7 +96,11 @@ class ConnectionTest &lt; Test::Unit::TestCase
   private
   
   def setup_configuration_for(clazz, name)
-    flexmock(clazz).should_receive(:mysql_connection).and_return(AdapterMock.new(RawConnection.new))
+    if ar22?
+      flexmock(ActiveRecord::ConnectionAdapters::ConnectionPool).new_instances.should_receive(:new_connection).and_return(AdapterMock.new(RawConnection.new))
+    else
+      flexmock(klass).should_receive(:mysql_connection).and_return(AdapterMock.new(RawConnection.new))      
+    end
     ActiveRecord::Base.configurations ||= HashWithIndifferentAccess.new
     ActiveRecord::Base.configurations[name] = HashWithIndifferentAccess.new({ :adapter =&gt; 'mysql', :database =&gt; name, :host =&gt; 'localhost'})
   end</diff>
      <filename>test/connection_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,6 +10,7 @@ class DatabaseTest &lt; Test::Unit::TestCase
   
   def setup
     ActiveRecord::Base.configurations = load_database_yml
+    DataFabric::ConnectionProxy.shard_pools.clear
   end
 
   def test_live_burrito</diff>
      <filename>test/database_test.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,34 +1,41 @@
-if !defined?(ROOT_PATH) # Don't evaluate this file twice.
-  ENV['RAILS_ENV'] = 'test'
-  RAILS_ENV = 'test'
-  ROOT_PATH = File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;))
-  DATABASE_YML_PATH = File.join(ROOT_PATH, &quot;test&quot;, &quot;database.yml&quot;)
-  Dir.chdir(ROOT_PATH)
+ENV['RAILS_ENV'] = 'test'
+RAILS_ENV = 'test'
+ROOT_PATH = File.expand_path(File.join(File.dirname(__FILE__), &quot;..&quot;))
+DATABASE_YML_PATH = File.join(ROOT_PATH, &quot;test&quot;, &quot;database.yml&quot;)
+Dir.chdir(ROOT_PATH)
 
-  require 'rubygems'
-  require 'test/unit'
+require 'rubygems'
+require 'test/unit'
 
-  # Bootstrap AR
-  gem 'activerecord', '=2.0.2'
-  require 'active_record'
-  require 'active_record/version'
-  ActiveRecord::Base.logger = Logger.new(STDOUT)
-  ActiveRecord::Base.logger.level = Logger::WARN
-  ActiveRecord::Base.allow_concurrency = false
+version = ENV['AR_VERSION']
+if version
+  puts &quot;Testing ActiveRecord #{version}&quot;
+  gem 'activerecord', &quot;=#{version}&quot;
+end
+
+require 'active_record'
+require 'active_record/version'
+ActiveRecord::Base.logger = Logger.new(STDOUT)
+ActiveRecord::Base.logger.level = Logger::WARN
+ActiveRecord::Base.logger = Logger.new(STDOUT)
 
-  # Bootstrap DF
-  Dependencies.load_paths &lt;&lt; File.join(File.dirname(__FILE__), '../lib')
-  require 'init'
+# Bootstrap DF
+deps = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : Dependencies
+deps.load_paths &lt;&lt; File.join(File.dirname(__FILE__), '../lib')
+require 'init'
 
-  def load_database_yml
-    filename = DATABASE_YML_PATH
-    YAML::load(ERB.new(IO.read(filename)).result)
-  end
+def load_database_yml
+  filename = DATABASE_YML_PATH
+  YAML::load(ERB.new(IO.read(filename)).result)
+end
+
+def ar22?
+  ActiveRecord::VERSION::STRING &gt;= '2.2.0'
+end
 
-  if !File.exist?(DATABASE_YML_PATH)
-    STDERR.puts &quot;\n*** ERROR ***:\n&quot; &lt;&lt;
-      &quot;You must have a 'test/database.yml' file in order to run the unit tests. &quot; &lt;&lt;
-      &quot;An example is provided in 'test/database.yml.example'.\n\n&quot;
-    exit 1
-  end
+if !File.exist?(DATABASE_YML_PATH)
+  puts &quot;\n*** ERROR ***:\n&quot; &lt;&lt;
+    &quot;You must have a 'test/database.yml' file in order to run the unit tests. &quot; &lt;&lt;
+    &quot;An example is provided in 'test/database.yml.example'.\n\n&quot;
+  exit 1
 end</diff>
      <filename>test/test_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -4,20 +4,28 @@ require 'erb'
 class ThreadTest &lt; Test::Unit::TestCase
   
   MUTEX = Mutex.new
-  
-  def test_concurrency_not_allowed
-    assert_raise ArgumentError do
-      Object.class_eval %{
-        class ThreadedEnchilada &lt; ActiveRecord::Base
-          self.allow_concurrency = true
-          set_table_name :enchiladas
-          data_fabric :prefix =&gt; 'fiveruns', :replicated =&gt; true, :shard_by =&gt; :city
-        end
-      }
+
+  if ActiveRecord::VERSION::STRING &lt; '2.2.0'
+    def test_concurrency_not_allowed
+      assert_raise ArgumentError do
+        Object.class_eval %{
+          class ThreadedEnchilada &lt; ActiveRecord::Base
+            self.allow_concurrency = true
+            set_table_name :enchiladas
+            data_fabric :prefix =&gt; 'fiveruns', :replicated =&gt; true, :shard_by =&gt; :city
+          end
+        }
+      end
     end
   end
   
-  def xtest_class_and_instance_connections
+  def test_class_and_instance_connections
+    Object.class_eval %{
+      class ThreadedEnchilada &lt; ActiveRecord::Base
+        set_table_name :enchiladas
+        data_fabric :prefix =&gt; 'fiveruns', :replicated =&gt; true, :shard_by =&gt; :city
+      end
+    }
     ActiveRecord::Base.configurations = load_database_yml
 
     cconn = ThreadedEnchilada.connection</diff>
      <filename>test/thread_test.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>fa5ef1b6c808856b64f1d8619652baf3d19084b3</id>
    </parent>
  </parents>
  <author>
    <name>Mike Perham</name>
    <email>mperham@gmail.com</email>
  </author>
  <url>http://github.com/fiveruns/data_fabric/commit/7d7a2acfaddc56fe016f6e61957b65075abba54f</url>
  <id>7d7a2acfaddc56fe016f6e61957b65075abba54f</id>
  <committed-date>2008-11-23T18:42:21-08:00</committed-date>
  <authored-date>2008-11-23T18:42:21-08:00</authored-date>
  <message>Refactor DataFabric to support ActiveRecord 2.0, 2.1 and 2.2.
AR 2.0 and 2.1 are supported by the code in ar20.rb.
AR 2.2+ is supported by the code in ar22.rb.
TODO One test still failing.</message>
  <tree>306a047b5ceeea999a31474939029476c2832980</tree>
  <committer>
    <name>Mike Perham</name>
    <email>mperham@gmail.com</email>
  </committer>
</commit>
