do_sqlserver 0.10.1-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CONNECTING.markdown +41 -0
- data/ChangeLog.markdown +25 -0
- data/FAQS.markdown +8 -0
- data/INSTALL.markdown +76 -0
- data/LICENSE +21 -0
- data/README.markdown +110 -0
- data/Rakefile +56 -0
- data/lib/dbd_odbc_patch.rb +50 -0
- data/lib/do_sqlserver.rb +296 -0
- data/lib/do_sqlserver/do_sqlserver.jar +0 -0
- data/lib/do_sqlserver/transaction.rb +36 -0
- data/lib/do_sqlserver/version.rb +5 -0
- data/spec/command_spec.rb +9 -0
- data/spec/connection_spec.rb +21 -0
- data/spec/encoding_spec.rb +8 -0
- data/spec/reader_spec.rb +8 -0
- data/spec/result_spec.rb +16 -0
- data/spec/spec_helper.rb +147 -0
- data/spec/typecast/array_spec.rb +8 -0
- data/spec/typecast/bigdecimal_spec.rb +9 -0
- data/spec/typecast/boolean_spec.rb +9 -0
- data/spec/typecast/byte_array_spec.rb +31 -0
- data/spec/typecast/class_spec.rb +8 -0
- data/spec/typecast/date_spec.rb +11 -0
- data/spec/typecast/datetime_spec.rb +9 -0
- data/spec/typecast/float_spec.rb +9 -0
- data/spec/typecast/integer_spec.rb +8 -0
- data/spec/typecast/nil_spec.rb +10 -0
- data/spec/typecast/other_spec.rb +8 -0
- data/spec/typecast/range_spec.rb +8 -0
- data/spec/typecast/string_spec.rb +8 -0
- data/spec/typecast/time_spec.rb +8 -0
- data/tasks/compile.rake +29 -0
- data/tasks/release.rake +14 -0
- data/tasks/spec.rake +23 -0
- metadata +161 -0
Binary file
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module DataObjects
|
2
|
+
|
3
|
+
module SqlServer
|
4
|
+
|
5
|
+
class Transaction < DataObjects::Transaction
|
6
|
+
|
7
|
+
def begin
|
8
|
+
connection.instance_variable_get("@connection").autocommit = false
|
9
|
+
end
|
10
|
+
|
11
|
+
def commit
|
12
|
+
connection.instance_variable_get("@connection").commit
|
13
|
+
ensure
|
14
|
+
connection.instance_variable_get("@connection").autocommit = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def rollback
|
18
|
+
connection.instance_variable_get("@connection").rollback
|
19
|
+
ensure
|
20
|
+
connection.instance_variable_get("@connection").autocommit = true
|
21
|
+
end
|
22
|
+
|
23
|
+
def rollback_prepared
|
24
|
+
# TODO: what should be done differently?
|
25
|
+
rollback
|
26
|
+
end
|
27
|
+
|
28
|
+
def prepare
|
29
|
+
# TODO: what should be done here?
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
4
|
+
require 'data_objects/spec/connection_spec'
|
5
|
+
|
6
|
+
describe DataObjects::SqlServer::Connection do
|
7
|
+
|
8
|
+
before do
|
9
|
+
@driver = CONFIG.scheme
|
10
|
+
@user = CONFIG.user
|
11
|
+
@password = CONFIG.pass
|
12
|
+
@host = CONFIG.host
|
13
|
+
@port = CONFIG.port
|
14
|
+
@database = CONFIG.database
|
15
|
+
end
|
16
|
+
|
17
|
+
behaves_like 'a Connection'
|
18
|
+
#behaves_like 'a Connection with authentication support'
|
19
|
+
# FIXME: behaves_like 'a Connection with JDBC URL support' if JRUBY
|
20
|
+
behaves_like 'a Connection via JDNI' if JRUBY
|
21
|
+
end
|
data/spec/reader_spec.rb
ADDED
data/spec/result_spec.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
4
|
+
require 'data_objects/spec/result_spec'
|
5
|
+
|
6
|
+
# splitting the descibe into two separate declaration avoids
|
7
|
+
# concurrent execution of the "behaves_like ....."
|
8
|
+
# needed by some databases (sqlite3)
|
9
|
+
|
10
|
+
describe DataObjects::SqlServer::Result do
|
11
|
+
behaves_like 'a Result'
|
12
|
+
end
|
13
|
+
|
14
|
+
describe DataObjects::SqlServer::Result do
|
15
|
+
behaves_like 'a Result which returns inserted keys'
|
16
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
$TESTING=true
|
2
|
+
JRUBY = RUBY_PLATFORM =~ /java/
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'date'
|
6
|
+
require 'ostruct'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
driver_lib = File.expand_path('../../lib', __FILE__)
|
10
|
+
$LOAD_PATH.unshift(driver_lib) unless $LOAD_PATH.include?(driver_lib)
|
11
|
+
|
12
|
+
# Prepend data_objects/do_jdbc in the repository to the load path.
|
13
|
+
# DO NOT USE installed gems, except when running the specs from gem.
|
14
|
+
repo_root = File.expand_path('../../..', __FILE__)
|
15
|
+
(['data_objects'] << ('do_jdbc' if JRUBY)).compact.each do |lib|
|
16
|
+
lib_path = "#{repo_root}/#{lib}/lib"
|
17
|
+
$LOAD_PATH.unshift(lib_path) if File.directory?(lib_path) && !$LOAD_PATH.include?(lib_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'data_objects'
|
21
|
+
require 'data_objects/spec/bacon'
|
22
|
+
require 'do_sqlserver'
|
23
|
+
|
24
|
+
DataObjects::SqlServer.logger = DataObjects::Logger.new(STDOUT, :off)
|
25
|
+
at_exit { DataObjects.logger.flush }
|
26
|
+
|
27
|
+
CONFIG = OpenStruct.new
|
28
|
+
CONFIG.scheme = 'sqlserver'
|
29
|
+
CONFIG.user = ENV['DO_SQLSERVER_USER'] || 'do_test'
|
30
|
+
CONFIG.pass = ENV['DO_SQLSERVER_PASS'] || 'do_test'
|
31
|
+
CONFIG.host = ENV['DO_SQLSERVER_HOST'] || 'localhost'
|
32
|
+
CONFIG.port = ENV['DO_SQLSERVER_PORT'] || '1433'
|
33
|
+
CONFIG.instance = ENV['DO_SQLSERVER_INSTANCE'] || 'SQLEXPRESS'
|
34
|
+
CONFIG.database = ENV['DO_SQLSERVER_DATABASE'] || "/do_test;instance=#{CONFIG.instance};"
|
35
|
+
|
36
|
+
CONFIG.uri = ENV["DO_SQLSERVER_SPEC_URI"] ||"#{CONFIG.scheme}://#{CONFIG.user}:#{CONFIG.pass}@#{CONFIG.host}:#{CONFIG.port}#{CONFIG.database}"
|
37
|
+
CONFIG.sleep = "WAITFOR DELAY '00:00:01'"
|
38
|
+
|
39
|
+
module DataObjectsSpecHelpers
|
40
|
+
|
41
|
+
def setup_test_environment
|
42
|
+
conn = DataObjects::Connection.new(CONFIG.uri)
|
43
|
+
|
44
|
+
conn.create_command(<<-EOF).execute_non_query
|
45
|
+
IF OBJECT_ID('invoices') IS NOT NULL DROP TABLE invoices
|
46
|
+
EOF
|
47
|
+
|
48
|
+
conn.create_command(<<-EOF).execute_non_query
|
49
|
+
IF OBJECT_ID('users') IS NOT NULL DROP TABLE users
|
50
|
+
EOF
|
51
|
+
|
52
|
+
conn.create_command(<<-EOF).execute_non_query
|
53
|
+
IF OBJECT_ID('widgets') IS NOT NULL DROP TABLE widgets
|
54
|
+
EOF
|
55
|
+
|
56
|
+
conn.create_command(<<-EOF).execute_non_query
|
57
|
+
CREATE TABLE "users" (
|
58
|
+
"id" int NOT NULL IDENTITY,
|
59
|
+
"name" nvarchar(200) default 'Billy' NULL,
|
60
|
+
"fired_at" timestamp,
|
61
|
+
PRIMARY KEY ("id")
|
62
|
+
);
|
63
|
+
EOF
|
64
|
+
|
65
|
+
conn.create_command(<<-EOF).execute_non_query
|
66
|
+
CREATE TABLE "invoices" (
|
67
|
+
"id" int NOT NULL IDENTITY,
|
68
|
+
"invoice_number" varchar(50) NOT NULL,
|
69
|
+
PRIMARY KEY ("id")
|
70
|
+
);
|
71
|
+
EOF
|
72
|
+
|
73
|
+
conn.create_command(<<-EOF).execute_non_query
|
74
|
+
CREATE TABLE "widgets" (
|
75
|
+
"id" int NOT NULL IDENTITY,
|
76
|
+
"code" char(8) default 'A14' NULL,
|
77
|
+
"name" varchar(200) default 'Super Widget' NULL,
|
78
|
+
"shelf_location" nvarchar(max) NULL,
|
79
|
+
"description" nvarchar(max) NULL,
|
80
|
+
"image_data" image NULL,
|
81
|
+
"ad_description" varchar(8000) NULL,
|
82
|
+
"ad_image" image NULL,
|
83
|
+
"whitepaper_text" nvarchar(max) NULL,
|
84
|
+
"cad_drawing" image NULL,
|
85
|
+
"flags" bit default 0,
|
86
|
+
"number_in_stock" smallint default 500,
|
87
|
+
"number_sold" int default 0,
|
88
|
+
"super_number" bigint default 9223372036854775807,
|
89
|
+
"weight" float default 1.23,
|
90
|
+
"cost1" real default 10.23,
|
91
|
+
"cost2" decimal(8,2) default 50.23,
|
92
|
+
"release_date" smalldatetime default '2008-02-14', -- date type is SQL Server 2008 only
|
93
|
+
"release_datetime" datetime default '2008-02-14 00:31:12',
|
94
|
+
"release_timestamp" smalldatetime /* default '2008-02-14 00:31:31' */,
|
95
|
+
-- "status" enum('active','out of stock') NOT NULL default 'active',
|
96
|
+
PRIMARY KEY ("id")
|
97
|
+
);
|
98
|
+
EOF
|
99
|
+
|
100
|
+
1.upto(16) do |n|
|
101
|
+
conn.create_command(<<-EOF).execute_non_query(::Extlib::ByteArray.new("CAD \001 \000 DRAWING"))
|
102
|
+
insert into widgets(code, name, shelf_location, description, image_data, ad_description, ad_image, whitepaper_text, cad_drawing, super_number, weight)
|
103
|
+
VALUES ('W#{n.to_s.rjust(7,"0")}', 'Widget #{n}', 'A14', 'This is a description', 'IMAGE DATA', 'Buy this product now!', 'AD IMAGE DATA', 'String', ?, 1234, 13.4);
|
104
|
+
EOF
|
105
|
+
end
|
106
|
+
|
107
|
+
conn.create_command(<<-EOF).execute_non_query
|
108
|
+
update widgets set flags = 1 where id = 2
|
109
|
+
EOF
|
110
|
+
|
111
|
+
conn.create_command(<<-EOF).execute_non_query
|
112
|
+
update widgets set ad_description = NULL where id = 3
|
113
|
+
EOF
|
114
|
+
|
115
|
+
conn.create_command(<<-EOF).execute_non_query
|
116
|
+
update widgets set flags = NULL where id = 4
|
117
|
+
EOF
|
118
|
+
|
119
|
+
conn.create_command(<<-EOF).execute_non_query
|
120
|
+
update widgets set cost1 = NULL where id = 5
|
121
|
+
EOF
|
122
|
+
|
123
|
+
conn.create_command(<<-EOF).execute_non_query
|
124
|
+
update widgets set cost2 = NULL where id = 6
|
125
|
+
EOF
|
126
|
+
|
127
|
+
conn.create_command(<<-EOF).execute_non_query
|
128
|
+
update widgets set release_date = NULL where id = 7
|
129
|
+
EOF
|
130
|
+
|
131
|
+
conn.create_command(<<-EOF).execute_non_query
|
132
|
+
update widgets set release_datetime = NULL where id = 8
|
133
|
+
EOF
|
134
|
+
|
135
|
+
# (cannot update a Timestamp column w/MSSQL)
|
136
|
+
# so we use a smalldatetime
|
137
|
+
conn.create_command(<<-EOF).execute_non_query
|
138
|
+
update widgets set release_timestamp = NULL where id = 9
|
139
|
+
EOF
|
140
|
+
|
141
|
+
conn.close
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
include DataObjectsSpecHelpers
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/bigdecimal_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with BigDecimal' do
|
7
|
+
behaves_like 'supporting BigDecimal'
|
8
|
+
behaves_like 'supporting BigDecimal autocasting'
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/boolean_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with Boolean' do
|
7
|
+
behaves_like 'supporting Boolean'
|
8
|
+
behaves_like 'supporting Boolean autocasting'
|
9
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/byte_array_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with ByteArray' do
|
7
|
+
# behaves_like 'supporting ByteArray'
|
8
|
+
#
|
9
|
+
# ByteArray is not yet supported on JRuby:
|
10
|
+
#
|
11
|
+
# Like Postgres, SQL Server doesn't typecast bytea type to integer, decimal,
|
12
|
+
# etc. In other words,
|
13
|
+
# @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(::Extlib::ByteArray.new("2"))
|
14
|
+
# results in the equivalent to the following query being executed:
|
15
|
+
# SELECT id FROM widgets WHERE id = 0x32
|
16
|
+
# BUT 0x32 as a parameter = (decimal) 50
|
17
|
+
# NOT the ASCII char for '2'.
|
18
|
+
#
|
19
|
+
# Other drivers (Postgres) override #setPreparedStatementParam in their
|
20
|
+
# DriverDefinition implementations and use ps.getParameterMetadata() to let
|
21
|
+
# the JDBC driver handle the casting.
|
22
|
+
#
|
23
|
+
# Unfortunately, we can't rely on ps.getParameterMetadata() because of the
|
24
|
+
# following bug in jTDS:
|
25
|
+
# https://sourceforge.net/tracker/?func=detail&aid=2220192&group_id=33291&atid=407762
|
26
|
+
# getParameterClassName(idx) => java.lang.Object
|
27
|
+
# getParameterTypeName(idx) => null
|
28
|
+
# getParameterType(idx) => 0 (NULL)
|
29
|
+
#
|
30
|
+
# Without this information we don't know what we should be casting to!
|
31
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/date_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with Date' do
|
7
|
+
behaves_like 'supporting Date'
|
8
|
+
|
9
|
+
# SqlServer will cast DATE type to Time
|
10
|
+
# behaves_like 'supporting Date autocasting'
|
11
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/datetime_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with DateTime' do
|
7
|
+
behaves_like 'supporting DateTime'
|
8
|
+
# behaves_like 'supporting DateTime autocasting'
|
9
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/float_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with Float' do
|
7
|
+
behaves_like 'supporting Float'
|
8
|
+
# behaves_like 'supporting Float autocasting'
|
9
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/nil_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::SqlServer with Nil' do
|
7
|
+
behaves_like 'supporting Nil'
|
8
|
+
behaves_like 'supporting writing an Nil'
|
9
|
+
behaves_like 'supporting Nil autocasting'
|
10
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
4
|
+
require 'data_objects/spec/typecast/other_spec'
|
5
|
+
|
6
|
+
describe 'DataObjects::H2 with other (unknown) type' do
|
7
|
+
behaves_like 'supporting other (unknown) type'
|
8
|
+
end
|
data/tasks/compile.rake
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
begin
|
2
|
+
gem 'rake-compiler', '~>0.7'
|
3
|
+
require 'rake/javaextensiontask'
|
4
|
+
|
5
|
+
# Hack to avoid "allocator undefined for Proc" issue when unpacking Gems:
|
6
|
+
# gemspec provided by Jeweler uses Rake::FileList for files, test_files and
|
7
|
+
# extra_rdoc_files, and procs cannot be marshalled.
|
8
|
+
def gemspec
|
9
|
+
@clean_gemspec ||= eval("#{Rake.application.jeweler.gemspec.to_ruby}") # $SAFE = 3\n
|
10
|
+
end
|
11
|
+
|
12
|
+
Rake::JavaExtensionTask.new('do_sqlserver', gemspec) do |ext|
|
13
|
+
ext.ext_dir = 'ext-java/src/main/java'
|
14
|
+
ext.lib_dir = 'lib/do_sqlserver'
|
15
|
+
ext.debug = ENV.has_key?('DO_JAVA_DEBUG') && ENV['DO_JAVA_DEBUG']
|
16
|
+
ext.classpath = '../do_jdbc/lib/do_jdbc_internal.jar'
|
17
|
+
end
|
18
|
+
|
19
|
+
# do_sqlserver is only available for JRuby: the normal behaviour of
|
20
|
+
# rake-compiler is to only chain 'compile:PLATFORM' tasks to 'compile' where
|
21
|
+
# PLATFORM is the platform of the current interpreter (i.e. 'compile:java'
|
22
|
+
# to 'compile' only if running on JRuby). However, we always want to compile
|
23
|
+
# for Java, even if running from MRI.
|
24
|
+
task 'compile:do_sqlserver' => ['compile:do_sqlserver:java']
|
25
|
+
task 'compile' => ['compile:java']
|
26
|
+
|
27
|
+
rescue LoadError
|
28
|
+
warn "To compile, install rake-compiler (gem install rake-compiler)"
|
29
|
+
end
|