Skip to content

Commit

Permalink
Refactored cache and mssql adapters to share common code.
Browse files Browse the repository at this point in the history
 * Added test cases for mssql
 * Added tsql helper as a place to share common tsql adapter code


git-svn-id: svn+ssh://rubyforge.org/var/svn/jruby-extras/trunk/activerecord-jdbc@971 8ba958d5-0c1a-0410-94a6-a65dfc1b28a6
  • Loading branch information
kofno committed Apr 23, 2008
1 parent 417551e commit de6c0bf
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 77 deletions.
6 changes: 6 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,12 @@ Rake::TestTask.new(:test_cachedb) do | t |
t.libs << 'test'
end

# Ensure that the jTDS driver in on your classpath before launching rake
Rake::TestTask.new(:test_mssql) do | t |
t.test_files = FileList[ 'test/mssql_simple_test.rb' ]
t.libs << 'test'
end

MANIFEST = FileList["History.txt", "Manifest.txt", "README.txt",
"Rakefile", "LICENSE.txt", "lib/**/*.rb", "lib/jdbc_adapter/jdbc_adapter_internal.jar", "test/**/*.rb",
"lib/**/*.rake", "src/**/*.java"]
Expand Down
24 changes: 4 additions & 20 deletions lib/jdbc_adapter/jdbc_cachedb.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'jdbc_adapter/tsql_helper'

module ::JdbcSpec
module ActiveRecordExtensions
def cachedb_connection( config )
Expand All @@ -9,6 +11,7 @@ def cachedb_connection( config )
end

module CacheDB
include TSqlMethods

def self.column_selector
[ /cache/i, lambda { | cfg, col | col.extend( ::JdbcSpec::CacheDB::Column ) } ]
Expand All @@ -20,26 +23,7 @@ def self.adapter_selector

module Column
end

def modify_types(tp)
tp[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
tp
end

def type_to_sql(type, limit = nil, precision = nil, scale = nil)
return super unless type.to_s == 'integer'

if limit.nil? || limit == 4
'INT'
elsif limit == 2
'SMALLINT'
elsif limit == 1
'TINYINT'
else
'BIGINT'
end
end


def create_table(name, options = { })
super(name, options)
primary_key = options[:primary_key] || "id"
Expand Down
61 changes: 4 additions & 57 deletions lib/jdbc_adapter/jdbc_mssql.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'jdbc_adapter/tsql_helper'

module ::ActiveRecord
class Base
# After setting large objects to empty, write data back with a helper method
Expand All @@ -19,6 +21,8 @@ def write_lobs() #:nodoc:

module JdbcSpec
module MsSQL
include TSqlMethods

def self.column_selector
[/sqlserver|tds/i, lambda {|cfg,col| col.extend(::JdbcSpec::MsSQL::Column)}]
end
Expand Down Expand Up @@ -94,14 +98,6 @@ def self.string_to_binary(value)
end
end

def modify_types(tp)
tp[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
tp[:integer][:limit] = nil
tp[:boolean] = {:name => "bit"}
tp[:binary] = { :name => "image"}
tp
end

def quote(value, column = nil)
return value.quoted_id if value.respond_to?(:quoted_id)

Expand Down Expand Up @@ -132,41 +128,6 @@ def quote_column_name(name)
"[#{name}]"
end

def add_limit_offset!(sql, options)
if options[:limit] and options[:offset]
total_rows = select_all("SELECT count(*) as TotalRows from (#{sql.gsub(/\bSELECT(\s+DISTINCT)?\b/i, "SELECT\\1 TOP 1000000000")}) tally")[0]["TotalRows"].to_i
if (options[:limit] + options[:offset]) >= total_rows
options[:limit] = (total_rows - options[:offset] >= 0) ? (total_rows - options[:offset]) : 0
end
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i, "SELECT * FROM (SELECT TOP #{options[:limit]} * FROM (SELECT\\1 TOP #{options[:limit] + options[:offset]} ")
sql << ") AS tmp1"
if options[:order]
options[:order] = options[:order].split(',').map do |field|
parts = field.split(" ")
tc = parts[0]
if sql =~ /\.\[/ and tc =~ /\./ # if column quoting used in query
tc.gsub!(/\./, '\\.\\[')
tc << '\\]'
end
if sql =~ /#{tc} AS (t\d_r\d\d?)/
parts[0] = $1
elsif parts[0] =~ /\w+\.(\w+)/
parts[0] = $1
end
parts.join(' ')
end.join(', ')
sql << " ORDER BY #{change_order_direction(options[:order])}) AS tmp2 ORDER BY #{options[:order]}"
else
sql << " ) AS tmp2"
end
elsif sql !~ /^\s*SELECT (@@|COUNT\()/i
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i) do
"SELECT#{$1} TOP #{options[:limit]}"
end unless options[:limit].nil?
end
end


def change_order_direction(order)
order.split(",").collect {|fragment|
case fragment
Expand Down Expand Up @@ -208,20 +169,6 @@ def rename_column(table, column, new_column_name)
execute "EXEC sp_rename '#{table}.#{column}', '#{new_column_name}'"
end

def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
return super unless type.to_s == 'integer'

if limit.nil? || limit == 4
'int'
elsif limit == 2
'smallint'
elsif limit ==1
'tinyint'
else
'bigint'
end
end

def change_column(table_name, column_name, type, options = {}) #:nodoc:
sql_commands = ["ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"]
if options_include_default?(options)
Expand Down
59 changes: 59 additions & 0 deletions lib/jdbc_adapter/tsql_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Common methods for handling TSQL databases.
module TSqlMethods

def modify_types(tp) #:nodoc:
tp[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
tp[:integer][:limit] = nil
tp[:boolean] = {:name => "bit"}
tp[:binary] = { :name => "image"}
tp
end

def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
return super unless type.to_s == 'integer'

if limit.nil? || limit == 4
'int'
elsif limit == 2
'smallint'
elsif limit == 1
'tinyint'
else
'bigint'
end
end

def add_limit_offset!(sql, options)
if options[:limit] and options[:offset]
total_rows = select_all("SELECT count(*) as TotalRows from (#{sql.gsub(/\bSELECT(\s+DISTINCT)?\b/i, "SELECT\\1 TOP 1000000000")}) tally")[0]["TotalRows"].to_i
if (options[:limit] + options[:offset]) >= total_rows
options[:limit] = (total_rows - options[:offset] >= 0) ? (total_rows - options[:offset]) : 0
end
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i, "SELECT * FROM (SELECT TOP #{options[:limit]} * FROM (SELECT\\1 TOP #{options[:limit] + options[:offset]} ")
sql << ") AS tmp1"
if options[:order]
options[:order] = options[:order].split(',').map do |field|
parts = field.split(" ")
tc = parts[0]
if sql =~ /\.\[/ and tc =~ /\./ # if column quoting used in query
tc.gsub!(/\./, '\\.\\[')
tc << '\\]'
end
if sql =~ /#{tc} AS (t\d_r\d\d?)/
parts[0] = $1
elsif parts[0] =~ /\w+\.(\w+)/
parts[0] = $1
end
parts.join(' ')
end.join(', ')
sql << " ORDER BY #{change_order_direction(options[:order])}) AS tmp2 ORDER BY #{options[:order]}"
else
sql << " ) AS tmp2"
end
elsif sql !~ /^\s*SELECT (@@|COUNT\()/i
sql.sub!(/^\s*SELECT(\s+DISTINCT)?/i) do
"SELECT#{$1} TOP #{options[:limit]}"
end unless options[:limit].nil?
end
end
end
9 changes: 9 additions & 0 deletions test/db/mssql.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
config = {
:username => 'blog',
:password => '',
:adapter => 'jdbc',
:url => "jdbc:jtds:sqlserver://localhost:1433/weblog_development",
:driver => 'net.sourceforge.jtds.jdbc.Driver'
}

ActiveRecord::Base.establish_connection( config )
6 changes: 6 additions & 0 deletions test/mssql_simple_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
require 'jdbc_common'
require 'db/mssql'

class MsSQLSimpleTest < Test::Unit::TestCase
include SimpleTestMethods
end

0 comments on commit de6c0bf

Please sign in to comment.