activerecord-jdbcteradata-adapter 0.4.2 → 0.5.0
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/Gemfile.lock +4 -4
- data/activerecord-jdbcteradata-adapter.gemspec +3 -2
- data/lib/arel/visitors/teradata.rb +17 -18
- data/lib/arjdbc/teradata/adapter.rb +63 -13
- data/lib/arjdbc/teradata/connection_methods.rb +37 -11
- data/lib/arjdbc/teradata/explain_support.rb +15 -0
- data/lib/arjdbc/teradata/teradata_java.jar +0 -0
- data/spec/adapter_spec.rb +37 -0
- data/spec/associations_spec.rb +9 -8
- data/spec/commons-dbcp-1.4.jar +0 -0
- data/spec/commons-pool-1.6.jar +0 -0
- data/spec/connection_spec.rb +40 -0
- data/spec/fixtures/wikimedia-commons-poty-2006.jpg +0 -0
- data/spec/models/model_with_blob.rb +17 -0
- data/spec/spec_helper.rb +9 -1
- metadata +15 -6
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
activerecord-jdbcteradata-adapter (0.4.
|
5
|
-
activerecord
|
4
|
+
activerecord-jdbcteradata-adapter (0.4.2)
|
5
|
+
activerecord (<= 3.2.13)
|
6
6
|
activerecord-jdbc-adapter
|
7
7
|
jdbc-teradata
|
8
8
|
|
@@ -17,7 +17,7 @@ GEM
|
|
17
17
|
activesupport (= 3.2.13)
|
18
18
|
arel (~> 3.0.2)
|
19
19
|
tzinfo (~> 0.3.29)
|
20
|
-
activerecord-jdbc-adapter (1.2.9)
|
20
|
+
activerecord-jdbc-adapter (1.2.9.1)
|
21
21
|
activesupport (3.2.13)
|
22
22
|
i18n (= 0.6.1)
|
23
23
|
multi_json (~> 1.0)
|
@@ -26,7 +26,7 @@ GEM
|
|
26
26
|
diff-lcs (1.2.4)
|
27
27
|
i18n (0.6.1)
|
28
28
|
jdbc-teradata (0.3.0)
|
29
|
-
multi_json (1.7.
|
29
|
+
multi_json (1.7.7)
|
30
30
|
rake (10.0.4)
|
31
31
|
rspec (2.13.0)
|
32
32
|
rspec-core (~> 2.13.0)
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'activerecord-jdbcteradata-adapter'
|
3
|
-
s.version = '0.
|
3
|
+
s.version = '0.5.0'
|
4
4
|
s.authors = ['Chris Parker']
|
5
5
|
s.email = %w(mrcsparker@gmail.com)
|
6
6
|
s.homepage = 'https://github.com/mrcsparker/activerecord-jdbcteradata-adapter'
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
lib/arjdbc/teradata/adapter.rb
|
25
25
|
lib/arjdbc/teradata/connection_methods.rb
|
26
26
|
lib/arjdbc/teradata/teradata_java.jar
|
27
|
+
lib/arjdbc/teradata/explain_support.rb
|
27
28
|
lib/arjdbc/teradata.rb
|
28
29
|
]
|
29
30
|
|
@@ -34,6 +35,6 @@ Gem::Specification.new do |s|
|
|
34
35
|
s.add_development_dependency 'rake'
|
35
36
|
s.add_development_dependency 'rspec'
|
36
37
|
s.add_dependency 'activerecord-jdbc-adapter'
|
37
|
-
s.add_dependency 'activerecord'
|
38
|
+
s.add_dependency 'activerecord', '<= 3.2.13'
|
38
39
|
s.add_dependency 'jdbc-teradata'
|
39
40
|
end
|
@@ -23,9 +23,9 @@ module Arel
|
|
23
23
|
end
|
24
24
|
|
25
25
|
class SelectManager < Arel::TreeManager
|
26
|
-
|
26
|
+
|
27
27
|
AR_CA_SQLSA_NAME = 'Teradata'.freeze
|
28
|
-
|
28
|
+
|
29
29
|
# Getting real Ordering objects is very important for us. We need to be able to call #uniq on
|
30
30
|
# a colleciton of them reliably as well as using their true object attributes to mutate them
|
31
31
|
# to grouping objects for the inner sql during a select statment with an offset/rownumber. So this
|
@@ -76,13 +76,13 @@ module Arel
|
|
76
76
|
lock_without_teradata(locking)
|
77
77
|
end
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
private
|
81
|
-
|
81
|
+
|
82
82
|
def engine_activerecord_teradata_adapter?
|
83
83
|
@engine.connection && @engine.connection.adapter_name == AR_CA_SQLSA_NAME
|
84
84
|
end
|
85
|
-
|
85
|
+
|
86
86
|
end
|
87
87
|
|
88
88
|
module Visitors
|
@@ -101,7 +101,7 @@ module Arel
|
|
101
101
|
visit_Arel_Nodes_SelectStatementWithOutOffset(o)
|
102
102
|
end
|
103
103
|
end
|
104
|
-
|
104
|
+
|
105
105
|
def visit_Arel_Nodes_UpdateStatement(o)
|
106
106
|
if o.orders.any? && o.limit.nil?
|
107
107
|
o.limit = Nodes::Limit.new(214748364)
|
@@ -120,7 +120,7 @@ module Arel
|
|
120
120
|
def visit_Arel_Nodes_Lock(o)
|
121
121
|
visit o.expr
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
def visit_Arel_Nodes_Ordering(o)
|
125
125
|
if o.respond_to?(:direction)
|
126
126
|
"#{visit o.expr} #{o.ascending? ? 'ASC' : 'DESC'}"
|
@@ -128,7 +128,7 @@ module Arel
|
|
128
128
|
visit o.expr
|
129
129
|
end
|
130
130
|
end
|
131
|
-
|
131
|
+
|
132
132
|
def visit_Arel_Nodes_Bin(o)
|
133
133
|
"#{visit o.expr} #{@connection.cs_equality_operator}"
|
134
134
|
end
|
@@ -203,7 +203,6 @@ module Arel
|
|
203
203
|
].compact.join ' '
|
204
204
|
end
|
205
205
|
|
206
|
-
|
207
206
|
# Teradata Helpers
|
208
207
|
|
209
208
|
def source_with_lock_for_select_statement(o)
|
@@ -248,18 +247,18 @@ module Arel
|
|
248
247
|
((p1.respond_to?(:distinct) && p1.distinct) ||
|
249
248
|
p1.respond_to?(:include?) && p1.include?('DISTINCT'))
|
250
249
|
end
|
251
|
-
|
250
|
+
|
252
251
|
def windowed_single_distinct_select_statement?(o)
|
253
252
|
o.limit && o.offset && single_distinct_select_statement?(o)
|
254
253
|
end
|
255
|
-
|
254
|
+
|
256
255
|
def single_distinct_select_everything_statement?(o)
|
257
256
|
single_distinct_select_statement?(o) && visit(o.cores.first.projections.first).ends_with?('.*')
|
258
257
|
end
|
259
|
-
|
258
|
+
|
260
259
|
def top_one_everything_for_through_join?(o)
|
261
|
-
single_distinct_select_everything_statement?(o) &&
|
262
|
-
(o.limit && !o.offset) &&
|
260
|
+
single_distinct_select_everything_statement?(o) &&
|
261
|
+
(o.limit && !o.offset) &&
|
263
262
|
join_in_select_statement?(o)
|
264
263
|
end
|
265
264
|
|
@@ -277,9 +276,9 @@ module Arel
|
|
277
276
|
|
278
277
|
def eager_limiting_select_statement?(o)
|
279
278
|
core = o.cores.first
|
280
|
-
single_distinct_select_statement?(o) &&
|
281
|
-
(o.limit && !o.offset) &&
|
282
|
-
core.groups.empty? &&
|
279
|
+
single_distinct_select_statement?(o) &&
|
280
|
+
(o.limit && !o.offset) &&
|
281
|
+
core.groups.empty? &&
|
283
282
|
!single_distinct_select_everything_statement?(o)
|
284
283
|
end
|
285
284
|
|
@@ -295,7 +294,7 @@ module Arel
|
|
295
294
|
o.limit &&
|
296
295
|
!join_in_select_statement?(o)
|
297
296
|
end
|
298
|
-
|
297
|
+
|
299
298
|
def select_primary_key_sql?(o)
|
300
299
|
core = o.cores.first
|
301
300
|
return false if core.projections.size != 1
|
@@ -1,8 +1,32 @@
|
|
1
1
|
require 'arjdbc/mssql/limit_helpers'
|
2
|
+
require 'arjdbc/teradata/explain_support'
|
2
3
|
|
3
4
|
module ::ArJdbc
|
4
5
|
module Teradata
|
5
6
|
|
7
|
+
require 'arjdbc/jdbc/serialized_attributes_helper'
|
8
|
+
ActiveRecord::Base.class_eval do
|
9
|
+
def after_save_with_teradata_lob
|
10
|
+
lob_columns = self.class.columns.select { |c| c.sql_type =~ /blob|clob/i }
|
11
|
+
lob_columns.each do |column|
|
12
|
+
value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
|
13
|
+
next if value.nil? # already set NULL
|
14
|
+
self.class.connection.write_large_object(
|
15
|
+
column.type == :binary, column.name,
|
16
|
+
self.class.table_name,
|
17
|
+
self.class.primary_key,
|
18
|
+
self.class.connection.quote(id), value
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
#Used to add after_save lob saving method to ActiveRecord when
|
25
|
+
#this adapter is used.
|
26
|
+
def self.included(base)
|
27
|
+
ActiveRecord::Base.after_save :after_save_with_teradata_lob
|
28
|
+
end
|
29
|
+
|
6
30
|
def self.column_selector
|
7
31
|
[ /teradata/i, lambda { |cfg, column| column.extend(::ArJdbc::Teradata::Column) } ]
|
8
32
|
end
|
@@ -70,6 +94,7 @@ module ::ArJdbc
|
|
70
94
|
:time => { :name => 'TIMESTAMP'},
|
71
95
|
:date => { :name => 'DATE'},
|
72
96
|
:binary => { :name => 'BLOB'},
|
97
|
+
:text => { :name => 'CLOB'},
|
73
98
|
:boolean => { :name => 'BYTEINT'},
|
74
99
|
:raw => { :name => 'BYTE'}
|
75
100
|
}
|
@@ -89,8 +114,6 @@ module ::ArJdbc
|
|
89
114
|
|
90
115
|
#- disconnect!
|
91
116
|
|
92
|
-
#- jdbc_columns
|
93
|
-
|
94
117
|
#- exec_query
|
95
118
|
|
96
119
|
#- exec_insert
|
@@ -136,9 +159,9 @@ module ::ArJdbc
|
|
136
159
|
|
137
160
|
#- select
|
138
161
|
def select(sql, *rest)
|
139
|
-
|
140
|
-
|
141
|
-
|
162
|
+
# TJC - Teradata does not like "= NULL", "!= NULL", or "<> NULL".
|
163
|
+
# TJC - Also does not like != so transforming that to <>
|
164
|
+
execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL").gsub("!=","<>"), *rest)
|
142
165
|
end
|
143
166
|
|
144
167
|
#- select_rows
|
@@ -175,7 +198,7 @@ module ::ArJdbc
|
|
175
198
|
|
176
199
|
schema = database_name unless schema
|
177
200
|
|
178
|
-
output = execute("SELECT count(*) as table_count FROM dbc.tables WHERE TableName = '#{table}' AND DatabaseName = '#{schema}'")
|
201
|
+
output = execute("SELECT count(*) as table_count FROM dbc.tables WHERE TableName (NOT CS) = '#{table}' (NOT CS) AND DatabaseName (NOT CS) = '#{schema}' (NOT CS) ")
|
179
202
|
output.first['table_count'].to_i > 0
|
180
203
|
end
|
181
204
|
|
@@ -189,10 +212,10 @@ module ::ArJdbc
|
|
189
212
|
|
190
213
|
schema = database_name unless schema
|
191
214
|
|
192
|
-
result = select_rows(
|
193
|
-
|
194
|
-
|
195
|
-
"
|
215
|
+
result = select_rows("SELECT DatabaseName, TableName, ColumnName, IndexType, IndexName, UniqueFlag" <<
|
216
|
+
" FROM DBC.Indices" <<
|
217
|
+
" WHERE TableName (NOT CS) = '#{table}' (NOT CS)" <<
|
218
|
+
" AND DatabaseName (NOT CS) = '#{schema}' (NOT CS)")
|
196
219
|
|
197
220
|
result.map do |row|
|
198
221
|
idx_table_name = row[1].to_s.strip
|
@@ -224,6 +247,15 @@ module ::ArJdbc
|
|
224
247
|
#- primary_key
|
225
248
|
|
226
249
|
#- primary_keys
|
250
|
+
def primary_keys(table)
|
251
|
+
if self.class.lowercase_schema_reflection
|
252
|
+
@connection.primary_keys(table).map do |key|
|
253
|
+
key.downcase
|
254
|
+
end
|
255
|
+
else
|
256
|
+
@connection.primary_keys(table)
|
257
|
+
end
|
258
|
+
end
|
227
259
|
|
228
260
|
#- to_sql
|
229
261
|
|
@@ -238,9 +270,7 @@ module ::ArJdbc
|
|
238
270
|
return false unless table_name
|
239
271
|
schema, table = extract_schema_and_table(table_name.to_s)
|
240
272
|
return false unless table
|
241
|
-
|
242
273
|
schema = database_name unless schema
|
243
|
-
|
244
274
|
@connection.columns_internal(table, nil, schema)
|
245
275
|
end
|
246
276
|
|
@@ -319,6 +349,7 @@ module ::ArJdbc
|
|
319
349
|
case field_type
|
320
350
|
when /^timestamp with(?:out)? time zone$/ then :datetime
|
321
351
|
when /byteint/i then :boolean
|
352
|
+
when /blob/i then :binary
|
322
353
|
else
|
323
354
|
super
|
324
355
|
end
|
@@ -335,7 +366,17 @@ module ::ArJdbc
|
|
335
366
|
return value.quoted_id if value.respond_to?(:quoted_id)
|
336
367
|
case value
|
337
368
|
when String
|
338
|
-
|
369
|
+
if String === value && column && (column.type == :binary || column.type == :text)
|
370
|
+
'NULL'
|
371
|
+
else
|
372
|
+
%Q{'#{quote_string(value)}'}
|
373
|
+
end
|
374
|
+
when Fixnum
|
375
|
+
if Fixnum === value && column and column.type == :string
|
376
|
+
%Q{'#{quote_string(value.to_s)}'}
|
377
|
+
else
|
378
|
+
super
|
379
|
+
end
|
339
380
|
when TrueClass
|
340
381
|
'1'
|
341
382
|
when FalseClass
|
@@ -417,6 +458,15 @@ module ActiveRecord
|
|
417
458
|
def jdbc_column_class
|
418
459
|
TeradataColumn
|
419
460
|
end
|
461
|
+
|
462
|
+
#- jdbc_columns
|
463
|
+
def jdbc_columns(table_name, name = nil)
|
464
|
+
return false unless table_name
|
465
|
+
schema, table = extract_schema_and_table(table_name.to_s)
|
466
|
+
return false unless table
|
467
|
+
schema = database_name unless schema
|
468
|
+
@connection.columns(table, nil, schema)
|
469
|
+
end
|
420
470
|
alias_chained_method :columns, :query_cache, :jdbc_columns
|
421
471
|
|
422
472
|
# some QUOTING caching :
|
@@ -7,18 +7,44 @@ class ActiveRecord::Base
|
|
7
7
|
rescue LoadError # assuming driver.jar is on the class-path
|
8
8
|
end
|
9
9
|
|
10
|
-
config[:
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
10
|
+
if config[:jndi]
|
11
|
+
jndi = config[:jndi].to_s
|
12
|
+
ctx = javax.naming.InitialContext.new
|
13
|
+
ds = nil
|
14
|
+
|
15
|
+
# Taken from oracle-enhanced (https://github.com/rsim/oracle-enhanced)
|
16
|
+
# tomcat needs first lookup method, oc4j (and maybe other application servers) need second method
|
17
|
+
begin
|
18
|
+
env = ctx.lookup('java:/comp/env')
|
19
|
+
ds = env.lookup(jndi)
|
20
|
+
rescue
|
21
|
+
ds = ctx.lookup(jndi)
|
22
|
+
end
|
23
|
+
|
24
|
+
# For ARJDBC we only need the URL, username, and password
|
25
|
+
# We set the database config entry because it's used by the adapter to determine database_name
|
26
|
+
config[:url] = ds.getUrl
|
27
|
+
config[:username] ||= ds.getUsername
|
28
|
+
config[:database] ||= config[:url][/DATABASE=(.*?),/m, 1] unless config[:url].nil?
|
29
|
+
config[:password] ||= ds.getPassword
|
30
|
+
|
31
|
+
else
|
32
|
+
config[:username] ||= Java::JavaLang::System.get_property('user.name')
|
33
|
+
config[:host] ||= 'localhost'
|
34
|
+
config[:port] ||= 1025
|
35
|
+
config[:tmode] ||= 'ANSI' # ANSI, Teradata, DEFAULT
|
36
|
+
config[:charset] ||= 'UTF8'
|
37
|
+
config[:cop] ||= 'OFF'
|
38
|
+
config[:log_level] ||= 'ERROR'
|
39
|
+
config[:xviews] ||= 'OFF'
|
40
|
+
config[:url] ||= "jdbc:teradata://#{config[:host]}/DATABASE=#{config[:database]},DBS_PORT=#{config[:port]},COP=#{config[:cop]},tmode=#{config[:tmode]},charset=#{config[:charset]},LOG=#{config[:log_level]},USEXVIEWS=#{config[:xviews]}"
|
41
|
+
end
|
42
|
+
config[:driver] ||= 'com.teradata.jdbc.TeraDriver'
|
43
|
+
config[:adapter_class] = ActiveRecord::ConnectionAdapters::TeradataAdapter
|
44
|
+
config[:adapter_spec] = ::ArJdbc::Teradata
|
45
|
+
jdbc_connection(config)
|
21
46
|
end
|
47
|
+
|
22
48
|
alias_method :jdbcteradata_connection, :teradata_connection
|
23
49
|
end
|
24
50
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module ::ArJdbc
|
2
|
+
module Teradata
|
3
|
+
def supports_explain?
|
4
|
+
true
|
5
|
+
end
|
6
|
+
|
7
|
+
def explain(arel, binds = [])
|
8
|
+
sql = "EXPLAIN #{to_sql(arel, binds)}"
|
9
|
+
raw_result = @connection.execute_query(sql)
|
10
|
+
raw_result
|
11
|
+
rows = raw_result.map { |hash| hash.values }
|
12
|
+
rows.join("\n")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
Binary file
|
data/spec/adapter_spec.rb
CHANGED
@@ -2,6 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
require 'models/simple_article'
|
4
4
|
require 'models/lowercase_model'
|
5
|
+
require 'models/model_with_blob'
|
5
6
|
|
6
7
|
describe 'Adapter' do
|
7
8
|
|
@@ -40,6 +41,13 @@ describe 'Adapter' do
|
|
40
41
|
articles.select { |i| i['title'] == article_2.title }.first.should_not be_nil
|
41
42
|
end
|
42
43
|
|
44
|
+
it '#explain' do
|
45
|
+
article_1 = Article.create(:title => 'exec_query_1', :body => 'exec_query_1')
|
46
|
+
explain_plan = @adapter.explain('select * from articles')
|
47
|
+
explain_plan.should include('WEBLOG_DEVELOPMENT.articles')
|
48
|
+
explain_plan.should include('total estimated time')
|
49
|
+
end
|
50
|
+
|
43
51
|
it '#last_insert_id(table)' do
|
44
52
|
article_1 = Article.create(:title => 'exec_query_1', :body => 'exec_query_1')
|
45
53
|
article_1.id.should eq(@adapter.last_insert_id('articles'))
|
@@ -135,4 +143,33 @@ describe 'Adapter' do
|
|
135
143
|
CreateShirts.down
|
136
144
|
end
|
137
145
|
end
|
146
|
+
|
147
|
+
context 'testing BLOB support' do
|
148
|
+
before(:each) do
|
149
|
+
CreateTestFiles.up
|
150
|
+
@connection = TestFile.connection
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'should be able to save a BLOB' do
|
154
|
+
file = TestFile.new
|
155
|
+
file.name = 'test'
|
156
|
+
|
157
|
+
path = File.join(File.dirname(__FILE__), '')
|
158
|
+
|
159
|
+
bytes = File.open(File.join(path, '/fixtures/wikimedia-commons-poty-2006.jpg'), 'rb')\
|
160
|
+
.read\
|
161
|
+
.to_java_bytes
|
162
|
+
file.data = bytes.to_s
|
163
|
+
file.save
|
164
|
+
TestFile.where(:name => 'test').count.should eq(1)
|
165
|
+
TestFile.where(:name => 'test').first.data.should eq(file.data)
|
166
|
+
#Uncomment this line to perform a visual test.
|
167
|
+
#The test.jpg image should be the same as the wikimedia commons jpg image.
|
168
|
+
#File.open(File.join(path, '/fixtures/test.jpg'), 'wb') { |file| file.write(TestFile.first.data.to_s) }
|
169
|
+
end
|
170
|
+
|
171
|
+
after(:each) do
|
172
|
+
CreateTestFiles.down
|
173
|
+
end
|
174
|
+
end
|
138
175
|
end
|
data/spec/associations_spec.rb
CHANGED
@@ -13,6 +13,7 @@ describe 'AssociationsSpec' do
|
|
13
13
|
|
14
14
|
it 'should create all of the tables' do
|
15
15
|
vendor = Vendor.new(:name => 'Test vendor', :catch_phrase => 'Hello, world')
|
16
|
+
puts vendor.inspect
|
16
17
|
vendor.products.build(:name => 'Test product', :price => 100.00)
|
17
18
|
vendor.save
|
18
19
|
|
@@ -38,8 +39,8 @@ describe 'AssociationsSpec' do
|
|
38
39
|
:product_id => vendor.products.first.id,
|
39
40
|
:code => 'Order 2',
|
40
41
|
:quantity => 1,
|
41
|
-
:order_line_items_attributes => [
|
42
|
-
{ :item_name => 'Test item' }
|
42
|
+
:order_line_items_attributes => [
|
43
|
+
{ :item_name => 'Test item' }
|
43
44
|
]
|
44
45
|
} }
|
45
46
|
|
@@ -57,14 +58,14 @@ describe 'AssociationsSpec' do
|
|
57
58
|
:code => 'Order 2',
|
58
59
|
:quantity => 1,
|
59
60
|
:order_feeling_attributes =>
|
60
|
-
{ :status => 'Wonderful' }
|
61
|
-
|
61
|
+
{ :status => 'Wonderful' }
|
62
|
+
|
62
63
|
} }
|
63
64
|
|
64
65
|
purchase_order = PurchaseOrder.create(params[:purchase_order])
|
65
66
|
purchase_order.order_feeling.status.should eq('Wonderful')
|
66
67
|
end
|
67
|
-
|
68
|
+
|
68
69
|
it 'it has_one#new' do
|
69
70
|
vendor = Vendor.new(:name => 'Test vendor', :catch_phrase => 'Hello, world')
|
70
71
|
vendor.products.build(:name => 'Test product', :price => 100.00)
|
@@ -75,15 +76,15 @@ describe 'AssociationsSpec' do
|
|
75
76
|
:code => 'Order 3',
|
76
77
|
:quantity => 1,
|
77
78
|
:order_feeling_attributes =>
|
78
|
-
{ :status => 'Wonderful' }
|
79
|
-
|
79
|
+
{ :status => 'Wonderful' }
|
80
|
+
|
80
81
|
} }
|
81
82
|
|
82
83
|
purchase_order = PurchaseOrder.new(params[:purchase_order])
|
83
84
|
purchase_order.save
|
84
85
|
purchase_order.order_feeling.status.should eq('Wonderful')
|
85
86
|
end
|
86
|
-
|
87
|
+
|
87
88
|
end
|
88
89
|
|
89
90
|
after(:all) do
|
Binary file
|
Binary file
|
data/spec/connection_spec.rb
CHANGED
@@ -1,8 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
+
require 'java'
|
3
|
+
require 'commons-pool-1.6.jar'
|
4
|
+
require 'commons-dbcp-1.4.jar'
|
2
5
|
|
3
6
|
describe 'Connection' do
|
4
7
|
it 'should create a connection' do
|
5
8
|
ActiveRecord::Base.connection.execute('select * from dbc.tables')
|
6
9
|
ActiveRecord::Base.connected?.should be_true
|
7
10
|
end
|
11
|
+
|
12
|
+
it "should create a new connection using JNDI" do
|
13
|
+
begin
|
14
|
+
import 'org.apache.commons.pool.impl.GenericObjectPool'
|
15
|
+
import 'org.apache.commons.dbcp.BasicDataSource'
|
16
|
+
import 'org.apache.commons.dbcp.BasicDataSourceFactory'
|
17
|
+
import 'org.apache.commons.dbcp.DriverManagerConnectionFactory'
|
18
|
+
rescue NameError => e
|
19
|
+
return pending e.message
|
20
|
+
end
|
21
|
+
|
22
|
+
class InitialContextMock
|
23
|
+
def initialize
|
24
|
+
url = "jdbc:teradata://#{TERADATA_CONFIG[:host]}/DATABASE=#{TERADATA_CONFIG[:database]},DBS_PORT=#{TERADATA_CONFIG[:port]}"
|
25
|
+
@data_source = BasicDataSource.new()
|
26
|
+
@data_source.set_driver_class_name('com.teradata.jdbc.TeraDriver')
|
27
|
+
@data_source.set_url(url)
|
28
|
+
@data_source.set_username(TERADATA_CONFIG[:username])
|
29
|
+
@data_source.set_password(TERADATA_CONFIG[:password])
|
30
|
+
|
31
|
+
@data_source.access_to_underlying_connection_allowed = true
|
32
|
+
end
|
33
|
+
def lookup(path)
|
34
|
+
if (path == 'java:/comp/env')
|
35
|
+
return self
|
36
|
+
else
|
37
|
+
return @data_source
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
javax.naming.InitialContext.stub!(:new).and_return(InitialContextMock.new)
|
43
|
+
|
44
|
+
ActiveRecord::Base.establish_connection(TERADATA_JNDI_CONFIG)
|
45
|
+
ActiveRecord::Base.connection.execute('select * from dbc.tables')
|
46
|
+
ActiveRecord::Base.connected?.should be_true
|
47
|
+
end
|
8
48
|
end
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateTestFiles < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table 'test_files' do |t|
|
4
|
+
t.string 'name', :null => false
|
5
|
+
t.binary 'data'
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table 'test_files'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class TestFile < ActiveRecord::Base
|
16
|
+
self.table_name = 'test_files'
|
17
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,11 +2,19 @@ require 'active_record'
|
|
2
2
|
|
3
3
|
TERADATA_CONFIG = {
|
4
4
|
:adapter => 'teradata',
|
5
|
-
:host => '
|
5
|
+
:host => (ENV['TERADATA_HOST'] || 'localhost'),
|
6
6
|
:database => 'weblog_development',
|
7
7
|
:port => 1025,
|
8
8
|
:username => 'dbc',
|
9
9
|
:password => 'dbc'
|
10
10
|
}
|
11
11
|
|
12
|
+
TERADATA_JNDI_CONFIG = {
|
13
|
+
:adapter => 'teradata',
|
14
|
+
:jndi => 'jdbc/TeradataDS',
|
15
|
+
:username => 'dbc',
|
16
|
+
:password => 'dbc',
|
17
|
+
:pool => 20
|
18
|
+
}
|
19
|
+
|
12
20
|
ActiveRecord::Base.establish_connection(TERADATA_CONFIG)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-jdbcteradata-adapter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-09-03 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -63,15 +63,15 @@ dependencies:
|
|
63
63
|
name: activerecord
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - <=
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
68
|
+
version: 3.2.13
|
69
69
|
none: false
|
70
70
|
requirement: !ruby/object:Gem::Requirement
|
71
71
|
requirements:
|
72
|
-
- -
|
72
|
+
- - <=
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: 3.2.13
|
75
75
|
none: false
|
76
76
|
prerelease: false
|
77
77
|
type: :runtime
|
@@ -112,14 +112,19 @@ files:
|
|
112
112
|
- lib/arjdbc/teradata/adapter.rb
|
113
113
|
- lib/arjdbc/teradata/connection_methods.rb
|
114
114
|
- lib/arjdbc/teradata/teradata_java.jar
|
115
|
+
- lib/arjdbc/teradata/explain_support.rb
|
115
116
|
- lib/arjdbc/teradata.rb
|
116
117
|
- spec/active_record_schema_spec.rb
|
117
118
|
- spec/adapter_spec.rb
|
118
119
|
- spec/associations_spec.rb
|
120
|
+
- spec/commons-dbcp-1.4.jar
|
121
|
+
- spec/commons-pool-1.6.jar
|
119
122
|
- spec/connection_spec.rb
|
123
|
+
- spec/fixtures/wikimedia-commons-poty-2006.jpg
|
120
124
|
- spec/models/active_record_models.rb
|
121
125
|
- spec/models/active_record_schema.rb
|
122
126
|
- spec/models/lowercase_model.rb
|
127
|
+
- spec/models/model_with_blob.rb
|
123
128
|
- spec/models/purchase_orders.rb
|
124
129
|
- spec/models/simple_article.rb
|
125
130
|
- spec/simple_spec.rb
|
@@ -152,10 +157,14 @@ test_files:
|
|
152
157
|
- spec/active_record_schema_spec.rb
|
153
158
|
- spec/adapter_spec.rb
|
154
159
|
- spec/associations_spec.rb
|
160
|
+
- spec/commons-dbcp-1.4.jar
|
161
|
+
- spec/commons-pool-1.6.jar
|
155
162
|
- spec/connection_spec.rb
|
163
|
+
- spec/fixtures/wikimedia-commons-poty-2006.jpg
|
156
164
|
- spec/models/active_record_models.rb
|
157
165
|
- spec/models/active_record_schema.rb
|
158
166
|
- spec/models/lowercase_model.rb
|
167
|
+
- spec/models/model_with_blob.rb
|
159
168
|
- spec/models/purchase_orders.rb
|
160
169
|
- spec/models/simple_article.rb
|
161
170
|
- spec/simple_spec.rb
|