From a6fefad354d36f3e9a91f8582659ffcda1a35855 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sat, 1 Jan 2005 18:55:04 +0000 Subject: Added the final touches to the Microsoft SQL Server adapter by DeLynn Berry that makes it suitable for actual use #394 [DeLynn Barry] git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@302 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../connection_adapters/sqlserver_adapter.rb | 49 ++++++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'activerecord/lib/active_record/connection_adapters') diff --git a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb index 5c48dc377d..d01085c395 100644 --- a/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/sqlserver_adapter.rb @@ -33,13 +33,17 @@ module ActiveRecord symbolize_strings_in_hash(config) - if config.has_key? :dsn - dsn = config[:dsn] + host = config[:host] + username = config[:username] ? config[:username].to_s : 'sa' + password = config[:password].to_s + + if config.has_key? :database + database = config[:database] else - raise ArgumentError, "No DSN specified" + raise ArgumentError, "No database specified. Missing argument: database." end - conn = DBI.connect(dsn) + conn = DBI.connect("DBI:ADO:Provider=SQLOLEDB;Data Source=#{host};Initial Catalog=#{database};User Id=#{username};Password=#{password};") conn["AutoCommit"] = true ConnectionAdapters::SQLServerAdapter.new(conn, logger) @@ -59,7 +63,7 @@ module ActiveRecord class SQLServerAdapter < AbstractAdapter # :nodoc: def quote_column_name(name) - " [#{name}] " + "[#{name}]" end def select_all(sql, name = nil) @@ -82,7 +86,6 @@ JOIN sysobjects AS s ON (c.id = s.id) LEFT OUTER JOIN syscomments AS com ON (c.cdefault = com.id) WHERE s.name = '#{table_name}' EOL - columns = [] log(sql, name, @connection) do |conn| @@ -151,8 +154,12 @@ EOL end end - alias_method :update, :execute - alias_method :delete, :execute + def update(sql, name = nil) + execute(sql, name) + affected_rows(name) + end + + alias_method :delete, :update def begin_db_transaction begin @@ -192,7 +199,13 @@ EOL end def add_limit!(sql, limit) - sql.gsub!(/SELECT/i, "SELECT TOP #{limit}") + limit_amount = limit.to_s.include?("OFFSET") ? get_offset_amount(limit) : Array.new([limit]) + order_by = sql.include?("ORDER BY") ? get_order_by(sql.sub(/.*ORDER\sBY./, "")) : nil + if limit_amount.size == 2 + sql.gsub!(/SELECT/i, "SELECT * FROM ( SELECT TOP #{limit_amount[0]} * FROM ( SELECT TOP #{limit_amount[1]}")<<" ) AS tmp1 ORDER BY #{order_by[1]} ) AS tmp2 ORDER BY #{order_by[0]}" + else + sql.gsub!(/SELECT/i, "SELECT TOP #{limit_amount[0]}") + end end private @@ -252,6 +265,24 @@ EOL def query_contains_identity_column(sql, col) return sql =~ /[\(\.\,]\s*#{col}/ end + + def get_order_by(sql) + return sql, sql.gsub(/\s*DESC\s*/, "").gsub(/\s*ASC\s*/, " DESC") + end + + def get_offset_amount(limit) + limit = limit.gsub!(/.OFFSET./i, ",").split(',') + return limit[0].to_i, limit[0].to_i+limit[1].to_i + end + + def affected_rows(name = nil) + sql = "SELECT @@ROWCOUNT AS AffectedRows" + log(sql, name, @connection) do |conn| + conn.select_all(sql) do |row| + return row[:AffectedRows].to_i + end + end + end end end end \ No newline at end of file -- cgit v1.2.3