<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>merb_activerecord/lib/generators/templates/session_migration/schema/migrations/%version%_database_sessions.rb</filename>
    </added>
    <added>
      <filename>merb_activerecord/specs/merb_active_record_session_spec.rb</filename>
    </added>
    <added>
      <filename>merb_sequel/specs/merb_sequel_session_spec.rb</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -316,11 +316,6 @@ namespace :db do
   end
 
   namespace :sessions do
-    desc &quot;Create sessions table&quot;
-    task :create =&gt; :merb_start do
-      Merb::ActiveRecordSession.create_table!
-    end
-
     desc &quot;Clear the sessions table&quot;
     task :clear =&gt; :merb_start do
       session_table = 'session'
@@ -330,10 +325,6 @@ namespace :db do
   end
 end
 
-def session_table_name
-  ActiveRecord::Base.pluralize_table_names ? :sessions : :session
-end
-
 def set_firebird_env(config)
   ENV[&quot;ISC_USER&quot;]     = config[&quot;username&quot;].to_s if config[&quot;username&quot;]
   ENV[&quot;ISC_PASSWORD&quot;] = config[&quot;password&quot;].to_s if config[&quot;password&quot;]</diff>
      <filename>merb_activerecord/lib/active_record/merbtasks.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,4 @@
 Merb::Generators::SessionMigrationGenerator.template :session_migration_activerecord, :orm =&gt; :activerecord do
-  source(File.dirname(__FILE__), 'templates/session_migration/schema/migrations/%version%_sessions.rb')
-  destination(&quot;schema/migrations/#{version}_sessions.rb&quot;)
+  source(File.dirname(__FILE__), 'templates/session_migration/schema/migrations/%version%_database_sessions.rb')
+  destination(&quot;schema/migrations/#{version}_database_sessions.rb&quot;)
 end
\ No newline at end of file</diff>
      <filename>merb_activerecord/lib/generators/session_migration.rb</filename>
    </modified>
    <modified>
      <diff>@@ -73,13 +73,6 @@ module Merb
           end
         end
 
-        # Registering this ORM lets the user choose active_record as a session
-        # in merb.yml's session_store: option.
-        def register_session_type
-          Merb.register_session_type(&quot;activerecord&quot;,
-          &quot;merb/session/active_record_session&quot;,
-          &quot;Using ActiveRecord database sessions&quot;)
-        end
       end
     end
   end</diff>
      <filename>merb_activerecord/lib/merb/orms/active_record/connection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,142 +1,65 @@
-require &quot;active_record&quot;
+require 'active_record'
+require 'merb-core/dispatch/session'
+require 'base64'
 
 module Merb
-  module SessionMixin
-    def setup_session
-      before = cookies[_session_id_key]
-      request.session, cookies[_session_id_key] = Merb::ActiveRecordSession.persist(cookies[_session_id_key])
-      @_fingerprint = Marshal.dump(request.session.data).hash
-      @_new_cookie = cookies[_session_id_key] != before
-    end
 
-    def finalize_session
-      request.session.save if @_fingerprint != Marshal.dump(request.session.data).hash
-      set_cookie(_session_id_key, request.session.session_id, Time.now + _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
-    end
+  # Sessions stored in ActiveRecord model.
+  #
+  # To use ActiveRecord based sessions add the following to config/init.rb:
+  #
+  # Merb::Config[:session_store] = 'activerecord'
+  
+  class ActiveRecordSessionStore &lt; ::ActiveRecord::Base
+  
+    table_name = (Merb::Plugins.config[:merb_active_record][:session_table_name] || &quot;sessions&quot;)
+  
+    set_table_name table_name
     
-    def session_store_type
-      &quot;activerecord&quot;
-    end
-  end # ActiveRecordMixin
-
-  class ActiveRecordSession &lt; ::ActiveRecord::Base
-    set_table_name 'sessions'
-    # Customizable data column name.  Defaults to 'data'.
-    cattr_accessor :data_column_name
-    self.data_column_name = 'data'
-    before_save :marshal_data!
-    before_save :raise_on_session_data_overflow!
-    attr_accessor :needs_new_cookie
-
+    serialize :data
+  
     class &lt;&lt; self
-      # Generates a new session ID and creates a row for the new session in the database.
-      def generate
-        create(:session_id =&gt; Merb::SessionMixin::rand_uuid, :data =&gt; {})
-      end
-
-      # Gets the existing session based on the &lt;tt&gt;session_id&lt;/tt&gt; available in cookies.
-      # If none is found, generates a new session.
-      def persist(session_id)
-        if session_id
-          session = find_by_session_id(session_id)
-        end
-        unless session
-          session = generate
+  
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to retrieve.
+      #
+      # ==== Returns
+      # ContainerSession:: The session corresponding to the ID.
+      def retrieve_session(session_id)
+        if item = find_by_session_id(session_id)
+          item.data
         end
-        [session, session.session_id]
-      end
-    
-      # Don't try to reload ARStore::Session in dev mode.
-      def reloadable?
-        false
-      end
-
-      def data_column_size_limit
-        @data_column_size_limit ||= columns_hash[@@data_column_name].limit
       end
 
-      def marshal(data)   Base64.encode64(Marshal.dump(data)) if data end
-      def unmarshal(data) Marshal.load(Base64.decode64(data)) if data end
-
-      def create_table!
-        connection.execute &lt;&lt;-end_sql
-          CREATE TABLE #{table_name} (
-            id INTEGER PRIMARY KEY,
-            #{connection.quote_column_name('session_id')} TEXT UNIQUE,
-            #{connection.quote_column_name(@@data_column_name)} TEXT(255)
-          )
-        end_sql
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to set.
+      # data&lt;ContainerSession&gt;:: The session to set.
+      def store_session(session_id, data)
+        if item = find_by_session_id(session_id)
+          item.update_attributes!(:data =&gt; data)
+        else
+          create(:session_id =&gt; session_id, :data =&gt; data)
+        end
       end
 
-      def drop_table!
-        connection.execute &quot;DROP TABLE #{table_name}&quot;
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to delete.
+      def delete_session(session_id)
+        delete_all([&quot;#{connection.quote_column_name('session_id')} IN (?)&quot;, session_id])
       end
-    end
-  
-    # Regenerate the Session ID
-    def regenerate
-      update_attributes(:session_id =&gt; Merb::SessionMixin::rand_uuid)
-      self.needs_new_cookie = true
-    end 
-   
-    # Recreates the cookie with the default expiration time 
-    # Useful during log in for pushing back the expiration date 
-    def refresh_expiration
-      self.needs_new_cookie = true
-    end 
-  
-    # Lazy-delete of session data 
-    def delete(key = nil)
-      key ? self.data.delete(key) : self.data.clear
-    end
-  
-    def [](key)
-      data[key]
-    end
-  
-    def empty?
-      data.empty?
-    end
-  
-    def each(&amp;b)
-      data.each(&amp;b)
+    
     end
 
-    def each_with_index(&amp;b)
-      data.each_with_index(&amp;b)
-    end
+  end
   
-    def []=(key, val)
-      data[key] = val
-    end
+  class ActiveRecordSession &lt; SessionStoreContainer
     
-    # Lazy-unmarshal session state.
-    def data
-      @data ||= self.class.unmarshal(read_attribute(@@data_column_name)) || {}
-    end
-
-    # Has the session been loaded yet?
-    def loaded?
-      !! @data
-    end
-
-    private
-      attr_writer :data
-
-      def marshal_data!
-        return false if !loaded?
-        write_attribute(@@data_column_name, self.class.marshal(self.data))
-      end
-
-      # Ensures that the data about to be stored in the database is not
-      # larger than the data storage column. Raises
-      # ActionController::SessionOverflowError.
-      def raise_on_session_data_overflow!
-        return false if !loaded?
-        limit = self.class.data_column_size_limit
-        if loaded? and limit and read_attribute(@@data_column_name).size &gt; limit
-          raise MerbController::SessionOverflowError
-        end
-      end
-  end # ActiveRecordSessionMixin
-end # Merb
+    # The session store type
+    self.session_store_type = :activerecord
+    
+    # The store object is the model class itself
+    self.store = ActiveRecordSessionStore
+    
+  end
+    
+end
\ No newline at end of file</diff>
      <filename>merb_activerecord/lib/merb/session/active_record_session.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,7 @@
 if defined?(Merb::Plugins)  
+  
   dependency &quot;activerecord&quot;
+  
   require File.join(File.dirname(__FILE__) / &quot;merb&quot; / &quot;orms&quot; / &quot;active_record&quot; / &quot;connection&quot;)
   Merb::Plugins.add_rakefiles(File.join(File.dirname(__FILE__) / &quot;active_record&quot; / &quot;merbtasks&quot;))
   
@@ -9,7 +11,10 @@ if defined?(Merb::Plugins)
 
     def self.run
       Merb::Orms::ActiveRecord.connect
-      Merb::Orms::ActiveRecord.register_session_type
+      if Merb::Config.session_stores.include?(:activerecord)
+        Merb.logger.debug &quot;Using ActiveRecord sessions&quot;
+        require File.join(File.dirname(__FILE__) / &quot;merb&quot; / &quot;session&quot; / &quot;active_record_session&quot;)
+      end
     end
 
   end</diff>
      <filename>merb_activerecord/lib/merb_activerecord.rb</filename>
    </modified>
    <modified>
      <diff>@@ -10,14 +10,12 @@ describe Merb::Orms::ActiveRecord::Connect do
   end
 end
 
-
-
 describe &quot;Merb ActiveRecord extension&quot; do
   before :all do
     @wd = Dir.pwd
     Merb.stub!(:dir_for).with(:config).and_return(@wd)
-    @config_file_path = @wd / &quot;database.yml&quot;
-    @sample_file_path = @wd / &quot;database.yml.sample&quot;
+    @config_file_path = @wd / &quot;config&quot; / &quot;database.yml&quot;
+    @sample_file_path = @wd / &quot;config&quot; / &quot;database.yml.sample&quot;
 
     @sample_source = Merb::Orms::ActiveRecord.sample_source
     @config_sample = Erubis.load_yaml_file(@sample_source)
@@ -52,11 +50,6 @@ describe &quot;Merb ActiveRecord extension&quot; do
     @config_sample[:development][:encoding].should == &quot;utf8&quot;
   end
 
-  it &quot;stores configurations from config file&quot; do
-    Erubis.should_receive(:load_yaml_file).with(@config_file_path).and_return(@config_sample)
-    Merb::Orms::ActiveRecord.configurations[:development][:database].should == &quot;sample_development&quot;
-  end
-
   it &quot;provides Rack with a way to start a transcantion&quot; do
     Merb::Orms::ActiveRecord.should respond_to(:open_sandbox!)
   end</diff>
      <filename>merb_activerecord/specs/merb_active_record_spec.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,5 +1,4 @@
 $TESTING = true
 $:.push File.join(File.dirname(__FILE__), '..', 'lib')
 require 'merb-core'
-require 'merb_activerecord'
-require 'merb/test/model_helper/active_record'
+require 'merb_activerecord'
\ No newline at end of file</diff>
      <filename>merb_activerecord/specs/spec_helper.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,4 +1,5 @@
 require &quot;fileutils&quot;
+require &quot;sequel&quot;
 
 module Merb
   module Orms
@@ -15,9 +16,7 @@ module Merb
         end
       
         def config
-
-          @config ||=
-          begin
+          @config ||= begin
             # Convert string keys to symbols
             full_config = Erubis.load_yaml_file(config_file)
             config = (Merb::Plugins.config[:merb_sequel] = {})
@@ -26,14 +25,10 @@ module Merb
             end
             config
           end
-
         end
       
         # Database connects as soon as the gem is loaded
         def connect
-          
-          require &quot;sequel&quot;
-
           if File.exists?(config_file)
             Merb.logger.info!(&quot;Connecting to the '#{config[:database]}' database on '#{config[:host]}' using '#{config[:adapter]}' ...&quot;)
             connection = ::Sequel.connect(config_options(config))
@@ -46,11 +41,9 @@ module Merb
             Merb.logger.error! &quot;A sample file was created called config/database.yml.sample for you to copy and edit.&quot;
             exit(1)
           end
-          
         end
         
         def config_options(config = {})
-          
           options = {}
           options[:adapter]  = (config[:adapter]  || &quot;sqlite&quot;)
           options[:host]     = (config[:host]     || &quot;localhost&quot;)
@@ -63,16 +56,6 @@ module Merb
           options[:logger]   = Merb.logger
           options
         end
-        
-        # Registering this ORM lets the user choose sequel as a session store
-        # in merb.yml's session_store: option.
-        def register_session_type
-          Merb.register_session_type(
-          &quot;sequel&quot;,
-          &quot;merb/session/sequel_session&quot;,
-          &quot;Using Sequel database sessions&quot;
-          )
-        end
 
       end
       </diff>
      <filename>merb_sequel/lib/merb/orms/sequel/connection.rb</filename>
    </modified>
    <modified>
      <diff>@@ -1,156 +1,106 @@
-require &quot;base64&quot;
+require 'sequel'
+require 'merb-core/dispatch/session'
+require 'base64'
 
 module Merb
 
-  module SessionMixin
-    def setup_session
-      before = cookies[_session_id_key]
-      request.session, cookies[_session_id_key] = Merb::SequelSession.persist(cookies[_session_id_key])
-      @_fingerprint = Marshal.dump(request.session.data).hash
-      @_new_cookie = cookies[_session_id_key] != before
-    end
-
-    def finalize_session
-      request.session.save if @_fingerprint != Marshal.dump(request.session.data).hash
-      set_cookie(_session_id_key, request.session.values[:session_id], Time.now + _session_expiry) if (@_new_cookie || request.session.needs_new_cookie)
-    end
-    
-    def session_store_type
-      &quot;sequel&quot;
-    end
-
-  end
-
   table_name = (Merb::Plugins.config[:merb_sequel][:session_table_name] || &quot;sessions&quot;)
 
-  class SequelSession &lt; Sequel::Model(table_name.to_sym)
+  # Sessions stored in Sequel model.
+  #
+  # To use Sequel based sessions add the following to config/init.rb:
+  #
+  # Merb::Config[:session_store] = 'sequel'
+
+  class SequelSessionStore &lt; Sequel::Model(table_name.to_sym)
     
     set_schema do
       primary_key :id
       varchar :session_id
-      varchar :data
+      text :data
       timestamp :created_at
     end
 
-    attr_accessor :needs_new_cookie
-
     class &lt;&lt; self
-      # Generates a new session ID and creates a row for the new session in the database.
-      def generate
-        create(:session_id =&gt; Merb::SessionMixin::rand_uuid,
-        :data =&gt; marshal({}), :created_at =&gt; Time.now)
+      
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to retrieve.
+      #
+      # ==== Returns
+      # ContainerSession:: The session corresponding to the ID.
+      def retrieve_session(session_id)
+        if item = find(:session_id =&gt; session_id)
+          item.data
+        end
       end
 
-      # Gets the existing session based on the &lt;tt&gt;session_id&lt;/tt&gt; available in cookies.
-      # If none is found, generates a new session.
-      def persist(session_id)
-        if session_id
-          session = find(:session_id =&gt; session_id)
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to set.
+      # data&lt;ContainerSession&gt;:: The session to set.
+      def store_session(session_id, data)
+        if item = find(:session_id =&gt; session_id)
+          item.update(:data =&gt; data)
+        else
+          create(:session_id =&gt; session_id, :data =&gt; data, :created_at =&gt; Time.now)
         end
-        unless session
-          session = generate
-        end
-        [session, session.values[:session_id]]
       end
 
-      # Don't try to reload ARStore::Session in dev mode.
-      def reloadable?
-        false
+      # ==== Parameters
+      # session_id&lt;String&gt;:: ID of the session to delete.
+      def delete_session(session_id)
+        if item = find(:session_id =&gt; session_id)
+          item.delete
+        end
       end
-
+    
+      # ==== Returns
+      # Integer:: The maximum length of the 'data' column.
       def data_column_size_limit
-        255
-      end
-
-      def marshal(data)
-        Base64.encode64(Marshal.dump(data)) if data
-      end
-
-      def unmarshal(data)
-        Marshal.load(Base64.decode64(data)) if data
+        512 # TODO - figure out how much space we actually have
       end
 
       alias :create_table! :create_table
       alias :drop_table! :drop_table
     end
 
-    # Regenerate the Session ID
-    def regenerate
-      update_attributes(:session_id =&gt; Merb::SessionMixin::rand_uuid)
-      self.needs_new_cookie = true
-    end 
-
-    # Recreates the cookie with the default expiration time 
-    # Useful during log in for pushing back the expiration date 
-    def refresh_expiration
-      self.needs_new_cookie = true
-    end
-
-    # Lazy-delete of session data 
-    def delete(key = nil)
-      key ? self.data.delete(key) : self.data.clear
-    end
-
-    def [](key)
-      data[key]
-    end
-
-    def []=(key, val)
-      data[key] = val
-    end
-
-    def empty?
-      data.empty?
-    end
-
-    def each(&amp;b)
-      data.each(&amp;b)
+    # Lazy-unserialize session state.
+    def data
+      @data ||= (@values[:data] ? Marshal.load(@values[:data]) : {})
     end
     
-    def each_with_index(&amp;b)
-      data.each_with_index(&amp;b)
-    end
-
-    # Lazy-unmarshal session state.
-    def data
-      @data ||= self.class.unmarshal(@values[:data]) || {}
+    # Virtual attribute writer - override.
+    def data=(hsh)
+      @data = hsh if hsh.is_a?(Hash)
     end
 
     # Has the session been loaded yet?
     def loaded?
-      !! @data
+      !!@data
     end
 
-    private
-
-    attr_writer :data
-
-    before_save do # marshal_data!
-      # return false if !loaded?
-      @values[:data] = self.class.marshal(self.data)
+    before_save do 
+      @values[:data] = Marshal.dump(self.data)
+      if @values[:data].size &gt; self.class.data_column_size_limit
+        raise Merb::SessionMixin::SessionOverflow
+      end    
     end
-
-    # Ensures that the data about to be stored in the database is not
-    # larger than the data storage column. Raises
-    # ActionController::SessionOverflowError.
-    # before_save do # raise_on_session_data_overflow!
-    # return false if !loaded?
-    # limit = self.class.data_column_size_limit
-    # if loaded? and limit and read_attribute(@@data_column_name).size &gt; limit
-    # raise MerbController::SessionOverflowError
-    # end
-    # end
     
   end
 
   unless Sequel::Model.db.table_exists?(table_name.to_sym)
     puts &quot;Warning: The database did not contain a '#{table_name}' table for sessions.&quot;
-
-    SequelSession.class_eval do
-      create_table unless table_exists?
-    end
-
+    SequelSessionStore.class_eval { create_table unless table_exists? }
     puts &quot;Created sessions table.&quot;
   end
+  
+  class SequelSession &lt; SessionStoreContainer
+    
+    # The session store type
+    self.session_store_type = :sequel
+    
+    # The store object is the model class itself
+    self.store = SequelSessionStore
+    
+  end
 
 end</diff>
      <filename>merb_sequel/lib/merb/session/sequel_session.rb</filename>
    </modified>
    <modified>
      <diff>@@ -9,7 +9,10 @@ if defined?(Merb::Plugins)
 
     def self.run
       Merb::Orms::Sequel.connect
-      Merb::Orms::Sequel.register_session_type
+      if Merb::Config.session_stores.include?(:sequel)
+        Merb.logger.debug &quot;Using Sequel sessions&quot;
+        require File.join(File.dirname(__FILE__) / &quot;merb&quot; / &quot;session&quot; / &quot;sequel_session&quot;)
+      end
     end
 
   end</diff>
      <filename>merb_sequel/lib/merb_sequel.rb</filename>
    </modified>
  </modified>
  <removed type="array">
    <removed>
      <filename>merb_activerecord/lib/generators/templates/session_migration/schema/migrations/%version%_sessions.rb</filename>
    </removed>
  </removed>
  <parents type="array">
    <parent>
      <id>dde7edf7d58e6b21071183ddd95fa85bf8ea782b</id>
    </parent>
  </parents>
  <author>
    <name>Fabien Franzen</name>
    <email>info@atelierfabien.be</email>
  </author>
  <url>http://github.com/wycats/merb-plugins/commit/9e68fba7d4d3f7a560a57e628fd34bd253575b6c</url>
  <id>9e68fba7d4d3f7a560a57e628fd34bd253575b6c</id>
  <committed-date>2008-09-07T09:46:19-07:00</committed-date>
  <authored-date>2008-09-07T09:46:19-07:00</authored-date>
  <message>Merged in new-sessions branch</message>
  <tree>21d12979e5289e925469aac4522313b743bc052c</tree>
  <committer>
    <name>Fabien Franzen</name>
    <email>info@atelierfabien.be</email>
  </committer>
</commit>
