aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb16
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb1
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb31
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb64
5 files changed, 88 insertions, 26 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
index 901b17124c..aac84cc5f4 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/connection_pool.rb
@@ -351,5 +351,21 @@ module ActiveRecord
retrieve_connection_pool klass.superclass
end
end
+
+ class ConnectionManagement
+ def initialize(app)
+ @app = app
+ end
+
+ def call(env)
+ @app.call(env)
+ ensure
+ # Don't return connection (and peform implicit rollback) if
+ # this request is a part of integration test
+ unless env.key?("rack.test")
+ ActiveRecord::Base.clear_active_connections!
+ end
+ end
+ end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
index 273f823e7f..24c734cddb 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb
@@ -8,6 +8,7 @@ module ActiveRecord
# An abstract definition of a column in a table.
class Column
TRUE_VALUES = [true, 1, '1', 't', 'T', 'true', 'TRUE'].to_set
+ FALSE_VALUES = [false, 0, '0', 'f', 'F', 'false', 'FALSE'].to_set
module Format
ISO_DATE = /\A(\d{4})-(\d\d)-(\d\d)\z/
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 913bb521ca..ec204d0f03 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -392,9 +392,28 @@ module ActiveRecord
quote_string(s)
end
+ # Checks the following cases:
+ #
+ # - table_name
+ # - "table.name"
+ # - schema_name.table_name
+ # - schema_name."table.name"
+ # - "schema.name".table_name
+ # - "schema.name"."table.name"
+ def quote_table_name(name)
+ schema, name_part = extract_pg_identifier_from_name(name.to_s)
+
+ unless name_part
+ quote_column_name(schema)
+ else
+ table_name, name_part = extract_pg_identifier_from_name(name_part)
+ "#{quote_column_name(schema)}.#{quote_column_name(table_name)}"
+ end
+ end
+
# Quotes column names for use in SQL queries.
def quote_column_name(name) #:nodoc:
- %("#{name}")
+ PGconn.quote_ident(name.to_s)
end
# Quote date/time values for use in SQL input. Includes microseconds
@@ -1045,6 +1064,16 @@ module ActiveRecord
ORDER BY a.attnum
end_sql
end
+
+ def extract_pg_identifier_from_name(name)
+ match_data = name[0,1] == '"' ? name.match(/\"([^\"]+)\"/) : name.match(/([^\.]+)/)
+
+ if match_data
+ rest = name[match_data[0].length..-1]
+ rest = rest[1..-1] if rest[0,1] == "."
+ [match_data[1], (rest.length > 0 ? rest : nil)]
+ end
+ end
end
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index cc9c46505f..75420f69aa 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -18,7 +18,7 @@ module ActiveRecord
db.busy_timeout(config[:timeout]) unless config[:timeout].nil?
- ConnectionAdapters::SQLite3Adapter.new(db, logger)
+ ConnectionAdapters::SQLite3Adapter.new(db, logger, config)
end
end
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
index 5390f49f04..afd6472db8 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb
@@ -17,9 +17,9 @@ module ActiveRecord
# "Downgrade" deprecated sqlite API
if SQLite.const_defined?(:Version)
- ConnectionAdapters::SQLite2Adapter.new(db, logger)
+ ConnectionAdapters::SQLite2Adapter.new(db, logger, config)
else
- ConnectionAdapters::DeprecatedSQLiteAdapter.new(db, logger)
+ ConnectionAdapters::DeprecatedSQLiteAdapter.new(db, logger, config)
end
end
end
@@ -72,10 +72,31 @@ module ActiveRecord
#
# * <tt>:database</tt> - Path to the database file.
class SQLiteAdapter < AbstractAdapter
+ class Version
+ include Comparable
+
+ def initialize(version_string)
+ @version = version_string.split('.').map(&:to_i)
+ end
+
+ def <=>(version_string)
+ @version <=> version_string.split('.').map(&:to_i)
+ end
+ end
+
+ def initialize(connection, logger, config)
+ super(connection, logger)
+ @config = config
+ end
+
def adapter_name #:nodoc:
'SQLite'
end
+ def supports_ddl_transactions?
+ sqlite_version >= '2.0.0'
+ end
+
def supports_migrations? #:nodoc:
true
end
@@ -83,6 +104,10 @@ module ActiveRecord
def requires_reloading?
true
end
+
+ def supports_add_column?
+ sqlite_version >= '3.1.6'
+ end
def disconnect!
super
@@ -164,7 +189,6 @@ module ActiveRecord
catch_schema_changes { @connection.rollback }
end
-
# SELECT ... FOR UPDATE is redundant since the table is locked.
def add_lock!(sql, options) #:nodoc:
sql
@@ -213,14 +237,20 @@ module ActiveRecord
execute "ALTER TABLE #{name} RENAME TO #{new_name}"
end
+ # See: http://www.sqlite.org/lang_altertable.html
+ # SQLite has an additional restriction on the ALTER TABLE statement
+ def valid_alter_table_options( type, options)
+ type.to_sym != :primary_key
+ end
+
def add_column(table_name, column_name, type, options = {}) #:nodoc:
- if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
- raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
+ if supports_add_column? && valid_alter_table_options( type, options )
+ super(table_name, column_name, type, options)
+ else
+ alter_table(table_name) do |definition|
+ definition.column(column_name, type, options)
+ end
end
-
- super(table_name, column_name, type, options)
- # See last paragraph on http://www.sqlite.org/lang_altertable.html
- execute "VACUUM"
end
def remove_column(table_name, *column_names) #:nodoc:
@@ -380,7 +410,7 @@ module ActiveRecord
end
def sqlite_version
- @sqlite_version ||= select_value('select sqlite_version(*)')
+ @sqlite_version ||= SQLiteAdapter::Version.new(select_value('select sqlite_version(*)'))
end
def default_primary_key_type
@@ -393,23 +423,9 @@ module ActiveRecord
end
class SQLite2Adapter < SQLiteAdapter # :nodoc:
- def supports_count_distinct? #:nodoc:
- false
- end
-
def rename_table(name, new_name)
move_table(name, new_name)
end
-
- def add_column(table_name, column_name, type, options = {}) #:nodoc:
- if @connection.respond_to?(:transaction_active?) && @connection.transaction_active?
- raise StatementInvalid, 'Cannot add columns to a SQLite database while inside a transaction'
- end
-
- alter_table(table_name) do |definition|
- definition.column(column_name, type, options)
- end
- end
end
class DeprecatedSQLiteAdapter < SQLite2Adapter # :nodoc: