activerecord-jdbcteradata-adapter 0.4.1 → 0.4.2
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 +1 -1
- data/Gemfile.lock +2 -2
- data/README.md +77 -6
- data/activerecord-jdbcteradata-adapter.gemspec +10 -10
- data/lib/arel/visitors/teradata.rb +13 -13
- data/lib/arjdbc/teradata/adapter.rb +64 -45
- data/lib/arjdbc/teradata/connection_methods.rb +2 -1
- data/lib/arjdbc/teradata/teradata_java.jar +0 -0
- data/spec/adapter_spec.rb +116 -56
- data/spec/models/lowercase_model.rb +17 -0
- metadata +4 -2
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
activerecord-jdbcteradata-adapter (0.4.
|
4
|
+
activerecord-jdbcteradata-adapter (0.4.1)
|
5
5
|
activerecord
|
6
6
|
activerecord-jdbc-adapter
|
7
7
|
jdbc-teradata
|
@@ -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.4)
|
30
30
|
rake (10.0.4)
|
31
31
|
rspec (2.13.0)
|
32
32
|
rspec-core (~> 2.13.0)
|
data/README.md
CHANGED
@@ -1,11 +1,82 @@
|
|
1
|
-
|
1
|
+
## ActiveRecord Teradata Adapter for JRuby
|
2
2
|
|
3
|
-
|
3
|
+
Are you using JRuby? ActiveRecord? Teradata? This is for you.
|
4
4
|
|
5
|
-
|
5
|
+
This is a driver that lets you use Teradata with ActiveRecord.
|
6
6
|
|
7
|
-
|
7
|
+
### Usage
|
8
|
+
|
9
|
+
In your `Gemfile` add
|
10
|
+
|
11
|
+
gem 'activerecord-jdbcteradata-driver'
|
12
|
+
|
13
|
+
In `database.yml` add something like
|
14
|
+
|
15
|
+
development:
|
16
|
+
adapter: teradata
|
17
|
+
username: user
|
18
|
+
password: pass
|
19
|
+
host: hostname
|
20
|
+
database: DBC
|
21
|
+
pool: 25
|
22
|
+
wait_timeout: 5
|
23
|
+
tmode: TERA
|
24
|
+
|
25
|
+
### License
|
26
|
+
|
27
|
+
MIT. Free for you to use any way you want.
|
28
|
+
|
29
|
+
### Force lowercase attributes
|
30
|
+
|
31
|
+
Ruby people like lowercase attribute names. If you have a table that
|
32
|
+
has upper case column names, you can force ActiveRecord to use lowercase
|
33
|
+
attribute names.
|
34
|
+
|
35
|
+
For example, if this:
|
36
|
+
|
37
|
+
user = User.new
|
38
|
+
user.first_name = "John"
|
39
|
+
|
40
|
+
looks better than:
|
41
|
+
|
42
|
+
user = User.name
|
43
|
+
user.FIRST_NAME = "John"
|
44
|
+
|
45
|
+
you can set:
|
46
|
+
|
47
|
+
ActiveRecord::ConnectionAdapters::TeradataAdapter.lowercase_schema_reflection = true
|
48
|
+
|
49
|
+
in config/initializers
|
50
|
+
|
51
|
+
### Building the code
|
52
|
+
|
53
|
+
A small part of the code is written in java. You are going to want to
|
54
|
+
run:
|
55
|
+
|
56
|
+
ruby java_compile.rb
|
57
|
+
|
58
|
+
### Running tests
|
59
|
+
|
60
|
+
bundle exec rspec spec
|
61
|
+
|
62
|
+
I am also testing against the activerecord test suite.
|
63
|
+
|
64
|
+
### Questions?
|
65
|
+
|
66
|
+
Post a message in the issues list. I am happy to respond.
|
67
|
+
|
68
|
+
### Patches?
|
69
|
+
|
70
|
+
Fork. Do a pull request. Thanks.
|
71
|
+
|
72
|
+
### Thanks for you contribution
|
73
|
+
|
74
|
+
Evgeny Rahman
|
75
|
+
|
76
|
+
* support for <> NULL, != NULL, and = NULL support, as suggested by his
|
77
|
+
colleague Tim Chevalier
|
78
|
+
* Downcase support. See #force_downcase_attributes
|
79
|
+
* COP mode support
|
80
|
+
* Support for users in the issues list
|
8
81
|
|
9
|
-
It is still under heavy development.
|
10
82
|
|
11
|
-
Right now I am testing this code with the ActiveRecord test suite.
|
@@ -1,14 +1,14 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
|
-
s.name =
|
3
|
-
s.version =
|
4
|
-
s.authors = [
|
5
|
-
s.email =
|
6
|
-
s.homepage =
|
2
|
+
s.name = 'activerecord-jdbcteradata-adapter'
|
3
|
+
s.version = '0.4.2'
|
4
|
+
s.authors = ['Chris Parker']
|
5
|
+
s.email = %w(mrcsparker@gmail.com)
|
6
|
+
s.homepage = 'https://github.com/mrcsparker/activerecord-jdbcteradata-adapter'
|
7
7
|
s.summary = %q{Teradata JDBC driver for JRuby on Rails.}
|
8
8
|
s.description = %q{Install this gem and require 'teradata' with JRuby on Rails.}
|
9
|
-
|
10
|
-
s.rubyforge_project =
|
11
|
-
|
9
|
+
|
10
|
+
s.rubyforge_project = 'activerecord-jdbcteradata-adapter'
|
11
|
+
|
12
12
|
s.files = %w[
|
13
13
|
Gemfile
|
14
14
|
Gemfile.lock
|
@@ -29,8 +29,8 @@ Gem::Specification.new do |s|
|
|
29
29
|
|
30
30
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
31
31
|
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
32
|
-
s.require_paths =
|
33
|
-
|
32
|
+
s.require_paths = %w(lib)
|
33
|
+
|
34
34
|
s.add_development_dependency 'rake'
|
35
35
|
s.add_development_dependency 'rspec'
|
36
36
|
s.add_dependency 'activerecord-jdbc-adapter'
|
@@ -48,7 +48,7 @@ module Arel
|
|
48
48
|
d = s =~ /(ASC|DESC)\Z/i ? $1.upcase : nil
|
49
49
|
e = d.nil? ? s : s.mb_chars[0...-d.length].strip
|
50
50
|
e = Arel.sql(e)
|
51
|
-
d && d ==
|
51
|
+
d && d == 'DESC' ? Arel::Nodes::Descending.new(e) : Arel::Nodes::Ascending.new(e)
|
52
52
|
end
|
53
53
|
else
|
54
54
|
e = Arel.sql(x.to_s)
|
@@ -155,10 +155,10 @@ module Arel
|
|
155
155
|
elsif top_one_everything_for_through_join?(o)
|
156
156
|
projections = projections.map { |x| projection_without_expression(x) }
|
157
157
|
end
|
158
|
-
[ (
|
158
|
+
[ ('SELECT' if !windowed),
|
159
159
|
(visit(core.set_quantifier) if core.set_quantifier && !windowed),
|
160
160
|
(visit(o.limit) if o.limit && !windowed),
|
161
|
-
(projections.map{ |x| v = visit(x); v ==
|
161
|
+
(projections.map{ |x| v = visit(x); v == '1' ? '1 AS __wrp' : v }.join(', ')),
|
162
162
|
(source_with_lock_for_select_statement(o)),
|
163
163
|
("WHERE #{core.wheres.map{ |x| visit(x) }.join ' AND ' }" unless core.wheres.empty?),
|
164
164
|
("GROUP BY #{groups.map { |x| visit x }.join ', ' }" unless groups.empty?),
|
@@ -171,15 +171,15 @@ module Arel
|
|
171
171
|
core = o.cores.first
|
172
172
|
o.limit ||= Arel::Nodes::Limit.new(214748364)
|
173
173
|
orders = rowtable_orders(o)
|
174
|
-
[
|
174
|
+
[ 'SELECT',
|
175
175
|
(visit(o.limit) if o.limit && !windowed_single_distinct_select_statement?(o)),
|
176
176
|
(rowtable_projections(o).map{ |x| visit(x) }.join(', ')),
|
177
|
-
|
177
|
+
'FROM (',
|
178
178
|
"SELECT #{core.set_quantifier ? 'DISTINCT DENSE_RANK()' : 'ROW_NUMBER()'} OVER (ORDER BY #{orders.map{ |x| visit(x) }.join(', ')}) AS __rn,",
|
179
179
|
visit_Arel_Nodes_SelectStatementWithOutOffset(o,true),
|
180
|
-
|
180
|
+
') AS __rnt',
|
181
181
|
(visit(o.offset) if o.offset),
|
182
|
-
|
182
|
+
'ORDER BY __rnt.__rn ASC'
|
183
183
|
].compact.join ' '
|
184
184
|
end
|
185
185
|
|
@@ -187,18 +187,18 @@ module Arel
|
|
187
187
|
core = o.cores.first
|
188
188
|
o.limit.expr = Arel.sql("#{o.limit.expr} + #{o.offset ? o.offset.expr : 0}") if o.limit
|
189
189
|
orders = rowtable_orders(o)
|
190
|
-
[
|
191
|
-
|
192
|
-
|
190
|
+
[ 'SELECT COUNT(count) AS count_id',
|
191
|
+
'FROM (',
|
192
|
+
'SELECT',
|
193
193
|
(visit(o.limit) if o.limit),
|
194
194
|
"ROW_NUMBER() OVER (ORDER BY #{orders.map{ |x| visit(x) }.join(', ')}) AS __rn,",
|
195
|
-
|
195
|
+
'1 AS count',
|
196
196
|
(source_with_lock_for_select_statement(o)),
|
197
197
|
("WHERE #{core.wheres.map{ |x| visit(x) }.join ' AND ' }" unless core.wheres.empty?),
|
198
198
|
("GROUP BY #{core.groups.map { |x| visit x }.join ', ' }" unless core.groups.empty?),
|
199
199
|
(visit(core.having) if core.having),
|
200
200
|
("ORDER BY #{o.orders.map{ |x| visit(x) }.join(', ')}" if !o.orders.empty?),
|
201
|
-
|
201
|
+
') AS __rnt',
|
202
202
|
(visit(o.offset) if o.offset)
|
203
203
|
].compact.join ' '
|
204
204
|
end
|
@@ -254,7 +254,7 @@ module Arel
|
|
254
254
|
end
|
255
255
|
|
256
256
|
def single_distinct_select_everything_statement?(o)
|
257
|
-
single_distinct_select_statement?(o) && visit(o.cores.first.projections.first).ends_with?(
|
257
|
+
single_distinct_select_statement?(o) && visit(o.cores.first.projections.first).ends_with?('.*')
|
258
258
|
end
|
259
259
|
|
260
260
|
def top_one_everything_for_through_join?(o)
|
@@ -6,7 +6,7 @@ module ::ArJdbc
|
|
6
6
|
def self.column_selector
|
7
7
|
[ /teradata/i, lambda { |cfg, column| column.extend(::ArJdbc::Teradata::Column) } ]
|
8
8
|
end
|
9
|
-
|
9
|
+
|
10
10
|
## ActiveRecord::ConnectionAdapters::JdbcAdapter
|
11
11
|
|
12
12
|
#- jdbc_connection_class
|
@@ -17,7 +17,7 @@ module ::ArJdbc
|
|
17
17
|
#- jdbc_column_class
|
18
18
|
|
19
19
|
#- jdbc_connection
|
20
|
-
|
20
|
+
|
21
21
|
#- adapter_spec
|
22
22
|
|
23
23
|
#+ modify_types
|
@@ -41,7 +41,7 @@ module ::ArJdbc
|
|
41
41
|
end
|
42
42
|
|
43
43
|
#- self.visitor_for
|
44
|
-
|
44
|
+
|
45
45
|
#+ self.arel2_visitors
|
46
46
|
def self.arel2_visitors(config)
|
47
47
|
{ 'teradata' => Arel::Visitors::Teradata, 'jdbcteradata' => Arel::Visitors::Teradata }
|
@@ -58,20 +58,22 @@ module ::ArJdbc
|
|
58
58
|
|
59
59
|
#+ native_database_types
|
60
60
|
def native_database_types
|
61
|
-
super.merge(
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
61
|
+
super.merge(
|
62
|
+
{
|
63
|
+
:primary_key => 'INTEGER PRIMARY KEY NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1 MINVALUE -2147483647 MAXVALUE 1000000000 NO CYCLE)',
|
64
|
+
:string => { :name => 'VARCHAR', :limit => 255 },
|
65
|
+
:integer => { :name => 'INTEGER'},
|
66
|
+
:float => { :name => 'FLOAT'},
|
67
|
+
:decimal => { :name => 'DECIMAL'},
|
68
|
+
:datetime => { :name => 'TIMESTAMP'},
|
69
|
+
:timestamp => { :name => 'TIMESTAMP'},
|
70
|
+
:time => { :name => 'TIMESTAMP'},
|
71
|
+
:date => { :name => 'DATE'},
|
72
|
+
:binary => { :name => 'BLOB'},
|
73
|
+
:boolean => { :name => 'BYTEINT'},
|
74
|
+
:raw => { :name => 'BYTE'}
|
75
|
+
}
|
76
|
+
)
|
75
77
|
end
|
76
78
|
|
77
79
|
#- database_name
|
@@ -102,7 +104,15 @@ module ::ArJdbc
|
|
102
104
|
#- execute
|
103
105
|
def _execute(sql, name = nil)
|
104
106
|
if self.class.select?(sql)
|
105
|
-
@connection.execute_query(sql)
|
107
|
+
result = @connection.execute_query(sql)
|
108
|
+
result.map! do |r|
|
109
|
+
new_hash = {}
|
110
|
+
r.each_pair do |k, v|
|
111
|
+
new_hash.merge!({k.downcase => v})
|
112
|
+
end
|
113
|
+
new_hash
|
114
|
+
end if self.class.lowercase_schema_reflection
|
115
|
+
result
|
106
116
|
elsif self.class.insert?(sql)
|
107
117
|
(@connection.execute_insert(sql) or last_insert_id(sql)).to_i
|
108
118
|
else
|
@@ -125,6 +135,11 @@ module ::ArJdbc
|
|
125
135
|
end
|
126
136
|
|
127
137
|
#- select
|
138
|
+
def select(sql, *rest)
|
139
|
+
# TJC - Teradata does not like "= NULL", "!= NULL", or "<> NULL".
|
140
|
+
# TJC - Also does not like != so transforming that to <>
|
141
|
+
execute(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL").gsub("!=","<>"), *rest)
|
142
|
+
end
|
128
143
|
|
129
144
|
#- select_rows
|
130
145
|
|
@@ -175,15 +190,13 @@ module ::ArJdbc
|
|
175
190
|
schema = database_name unless schema
|
176
191
|
|
177
192
|
result = select_rows('SELECT' <<
|
178
|
-
|
179
|
-
|
193
|
+
' DatabaseName, TableName, ColumnName, IndexType, IndexName, UniqueFlag' <<
|
194
|
+
' FROM DBC.Indices' <<
|
180
195
|
" WHERE TableName = '#{table}' AND DatabaseName = '#{schema}'")
|
181
|
-
|
196
|
+
|
182
197
|
result.map do |row|
|
183
|
-
idx_database_name = row[0].to_s.strip
|
184
198
|
idx_table_name = row[1].to_s.strip
|
185
199
|
idx_column_name = row[2].to_s.strip
|
186
|
-
idx_index_type = row[3].to_s.strip
|
187
200
|
idx_index_name = row[4].to_s.strip
|
188
201
|
idx_unique_flag = row[5].to_s.strip
|
189
202
|
|
@@ -207,7 +220,7 @@ module ::ArJdbc
|
|
207
220
|
#- write_large_object
|
208
221
|
|
209
222
|
#- pk_and_sequence_for
|
210
|
-
|
223
|
+
|
211
224
|
#- primary_key
|
212
225
|
|
213
226
|
#- primary_keys
|
@@ -219,7 +232,7 @@ module ::ArJdbc
|
|
219
232
|
#- table_exists?
|
220
233
|
|
221
234
|
#- index_exists?
|
222
|
-
|
235
|
+
|
223
236
|
#- columns
|
224
237
|
def columns(table_name, name = nil)
|
225
238
|
return false unless table_name
|
@@ -236,11 +249,11 @@ module ::ArJdbc
|
|
236
249
|
#- create_table
|
237
250
|
|
238
251
|
#- change_table
|
239
|
-
|
252
|
+
|
240
253
|
#+ rename_table
|
241
254
|
|
242
255
|
#- drop_table
|
243
|
-
|
256
|
+
|
244
257
|
#- add_column
|
245
258
|
|
246
259
|
#- remove_column
|
@@ -255,21 +268,21 @@ module ::ArJdbc
|
|
255
268
|
# cannot be shortened, one column type cannot be converted to another.
|
256
269
|
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
257
270
|
change_column_sql = "ALTER TABLE #{quote_table_name(table_name)} " <<
|
258
|
-
|
271
|
+
"ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit])}"
|
259
272
|
add_column_options!(change_column_sql, options)
|
260
273
|
execute(change_column_sql)
|
261
274
|
end
|
262
275
|
|
263
276
|
#+ change_column_default
|
264
277
|
def change_column_default(table_name, column_name, default) #:nodoc:
|
265
|
-
execute "ALTER TABLE #{quote_table_name(table_name)} " +
|
278
|
+
execute "ALTER TABLE #{quote_table_name(table_name)} " +
|
266
279
|
"ADD #{quote_column_name(column_name)} DEFAULT #{quote(default)}"
|
267
280
|
end
|
268
281
|
|
269
282
|
#+ rename_column
|
270
283
|
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
271
284
|
execute "ALTER TABLE #{quote_table_name(table_name)} " <<
|
272
|
-
|
285
|
+
"RENAME COLUMN #{quote_column_name(column_name)} to #{quote_column_name(new_column_name)}"
|
273
286
|
end
|
274
287
|
|
275
288
|
#- add_index
|
@@ -291,7 +304,7 @@ module ::ArJdbc
|
|
291
304
|
#- assume_migrated_upto_version
|
292
305
|
|
293
306
|
#- type_to_sql
|
294
|
-
|
307
|
+
|
295
308
|
#- add_column_options!
|
296
309
|
|
297
310
|
#- distinct
|
@@ -304,10 +317,10 @@ module ::ArJdbc
|
|
304
317
|
# Maps Teradata types of logical Rails types
|
305
318
|
def simplified_type(field_type)
|
306
319
|
case field_type
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
320
|
+
when /^timestamp with(?:out)? time zone$/ then :datetime
|
321
|
+
when /byteint/i then :boolean
|
322
|
+
else
|
323
|
+
super
|
311
324
|
end
|
312
325
|
end
|
313
326
|
end # column
|
@@ -321,13 +334,13 @@ module ::ArJdbc
|
|
321
334
|
def quote(value, column = nil)
|
322
335
|
return value.quoted_id if value.respond_to?(:quoted_id)
|
323
336
|
case value
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
337
|
+
when String
|
338
|
+
%Q{'#{quote_string(value)}'}
|
339
|
+
when TrueClass
|
340
|
+
'1'
|
341
|
+
when FalseClass
|
342
|
+
'0'
|
343
|
+
else super
|
331
344
|
end
|
332
345
|
end
|
333
346
|
|
@@ -351,9 +364,9 @@ module ::ArJdbc
|
|
351
364
|
index_name, index_type, index_columns = add_index_options(table_name, column_name, options)
|
352
365
|
execute "CREATE #{index_type} INDEX #{quote_column_name(index_name)} (#{index_columns}) ON #{quote_table_name(table_name)}"
|
353
366
|
end
|
354
|
-
|
367
|
+
|
355
368
|
IDENTIFIER_LENGTH = 30 # :nodoc:
|
356
|
-
|
369
|
+
|
357
370
|
# maximum length of Teradata identifiers is 30
|
358
371
|
def table_alias_length; IDENTIFIER_LENGTH
|
359
372
|
end # :nodoc:
|
@@ -373,7 +386,11 @@ module ActiveRecord
|
|
373
386
|
include ::ArJdbc::Teradata::Column
|
374
387
|
|
375
388
|
def initialize(name, *args)
|
389
|
+
|
376
390
|
if Hash === name
|
391
|
+
if name.has_key? :adapter_class
|
392
|
+
args[0].downcase! if name[:adapter_class].lowercase_schema_reflection
|
393
|
+
end
|
377
394
|
super
|
378
395
|
else
|
379
396
|
super(nil, name, *args)
|
@@ -387,6 +404,8 @@ module ActiveRecord
|
|
387
404
|
class TeradataAdapter < JdbcAdapter
|
388
405
|
include ::ArJdbc::Teradata
|
389
406
|
|
407
|
+
cattr_accessor :lowercase_schema_reflection
|
408
|
+
|
390
409
|
def initialize(*args)
|
391
410
|
super
|
392
411
|
end
|
@@ -422,7 +441,7 @@ module ActiveRecord
|
|
422
441
|
quoted
|
423
442
|
end
|
424
443
|
end
|
425
|
-
|
444
|
+
|
426
445
|
end
|
427
446
|
end
|
428
447
|
|
@@ -12,7 +12,8 @@ class ActiveRecord::Base
|
|
12
12
|
config[:port] ||= 1025
|
13
13
|
config[:tmode] ||= 'ANSI' # ANSI, Teradata, DEFAULT
|
14
14
|
config[:charset] ||= 'UTF8'
|
15
|
-
config[:
|
15
|
+
config[:cop] ||= 'OFF'
|
16
|
+
config[:url] ||= "jdbc:teradata://#{config[:host]}/DATABASE=#{config[:database]},DBS_PORT=#{config[:port]},COP=#{config[:cop]},tmode=#{config[:tmode]},charset=#{config[:charset]}"
|
16
17
|
config[:driver] ||= 'com.teradata.jdbc.TeraDriver'
|
17
18
|
config[:adapter_class] = ActiveRecord::ConnectionAdapters::TeradataAdapter
|
18
19
|
config[:adapter_spec] = ::ArJdbc::Teradata
|
Binary file
|
data/spec/adapter_spec.rb
CHANGED
@@ -1,78 +1,138 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
require 'models/simple_article'
|
4
|
+
require 'models/lowercase_model'
|
4
5
|
|
5
6
|
describe 'Adapter' do
|
6
|
-
before(:all) do
|
7
|
-
CreateArticles.up
|
8
|
-
@adapter = Article.connection
|
9
|
-
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
context 'instance methods' do
|
9
|
+
before(:all) do
|
10
|
+
CreateArticles.up
|
11
|
+
@adapter = Article.connection
|
12
|
+
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
it '#adapter_name' do
|
15
|
+
@adapter.adapter_name.should eq('Teradata')
|
16
|
+
end
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
it '#database_name' do
|
24
|
-
@adapter.database_name.should == 'weblog_development'
|
25
|
-
end
|
18
|
+
it '#supports_migrations?' do
|
19
|
+
@adapter.supports_migrations?.should be_true
|
20
|
+
end
|
26
21
|
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
it '#native_database_types' do
|
23
|
+
@adapter.native_database_types.count.should > 0
|
24
|
+
end
|
30
25
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
articles = @adapter.exec_query('select * from articles')
|
35
|
-
|
36
|
-
articles.select { |i| i['title'] == article_1.title }.first.should_not be_nil
|
37
|
-
articles.select { |i| i['title'] == article_2.title }.first.should_not be_nil
|
38
|
-
end
|
26
|
+
it '#database_name' do
|
27
|
+
@adapter.database_name.should == 'weblog_development'
|
28
|
+
end
|
39
29
|
|
40
|
-
|
41
|
-
|
42
|
-
|
30
|
+
it '#active?' do
|
31
|
+
@adapter.active?.should be_true
|
32
|
+
end
|
43
33
|
|
44
|
-
|
45
|
-
|
46
|
-
|
34
|
+
it '#exec_query' do
|
35
|
+
article_1 = Article.create(:title => 'exec_query_1', :body => 'exec_query_1')
|
36
|
+
article_2 = Article.create(:title => 'exec_query_2', :body => 'exec_query_2')
|
37
|
+
articles = @adapter.exec_query('select * from articles')
|
47
38
|
|
48
|
-
|
49
|
-
|
39
|
+
articles.select { |i| i['title'] == article_1.title }.first.should_not be_nil
|
40
|
+
articles.select { |i| i['title'] == article_2.title }.first.should_not be_nil
|
41
|
+
end
|
50
42
|
|
51
|
-
|
52
|
-
|
53
|
-
|
43
|
+
it '#last_insert_id(table)' do
|
44
|
+
article_1 = Article.create(:title => 'exec_query_1', :body => 'exec_query_1')
|
45
|
+
article_1.id.should eq(@adapter.last_insert_id('articles'))
|
54
46
|
|
55
|
-
|
56
|
-
@adapter.table_exists?('articles').should be_true
|
57
|
-
end
|
47
|
+
article_2 = Article.create(:title => 'exec_query_2', :body => 'exec_query_2')
|
58
48
|
|
59
|
-
|
60
|
-
id_index = @adapter.indexes('articles').first
|
61
|
-
id_index.table.should eq('articles')
|
62
|
-
id_index.name.should == ''
|
63
|
-
id_index.unique.should be_true
|
64
|
-
id_index.columns.should eq(%w(id))
|
65
|
-
end
|
49
|
+
article_1.id.should_not eq(article_2.id)
|
66
50
|
|
67
|
-
|
68
|
-
|
69
|
-
|
51
|
+
article_2.id.should eq(@adapter.last_insert_id('articles'))
|
52
|
+
end
|
53
|
+
|
54
|
+
it '#tables' do
|
55
|
+
@adapter.tables.should include('articles')
|
56
|
+
end
|
57
|
+
|
58
|
+
it '#table_exists?' do
|
59
|
+
@adapter.table_exists?('articles').should be_true
|
60
|
+
end
|
61
|
+
|
62
|
+
it '#indexes' do
|
63
|
+
id_index = @adapter.indexes('articles').first
|
64
|
+
id_index.table.should eq('articles')
|
65
|
+
id_index.name.should == ''
|
66
|
+
id_index.unique.should be_true
|
67
|
+
id_index.columns.should eq(%w(id))
|
68
|
+
end
|
69
|
+
|
70
|
+
it '#pk_and_sequence_for' do
|
71
|
+
@adapter.pk_and_sequence_for('articles').should eq(['id', nil])
|
72
|
+
end
|
73
|
+
|
74
|
+
it '#primary_key' do
|
75
|
+
@adapter.primary_key('articles').should eq('id')
|
76
|
+
end
|
77
|
+
|
78
|
+
after(:all) do
|
79
|
+
CreateArticles.down
|
80
|
+
end
|
70
81
|
|
71
|
-
it '#primary_key' do
|
72
|
-
@adapter.primary_key('articles').should eq('id')
|
73
82
|
end
|
74
83
|
|
75
|
-
|
76
|
-
|
84
|
+
context 'testing #lowercase_schema_reflection' do
|
85
|
+
before(:each) do
|
86
|
+
CreateShirts.up
|
87
|
+
Shirt.reset_column_information
|
88
|
+
@connection = Shirt.connection
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'should be able to use uppercase attributes' do
|
92
|
+
@connection.lowercase_schema_reflection = false
|
93
|
+
shirt = Shirt.new
|
94
|
+
shirt.COLOR = 'blue'
|
95
|
+
shirt.STATUS_CODE = 'good'
|
96
|
+
shirt.save
|
97
|
+
|
98
|
+
Shirt.where(:COLOR => 'blue', :STATUS_CODE => 'good').count.should eq(1)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should be able to use lowercase attributes when #lowercase_schema_reflection = true' do
|
102
|
+
@connection.lowercase_schema_reflection = true
|
103
|
+
|
104
|
+
shirt = Shirt.new
|
105
|
+
shirt.color = 'red'
|
106
|
+
shirt.status_code = 'very red'
|
107
|
+
shirt.save
|
108
|
+
|
109
|
+
Shirt.where(:color => 'red', :status_code => 'very red').count.should eq(1)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should be able to use lowercase attributes when ActiveRecord::ConnectionAdapters::TeradataAdapter.lowercase_schema_reflection = true' do
|
113
|
+
ActiveRecord::ConnectionAdapters::TeradataAdapter.lowercase_schema_reflection = true
|
114
|
+
|
115
|
+
shirt = Shirt.new
|
116
|
+
shirt.color = 'orange'
|
117
|
+
shirt.status_code = 'very orange'
|
118
|
+
shirt.save
|
119
|
+
|
120
|
+
Shirt.where(:color => 'orange', :status_code => 'very orange').count.should eq(1)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'should be able to use uppercase attributes when ActiveRecord::ConnectionAdapters::TeradataAdapter.lowercase_schema_reflection = false' do
|
124
|
+
ActiveRecord::ConnectionAdapters::TeradataAdapter.lowercase_schema_reflection = false
|
125
|
+
|
126
|
+
shirt = Shirt.new
|
127
|
+
shirt.COLOR = 'yellow'
|
128
|
+
shirt.STATUS_CODE = 'somewhat yellow'
|
129
|
+
shirt.save
|
130
|
+
|
131
|
+
Shirt.where(:COLOR => 'yellow', :STATUS_CODE => 'somewhat yellow').count.should eq(1)
|
132
|
+
end
|
133
|
+
|
134
|
+
after(:each) do
|
135
|
+
CreateShirts.down
|
136
|
+
end
|
77
137
|
end
|
78
138
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateShirts < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table 'SHIRTS' do |t|
|
4
|
+
t.string 'COLOR', :null => false
|
5
|
+
t.string 'STATUS_CODE', :null => false
|
6
|
+
t.timestamps
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
drop_table 'SHIRTS'
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class Shirt < ActiveRecord::Base
|
16
|
+
self.table_name = 'SHIRTS'
|
17
|
+
end
|
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.
|
4
|
+
version: 0.4.2
|
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-05
|
12
|
+
date: 2013-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -119,6 +119,7 @@ files:
|
|
119
119
|
- spec/connection_spec.rb
|
120
120
|
- spec/models/active_record_models.rb
|
121
121
|
- spec/models/active_record_schema.rb
|
122
|
+
- spec/models/lowercase_model.rb
|
122
123
|
- spec/models/purchase_orders.rb
|
123
124
|
- spec/models/simple_article.rb
|
124
125
|
- spec/simple_spec.rb
|
@@ -154,6 +155,7 @@ test_files:
|
|
154
155
|
- spec/connection_spec.rb
|
155
156
|
- spec/models/active_record_models.rb
|
156
157
|
- spec/models/active_record_schema.rb
|
158
|
+
- spec/models/lowercase_model.rb
|
157
159
|
- spec/models/purchase_orders.rb
|
158
160
|
- spec/models/simple_article.rb
|
159
161
|
- spec/simple_spec.rb
|