Class: TeradataCli::Connection

Inherits:
Object
  • Object
show all
Includes:
SQLUtils
Defined in:
lib/teradata-cli/dbobject.rb,
lib/teradata-cli/connection.rb

Overview

reopen

Defined Under Namespace

Classes: NullLogger, Perms, StringExtractor

Constant Summary collapse

ROOT_DATABASE_NAME =
'DBC'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(logon_string, options = {}) ⇒ Connection

Returns a new instance of Connection.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/teradata-cli/connection.rb', line 49

def initialize(logon_string, options = {})
  session_charset = options[:session_charset] || Connection.default_session_charset
  # FIXME: internal_encoding = options[:internal_encoding] || default_internal_encoding()
  internal_encoding = options[:internal_encoding]
  @logger = options[:logger] || NullLogger.new
  @logon_string = TeradataCli::LogonString.intern(logon_string)
  @session_charset = TeradataCli::SessionCharset.intern(session_charset)
  @external_encoding = @session_charset.encoding
  @internal_encoding = internal_encoding
  ex = StringExtractor.get(@external_encoding, @internal_encoding)
  log { "session charset = #{@session_charset}" }
  log { "external encoding = #{@external_encoding}" }
  log { "internal encoding = #{@internal_encoding}" }
  log { "logon... (#{@logon_string.safe_string})" }
  @cli = CLI.new(logon_string.to_s, @session_charset.name)
  log { "logon succeeded" }
  @cli.string_extractor = ex
  @cli.logger = @logger
  if block_given?
    begin
      yield self
    ensure
      close unless closed?
    end
  end
end

Instance Attribute Details

#external_encodingObject (readonly)

Returns the value of attribute external_encoding.



102
103
104
# File 'lib/teradata-cli/connection.rb', line 102

def external_encoding
  @external_encoding
end

#internal_encodingObject (readonly)

Returns the value of attribute internal_encoding.



103
104
105
# File 'lib/teradata-cli/connection.rb', line 103

def internal_encoding
  @internal_encoding
end

#logon_stringObject (readonly)

Returns the value of attribute logon_string.



101
102
103
# File 'lib/teradata-cli/connection.rb', line 101

def logon_string
  @logon_string
end

Class Method Details

.default_session_charsetObject



45
46
47
# File 'lib/teradata-cli/connection.rb', line 45

def Connection.default_session_charset
  TeradataCli::SessionCharset.new('UTF8')
end

Instance Method Details

#abortObject



224
225
226
# File 'lib/teradata-cli/connection.rb', line 224

def abort
  execute_update "ABORT"
end

#begin_transactionObject



216
217
218
# File 'lib/teradata-cli/connection.rb', line 216

def begin_transaction
  execute_update "BEGIN TRANSACTION"
end

#child_databases(name) ⇒ Object



94
95
96
97
98
99
100
# File 'lib/teradata-cli/dbobject.rb', line 94

def child_databases(name)
  entries(<<-EndSQL).map {|rec| new_database(rec[0].strip.upcase, rec[1].strip) }
    SELECT dbKind, databaseName
    FROM dbc.databases
    WHERE ownerName = #{sql_string name}
  EndSQL
end

#closeObject



247
248
249
250
251
252
# File 'lib/teradata-cli/connection.rb', line 247

def close
  log { "logoff..." }
  debug { "CLI.logoff" }
  @cli.logoff
  log { "logoff succeeded" }
end

#close_requestObject

:nodoc: internal use only



241
242
243
244
245
# File 'lib/teradata-cli/connection.rb', line 241

def close_request
  @cli.skip_current_request
  debug { "CLI.end_request" }
  @cli.end_request
end

#closed?Boolean

Returns:

  • (Boolean)


254
255
256
# File 'lib/teradata-cli/connection.rb', line 254

def closed?
  not @cli.logging_on?
end

#column(obj, name) ⇒ Object



189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/teradata-cli/dbobject.rb', line 189

def column(obj, name)
  recs = entries(<<-EndSQL)
    SELECT * FROM dbc.columns
    WHERE databaseName = #{sql_string obj.database}
            AND tableName = #{sql_string obj.unqualified_name}
            AND columnName = #{sql_string name}
  EndSQL
  unless recs.size == 1
    raise ArgumentError, "could not specify a column: #{obj.name}.#{name}"
  end
  Column.for_record(recs.first)
end

#database(name) ⇒ Object



31
32
33
34
35
# File 'lib/teradata-cli/dbobject.rb', line 31

def database(name)
  kind = database_kind(name) or
      raise ObjectError, "no such database: #{name.inspect}"
  kind.new(name, self)
end

#database_exist?(name) ⇒ Boolean Also known as: database?

Returns:

  • (Boolean)


50
51
52
# File 'lib/teradata-cli/dbobject.rb', line 50

def database_exist?(name)
  database_kind(name) ? true : false
end

#database_kind(name) ⇒ Object



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/teradata-cli/dbobject.rb', line 37

def database_kind(name)
  recs = entries(<<-EndSQL)
    SELECT dbKind
    FROM dbc.databases
    WHERE databaseName = #{sql_string name}
  EndSQL
  return nil if recs.empty?
  if recs.size > 1
    raise "multiple database entries exist in dbc.databases???: #{name.inspect}"
  end
  class_from_kind_char(recs.first[0].strip.upcase)
end

#database_own_perms(name) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/teradata-cli/dbobject.rb', line 114

def database_own_perms(name)
  perms = entries(<<-EndSQL).first
    SELECT
            sum(currentPerm)
            , sum(maxPerm)
            , sum(peakPerm)
    FROM dbc.diskSpace
    WHERE databaseName = #{sql_string name}
  EndSQL
  unless perms
    raise ObjectError, "database does not exist in dbc.diskSpace: #{name.inspect}"
  end
  Perms.new(* perms.to_a.map {|n| n.to_i })
end

#database_owner(name) ⇒ Object

Database owner. Returns nil for root database (DBC).



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/teradata-cli/dbobject.rb', line 75

def database_owner(name)
  return nil if name.downcase == 'dbc'
  owners = entries(<<-EndSQL).map {|rec| [rec[0].strip.upcase, rec[1].strip] }
    SELECT owner.dbKind, self.ownerName
    FROM dbc.databases self INNER JOIN dbc.databases owner
            ON self.ownerName = owner.databaseName
    WHERE self.databaseName = #{sql_string name}
  EndSQL
  if owners.empty?
    raise ObjectError, "database not exist: #{name.inspect}"
  end
  if owners.size > 1
    raise "multiple database entries exist in dbc.databases???: #{name.inspect}"
  end
  kind_char, owner = owners.first
  return nil if owner.downcase == name.downcase
  new_database(kind_char, owner)
end

#database_total_perms(name) ⇒ Object



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/teradata-cli/dbobject.rb', line 129

def database_total_perms(name)
  recs = entries(<<-EndSQL)
    SELECT
            sum(ds.currentPerm)
            , sum(ds.maxPerm)
            , sum(ds.peakPerm)
    FROM
            (
              (SELECT d.databaseName, d.databaseName FROM dbc.databases d)
              UNION
              (SELECT parent, child FROM dbc.children)
            ) as c (parent, child)
            INNER JOIN dbc.diskSpace ds
            ON c.child = ds.databaseName
    WHERE
            c.parent = #{sql_string name}
  EndSQL
  if recs.empty?
    raise ObjectError, "database does not exist in dbc.diskSpace: #{@name.inspect}"
  end
  if recs.size > 1
    raise "multiple database entry exist on dbc.diskSpace???: #{name.inspect}; size=#{recs.size}"
  end
  Perms.new(* recs.first.to_a.map {|n| n.to_i })
end

#drop(obj) ⇒ Object



228
229
230
# File 'lib/teradata-cli/connection.rb', line 228

def drop(obj)
  execute_update "DROP #{obj.type_name} #{obj.name};"
end

#end_transactionObject



220
221
222
# File 'lib/teradata-cli/connection.rb', line 220

def end_transaction
  execute_update "END TRANSACTION"
end

#entries(sql) ⇒ Object



192
193
194
# File 'lib/teradata-cli/connection.rb', line 192

def entries(sql)
  execute_query(sql).entries
end

#execute_query(sql) ⇒ Object Also known as: query



167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/teradata-cli/connection.rb', line 167

def execute_query(sql)
  log { "[SEL] #{sql}" }
  @cli.request canonicalize(sql)
  begin
    rs = @cli.read_result_set
    rs.value
    if block_given?
      yield rs
    else
      rs.fetch_all
    end
  ensure
    close_request
  end
  rs
end

#execute_update(sql) ⇒ Object Also known as: update



153
154
155
156
157
158
159
160
161
162
163
# File 'lib/teradata-cli/connection.rb', line 153

def execute_update(sql)
  log { "[UPD] #{sql}" }
  @cli.request canonicalize(sql)
  begin
    rs = @cli.read_result_set
    rs.value_all
    return rs
  ensure
    close_request
  end
end

#infoObject



232
233
234
235
236
237
238
# File 'lib/teradata-cli/connection.rb', line 232

def info
  recs = entries("HELP SESSION")
  unless recs.size == 1
    raise "HELP SESSION did not return 1 record??? size=#{recs.size}"
  end
  SessionInfo.for_record(recs.first)
end

#inspectObject



105
106
107
# File 'lib/teradata-cli/connection.rb', line 105

def inspect
  "\#<#{self.class} #{@logon_string.safe_string}>"
end

#objects(database) ⇒ Object



183
184
185
186
187
# File 'lib/teradata-cli/dbobject.rb', line 183

def objects(database)
  entries("HELP DATABASE #{database}").map {|rec|
    ::TeradataCli::DBObject.create(rec[1].strip, database, rec[0].strip)
  }
end

#parent_databases(name) ⇒ Object



62
63
64
65
66
67
68
69
70
71
# File 'lib/teradata-cli/dbobject.rb', line 62

def parent_databases(name)
  parents = [Database.new(name, self)]
  while true
    db = database_owner(parents.last.name)
    break unless db
    parents.push db
  end
  parents.shift   # remove myself
  parents
end

#root_databaseObject Also known as: dbc



25
26
27
# File 'lib/teradata-cli/dbobject.rb', line 25

def root_database
  User.new(ROOT_DATABASE_NAME, self)
end

#tables(database) ⇒ Object



155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/teradata-cli/dbobject.rb', line 155

def tables(database)
  recs = entries(<<-EndSQL)
    SELECT trim(tableName)
            , sum(currentPerm)
            , sum(peakPerm)
    FROM dbc.tableSize
    WHERE databaseName = #{sql_string database}
    GROUP BY tableName
  EndSQL
  c = ::TeradataCli::Table
  recs.map {|rec|
    name, curr, peak = *rec.to_a
    c.new(database, name, curr.to_i, peak.to_i)
  }
end

#transactionObject



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/teradata-cli/connection.rb', line 196

def transaction
  aborting = false
  begin_transaction
  begin
    yield
  rescue UserAbort => err
    aborting = true
    raise err
  ensure
    if $@
      begin
        abort unless aborting
      rescue UserAbort   # do not override original exception
      end
    else
      end_transaction
    end
  end
end

#user_exist?(name) ⇒ Boolean Also known as: user?

Returns:

  • (Boolean)


56
57
58
# File 'lib/teradata-cli/dbobject.rb', line 56

def user_exist?(name)
  database_kind(name) == User
end

#views(database) ⇒ Object



171
172
173
# File 'lib/teradata-cli/dbobject.rb', line 171

def views(database)
  fetch_objects(database, ::TeradataCli::View)
end