teradata-cli 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +20 -0
- data/COPYING +515 -0
- data/Gemfile +4 -0
- data/README.md +47 -0
- data/Rakefile +1 -0
- data/examples/query.rb +38 -0
- data/examples/show-queryband.rb +26 -0
- data/examples/tu/excel/excel.rb +86 -0
- data/examples/tu/excel/fill.rb +94 -0
- data/examples/tu/excel/template.xls +0 -0
- data/examples/tu/tusample1.rb +6 -0
- data/examples/tu/tusample2.rb +7 -0
- data/examples/tu/web/bitdao.rb +197 -0
- data/examples/tu/web/bitdao/teradata.rb +23 -0
- data/examples/tu/web/bitweb.rb +575 -0
- data/examples/tu/web/messages +0 -0
- data/examples/tu/web/server.rb +94 -0
- data/examples/tu/web/tdwalker.rb +42 -0
- data/examples/tu/web/template/database/show +56 -0
- data/examples/tu/web/template/footer +2 -0
- data/examples/tu/web/template/header +7 -0
- data/examples/update.rb +31 -0
- data/ext/teradata/cli/cli.c +363 -0
- data/ext/teradata/cli/extconf.rb +20 -0
- data/lib/teradata.rb +14 -0
- data/lib/teradata/cli.rb +4 -0
- data/lib/teradata/cli/version.rb +5 -0
- data/lib/teradata/connection.rb +1125 -0
- data/lib/teradata/dbobject.rb +453 -0
- data/lib/teradata/exception.rb +15 -0
- data/lib/teradata/utils.rb +184 -0
- data/teradata-cli.gemspec +24 -0
- data/test/all +7 -0
- data/test/rubyclitestutils.rb +99 -0
- data/test/test_connection.rb +298 -0
- data/test/test_dbobject.rb +153 -0
- data/test/test_record.rb +210 -0
- metadata +115 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
#
|
2
|
+
# $Id: exception.rb 7 2010-03-04 16:54:09Z tdaoki $
|
3
|
+
#
|
4
|
+
# Copyright (C) 2009,2010 Teradata Japan, LTD.
|
5
|
+
#
|
6
|
+
# This program is free software.
|
7
|
+
# You can distribute/modify this program under the terms of
|
8
|
+
# the GNU LGPL2, Lesser General Public License version 2.
|
9
|
+
#
|
10
|
+
|
11
|
+
module Teradata
|
12
|
+
|
13
|
+
class Error < StandardError; end
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,184 @@
|
|
1
|
+
#
|
2
|
+
# $Id: utils.rb 7 2010-03-04 16:54:09Z tdaoki $
|
3
|
+
#
|
4
|
+
# Copyright (C) 2009,2010 Teradata Japan, LTD.
|
5
|
+
#
|
6
|
+
# This program is free software.
|
7
|
+
# You can distribute/modify this program under the terms of
|
8
|
+
# the GNU LGPL2, Lesser General Public License version 2.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'teradata/exception'
|
12
|
+
|
13
|
+
module Teradata
|
14
|
+
|
15
|
+
class BadLogonString < Error; end
|
16
|
+
|
17
|
+
class LogonString
|
18
|
+
def LogonString.intern(arg)
|
19
|
+
arg.kind_of?(LogonString) ? arg : LogonString.parse(arg.to_s)
|
20
|
+
end
|
21
|
+
|
22
|
+
def LogonString.parse(str)
|
23
|
+
m = %r<\A(?:([^/\s]+)/)?(\w+),(\w+)(?:,('.*'))?\z>.match(str) or
|
24
|
+
raise BadLogonString, "bad logon string: #{str.inspect}"
|
25
|
+
new(* m.captures)
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(tdpid, user, password, account = nil)
|
29
|
+
@tdpid = tdpid
|
30
|
+
@user = user
|
31
|
+
@password = password
|
32
|
+
@account = account
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_reader :tdpid
|
36
|
+
attr_reader :user
|
37
|
+
attr_reader :password
|
38
|
+
attr_reader :account
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
"#{@tdpid ? @tdpid + '/' : ''}#{@user},#{@password}#{@account ? ',' + @account : ''}"
|
42
|
+
end
|
43
|
+
|
44
|
+
def safe_string
|
45
|
+
"#{@tdpid ? @tdpid + '/' : ''}#{@user},****#{@account ? ',' + @account : ''}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def inspect
|
49
|
+
"\#<#{self.class} #{to_s}>"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class SessionCharset
|
54
|
+
def SessionCharset.intern(arg)
|
55
|
+
arg.kind_of?(SessionCharset) ? arg : SessionCharset.new(arg.to_s)
|
56
|
+
end
|
57
|
+
|
58
|
+
def initialize(name)
|
59
|
+
@name = name
|
60
|
+
end
|
61
|
+
|
62
|
+
attr_reader :name
|
63
|
+
alias to_s name
|
64
|
+
|
65
|
+
if defined?(::Encoding) # M17N
|
66
|
+
def encoding
|
67
|
+
case @name
|
68
|
+
when /UTF8/i then Encoding::UTF_8
|
69
|
+
when /KANJISJIS_0S/i then Encoding::Windows_31J
|
70
|
+
when /KANJIEUC_0U/i then Encoding::EUC_JP
|
71
|
+
when /ASCII/i then Encoding::US_ASCII
|
72
|
+
else
|
73
|
+
raise ArgumentError, "could not convert session charset to encoding name: #{sc.inspect}"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
else
|
77
|
+
def encoding
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
module MetadataUtils
|
84
|
+
def adjust_list_size(list, size)
|
85
|
+
if list.size > size
|
86
|
+
list[0...size]
|
87
|
+
else
|
88
|
+
list.push nil while list.size < size
|
89
|
+
list
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
SESSION_ATTRIBUTES = [
|
95
|
+
:user_name,
|
96
|
+
:account_name,
|
97
|
+
:logon_date,
|
98
|
+
:logon_time,
|
99
|
+
:current_database,
|
100
|
+
:collation,
|
101
|
+
:character_set,
|
102
|
+
:transaction_semantics,
|
103
|
+
:current_dateform,
|
104
|
+
:timezone,
|
105
|
+
:default_character_type,
|
106
|
+
:export_latin,
|
107
|
+
:export_unicode,
|
108
|
+
:export_unicode_adjust,
|
109
|
+
:export_kanjisjis,
|
110
|
+
:export_graphic,
|
111
|
+
:default_date_format,
|
112
|
+
:radix_separator,
|
113
|
+
:group_separator,
|
114
|
+
:grouping_rule,
|
115
|
+
:currency_radix_separator,
|
116
|
+
:currency_graphic_rule,
|
117
|
+
:currency_grouping_rule,
|
118
|
+
:currency_name,
|
119
|
+
:currency,
|
120
|
+
:iso_currency,
|
121
|
+
:dual_currency_name,
|
122
|
+
:dual_currency,
|
123
|
+
:dual_iso_currency,
|
124
|
+
:default_byteint_format,
|
125
|
+
:default_integer_format,
|
126
|
+
:default_smallint_format,
|
127
|
+
:default_numeric_format,
|
128
|
+
:default_real_format,
|
129
|
+
:default_time_format,
|
130
|
+
:default_timestamp_format,
|
131
|
+
:current_role,
|
132
|
+
:logon_account,
|
133
|
+
:profile,
|
134
|
+
:ldap,
|
135
|
+
:audit_trail_id,
|
136
|
+
:current_isolation_level,
|
137
|
+
:default_bigint_format,
|
138
|
+
:query_band
|
139
|
+
]
|
140
|
+
|
141
|
+
SessionInfo = Struct.new(*SESSION_ATTRIBUTES)
|
142
|
+
|
143
|
+
class SessionInfo # reopen
|
144
|
+
extend MetadataUtils
|
145
|
+
|
146
|
+
def SessionInfo.for_record(rec)
|
147
|
+
new(* adjust_list_size(rec.to_a, SESSION_ATTRIBUTES.size))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
module SQLUtils
|
152
|
+
private
|
153
|
+
|
154
|
+
def sql_int(n)
|
155
|
+
return 'NULL' unless n
|
156
|
+
n
|
157
|
+
end
|
158
|
+
|
159
|
+
alias int sql_int
|
160
|
+
|
161
|
+
def sql_string(str)
|
162
|
+
return 'NULL' unless str
|
163
|
+
"'" + str.gsub(/'/, "''") + "'"
|
164
|
+
end
|
165
|
+
|
166
|
+
alias string sql_string
|
167
|
+
|
168
|
+
def sql_date(d)
|
169
|
+
return 'NULL' unless d
|
170
|
+
"DATE '#{d.strftime('%Y-%m-%d')}'"
|
171
|
+
end
|
172
|
+
|
173
|
+
alias date sql_date
|
174
|
+
|
175
|
+
def sql_timestamp(t)
|
176
|
+
return 'NULL' unless t
|
177
|
+
"TIMESTAMP '#{t.strftime('%Y-%m-%d %H:%M:%S')}'"
|
178
|
+
end
|
179
|
+
|
180
|
+
alias timestamp sql_timestamp
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'teradata/cli/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "teradata-cli"
|
8
|
+
spec.version = Teradata::Cli::VERSION
|
9
|
+
spec.authors = ["Giuseppe Privitera"]
|
10
|
+
spec.email = ["priviterag@gmail.com"]
|
11
|
+
spec.description = %q{ruby extension for Teradata Cliv2}
|
12
|
+
spec.summary = %q{ruby extension for Teradata Cliv2}
|
13
|
+
spec.homepage = "https://github.com/priviterag/teradata-cli"
|
14
|
+
spec.license = "LGPL2"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.extensions = ["ext/teradata/cli/extconf.rb"]
|
19
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
23
|
+
spec.add_development_dependency "rake"
|
24
|
+
end
|
data/test/all
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
module RubyCLITestUtils
|
2
|
+
|
3
|
+
def logon_string
|
4
|
+
s = ENV['TEST_LOGON_STRING'] or raise ArgumentError, "environ TEST_LOGON_STRING not given"
|
5
|
+
Teradata::LogonString.parse(s)
|
6
|
+
end
|
7
|
+
|
8
|
+
def playpen_string
|
9
|
+
s = ENV['TEST_PLAYPEN_STRING']
|
10
|
+
s == '' ? nil : "#{s}"
|
11
|
+
end
|
12
|
+
|
13
|
+
def env_string
|
14
|
+
s = ENV['TEST_ENV_STRING']
|
15
|
+
s == '' ? nil : "#{s}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def get_table_name(name)
|
19
|
+
"#{playpen_string ? playpen_string + '.' : ''}#{env_string ? env_string + '_' : ''}#{name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def connect(*args)
|
23
|
+
options = {}
|
24
|
+
unless args.empty?
|
25
|
+
charset, internal = args
|
26
|
+
options[:session_charset] = charset if charset
|
27
|
+
options[:internal_encoding] = internal if internal
|
28
|
+
end
|
29
|
+
Teradata::Connection.open(logon_string, options) {|conn|
|
30
|
+
begin
|
31
|
+
@conn = conn
|
32
|
+
yield conn
|
33
|
+
ensure
|
34
|
+
@conn = nil
|
35
|
+
end
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def using_test_table(name = "#{get_table_name('t')}", conn = @conn, &block)
|
40
|
+
unless conn
|
41
|
+
connect {|_conn| using_test_table(name, _conn, &block) }
|
42
|
+
return
|
43
|
+
end
|
44
|
+
using_table(name, 'x INTEGER, y INTEGER', conn) do |n|
|
45
|
+
%w(1,2 3,4 5,6).each do |values|
|
46
|
+
insert n, values, conn
|
47
|
+
end
|
48
|
+
yield n
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def using_table(name, fields, conn = @conn, &block)
|
53
|
+
unless conn
|
54
|
+
connect {|_conn| using_table(name, fields, _conn, &block) }
|
55
|
+
return
|
56
|
+
end
|
57
|
+
drop_table_force name, conn
|
58
|
+
conn.execute_update "CREATE TABLE #{name} (#{fields});"
|
59
|
+
begin
|
60
|
+
yield name
|
61
|
+
ensure
|
62
|
+
drop_table_force name, conn
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def create_table(name, fields, conn = @conn)
|
67
|
+
conn.execute_update "CREATE TABLE #{name} (#{fields});"
|
68
|
+
end
|
69
|
+
|
70
|
+
ERR_OBJECT_NOT_EXIST = 3807
|
71
|
+
ERR_INDEX_NOT_EXIST = 3526
|
72
|
+
|
73
|
+
def drop_table_force(name, conn = @conn)
|
74
|
+
drop_table name, conn
|
75
|
+
rescue Teradata::SQLError => err
|
76
|
+
raise err unless err.code == ERR_OBJECT_NOT_EXIST
|
77
|
+
end
|
78
|
+
|
79
|
+
def drop_table(name, conn = @conn)
|
80
|
+
drop 'TABLE', name, conn
|
81
|
+
end
|
82
|
+
|
83
|
+
def drop(type, name, conn = @conn)
|
84
|
+
conn.execute_update "DROP #{type} #{name};"
|
85
|
+
end
|
86
|
+
|
87
|
+
def delete(table, conn = @conn)
|
88
|
+
conn.execute_update "DELETE FROM #{table};"
|
89
|
+
end
|
90
|
+
|
91
|
+
def insert(table, values, conn = @conn)
|
92
|
+
conn.execute_update "INSERT INTO #{table} (#{values});"
|
93
|
+
end
|
94
|
+
|
95
|
+
def select(table, conn = @conn)
|
96
|
+
conn.entries "SELECT * FROM #{table} ORDER BY 1;"
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
@@ -0,0 +1,298 @@
|
|
1
|
+
require 'teradata'
|
2
|
+
require 'test/unit'
|
3
|
+
libdir = File.dirname(__FILE__)
|
4
|
+
$LOAD_PATH.unshift libdir unless $LOAD_PATH.include?(libdir)
|
5
|
+
require 'rubyclitestutils'
|
6
|
+
|
7
|
+
class Test_Connection < Test::Unit::TestCase
|
8
|
+
|
9
|
+
include RubyCLITestUtils
|
10
|
+
|
11
|
+
def test_s_open
|
12
|
+
begin
|
13
|
+
conn = Teradata::Connection.open(logon_string)
|
14
|
+
assert_instance_of Teradata::Connection, conn
|
15
|
+
assert_equal false, conn.closed?
|
16
|
+
ensure
|
17
|
+
begin
|
18
|
+
conn.close
|
19
|
+
rescue
|
20
|
+
end
|
21
|
+
assert_equal true, conn.closed?
|
22
|
+
end
|
23
|
+
|
24
|
+
Teradata::Connection.open(logon_string) {|c| assert_instance_of(Teradata::Connection, c); assert_equal(false, c.closed?)}
|
25
|
+
assert_equal true, conn.closed?
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_execute_update
|
29
|
+
connect {
|
30
|
+
drop_table_force "#{get_table_name('t')}"
|
31
|
+
x = @conn.execute_update("CREATE TABLE #{get_table_name('t')} (x INTEGER);")
|
32
|
+
assert_instance_of Teradata::ResultSet, x
|
33
|
+
assert_equal true, x.closed?
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_txn
|
38
|
+
using_table("#{get_table_name('t')}", "x INTEGER, y INTEGER") {|name|
|
39
|
+
@conn.execute_update "BEGIN TRANSACTION;"
|
40
|
+
@conn.execute_update "INSERT INTO #{name} (x,y) VALUES (1,2);"
|
41
|
+
@conn.execute_update "INSERT INTO #{name} (x,y) VALUES (3,4);"
|
42
|
+
@conn.execute_update "END TRANSACTION;"
|
43
|
+
recs = @conn.entries("SELECT * FROM #{name} ORDER BY 1;")
|
44
|
+
assert_equal 2, recs.size
|
45
|
+
|
46
|
+
begin
|
47
|
+
@conn.execute_update "BEGIN TRANSACTION;"
|
48
|
+
@conn.execute_update "DELETE FROM #{name};"
|
49
|
+
@conn.execute_update "ABORT;"
|
50
|
+
rescue Teradata::UserAbort
|
51
|
+
end
|
52
|
+
recs = @conn.entries("SELECT * FROM #{name} ORDER BY 1;")
|
53
|
+
assert_equal 2, recs.size
|
54
|
+
assert_equal 1, recs[0][:x]
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_execute_query
|
59
|
+
using_test_table {|name|
|
60
|
+
_test_single_rs name, @conn
|
61
|
+
_test_single_rs2 name, @conn
|
62
|
+
_test_multiple_rs name, @conn
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def _test_single_rs(name, conn)
|
67
|
+
buf = []
|
68
|
+
conn.execute_query("SELECT * FROM #{name} ORDER BY 1") {|rs|
|
69
|
+
assert_instance_of Teradata::ResultSet, rs
|
70
|
+
rs.each do |rec|
|
71
|
+
buf.push rec
|
72
|
+
end
|
73
|
+
}
|
74
|
+
assert_equal 3, buf.size
|
75
|
+
assert_instance_of Teradata::Record, buf[0]
|
76
|
+
assert_equal 1, buf[0][:x]
|
77
|
+
assert_equal 2, buf[0][:y]
|
78
|
+
assert_instance_of Teradata::Record, buf[1]
|
79
|
+
assert_equal 3, buf[1][:x]
|
80
|
+
assert_equal 4, buf[1][:y]
|
81
|
+
assert_instance_of Teradata::Record, buf[2]
|
82
|
+
assert_equal 5, buf[2][:x]
|
83
|
+
assert_equal 6, buf[2][:y]
|
84
|
+
end
|
85
|
+
|
86
|
+
def _test_single_rs2(name, conn)
|
87
|
+
buf = []
|
88
|
+
num_rs = 0
|
89
|
+
conn.execute_query("SELECT * FROM #{name} ORDER BY 1") {|sets|
|
90
|
+
assert_instance_of Teradata::ResultSet, sets
|
91
|
+
sets.each_result_set do |rs|
|
92
|
+
num_rs += 1
|
93
|
+
assert_instance_of Teradata::ResultSet, rs
|
94
|
+
rs.each do |rec|
|
95
|
+
buf.push rec
|
96
|
+
end
|
97
|
+
end
|
98
|
+
}
|
99
|
+
assert_equal 1, num_rs
|
100
|
+
assert_equal 3, buf.size
|
101
|
+
buf.each do |r|
|
102
|
+
assert_instance_of Teradata::Record, r
|
103
|
+
end
|
104
|
+
assert_equal [1,2], [buf[0][:x], buf[0][:y]]
|
105
|
+
assert_equal [3,4], [buf[1][:x], buf[1][:y]]
|
106
|
+
assert_equal [5,6], [buf[2][:x], buf[2][:y]]
|
107
|
+
end
|
108
|
+
|
109
|
+
def _test_multiple_rs(name, conn)
|
110
|
+
buf = []
|
111
|
+
num_rs = 0
|
112
|
+
conn.execute_query(
|
113
|
+
"SELECT * FROM #{name} ORDER BY 1;
|
114
|
+
SELECT * FROM #{name} ORDER BY 1 DESC;") {|sets|
|
115
|
+
assert_instance_of Teradata::ResultSet, sets
|
116
|
+
sets.each_result_set do |rs|
|
117
|
+
num_rs += 1
|
118
|
+
assert_instance_of Teradata::ResultSet, rs
|
119
|
+
rs.each do |rec|
|
120
|
+
buf.push rec
|
121
|
+
end
|
122
|
+
end
|
123
|
+
}
|
124
|
+
assert_equal 2, num_rs
|
125
|
+
assert_equal 6, buf.size
|
126
|
+
buf.each do |r|
|
127
|
+
assert_instance_of Teradata::Record, r
|
128
|
+
end
|
129
|
+
assert_equal [1,2], [buf[0][:x], buf[0][:y]]
|
130
|
+
assert_equal [3,4], [buf[1][:x], buf[1][:y]]
|
131
|
+
assert_equal [5,6], [buf[2][:x], buf[2][:y]]
|
132
|
+
assert_equal [5,6], [buf[3][:x], buf[3][:y]]
|
133
|
+
assert_equal [3,4], [buf[4][:x], buf[4][:y]]
|
134
|
+
assert_equal [1,2], [buf[5][:x], buf[5][:y]]
|
135
|
+
end
|
136
|
+
|
137
|
+
def test_execute_query_without_block
|
138
|
+
using_test_table {|name|
|
139
|
+
rs = @conn.execute_query("SELECT * FROM #{get_table_name('t')} ORDER BY 1;")
|
140
|
+
|
141
|
+
recs = []
|
142
|
+
rs.each do |rec|
|
143
|
+
recs.push rec
|
144
|
+
end
|
145
|
+
assert_equal 3, recs.size
|
146
|
+
assert_equal 1, recs[0][:x]
|
147
|
+
assert_equal 6, recs[2][:y]
|
148
|
+
|
149
|
+
recs = rs.entries
|
150
|
+
assert_equal 3, recs.size
|
151
|
+
assert_equal 1, recs[0][:x]
|
152
|
+
assert_equal 6, recs[2][:y]
|
153
|
+
}
|
154
|
+
end
|
155
|
+
|
156
|
+
def test_entries
|
157
|
+
using_test_table {|name|
|
158
|
+
recs = @conn.entries("SELECT * FROM #{name} ORDER BY 1;")
|
159
|
+
assert_equal 3, recs.size
|
160
|
+
assert_equal 1, recs[0][:x]
|
161
|
+
assert_equal 6, recs[2][:y]
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
# Teradata hates "\n", check it.
|
166
|
+
def test_line_terms
|
167
|
+
using_test_table {|name|
|
168
|
+
recs = @conn.entries("SELECT *\nFROM #{name} \n ORDER BY 1;")
|
169
|
+
assert_equal 3, recs.size
|
170
|
+
|
171
|
+
assert_nothing_thrown {
|
172
|
+
@conn.execute_update "INSERT INTO #{name}\n(x,y)\nVALUES \n (7,8);"
|
173
|
+
}
|
174
|
+
recs = @conn.entries("SELECT *\nFROM #{name} \n ORDER BY 1;")
|
175
|
+
assert_equal 4, recs.size
|
176
|
+
}
|
177
|
+
end
|
178
|
+
|
179
|
+
# connection/request intersection test
|
180
|
+
def test_duplicated_connections
|
181
|
+
assert_nothing_thrown {
|
182
|
+
connect {|c1|
|
183
|
+
connect {|c2|
|
184
|
+
drop_table_force "#{get_table_name('t')}", c1
|
185
|
+
c2.execute_update "CREATE TABLE #{get_table_name('t')} (x INTEGER);"
|
186
|
+
drop_table_force "#{get_table_name('t')}", c1
|
187
|
+
c2.execute_update "CREATE TABLE #{get_table_name('t')} (x INTEGER);"
|
188
|
+
drop_table_force "#{get_table_name('t')}", c1
|
189
|
+
}
|
190
|
+
}
|
191
|
+
}
|
192
|
+
end
|
193
|
+
|
194
|
+
def test_tables
|
195
|
+
db = playpen_string
|
196
|
+
connect {|conn|
|
197
|
+
# assert_equal [], @conn.tables(db)
|
198
|
+
using_test_table(get_table_name('t1')) {
|
199
|
+
using_test_table(get_table_name('t2')) {
|
200
|
+
list = @conn.tables(db)
|
201
|
+
assert(list.include? Teradata::Table.new(db, 't1'))
|
202
|
+
assert(list.include? Teradata::Table.new(db, 't2'))
|
203
|
+
}}
|
204
|
+
}
|
205
|
+
end
|
206
|
+
|
207
|
+
def test_views
|
208
|
+
db = playpen_string
|
209
|
+
using_test_table do
|
210
|
+
using_view("#{get_table_name('v')}", 'select 1 as i') do
|
211
|
+
assert(@conn.views(db).include? Teradata::View.new(db, 'v'))
|
212
|
+
end
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_objects
|
217
|
+
db = playpen_string
|
218
|
+
connect do
|
219
|
+
# assert_equal [], @conn.objects(db)
|
220
|
+
using_test_table(get_table_name('t')) do
|
221
|
+
using_view("#{get_table_name('v')}", 'select 1 as i') do
|
222
|
+
objects = @conn.objects(db)
|
223
|
+
assert(objects.include? Teradata::Table.new(db, 't'))
|
224
|
+
assert(objects.include? Teradata::View.new(db, 'v'))
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def using_view(name, query, conn = @conn)
|
231
|
+
drop_view_force name, conn
|
232
|
+
begin
|
233
|
+
conn.execute_update "CREATE VIEW #{name} AS #{query}"
|
234
|
+
yield name
|
235
|
+
ensure
|
236
|
+
drop_view_force name, conn
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def drop_view_force(name, conn = @conn)
|
241
|
+
conn.execute_update "DROP VIEW #{name}"
|
242
|
+
rescue Teradata::SQLError
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_info
|
246
|
+
connect {
|
247
|
+
info = @conn.info
|
248
|
+
assert_instance_of Teradata::SessionInfo, info
|
249
|
+
assert_equal logon_string.user.downcase, info.user_name.downcase
|
250
|
+
}
|
251
|
+
end
|
252
|
+
|
253
|
+
def test_column
|
254
|
+
db = playpen_string
|
255
|
+
using_table("#{get_table_name('t')}", "x INTEGER, y INTEGER") do
|
256
|
+
col = @conn.column(Teradata::Table.new(db, 't'), 'x')
|
257
|
+
assert_instance_of Teradata::Column, col
|
258
|
+
assert_equal 'x', col.column_name.strip.downcase
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
def test_transaction
|
263
|
+
connect {|conn|
|
264
|
+
using_test_table("#{get_table_name('t')}") {|table|
|
265
|
+
n_records = count(table, conn)
|
266
|
+
|
267
|
+
# transaction fails #1
|
268
|
+
assert_raise(RuntimeError) {
|
269
|
+
conn.transaction {
|
270
|
+
conn.query "DELETE FROM #{table}"
|
271
|
+
raise RuntimeError, "USER ABORT"
|
272
|
+
}
|
273
|
+
}
|
274
|
+
assert_equal n_records, count(table, conn)
|
275
|
+
|
276
|
+
# transaction fails #2
|
277
|
+
assert_raise(Teradata::UserAbort) {
|
278
|
+
conn.transaction {
|
279
|
+
conn.query "DELETE FROM #{table}"
|
280
|
+
conn.abort
|
281
|
+
}
|
282
|
+
}
|
283
|
+
assert_equal n_records, count(table, conn)
|
284
|
+
|
285
|
+
# transaction success
|
286
|
+
conn.transaction {
|
287
|
+
conn.query "DELETE FROM #{table}"
|
288
|
+
}
|
289
|
+
assert_equal 0, count(table, conn)
|
290
|
+
}
|
291
|
+
}
|
292
|
+
end
|
293
|
+
|
294
|
+
def count(table, conn)
|
295
|
+
conn.entries("SELECT count(*) FROM #{table}").first[0]
|
296
|
+
end
|
297
|
+
|
298
|
+
end
|