diff --git a/README.markdown b/README.markdown index c08ba1a..f6e0426 100755 --- a/README.markdown +++ b/README.markdown @@ -6,7 +6,7 @@ A session store that avoids the pitfalls usually associated with concurrent acce Derived from SqlSessionStore, see http://railsexpress.de/blog/articles/2005/12/19/roll-your-own-sql-session-store -Requires rails 3 or higher. +Requires rails 3 or 4. Rails 5 support coming soon. Installation ========== @@ -18,7 +18,24 @@ gem 'smart_session' Step 2 ------- -Generate your sessions table using rake db:sessions:create + +Generate a migration like below (Assuming you have configured your session table named as "sessions": + +```ruby +class xxx_migration_name < ActiveRecord::Migration + def change + create_table :sessions do |t| + t.string :session_id, :null => false + t.text :data + t.integer :lock_version + t.timestamps + end + + add_index :sessions, :session_id, :unique => true + add_index :sessions, :updated_at + end +end +``` Step 3 ------- diff --git a/gemfiles/Gemfile.ci b/gemfiles/Gemfile.ci index 771c100..42ba753 100644 --- a/gemfiles/Gemfile.ci +++ b/gemfiles/Gemfile.ci @@ -1,7 +1,7 @@ source 'https://rubygems.org' -gem "actionpack", "3.2.13" -gem "activerecord", "3.2.13" +gem "actionpack", "4.2.6" +gem "activerecord", "4.2.6" gem "mysql2" gem "sqlite3" gem "pg" diff --git a/lib/smart_session/postgresql.rb b/lib/smart_session/postgresql.rb index 8dbf163..1dff1d1 100644 --- a/lib/smart_session/postgresql.rb +++ b/lib/smart_session/postgresql.rb @@ -72,9 +72,9 @@ def create_session(session_id, data) # caller's responsibility to pass a valid sql condition def delete_all(condition=nil) if condition - session_connection.query("DELETE FROM #{SmartSession::SqlSession.table_name} WHERE #{condition}") + session_connection.execute("DELETE FROM #{SmartSession::SqlSession.table_name} WHERE #{condition}") else - session_connection.query("DELETE FROM #{SmartSession::SqlSession.table_name}") + session_connection.execute("DELETE FROM #{SmartSession::SqlSession.table_name}") end end @@ -91,15 +91,15 @@ def update_session(data) # if @id is not nil, this is a session already stored in the database # update the relevant field using @id as key if SmartSession::SqlSession.locking_enabled? - connection.query("UPDATE #{SmartSession::SqlSession.table_name} SET \"updated_at\"=NOW(), \"data\"=#{quoted_data}, lock_version=lock_version+1 WHERE id=#{@id}") + connection.execute("UPDATE #{SmartSession::SqlSession.table_name} SET \"updated_at\"=NOW(), \"data\"=#{quoted_data}, lock_version=lock_version+1 WHERE id=#{@id}") @lock_version += 1 #if we are here then we hold a lock on the table - we know our version is up to date else - connection.query("UPDATE #{SmartSession::SqlSession.table_name} SET \"updated_at\"=NOW(), \"data\"=#{quoted_data} WHERE id=#{@id}") + connection.execute("UPDATE #{SmartSession::SqlSession.table_name} SET \"updated_at\"=NOW(), \"data\"=#{quoted_data} WHERE id=#{@id}") end else # if @id is nil, we need to create a new session in the database # and set @id to the primary key of the inserted record - connection.query("INSERT INTO #{SmartSession::SqlSession.table_name} (\"created_at\", \"updated_at\", \"session_id\", \"data\") VALUES (NOW(), NOW(), #{@quoted_session_id}, #{quoted_data})") + connection.execute("INSERT INTO #{SmartSession::SqlSession.table_name} (\"created_at\", \"updated_at\", \"session_id\", \"data\") VALUES (NOW(), NOW(), #{@quoted_session_id}, #{quoted_data})") @id = connection.lastval rescue connection.query("select lastval()")[0][0].to_i @lock_version = 0 end @@ -111,7 +111,7 @@ def update_session_optimistically(data) connection = self.class.session_connection quoted_data = connection.quote(data) result = connection.execute("UPDATE #{SmartSession::SqlSession.table_name} SET \"updated_at\"=NOW(), \"data\"=#{quoted_data}, lock_version=lock_version+1 WHERE id=#{@id} AND lock_version=#{@lock_version}") - if result.cmd_tuples == 1 + if (result.class == Fixnum and result == 1) or (result.class != Fixnum and result.cmd_tuples == 1) @lock_version += 1 true else diff --git a/lib/smart_session/store.rb b/lib/smart_session/store.rb index 90afa8d..dff1ee7 100644 --- a/lib/smart_session/store.rb +++ b/lib/smart_session/store.rb @@ -45,7 +45,7 @@ def self.session_class= symbol_or_class private def get_session(env, sid) - ActiveRecord::Base.silence do + ActiveRecord::Base.logger.silence_logger do sid ||= generate_sid session = find_session(sid) env[SESSION_RECORD_KEY] = session @@ -54,7 +54,7 @@ def get_session(env, sid) end def set_session(env, sid, session_data, options) - ActiveRecord::Base.silence do + ActiveRecord::Base.logger.silence_logger do record = get_session_model(env, sid) data, session = save_session(record, session_data) diff --git a/smart_session.gemspec b/smart_session.gemspec index bbdcfcc..27f4ef3 100644 --- a/smart_session.gemspec +++ b/smart_session.gemspec @@ -11,8 +11,8 @@ Gem::Specification.new do |gem| gem.description = %q{A session store that avoids the pitfalls usually associated with concurrent access to the session} gem.summary = %q{A session store that avoids the pitfalls usually associated with concurrent access to the session} gem.homepage = "" - gem.add_dependency "actionpack", '>=3.0.0', '< 4.0.0' - gem.add_dependency "activerecord", '>=3.0.0', '< 4.0.0' + gem.add_dependency "actionpack", '>=3.0.0', '< 5.0.0' + gem.add_dependency "activerecord", '>=3.0.0', '< 5.0.0' gem.add_development_dependency "mysql2" gem.add_development_dependency "sqlite3" gem.add_development_dependency "pg"