<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -49,9 +49,16 @@ module Ribs
       h = Ribs::Handle.get(from)
       yield h
     ensure
-      h.release
+      h.release if h
     end
 
+    def with_simple_handle(from = :default)
+      h = Ribs::Handle.get_simple(from)
+      yield h
+    ensure
+      h.simple_release if h
+    end
+    
     # Defines a model with the given name, defining attribute
     # accessors and also providing the Ribs mapping from the block
     def define_model(name, options = {}, &amp;block)
@@ -93,6 +100,6 @@ module Kernel
   def Ribs!(user_options = {}, &amp;block)
     default_options = {:on =&gt; self, :db =&gt; :default, :from =&gt; nil}
     options = default_options.merge user_options
-    Ribs::define_ribs(options[:on], options, &amp;block)
+    Ribs::define_delayed_ribs(options[:on], options, &amp;block)
   end
 end</diff>
      <filename>lib/ribs.rb</filename>
    </modified>
    <modified>
      <diff>@@ -126,6 +126,9 @@ module Ribs
     def initialize(name = :main)
       self.name = name
       self.properties = {}
+      class &lt;&lt; self
+        alias session_factory session_factory_create
+      end
     end
     
     # Is this database the default?
@@ -148,13 +151,32 @@ module Ribs
       @configuration = Configuration.new.add_properties(properties)
       @configuration.set_interceptor org.jruby.ribs.RubyInterceptor.new(self, (self.default? ? :default : self.name).to_s)
       @mappings = @configuration.create_mappings
+      @simple_configuration = Configuration.new.add_properties(properties)
+      @simple_session_factory = @simple_configuration.build_session_factory
       reset_session_factory!
     end
 
     # Resets the session factory. This is necessary after some
     # configuration changes have happened.
     def reset_session_factory!
+      if @session_factory
+        @session_factory = nil
+        class &lt;&lt; self
+          alias session_factory session_factory_create
+        end
+      end
+    end
+    
+    def session_factory_create
       @session_factory = @configuration.build_session_factory
+      class &lt;&lt; self
+        alias session_factory session_factory_return
+      end
+      @session_factory
+    end
+
+    def session_factory_return
+      @session_factory
     end
     
     # Fetch a new Ribs handle connected to the this database. Returns
@@ -165,7 +187,21 @@ module Ribs
         curr[1] += 1 #reference count
         Handle.new(self, curr[0])
       else
-        sess = @session_factory.open_session
+        sess = self.session_factory.open_session
+        sessions[self.object_id] = [sess,1]
+        Handle.new(self, sess)
+      end
+    end
+
+    # Fetch a new simple Ribs handle connected to the this database. Returns
+    # a Ribs::Handle object.
+    def simple_handle
+      sessions = (Thread.current[:ribs_db_simple_sessions] ||= {})
+      if curr = sessions[self.object_id]
+        curr[1] += 1 #reference count
+        Handle.new(self, curr[0])
+      else
+        sess = @simple_session_factory.open_session
         sessions[self.object_id] = [sess,1]
         Handle.new(self, sess)
       end
@@ -184,5 +220,19 @@ module Ribs
         end
       end
     end
+
+    # Release a simple Ribs::Handle object that is connected to this
+    # database. That Handle object should not be used after this
+    # method has been invoked.
+    def simple_release(handle)
+      res = Thread.current[:ribs_db_simple_sessions][self.object_id]
+      if res[0] == handle.hibernate_session
+        res[1] -= 1
+        if res[1] == 0
+          res[0].close
+          Thread.current[:ribs_db_simple_sessions].delete(self.object_id)
+        end
+      end
+    end
   end
 end</diff>
      <filename>lib/ribs/db.rb</filename>
    </modified>
    <modified>
      <diff>@@ -83,6 +83,7 @@ module Ribs
   Property = org.hibernate.mapping.Property
   SimpleValue = org.hibernate.mapping.SimpleValue
   ManyToOne = org.hibernate.mapping.ManyToOne
+  OneToOne = org.hibernate.mapping.OneToOne
 
   # A simple helper class that allows the Java parts of the system to
   # get the Ruby class from the PersistentClass instance.
@@ -138,6 +139,37 @@ module Ribs
       R(eval(name), db || :default)
     end
 
+    def define_delayed_ribs(on, options = {}, &amp;block)
+      unless options[:metadata]
+        options[:metadata] = Ribs::MetaData.new      
+      end
+
+      rm = options[:metadata]
+      Ribs::add_metadata_for(options[:db], on, rm)
+      rm.identity_map = options.key?(:identity_map) ? options[:identity_map] : true
+
+      with_simple_handle(options[:db] || :default) do |h|
+        db = h.db
+        m = h.meta_data
+
+        name = table_name_for((options[:table] || on.name), m)
+
+        tables = m.get_tables nil, nil, name.to_s, %w(TABLE VIEW ALIAS SYNONYM).to_java(:String)
+        if tables.next
+          rm.table = Table.new(tables.get_string(3))
+        end
+      end
+      
+      (@delayed ||= []) &lt;&lt; [on, options, block]
+    end
+
+    def execute_delayed_ribs!
+      delayed, @delayed = @delayed, []
+      (delayed &amp;&amp; delayed.each do |v|
+        define_ribs(v[0], v[1], &amp;v[2])
+      end)
+    end
+    
     # Define a rib for the class +on+. If a block is given, will first
     # yield an instance of Rib to it and then base the mapping
     # definition on that.
@@ -150,14 +182,8 @@ module Ribs
     def define_ribs(on, options = {})
       rib = Rib.new
       yield rib if block_given?
-       
-      unless options[:metadata]
-        options[:metadata] = Ribs::MetaData.new      
-      end
-
+      
       rm = options[:metadata]
-      Ribs::add_metadata_for(options[:db], on, rm)
-      rm.identity_map = options.key?(:identity_map) ? options[:identity_map] : true
 
       unless options[:from]
         options[:from] = R(on, options[:db] || :default)
@@ -167,7 +193,7 @@ module Ribs
       rib_data = rib.__column_data__
       
       db = nil
-      with_handle(options[:db] || :default) do |h|
+      with_simple_handle(options[:db] || :default) do |h|
         db = h.db
         m = h.meta_data
 
@@ -176,7 +202,6 @@ module Ribs
         tables = m.get_tables nil, nil, name.to_s, %w(TABLE VIEW ALIAS SYNONYM).to_java(:String)
         if tables.next
           table = Table.new(tables.get_string(3))
-          rm.table = table
           c = tables.get_string(1)
           table.catalog = c if c &amp;&amp; c.length &gt; 0
           c = tables.get_string(2)
@@ -252,6 +277,20 @@ module Ribs
             prop.value = val
             pc.add_property(prop)
           end
+
+          rib_data.associations[:has_one].each do |col_name, definition|
+            prop = Property.new
+            prop.persistent_class = pc
+            prop.name = definition[0]
+
+            val = OneToOne.new(table, pc)
+#            val.add_column(table.get_column(Column.new(col_name)))
+
+            ensure_valid_entity_name(options[:db], definition[1]).metadata
+            val.referenced_entity_name = definition[1]
+            prop.value = val
+            pc.add_property(prop)
+          end
           
           pc.create_primary_key
           db.mappings.add_class(pc)</diff>
      <filename>lib/ribs/definition.rb</filename>
    </modified>
    <modified>
      <diff>@@ -33,6 +33,18 @@ module Ribs
              end
         db.handle
       end
+
+      def get_simple(from = :default)
+        db = case from
+             when :default
+               Ribs::DB::get
+             when Ribs::DB
+               from
+             else
+               Ribs::DB::get(from)
+             end
+        db.simple_handle
+      end
     end
     
     # The current database for this handle
@@ -56,6 +68,12 @@ module Ribs
       @db.release(self)
     end
 
+    def simple_release
+      chk_conn
+      @connected = false
+      @db.simple_release(self)
+    end
+    
     # LOW LEVEL - shouldn't be used except by Ribs
     def hibernate_session # :nodoc:
       @hibernate_session</diff>
      <filename>lib/ribs/handle.rb</filename>
    </modified>
    <modified>
      <diff>@@ -11,6 +11,7 @@ module Ribs
   # Ribs::Repository::FooBar::ClassMethods so you can add behavior to
   # these that map over all databases.
   def self.Repository(obj, db = :default)
+    Ribs.execute_delayed_ribs!
     db_name = &quot;DB_#{db}&quot;
     model_type = case obj
           when Class</diff>
      <filename>lib/ribs/repository.rb</filename>
    </modified>
    <modified>
      <diff>@@ -80,10 +80,27 @@ module Ribs
         simple_name = args.first.to_s
         name = simple_name.gsub(/([[:lower:]][0-9]*)([[:upper:]]+)/, '\1_\2').downcase
 
-        opts = {:column =&gt; &quot;#{name}_id&quot;}.merge(opts)
+        opts = {:column =&gt; &quot;#{name}_id&quot;,
+                :name =&gt; name}.merge(opts)
 
         @columns[name] = [opts[:column].to_s, opts, :belongs_to]
-        @associations[:belongs_to][opts[:column]] = [name, simple_name, opts[:column], opts]
+        @associations[:belongs_to][opts[:column]] = [opts[:name].to_s, simple_name, opts[:column], opts]
+      end
+    end
+
+    def has_one(*args)
+      if args==[] || args.first.is_a?(Hash) || [:primary_key, :avoid, :default].include?(args.first)
+        method_missing(:has_one, *args)
+      else
+        opts = args.grep(Hash).first || {}
+        simple_name = args.first.to_s
+        name = simple_name.gsub(/([[:lower:]][0-9]*)([[:upper:]]+)/, '\1_\2').downcase
+
+        opts = {:column =&gt; &quot;#{name}_id&quot;,
+                :name =&gt; name}.merge(opts)
+
+        @columns[name] = [opts[:column].to_s, opts, :has_one]
+        @associations[:has_one][opts[:column]] = [opts[:name].to_s, simple_name, opts[:column], opts]
       end
     end
     </diff>
      <filename>lib/ribs/rib.rb</filename>
    </modified>
    <modified>
      <diff>@@ -5,7 +5,7 @@ class Owner
 end
 
 class Blog
-  attr_accessor :owner, :name
+  attr_accessor :id, :owner, :name
 
   Ribs! do |blog|
     blog.belongs_to Owner</diff>
      <filename>test/belongs_to_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,2 +1,52 @@
 require File.join(File.dirname(__FILE__), 'test_helper')
 
+class Owner2
+  attr_accessor :id, :name, :blog
+  
+  Ribs! :table =&gt; 'owner' do |owner|
+    # owner_id shouldn't really need to be specified here... Hmm.
+    # default for this kind of thing should probably be table + id
+    owner.has_one Blog2, :name =&gt; :blog, :column =&gt; 'owner_id'
+  end
+end
+
+class Blog2
+  attr_accessor :id, :owner_id, :name
+
+  Ribs! :table =&gt; 'blog'
+end
+
+describe Owner2 do 
+  describe &quot;has_one&quot; do
+    it &quot;should include blog field when getting&quot; do 
+      owner = R(Owner2).get(1)
+      owner.name.should == &quot;Foo&quot;
+      owner.blog.class.should == Blog2
+      owner.blog.id.should == 1
+      owner.blog.name.should == &quot;One&quot;
+      owner.blog.owner_id.should == 1
+
+      owner = R(Owner2).get(2)
+      owner.name.should == &quot;Bar&quot;
+      owner.blog.class.should == Blog2
+      owner.blog.id.should == 2
+      owner.blog.name.should == &quot;Two&quot;
+      owner.blog.owner_id.should == 2
+    end
+
+    it &quot;should include blog field when using all&quot; do 
+      owners = R(Owner2).all
+      owners[0].name.should == &quot;Foo&quot;
+      owners[0].blog.class.should == Blog2
+      owners[0].blog.id.should == 1
+      owners[0].blog.name.should == &quot;One&quot;
+      owners[0].blog.owner_id.should == 1
+
+      owners[1].name.should == &quot;Bar&quot;
+      owners[1].blog.class.should == Blog2
+      owners[1].blog.id.should == 2
+      owners[1].blog.name.should == &quot;Two&quot;
+      owners[1].blog.owner_id.should == 2
+    end
+  end
+end</diff>
      <filename>test/has_one_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -3,7 +3,7 @@ require File.join(File.dirname(__FILE__), 'test_helper')
 describe Ribs::Rib do 
   it &quot;should not have any methods defined except for method_missing&quot; do 
     Ribs::Rib.instance_methods.sort.should == 
-      %w(Ribs! __send__ __id__ rspec_reset 
+      %w(Ribs! __send__ __id__ rspec_reset has_one
          rspec_verify should_receive belongs_to
          should_not_receive R received_message? 
          stub! __column_data__ method_missing).sort</diff>
      <filename>test/rib_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -32,6 +32,8 @@ end
 
 # R(Track).define_accessors
 
+R(Track)
+
 describe Track do 
   it &quot;should be able to find things based on mapped primary key&quot; do
     track = R(Track).get(2)</diff>
      <filename>test/track_spec.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>c50b441acf55e7ad3a9f25f2a2ca01bca093c9ca</id>
    </parent>
  </parents>
  <author>
    <name>Ola Bini</name>
    <email>ola.bini@gmail.com</email>
  </author>
  <url>http://github.com/olabini/ribs/commit/8ed549f503df069dd91448f8e459819295f2aa53</url>
  <id>8ed549f503df069dd91448f8e459819295f2aa53</id>
  <committed-date>2008-10-09T08:59:17-07:00</committed-date>
  <authored-date>2008-10-09T08:59:17-07:00</authored-date>
  <message>Add support for even MORE laziness in initialization, due to the way Hibernate works. Also add a simple database access that doesn't use any predefined models. Also add very simple support for has_one.</message>
  <tree>7645436dc5c00df16595410b559a540e41c9117d</tree>
  <committer>
    <name>Ola Bini</name>
    <email>ola.bini@gmail.com</email>
  </committer>
</commit>
