<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>tasks/database.rake</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -3,21 +3,40 @@
 == What
 
 NullDB is a Rails database connection adapter that interprets common
-database operations as no-ops.
+database operations as no-ops.  It is the Null Object pattern as
+applied to database adapters.
 
 == How 
 
-In your database.yml:
+Once installed, NullDB can be used much like any other ActiveRecord
+database adapter:
+
+  ActiveRecord::Base.establish_connection :adapter =&gt; nulldb
+
+NullDB needs to know where you keep your schema file in order to
+reflect table metadata.  By default it looks in
+RAILS_ROOT/db/schema.rb.  You can override that by setting the
++schema+ option:
+
+  ActiveRecord::Base.establish_connection :adapter =&gt; nulldb,
+                                          :schema  =&gt; foo/myschema.rb
+
+There is a helper method included for configuring RSpec sessions to
+use NullDB.  Just put the following in your spec/spec_helper.rb:
+
+  Spec::Runner.configure do |config|
+    ::NullDB.insinuate_into_spec(config)
+  end
+
+You can also experiment with putting NullDB in your database.yml:
 
   unit_test:
     adapter: nulldb
 
-That's all there is to it.  Now any code run in the +unit_test+
-environment, *including* schema definitions, will execute using the
-NullDB database connector.  Most simple database operations will be
-safe no-ops.  If a schema definition is executed - which is normally
-done automatically before unit tests and specs in Rails - NullDB will
-use the schema information to reflect table and column metadata.
+However, due to the way Rails hard-codes specific database adapters
+into its standard Rake tasks, you may find that this generates
+unexpected and difficult-to-debug behavior.  Workarounds for this are
+under development.
 
 == Why 
 
@@ -31,19 +50,19 @@ UnitRecord[http://unit-test-ar.rubyforge.org/] libraries.  It differs
 from them in a couple of ways:
 
 1. It works.  At the time of writing both ARBS and UnitRecord were
-   broken out of the box when used with Rails 2.0. 
+   not working for me out of the box with Rails 2.0. 
 
-2. It avoids monkey-patching.  Rather than re-wiring the secret inner
-   workings of ActiveRecord (and thus being tightly coupled to said
-   inner workings), NullDB implements the same well-documented public
-   interface that the other standard database adapters, like MySQL
-   and SQLServer, implement.
+2. It avoids monkey-patching as much as possible.  Rather than
+   re-wiring the secret inner workings of ActiveRecord (and thus being
+   tightly coupled to those inner workings), NullDB implements the
+   same [semi-]well-documented public interface that the other standard
+   database adapters, like MySQL and SQLServer, implement.
 
 3. UnitRecord takes the approach of eliminating database interaction
    in tests by turning almost every database interaction into an
-   exception.  NullDB recognizes that today's ActiveRecord objects
-   can't take two steps without consulting the database, and instead
-   turns database interactions into safe no-ops.
+   exception.  NullDB recognizes that ActiveRecord objects typically
+   can't take two steps without consulting the database, so instead it
+   turns database interactions into no-ops.
 
 One concrete advantage of this null-object pattern design is that it
 is possible with NullDB to test +after_save+ hooks.  With NullDB, you
@@ -60,7 +79,7 @@ nothing will be saved.
 
 == Who 
 
-NullDB was written by Avdi Grimm &lt;avdi@avdi.org&gt;
+NullDB was written by Avdi Grimm &lt;mailto:avdi@avdi.org&gt;
 
 == License
 </diff>
      <filename>README</filename>
    </modified>
    <modified>
      <diff>@@ -9,5 +9,5 @@ end
 
 Rake::RDocTask.new do |rd|
   rd.main = &quot;README&quot;
-  rd.rdoc_files.include(&quot;README&quot;, &quot;lib/**/*.rb&quot;)
+  rd.rdoc_files.include(&quot;README&quot;, &quot;LICENSE&quot;, &quot;lib/**/*.rb&quot;)
 end</diff>
      <filename>Rakefile</filename>
    </modified>
    <modified>
      <diff>@@ -1 +1,3 @@
-# Nothing do to here...
+require 'active_record/connection_adapters/nulldb_adapter'
+
+::NullDB = ActiveRecord::ConnectionAdapters::NullDB</diff>
      <filename>init.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,25 +1,45 @@
 require 'logger'
 require 'stringio'
+require 'singleton'
 require 'active_record/connection_adapters/abstract_adapter'
 
 class ActiveRecord::Base
+  # Instantiate a new NullDB connection.  Used by ActiveRecord internally.
   def self.nulldb_connection(config)
-    ActiveRecord::ConnectionAdapters::NullDB.new
+    ActiveRecord::ConnectionAdapters::NullDB.new(config)
   end
 end
 
 class ActiveRecord::ConnectionAdapters::NullDB &lt;
     ActiveRecord::ConnectionAdapters::AbstractAdapter
 
+  TableDefinition = ActiveRecord::ConnectionAdapters::TableDefinition
+
+  # A convenience method for integratinginto RSpec.  See README for example of
+  # use.
+  def self.insinuate_into_spec(config)
+    config.before :all do
+      ActiveRecord::Base.establish_connection(:adapter =&gt; :nulldb)
+    end
+
+    config.after :all do
+      ActiveRecord::Base.establish_connection(:test)
+    end
+  end
+
   def self.execution_log
     (@@execution_log ||= [])
   end
 
-  def initialize
+  # Recognized options:
+  #
+  # [+:schema+] path to the schema file, relative to RAILS_ROOT
+  def initialize(config={})
     @log            = StringIO.new
     @logger         = Logger.new(@log)
-    @tables         = {}
     @last_unique_id = 0
+    @tables         = {'schema_info' =&gt;  TableDefinition.new(nil)}
+    @schema_path    = config.fetch(:schema){ &quot;db/schema.rb&quot; }
     super(nil, @logger)
   end
 
@@ -42,12 +62,21 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
     @tables[table_name] = table_definition
   end
 
+  def tables
+    @tables.keys.map(&amp;:to_s)
+  end
+
   def columns(table_name, name = nil)
-    @tables[table_name].columns.map do |col_def|
+    if @tables.size &lt;= 1
+      ActiveRecord::Migration.verbose = false
+      Kernel.load(File.join(RAILS_ROOT, @schema_path))
+    end
+    table = @tables[table_name]
+    table.columns.map do |col_def|
       ActiveRecord::ConnectionAdapters::Column.new(col_def.name.to_s,
-                                                   col_def.default,
-                                                   col_def.type,
-                                                   col_def.null)
+                                                    col_def.default,
+                                                    col_def.type,
+                                                    col_def.null)
     end
   end
 
@@ -60,6 +89,10 @@ class ActiveRecord::ConnectionAdapters::NullDB &lt;
     object_id || next_unique_id
   end
 
+  def select(statement, name)
+    []
+  end
+
   private
 
   def next_unique_id</diff>
      <filename>lib/active_record/connection_adapters/nulldb_adapter.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,6 +9,35 @@ class Employee &lt; ActiveRecord::Base
   end
 end
 
+RAILS_ROOT = &quot;RAILS_ROOT&quot;
+
+describe &quot;NullDB with no schema pre-loaded&quot; do
+  before :each do
+    Kernel.stub!(:load)
+    ActiveRecord::Migration.stub!(:verbose=)
+  end
+
+  it &quot;should load RAILS_ROOT/db/schema.rb if no alternate is specified&quot; do
+    ActiveRecord::Base.establish_connection :adapter =&gt; :nulldb
+    Kernel.should_receive(:load).with(&quot;RAILS_ROOT/db/schema.rb&quot;)
+    ActiveRecord::Base.connection.columns('schema_info')
+  end
+
+  it &quot;should load the specified schema relative to RAILS_ROOT&quot; do
+    Kernel.should_receive(:load).with(&quot;RAILS_ROOT/foo/myschema.rb&quot;)
+    ActiveRecord::Base.establish_connection :adapter =&gt; :nulldb,
+                                            :schema =&gt; &quot;foo/myschema.rb&quot;
+    ActiveRecord::Base.connection.columns('schema_info')
+  end
+
+  it &quot;should suppress migration output&quot; do
+    ActiveRecord::Migration.should_receive(:verbose=).with(false)
+    ActiveRecord::Base.establish_connection :adapter =&gt; :nulldb,
+                                            :schema =&gt; &quot;foo/myschema.rb&quot;
+    ActiveRecord::Base.connection.columns('schema_info')
+  end
+end
+
 describe &quot;NullDB&quot; do
   before :all do
     ActiveRecord::Base.establish_connection :adapter =&gt; :nulldb
@@ -88,6 +117,14 @@ describe &quot;NullDB&quot; do
     @employee.connection.supports_migrations?.should be_true
   end
 
+  it &quot;should always have a schema_info table definition&quot; do
+    @employee.connection.tables.should include(&quot;schema_info&quot;)
+  end
+
+  it &quot;should return an empty array from #select&quot; do
+    @employee.connection.select(&quot;who cares&quot;, &quot;blah&quot;).should == []
+  end
+
   def should_have_column(klass, col_name, col_type)
     col = klass.columns_hash[col_name.to_s]
     col.should_not be_nil</diff>
      <filename>spec/nulldb_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>a19a383225e06d6f291950b4f1e80a7b8284c459</id>
    </parent>
  </parents>
  <author>
    <name>Avdi Grimm</name>
    <email>avdi@avdi.org</email>
  </author>
  <url>http://github.com/technicalpickles/nulldb/commit/2e46b54bbbd4dfba807d47de4002eb2c08987c4d</url>
  <id>2e46b54bbbd4dfba807d47de4002eb2c08987c4d</id>
  <committed-date>2008-02-17T21:34:16-08:00</committed-date>
  <authored-date>2008-02-17T21:34:16-08:00</authored-date>
  <message>
 * Actually works in a real world project.
 * Updated documentation.</message>
  <tree>eae2a7417244eea5571a77c571f1e8c787e53d67</tree>
  <committer>
    <name>Avdi Grimm</name>
    <email>avdi@avdi.org</email>
  </committer>
</commit>
