From 4cd9c9561adcbb8f3267003bd3b01931e457ed6a Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 28 Dec 2004 16:26:06 +0000 Subject: [PATCH] Added the possibility for adapters to overwrite add_limit! to implement a different limiting scheme than "LIMIT X" used by MySQL, PostgreSQL, and SQLite. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@269 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- activerecord/lib/active_record/base.rb | 8 +- .../connection_adapters/abstract_adapter.rb | 4 + .../connection_adapters/sqlserver_adapter.rb | 129 ++++++------------ 3 files changed, 53 insertions(+), 88 deletions(-) diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 8a0fab2252..ce10f03789 100755 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -288,8 +288,9 @@ def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) sql << "#{joins} " if joins add_conditions!(sql, conditions) sql << "ORDER BY #{orderings} " unless orderings.nil? - sql << "LIMIT #{sanitize_conditions(limit)} " unless limit.nil? - + + connection.add_limit!(sql, sanitize_conditions(limit)) unless limit.nil? + find_by_sql(sql) end @@ -310,7 +311,8 @@ def find_first(conditions = nil, orderings = nil) sql = "SELECT * FROM #{table_name} " add_conditions!(sql, conditions) sql << "ORDER BY #{orderings} " unless orderings.nil? - sql << "LIMIT 1" + + connection.add_limit!(sql, 1) record = connection.select_one(sql, "#{name} Load First") instantiate(record) unless record.nil? diff --git a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb index a2fb480b8c..1ca6d59977 100755 --- a/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb @@ -345,6 +345,10 @@ def quote_column_name(name) # Returns a string of the CREATE TABLE SQL statements for recreating the entire structure of the database. def structure_dump() end + def add_limit!(sql, limit) + sql << " LIMIT #{limit}" + end + protected def log(sql, name, connection, &action) begin diff --git a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb index 544a691848..5c48dc377d 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -30,7 +30,6 @@ module ActiveRecord class Base def self.sqlserver_connection(config) require_library_or_gem 'dbi' unless self.class.const_defined?(:DBI) - class_eval { include ActiveRecord::SQLServerBaseExtensions } symbolize_strings_in_hash(config) @@ -47,50 +46,6 @@ def self.sqlserver_connection(config) end end - module SQLServerBaseExtensions #:nodoc: - def self.append_features(base) - super - base.extend(ClassMethods) - end - - module ClassMethods #:nodoc: - def find_first(conditions = nil, orderings = nil) - sql = "SELECT TOP 1 * FROM #{table_name} " - add_conditions!(sql, conditions) - sql << "ORDER BY #{orderings} " unless orderings.nil? - - record = connection.select_one(sql, "#{name} Load First") - instantiate(record) unless record.nil? - end - - def find_all(conditions = nil, orderings = nil, limit = nil, joins = nil) - sql = "SELECT " - sql << "TOP #{limit} " unless limit.nil? - sql << " * FROM #{table_name} " - sql << "#{joins} " if joins - add_conditions!(sql, conditions) - sql << "ORDER BY #{orderings} " unless orderings.nil? - - find_by_sql(sql) - end - end - - def attributes_with_quotes - columns_hash = self.class.columns_hash - - attrs = @attributes.dup - - attrs = attrs.reject do |name, value| - columns_hash[name].identity - end - - attrs.inject({}) do |attrs_quoted, pair| - attrs_quoted[pair.first] = quote(pair.last, columns_hash[pair.first]) - attrs_quoted - end - end - end - module ConnectionAdapters class ColumnWithIdentity < Column# :nodoc: attr_reader :identity @@ -236,63 +191,67 @@ def create_database(name) execute "CREATE DATABASE #{name}" end + def add_limit!(sql, limit) + sql.gsub!(/SELECT/i, "SELECT TOP #{limit}") + end + private - def select(sql, name = nil) - rows = [] + def select(sql, name = nil) + rows = [] - log(sql, name, @connection) do |conn| - conn.select_all(sql) do |row| - record = {} + log(sql, name, @connection) do |conn| + conn.select_all(sql) do |row| + record = {} - row.column_names.each do |col| - record[col] = row[col] - end + row.column_names.each do |col| + record[col] = row[col] + end - rows << record + rows << record + end end + + rows end - rows - end + def enable_identity_insert(table_name, enable = true) + if has_identity_column(table_name) + "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}" + end + end - def enable_identity_insert(table_name, enable = true) - if has_identity_column(table_name) - "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}" + def get_table_name(sql) + if sql =~ /into\s*([^\s]+)\s*/i or + sql =~ /update\s*([^\s]+)\s*/i + $1 + else + nil + end end - end - def get_table_name(sql) - if sql =~ /into\s*([^\s]+)\s*/i or - sql =~ /update\s*([^\s]+)\s*/i - $1 - else - nil + def has_identity_column(table_name) + return get_identity_column(table_name) != nil end - end - def has_identity_column(table_name) - return get_identity_column(table_name) != nil - end + def get_identity_column(table_name) + if not @table_columns + @table_columns = {} + end - def get_identity_column(table_name) - if not @table_columns - @table_columns = {} - end + if @table_columns[table_name] == nil + @table_columns[table_name] = columns(table_name) + end - if @table_columns[table_name] == nil - @table_columns[table_name] = columns(table_name) - end + @table_columns[table_name].each do |col| + return col.name if col.identity + end - @table_columns[table_name].each do |col| - return col.name if col.identity + return nil end - return nil - end - - def query_contains_identity_column(sql, col) - return sql =~ /[\(\.\,]\s*#{col}/ - end + def query_contains_identity_column(sql, col) + return sql =~ /[\(\.\,]\s*#{col}/ + end end end end \ No newline at end of file -- GitLab