diff options
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters')
15 files changed, 115 insertions, 170 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb index 947796eea0..2c352819fb 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb @@ -126,22 +126,16 @@ module ActiveRecord id_value || last_inserted_id(value) end alias create insert - alias insert_sql insert - deprecate insert_sql: :insert # Executes the update statement and returns the number of rows affected. def update(arel, name = nil, binds = []) exec_update(to_sql(arel, binds), name, binds) end - alias update_sql update - deprecate update_sql: :update # Executes the delete statement and returns the number of rows affected. def delete(arel, name = nil, binds = []) exec_delete(to_sql(arel, binds), name, binds) end - alias delete_sql delete - deprecate delete_sql: :delete # Returns +true+ when the connection adapter supports prepared statement # caching, otherwise returns +false+ @@ -334,17 +328,12 @@ module ActiveRecord # Sanitizes the given LIMIT parameter in order to prevent SQL injection. # # The +limit+ may be anything that can evaluate to a string via #to_s. It - # should look like an integer, or a comma-delimited list of integers, or - # an Arel SQL literal. + # should look like an integer, or an Arel SQL literal. # # Returns Integer and Arel::Nodes::SqlLiteral limits as is. - # Returns the sanitized limit parameter, either as an integer, or as a - # string which contains a comma-delimited list of integers. def sanitize_limit(limit) if limit.is_a?(Integer) || limit.is_a?(Arel::Nodes::SqlLiteral) limit - elsif limit.to_s.include?(",") - Arel.sql limit.to_s.split(",").map { |i| Integer(i) }.join(",") else Integer(limit) end @@ -360,7 +349,7 @@ module ActiveRecord end alias join_to_delete join_to_update - protected + private # Returns a subquery for the given key using the join information. def subquery_for(key, select) diff --git a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb index bbd52b8a91..0c6bc16e6f 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb @@ -5,20 +5,10 @@ module ActiveRecord module Quoting # Quotes the column value to help prevent # {SQL injection attacks}[http://en.wikipedia.org/wiki/SQL_injection]. - def quote(value, column = nil) + def quote(value) # records are quoted as their primary key return value.quoted_id if value.respond_to?(:quoted_id) - if column - ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing a column to `quote` has been deprecated. It is only used - for type casting, which should be handled elsewhere. See - https://github.com/rails/arel/commit/6160bfbda1d1781c3b08a33ec4955f170e95be11 - for more information. - MSG - value = type_cast_from_column(column, value) - end - _quote(value) 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 f783b1941b..9b324c090b 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb @@ -100,6 +100,8 @@ module ActiveRecord end end + # TODO Change this to private once we've dropped Ruby 2.2 support. + # Workaround for Ruby 2.2 "private attribute?" warning. protected attr_reader :name, :polymorphic, :index, :foreign_key, :type, :options diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb index 5623257fe8..e5c0e1690c 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb @@ -43,7 +43,7 @@ module ActiveRecord end # Returns an array of table names defined in the database. - def tables(name = nil) + def tables raise NotImplementedError, "#tables is not implemented" end @@ -994,15 +994,15 @@ module ActiveRecord end def insert_versions_sql(versions) # :nodoc: - sm_table = ActiveRecord::Migrator.schema_migrations_table_name + sm_table = quote_table_name(ActiveRecord::Migrator.schema_migrations_table_name) if versions.is_a?(Array) sql = "INSERT INTO #{sm_table} (version) VALUES\n" - sql << versions.map { |v| "('#{v}')" }.join(",\n") + sql << versions.map { |v| "(#{quote(v)})" }.join(",\n") sql << ";\n\n" sql else - "INSERT INTO #{sm_table} (version) VALUES ('#{versions}');" + "INSERT INTO #{sm_table} (version) VALUES (#{quote(versions)});" end end @@ -1032,7 +1032,7 @@ module ActiveRecord end unless migrated.include?(version) - execute "INSERT INTO #{sm_table} (version) VALUES ('#{version}')" + execute "INSERT INTO #{sm_table} (version) VALUES (#{quote(version)})" end inserting = (versions - migrated).select { |v| v < version } @@ -1169,7 +1169,7 @@ module ActiveRecord raise NotImplementedError, "#{self.class} does not support changing column comments" end - protected + private def add_index_sort_order(quoted_columns, **options) if order = options[:order] @@ -1253,7 +1253,6 @@ module ActiveRecord end end - private def create_table_definition(*args) TableDefinition.new(*args) end @@ -1262,7 +1261,7 @@ module ActiveRecord AlterTable.new create_table_definition(name) end - def index_name_options(column_names) # :nodoc: + def index_name_options(column_names) if column_names.is_a?(String) column_names = column_names.scan(/\w+/).join("_") end @@ -1270,7 +1269,7 @@ module ActiveRecord { column: column_names } end - def foreign_key_name(table_name, options) # :nodoc: + def foreign_key_name(table_name, options) identifier = "#{table_name}_#{options.fetch(:column)}_fk" hashed_identifier = Digest::SHA256.hexdigest(identifier).first(10) options.fetch(:name) do @@ -1278,7 +1277,7 @@ module ActiveRecord end end - def validate_index_length!(table_name, new_name, internal = false) # :nodoc: + def validate_index_length!(table_name, new_name, internal = false) max_index_length = internal ? index_name_length : allowed_index_name_length if new_name.length > max_index_length diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index 284529b46e..4046b3829d 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -499,9 +499,9 @@ module ActiveRecord result end - protected + private - def initialize_type_map(m) # :nodoc: + def initialize_type_map(m) register_class_with_limit m, %r(boolean)i, Type::Boolean register_class_with_limit m, %r(char)i, Type::String register_class_with_limit m, %r(binary)i, Type::Binary @@ -532,37 +532,37 @@ module ActiveRecord end end - def reload_type_map # :nodoc: + def reload_type_map type_map.clear initialize_type_map(type_map) end - def register_class_with_limit(mapping, key, klass) # :nodoc: + def register_class_with_limit(mapping, key, klass) mapping.register_type(key) do |*args| limit = extract_limit(args.last) klass.new(limit: limit) end end - def register_class_with_precision(mapping, key, klass) # :nodoc: + def register_class_with_precision(mapping, key, klass) mapping.register_type(key) do |*args| precision = extract_precision(args.last) klass.new(precision: precision) end end - def extract_scale(sql_type) # :nodoc: + def extract_scale(sql_type) case sql_type when /\((\d+)\)/ then 0 when /\((\d+)(,(\d+))\)/ then $3.to_i end end - def extract_precision(sql_type) # :nodoc: + def extract_precision(sql_type) $1.to_i if sql_type =~ /\((\d+)(,\d+)?\)/ end - def extract_limit(sql_type) # :nodoc: + def extract_limit(sql_type) case sql_type when /^bigint/i 8 @@ -583,7 +583,7 @@ module ActiveRecord exception end - def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) + def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc: @instrumenter.instrument( "sql.active_record", sql: sql, @@ -610,7 +610,7 @@ module ActiveRecord !prepared_statements || binds.empty? end - def column_for(table_name, column_name) # :nodoc: + def column_for(table_name, column_name) column_name = column_name.to_s columns(table_name).detect { |c| c.name == column_name } || raise(ActiveRecordError, "No such column: #{table_name}.#{column_name}") diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb index d02340d961..01cd1e5446 100644 --- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb @@ -310,45 +310,36 @@ module ActiveRecord show_variable "collation_database" end - def tables(name = nil) # :nodoc: - ActiveSupport::Deprecation.warn(<<-MSG.squish) - #tables currently returns both tables and views. - This behavior is deprecated and will be changed with Rails 5.1 to only return tables. - Use #data_sources instead. - MSG + def tables # :nodoc: + sql = "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'" + sql << " AND table_schema = #{quote(@config[:database])}" - if name - ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing arguments to #tables is deprecated without replacement. - MSG - end + select_values(sql, "SCHEMA") + end - data_sources + def views # :nodoc: + select_values("SHOW FULL TABLES WHERE table_type = 'VIEW'", "SCHEMA") end - def data_sources + def data_sources # :nodoc: sql = "SELECT table_name FROM information_schema.tables " sql << "WHERE table_schema = #{quote(@config[:database])}" select_values(sql, "SCHEMA") end - def truncate(table_name, name = nil) - execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name - end + def table_exists?(table_name) # :nodoc: + return false unless table_name.present? - def table_exists?(table_name) - # Update lib/active_record/internal_metadata.rb when this gets removed - ActiveSupport::Deprecation.warn(<<-MSG.squish) - #table_exists? currently checks both tables and views. - This behavior is deprecated and will be changed with Rails 5.1 to only check tables. - Use #data_source_exists? instead. - MSG + schema, name = extract_schema_qualified_name(table_name) + + sql = "SELECT table_name FROM information_schema.tables WHERE table_type = 'BASE TABLE'" + sql << " AND table_schema = #{quote(schema)} AND table_name = #{quote(name)}" - data_source_exists?(table_name) + select_values(sql, "SCHEMA").any? end - def data_source_exists?(table_name) + def data_source_exists?(table_name) # :nodoc: return false unless table_name.present? schema, name = extract_schema_qualified_name(table_name) @@ -359,10 +350,6 @@ module ActiveRecord select_values(sql, "SCHEMA").any? end - def views # :nodoc: - select_values("SHOW FULL TABLES WHERE table_type = 'VIEW'", "SCHEMA") - end - def view_exists?(view_name) # :nodoc: return false unless view_name.present? @@ -374,6 +361,10 @@ module ActiveRecord select_values(sql, "SCHEMA").any? end + def truncate(table_name, name = nil) + execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name + end + # Returns an array of indexes for the given table. def indexes(table_name, name = nil) #:nodoc: indexes = [] @@ -649,9 +640,9 @@ module ActiveRecord !native_database_types[type].nil? end - protected + private - def initialize_type_map(m) # :nodoc: + def initialize_type_map(m) super register_class_with_limit m, %r(char)i, MysqlString @@ -691,7 +682,7 @@ module ActiveRecord end end - def register_integer_type(mapping, key, options) # :nodoc: + def register_integer_type(mapping, key, options) mapping.register_type(key) do |sql_type| if /\bunsigned\b/.match?(sql_type) Type::UnsignedInteger.new(options) @@ -837,8 +828,6 @@ module ActiveRecord [remove_column_sql(table_name, :updated_at), remove_column_sql(table_name, :created_at)] end - private - # MySQL is too stupid to create a temporary table for use subquery, so we have # to give it some prompting in the form of a subsubquery. Ugh! def subquery_for(key, select) @@ -908,7 +897,7 @@ module ActiveRecord end.compact.join(", ") # ...and send them all in one query - @connection.query "SET #{encoding} #{sql_mode_assignment} #{variable_assignments}" + execute "SET #{encoding} #{sql_mode_assignment} #{variable_assignments}" end def column_definitions(table_name) # :nodoc: diff --git a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb index c7098105a8..78e7181266 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb @@ -52,14 +52,12 @@ module ActiveRecord end alias :exec_update :exec_delete - protected + private def last_inserted_id(result) @connection.last_id end - private - def select_result(sql, name = nil, binds = []) if without_prepared_statement?(binds) execute_and_free(sql, name) { |result| yield result } 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 520a50506f..9a2017b443 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb @@ -134,7 +134,7 @@ module ActiveRecord super end - protected :sql_for_insert + private :sql_for_insert def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil) if use_insert_returning? || pk == false diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb index d9daaaa23e..8ccdd69b1d 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/array.rb @@ -6,7 +6,7 @@ module ActiveRecord include Type::Helpers::Mutable attr_reader :subtype, :delimiter - delegate :type, :user_input_in_time_zone, :limit, to: :subtype + delegate :type, :user_input_in_time_zone, :limit, :precision, :scale, to: :subtype def initialize(subtype, delimiter = ",") @subtype = subtype diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb index 302d393277..0a505f46a7 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/oid/bit.rb @@ -41,6 +41,8 @@ module ActiveRecord /\A[0-9A-F]*\Z/i.match?(value) end + # TODO Change this to private once we've dropped Ruby 2.2 support. + # Workaround for Ruby 2.2 "private attribute?" warning. protected attr_reader :value 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 9e7487b27f..85836fc575 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb @@ -71,13 +71,7 @@ module ActiveRecord end # Returns the list of all tables in the schema search path. - def tables(name = nil) - if name - ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing arguments to #tables is deprecated without replacement. - MSG - end - + def tables select_values("SELECT tablename FROM pg_tables WHERE schemaname = ANY(current_schemas(false))", "SCHEMA") end @@ -91,40 +85,42 @@ module ActiveRecord SQL end + def views # :nodoc: + select_values(<<-SQL, "SCHEMA") + SELECT c.relname + FROM pg_class c + LEFT JOIN pg_namespace n ON n.oid = c.relnamespace + WHERE c.relkind IN ('v','m') -- (v)iew, (m)aterialized view + AND n.nspname = ANY (current_schemas(false)) + SQL + end + # Returns true if table exists. # If the schema is not specified as part of +name+ then it will only find tables within # the current schema search path (regardless of permissions to access tables in other schemas) def table_exists?(name) - ActiveSupport::Deprecation.warn(<<-MSG.squish) - #table_exists? currently checks both tables and views. - This behavior is deprecated and will be changed with Rails 5.1 to only check tables. - Use #data_source_exists? instead. - MSG - - data_source_exists?(name) - end - - def data_source_exists?(name) name = Utils.extract_schema_qualified_name(name.to_s) return false unless name.identifier select_values(<<-SQL, "SCHEMA").any? - SELECT c.relname - FROM pg_class c - LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE c.relkind IN ('r','v','m') -- (r)elation/table, (v)iew, (m)aterialized view - AND c.relname = #{quote(name.identifier)} - AND n.nspname = #{name.schema ? quote(name.schema) : "ANY (current_schemas(false))"} + SELECT tablename + FROM pg_tables + WHERE tablename = #{quote(name.identifier)} + AND schemaname = #{name.schema ? quote(name.schema) : "ANY (current_schemas(false))"} SQL end - def views # :nodoc: - select_values(<<-SQL, "SCHEMA") + def data_source_exists?(name) # :nodoc: + name = Utils.extract_schema_qualified_name(name.to_s) + return false unless name.identifier + + select_values(<<-SQL, "SCHEMA").any? SELECT c.relname FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = c.relnamespace - WHERE c.relkind IN ('v','m') -- (v)iew, (m)aterialized view - AND n.nspname = ANY (current_schemas(false)) + WHERE c.relkind IN ('r','v','m') -- (r)elation/table, (v)iew, (m)aterialized view + AND c.relname = #{quote(name.identifier)} + AND n.nspname = #{name.schema ? quote(name.schema) : "ANY (current_schemas(false))"} SQL end diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/utils.rb b/activerecord/lib/active_record/connection_adapters/postgresql/utils.rb index 1412928ca5..a3f9ce6d64 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql/utils.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql/utils.rb @@ -35,6 +35,12 @@ module ActiveRecord end protected + + def parts + @parts ||= [@schema, @identifier].compact + end + + private def unquote(part) if part && part.start_with?('"') part[1..-2] @@ -42,10 +48,6 @@ module ActiveRecord part end end - - def parts - @parts ||= [@schema, @identifier].compact - end end module Utils # :nodoc: diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb index 33cdcf9a76..0ebd907cc0 100644 --- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb @@ -404,7 +404,7 @@ module ActiveRecord @connection.server_version end - protected + private # See http://www.postgresql.org/docs/current/static/errcodes-appendix.html VALUE_LIMIT_VIOLATION = "22001" @@ -438,9 +438,7 @@ module ActiveRecord end end - private - - def get_oid_type(oid, fmod, column_name, sql_type = "") # :nodoc: + def get_oid_type(oid, fmod, column_name, sql_type = "") if !type_map.key?(oid) load_additional_types(type_map, [oid]) end @@ -453,7 +451,7 @@ module ActiveRecord } end - def initialize_type_map(m) # :nodoc: + def initialize_type_map(m) register_class_with_limit m, "int2", Type::Integer register_class_with_limit m, "int4", Type::Integer register_class_with_limit m, "int8", Type::Integer @@ -521,7 +519,7 @@ module ActiveRecord load_additional_types(m) end - def extract_limit(sql_type) # :nodoc: + def extract_limit(sql_type) case sql_type when /^bigint/i, /^int8/i 8 @@ -533,7 +531,7 @@ module ActiveRecord end # Extracts the value from a PostgreSQL column default definition. - def extract_value_from_default(default) # :nodoc: + def extract_value_from_default(default) case default # Quoted types when /\A[\(B]?'(.*)'.*::"?([\w. ]+)"?(?:\[\])?\z/m @@ -559,15 +557,15 @@ module ActiveRecord end end - def extract_default_function(default_value, default) # :nodoc: + def extract_default_function(default_value, default) default if has_default_function?(default_value, default) end - def has_default_function?(default_value, default) # :nodoc: + def has_default_function?(default_value, default) !default_value && (%r{\w+\(.*\)|\(.*\)::\w+} === default) end - def load_additional_types(type_map, oids = nil) # :nodoc: + def load_additional_types(type_map, oids = nil) initializer = OID::TypeMapInitializer.new(type_map) if supports_ranges? @@ -735,7 +733,7 @@ module ActiveRecord end # Returns the current ID of a table's sequence. - def last_insert_id_result(sequence_name) # :nodoc: + def last_insert_id_result(sequence_name) exec_query("SELECT currval('#{sequence_name}')", "SQL") end @@ -757,7 +755,7 @@ module ActiveRecord # Query implementation notes: # - format_type includes the column size constraint, e.g. varchar(50) # - ::regclass is a function that gives the id for a table name - def column_definitions(table_name) # :nodoc: + def column_definitions(table_name) query(<<-end_sql, "SCHEMA") SELECT a.attname, format_type(a.atttypid, a.atttypmod), pg_get_expr(d.adbin, d.adrelid), a.attnotnull, a.atttypid, a.atttypmod, @@ -772,12 +770,12 @@ module ActiveRecord end_sql end - def extract_table_ref_from_insert_sql(sql) # :nodoc: + def extract_table_ref_from_insert_sql(sql) sql[/into\s("[A-Za-z0-9_."\[\]\s]+"|[A-Za-z0-9_."\[\]]+)\s*/im] $1.strip if $1 end - def create_table_definition(*args) # :nodoc: + def create_table_definition(*args) PostgreSQL::TableDefinition.new(*args) end diff --git a/activerecord/lib/active_record/connection_adapters/schema_cache.rb b/activerecord/lib/active_record/connection_adapters/schema_cache.rb index 3a319c4029..4d339b0a8c 100644 --- a/activerecord/lib/active_record/connection_adapters/schema_cache.rb +++ b/activerecord/lib/active_record/connection_adapters/schema_cache.rb @@ -48,8 +48,6 @@ module ActiveRecord @data_sources[name] = connection.data_source_exists?(name) end - alias table_exists? data_source_exists? - deprecate table_exists?: "use #data_source_exists? instead" # Add internal cache for table with +table_name+. def add(table_name) @@ -63,8 +61,6 @@ module ActiveRecord def data_sources(name) @data_sources[name] end - alias tables data_sources - deprecate tables: "use #data_sources instead" # Get the columns for a table def columns(table_name) @@ -99,8 +95,6 @@ module ActiveRecord @primary_keys.delete name @data_sources.delete name end - alias clear_table_cache! clear_data_source_cache! - deprecate clear_table_cache!: "use #clear_data_source_cache! instead" def marshal_dump # if we get current version during initialization, it happens stack over flow. diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb index a7c4a2cd86..297e2997a9 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb @@ -259,47 +259,34 @@ module ActiveRecord # SCHEMA STATEMENTS ======================================== - def tables(name = nil) # :nodoc: - ActiveSupport::Deprecation.warn(<<-MSG.squish) - #tables currently returns both tables and views. - This behavior is deprecated and will be changed with Rails 5.1 to only return tables. - Use #data_sources instead. - MSG - - if name - ActiveSupport::Deprecation.warn(<<-MSG.squish) - Passing arguments to #tables is deprecated without replacement. - MSG - end - - data_sources + def tables # :nodoc: + select_values("SELECT name FROM sqlite_master WHERE type = 'table' AND name <> 'sqlite_sequence'", "SCHEMA") end - def data_sources + def data_sources # :nodoc: select_values("SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'", "SCHEMA") end - def table_exists?(table_name) - ActiveSupport::Deprecation.warn(<<-MSG.squish) - #table_exists? currently checks both tables and views. - This behavior is deprecated and will be changed with Rails 5.1 to only check tables. - Use #data_source_exists? instead. - MSG - - data_source_exists?(table_name) + def views # :nodoc: + select_values("SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'", "SCHEMA") end - def data_source_exists?(table_name) + def table_exists?(table_name) # :nodoc: return false unless table_name.present? - sql = "SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'" + sql = "SELECT name FROM sqlite_master WHERE type = 'table' AND name <> 'sqlite_sequence'" sql << " AND name = #{quote(table_name)}" select_values(sql, "SCHEMA").any? end - def views # :nodoc: - select_values("SELECT name FROM sqlite_master WHERE type = 'view' AND name <> 'sqlite_sequence'", "SCHEMA") + def data_source_exists?(table_name) # :nodoc: + return false unless table_name.present? + + sql = "SELECT name FROM sqlite_master WHERE type IN ('table','view') AND name <> 'sqlite_sequence'" + sql << " AND name = #{quote(table_name)}" + + select_values(sql, "SCHEMA").any? end def view_exists?(view_name) # :nodoc: @@ -431,16 +418,16 @@ module ActiveRecord rename_column_indexes(table_name, column.name, new_column_name) end - protected + private - def table_structure(table_name) # :nodoc: + def table_structure(table_name) structure = exec_query("PRAGMA table_info(#{quote_table_name(table_name)})", "SCHEMA") raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty? table_structure_with_collation(table_name, structure) end alias column_definitions table_structure - def alter_table(table_name, options = {}) #:nodoc: + def alter_table(table_name, options = {}) altered_table_name = "a#{table_name}" caller = lambda { |definition| yield definition if block_given? } @@ -451,12 +438,12 @@ module ActiveRecord end end - def move_table(from, to, options = {}, &block) #:nodoc: + def move_table(from, to, options = {}, &block) copy_table(from, to, options, &block) drop_table(from) end - def copy_table(from, to, options = {}) #:nodoc: + def copy_table(from, to, options = {}) from_primary_key = primary_key(from) options[:id] = false create_table(to, options) do |definition| @@ -482,7 +469,7 @@ module ActiveRecord options[:rename] || {}) end - def copy_table_indexes(from, to, rename = {}) #:nodoc: + def copy_table_indexes(from, to, rename = {}) indexes(from).each do |index| name = index.name if to == "a#{from}" @@ -505,7 +492,7 @@ module ActiveRecord end end - def copy_table_contents(from, to, columns, rename = {}) #:nodoc: + def copy_table_contents(from, to, columns, rename = {}) column_mappings = Hash[columns.map { |name| [name, name] }] rename.each { |a| column_mappings[a.last] = a.first } from_columns = columns(from).collect(&:name) @@ -537,7 +524,6 @@ module ActiveRecord end end - private COLLATE_REGEX = /.*\"(\w+)\".*collate\s+\"(\w+)\".*/i.freeze def table_structure_with_collation(table_name, basic_structure) |