diff options
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
6 files changed, 62 insertions, 25 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/connection_specification.rb b/activerecord/lib/active_record/connection_adapters/connection_specification.rb index a8ab52be74..b79d1a4458 100644 --- a/activerecord/lib/active_record/connection_adapters/connection_specification.rb +++ b/activerecord/lib/active_record/connection_adapters/connection_specification.rb @@ -62,8 +62,8 @@ module ActiveRecord # Converts the query parameters of the URI into a hash. # - # "localhost?pool=5&reap_frequency=2" - # # => { "pool" => "5", "reap_frequency" => "2" } + # "localhost?pool=5&reaping_frequency=2" + # # => { "pool" => "5", "reaping_frequency" => "2" } # # returns empty hash if no query present. # diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb index a5fb048b1e..168b08ba75 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb @@ -44,10 +44,32 @@ module ActiveRecord end end + def select_value(arel, name = nil, binds = []) + arel, binds = binds_from_relation arel, binds + sql = to_sql(arel, binds) + execute_and_clear(sql, name, binds) do |result| + result.getvalue(0, 0) if result.ntuples > 0 && result.nfields > 0 + end + end + + def select_values(arel, name = nil) + arel, binds = binds_from_relation arel, [] + sql = to_sql(arel, binds) + execute_and_clear(sql, name, binds) do |result| + if result.nfields > 0 + result.column_values(0) + else + [] + end + end + end + # Executes a SELECT query and returns an array of rows. Each row is an # array of field values. def select_rows(sql, name = nil, binds = []) - exec_query(sql, name, binds).rows + execute_and_clear(sql, name, binds) do |result| + result.values + end end # Executes an INSERT query and returns the new record's ID @@ -134,28 +156,20 @@ module ActiveRecord end def exec_query(sql, name = 'SQL', binds = []) - result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) : - exec_cache(sql, name, binds) - - types = {} - fields = result.fields - fields.each_with_index do |fname, i| - ftype = result.ftype i - fmod = result.fmod i - types[fname] = get_oid_type(ftype, fmod, fname) + execute_and_clear(sql, name, binds) do |result| + types = {} + fields = result.fields + fields.each_with_index do |fname, i| + ftype = result.ftype i + fmod = result.fmod i + types[fname] = get_oid_type(ftype, fmod, fname) + end + ActiveRecord::Result.new(fields, result.values, types) end - - ret = ActiveRecord::Result.new(fields, result.values, types) - result.clear - return ret end def exec_delete(sql, name = 'SQL', binds = []) - result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) : - exec_cache(sql, name, binds) - affected = result.cmd_tuples - result.clear - affected + execute_and_clear(sql, name, binds) {|result| result.cmd_tuples } end alias :exec_update :exec_delete diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb index ac3b0f713d..403e37fde9 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/quoting.rb @@ -182,6 +182,15 @@ module ActiveRecord end result end + + # Does not quote function default values for UUID columns + def quote_default_value(value, column) #:nodoc: + if column.type == :uuid && value =~ /\(\)/ + value + else + quote(value) + end + end end end end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb index 1229b4851a..1dc7a6f0fd 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -187,6 +187,10 @@ module ActiveRecord end end + def column_for(table_name, column_name) #:nodoc: + columns(table_name).detect { |c| c.name == column_name.to_s } + end + # Returns the current database name. def current_database query('select current_database()', 'SCHEMA')[0][0] @@ -404,13 +408,15 @@ module ActiveRecord # Changes the default value of a table column. def change_column_default(table_name, column_name, default) clear_cache! - execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote(default)}" + column = column_for(table_name, column_name) + execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT #{quote_default_value(default, column)}" if column end def change_column_null(table_name, column_name, null, default = nil) clear_cache! unless null || default.nil? - execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL") + column = column_for(table_name, column_name) + execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_value(default, column)} WHERE #{quote_column_name(column_name)} IS NULL") if column end execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL") end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 56dd2da249..764cb576d9 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -658,6 +658,14 @@ module ActiveRecord FEATURE_NOT_SUPPORTED = "0A000" #:nodoc: + def execute_and_clear(sql, name, binds) + result = without_prepared_statement?(binds) ? exec_no_cache(sql, name, binds) : + exec_cache(sql, name, binds) + ret = yield result + result.clear + ret + end + def exec_no_cache(sql, name, binds) log(sql, name, binds) { @connection.async_exec(sql) } end diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index f59c2432dd..dd4261cec7 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -30,7 +30,7 @@ module ActiveRecord db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout] - ConnectionAdapters::SQLite3Adapter.new(db, logger, config) + ConnectionAdapters::SQLite3Adapter.new(db, logger, nil, config) rescue Errno::ENOENT => error if error.message.include?("No such file or directory") raise ActiveRecord::NoDatabaseError.new(error.message, error) @@ -123,7 +123,7 @@ module ActiveRecord end end - def initialize(connection, logger, config) + def initialize(connection, logger, connection_options, config) super(connection, logger) @active = nil |