diff --git a/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb b/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb
index 0358c348..df57e79b 100644
--- a/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb
+++ b/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb
@@ -27,26 +27,6 @@ def truncate(table_name, name = nil)
execute("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
end
- def limited_update_conditions(where_sql, _quoted_table_name, _quoted_primary_key)
- where_sql
- end
-
- def join_to_update(update, select) #:nodoc:
- if select.limit || select.offset || select.orders.any?
- subsubselect = select.clone
- subsubselect.projections = [update.key]
-
- subselect = Arel::SelectManager.new(select.engine)
- subselect.project Arel.sql(update.key.name)
- subselect.from subsubselect.as('__active_record_temp')
-
- update.where update.key.in(subselect)
- else
- update.table select.source
- update.wheres = select.constraints
- end
- end
-
# Quotes a string, escaping any ' (single quote) and \ (backslash)
# characters.
def quote_string(string)
@@ -113,9 +93,8 @@ def rename_table(name, new_name)
end
def change_column(table_name, column_name, type, options = {})
- # column_name.to_s used in case column_name is a symbol
unless options_include_default?(options)
- options[:default] = columns(table_name).find { |c| c.name == column_name.to_s }.default
+ options[:default] = column_for(table_name, column_name).default
end
change_column_sql = "ALTER TABLE #{table_name} CHANGE #{column_name} #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
@@ -139,34 +118,15 @@ def change_column_null(table_name, column_name, null, default = nil)
end
def rename_column(table_name, column_name, new_column_name)
- col = columns(table_name).detect { |c| c.name == column_name.to_s }
- current_type = col.native_type
- current_type << "(#{col.limit})" if col.limit
+ column = column_for(table_name, column_name)
+ current_type = column.native_type
+ current_type << "(#{column.limit})" if column.limit
execute("ALTER TABLE #{table_name} CHANGE #{column_name} #{new_column_name} #{current_type}")
end
# Skip primary key indexes
def indexes(table_name, name = nil)
- super(table_name, name).delete_if { |i| i.unique && i.name =~ /^PRIMARY$/ }
- end
-
- # MySQL 5.x doesn't allow DEFAULT NULL for first timestamp column in a
- # table
- def options_include_default?(options)
- if options.include?(:default) && options[:default].nil?
- if options.include?(:column) && options[:column].native_type =~ /timestamp/i
- options.delete(:default)
- end
- end
- super(options)
- end
-
- def structure_dump
- select_all("SHOW FULL TABLES WHERE Table_type = 'BASE TABLE'").map do |table|
- table.delete('Table_type')
- sql = "SHOW CREATE TABLE #{quote_table_name(table.to_a.first.last)}"
- exec_query(sql).first['Create Table'] + ";\n\n"
- end.join
+ super(table_name, name).reject { |i| i.unique && i.name =~ /^PRIMARY$/ }
end
protected
@@ -179,6 +139,19 @@ def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
def last_inserted_id(_result)
select_value('SELECT LAST_INSERT_ID()').to_i
end
+
+ private
+
+ # MySQL 5.x doesn't allow DEFAULT NULL for first timestamp column in a
+ # table
+ def options_include_default?(options)
+ if options.include?(:default) && options[:default].nil?
+ if options.include?(:column) && options[:column].native_type =~ /timestamp/i
+ options.delete(:default)
+ end
+ end
+ super(options)
+ end
end
end
end
diff --git a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb
index 981f02c4..f6721e02 100644
--- a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb
+++ b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb
@@ -6,6 +6,8 @@ class PostgreSQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter
BOOLEAN_TYPE = 'bool'.freeze
PRIMARY_KEY = 'SERIAL PRIMARY KEY'.freeze
+ alias :create :insert
+
# Override to handle booleans appropriately
def native_database_types
@native_database_types ||= super.merge(boolean: { name: 'bool' })
@@ -25,34 +27,14 @@ def truncate(table_name, name = nil)
exec_query("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
end
- # Returns the sequence name for a table's primary key or some other specified key.
+ # Returns the sequence name for a table's primary key or some other
+ # specified key.
def default_sequence_name(table_name, pk = nil) #:nodoc:
serial_sequence(table_name, pk || 'id').split('.').last
rescue ActiveRecord::StatementInvalid
"#{table_name}_#{pk || 'id'}_seq"
end
- # Returns the current ID of a table's sequence.
- def last_insert_id(sequence_name)
- r = exec_query("SELECT currval('#{sequence_name}')", 'SQL')
- Integer(r.rows.first.first)
- end
-
- # Executes an INSERT query and returns the new record's ID
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
- unless pk
- table_ref = extract_table_ref_from_insert_sql(sql)
- pk = primary_key(table_ref) if table_ref
- end
-
- if pk
- select_value("#{sql} RETURNING #{quote_column_name(pk)}")
- else
- super
- end
- end
- alias :create :insert
-
def sql_for_insert(sql, pk, id_value, sequence_name, binds)
unless pk
table_ref = extract_table_ref_from_insert_sql(sql)
@@ -88,13 +70,14 @@ def disable_referential_integrity #:nodoc:
execute(tables.map { |name| "ALTER TABLE #{quote_table_name(name)} ENABLE TRIGGER ALL" }.join(';'))
end
- # Create a new PostgreSQL database. Options include :owner, :template,
- # :encoding, :tablespace, and :connection_limit (note that MySQL
- # uses :charset while PostgreSQL uses :encoding).
+ # Create a new PostgreSQL database. Options include :owner,
+ # :template, :encoding, :tablespace, and
+ # :connection_limit (note that MySQL uses :charset
+ # while PostgreSQL uses :encoding).
#
# Example:
# create_database config[:database], config
- # create_database 'foo_development', :encoding => 'unicode'
+ # create_database 'foo_development', encoding: 'unicode'
def create_database(name, options = {})
options = options.reverse_merge(encoding: 'utf8')
@@ -121,7 +104,7 @@ def create_database(name, options = {})
# Drops a PostgreSQL database.
#
# Example:
- # drop_database 'matt_development'
+ # drop_database 'rails_development'
def drop_database(name) #:nodoc:
execute "DROP DATABASE IF EXISTS #{quote_table_name(name)}"
end
@@ -152,17 +135,19 @@ def rename_index(table_name, old_name, new_name)
execute("ALTER INDEX #{quote_column_name(old_name)} RENAME TO #{quote_table_name(new_name)}")
end
- # Returns a SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
+ # Returns a SELECT DISTINCT clause for a given set of columns and a given
+ # ORDER BY clause.
#
- # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and
- # requires that the ORDER BY include the distinct column.
+ # PostgreSQL requires the ORDER BY columns in the select list for
+ # distinct queries, and requires that the ORDER BY include the distinct
+ # column.
#
# distinct("posts.id", "posts.created_at desc")
def distinct(columns, orders)
return "DISTINCT #{columns}" if orders.empty?
- # Construct a clean list of column names from the ORDER BY clause, removing
- # any ASC/DESC modifiers
+ # Construct a clean list of column names from the ORDER BY clause,
+ # removing any ASC/DESC modifiers
order_columns = orders.map { |s| s.gsub(/\s+(ASC|DESC)\s*(NULLS\s+(FIRST|LAST)\s*)?/i, '') }
order_columns.reject! { |c| c.blank? }
order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
@@ -170,6 +155,28 @@ def distinct(columns, orders)
"DISTINCT #{columns}, #{order_columns * ', '}"
end
+ protected
+
+ # Executes an INSERT query and returns the new record's ID
+ def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
+ unless pk
+ table_ref = extract_table_ref_from_insert_sql(sql)
+ pk = primary_key(table_ref) if table_ref
+ end
+
+ if pk
+ select_value("#{sql} RETURNING #{quote_column_name(pk)}")
+ else
+ super
+ end
+ end
+
+ # Returns the current ID of a table's sequence.
+ def last_insert_id(sequence_name)
+ r = exec_query("SELECT currval('#{sequence_name}')", 'SQL')
+ Integer(r.rows.first.first)
+ end
+
private
def serial_sequence(table, column)