teradata-ar 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e2782e323965d4d88ac3786289701ae7167d31f2
4
- data.tar.gz: b7ccdf30cfc3f6dad319747313f09763a40e3074
3
+ metadata.gz: 498cdd551375bd432cdf0d6f76c5dbdb3fe8ce1b
4
+ data.tar.gz: 9f092600d613e3d31c3fc9b935e08cde84488d9e
5
5
  SHA512:
6
- metadata.gz: 7517fb456cb70b3f7c01e5e7cf2b3c9a85bc8c4eb2e256b26133674f591b636b12e47b34492eb4407e3cf77d4a5f260ed7aa0bdeed946cdf6bbeec557eaa63dd
7
- data.tar.gz: 534eb4c75cf4ca1f25490683ef7a7cb69f27fd19a65ee0b3fa23eae79ad75a34df62c4d12072a94068b7e8a6296c69ebdb4f2e6b6a14357416f745a9521659ad
6
+ metadata.gz: 125abcaa7940d177e0c8c8a06d92d0dbdb171df1d67fdd9a4a3a46c7972c4cf439f52d017cb8c018a2891c3a527e0f52f71ee55a07d4979fd3a02b049c79639d
7
+ data.tar.gz: 43539430c99e2c2270e21a61c2699b10733ac01baaae1b060e3f39cb6a366102a98d5ce46b546e3a9cf84f885c60f7711670827706ade859cf1dbcff9daf2285
@@ -1,8 +1,20 @@
1
1
  require 'active_record/connection_adapters/abstract_adapter'
2
+ require 'arel/visitors/bind_visitor'
2
3
 
3
4
  #gem 'teradata-cli', :path => '~/projects/teradata-cli'
4
5
  require 'teradata-cli'
5
6
 
7
+ class ActiveRecord::Base
8
+ def self.table_name_prefix
9
+ Rails.configuration.database_configuration[Rails.env]['table_name_prefix']
10
+ end
11
+ end
12
+
13
+ class ActiveRecord::Migration
14
+ def self.check_pending!
15
+ end
16
+ end
17
+
6
18
  module ActiveRecord
7
19
  module ConnectionHandling
8
20
  def teradata_connection(config)
@@ -20,12 +32,30 @@ module ActiveRecord
20
32
  module ConnectionAdapters
21
33
  class TeradataAdapter < AbstractAdapter
22
34
 
35
+ class BindSubstitution < Arel::Visitors::ToSql
36
+ include Arel::Visitors::BindVisitor
37
+
38
+ def visit_Arel_Nodes_Limit o
39
+ end
40
+ def visit_Arel_Nodes_Offset o
41
+ end
42
+
43
+ def visit_Arel_Nodes_Top o
44
+ "TOP #{o.expr}"
45
+ end
46
+
47
+ end
48
+
23
49
  def initialize(logger, logon_string, config)
24
50
  @logon_string = logon_string
25
51
  @charset = config[:charset]
52
+ @database = config[:database]
53
+ @table_name_prefix = config[:table_name_prefix]
26
54
  @config = config
27
55
  connect
28
56
  super @connection, logger
57
+ @visitor = unprepared_visitor
58
+ configure_connection
29
59
  end
30
60
 
31
61
  def adapter_name
@@ -37,10 +67,160 @@ module ActiveRecord
37
67
  end
38
68
  private :connect
39
69
 
70
+ def configure_connection
71
+ execute("DATABASE #{@database}") if @database
72
+ end
73
+ private :configure_connection
74
+
75
+ # CONNECTION MANAGEMENT ====================================
76
+
77
+ def active?
78
+ @connection.execute_query('SELECT 1')
79
+ true
80
+ rescue
81
+ false
82
+ end
83
+
84
+ def reconnect!
85
+ super
86
+ disconnect!
87
+ connect
88
+ configure_connection
89
+ end
90
+ alias :reset! :reconnect!
91
+
92
+ # Disconnects from the database if already connected.
93
+ # Otherwise, this method does nothing.
94
+ def disconnect!
95
+ super
96
+ unless @connection.nil?
97
+ @connection.close
98
+ @connection = nil
99
+ end
100
+ end
101
+
102
+ # DATABASE STATEMENTS ======================================
103
+
40
104
  def tables(name = nil)
41
- # FIXME: fetch metadata from database
42
- ['shohins']
105
+ sql = "SELECT TABLENAME FROM DBC.TABLES "
106
+ clauses = []
107
+ clauses << "DATABASENAME = '#{@database}'" if @database
108
+ clauses << "TABLENAME = '#{name}'" if name
109
+ clauses << "TABLENAME LIKE '#{@table_name_prefix}%'" if @table_name_prefix
110
+ unless clauses.empty?
111
+ sql << " WHERE " + clauses.join(' AND ')
112
+ end
113
+ rs = execute(sql)
114
+ rs.entries.collect {|record| record['TableName'].strip}
43
115
  end
116
+
117
+ # Executes the SQL statement in the context of this connection.
118
+ def execute(sql, name = nil)
119
+ if name == :skip_logging
120
+ @connection.query(sql)
121
+ else
122
+ log(sql, name) { @connection.query(sql) }
123
+ end
124
+ end
125
+
126
+ # Executes +sql+ statement in the context of this connection using
127
+ # +binds+ as the bind substitutes. +name+ is logged along with
128
+ # the executed +sql+ statement.
129
+ def exec_query(sql, name = 'SQL', binds = [])
130
+ result = execute(sql, name)
131
+ if result && result.count > 0
132
+ ActiveRecord::Result.new(result.entries[0].keys, result.entries.collect{|r|r.collect{|v|v}})
133
+ else
134
+ ActiveRecord::Result.new([],[])
135
+ end
136
+ end
137
+
138
+ # Returns an ActiveRecord::Result instance.
139
+ def select(sql, name = nil, binds = [])
140
+ exec_query(sql, name)
141
+ end
142
+
143
+ # Returns an array of arrays containing the field values.
144
+ # Order is the same as that returned by +columns+.
145
+ def select_rows(sql, name = nil)
146
+ result = execute(sql, name)
147
+ if result && result.count > 0
148
+ result.entries.collect{|r|r.collect{|v|v}}
149
+ else
150
+ []
151
+ end
152
+ end
153
+
154
+ def execute_update(sql, name = nil)
155
+ log(sql, name) { @connection.execute_update(sql) }
156
+ end
157
+
158
+ def begin_db_transaction
159
+ execute_update "BEGIN TRANSACTION"
160
+ end
161
+
162
+ def commit_db_transaction
163
+ execute_update "END TRANSACTION"
164
+ end
165
+
166
+ def rollback_db_transaction
167
+ execute_update "ROLLBACK"
168
+ end
169
+
170
+ # Returns an array of +Column+ objects for the table specified by +table_name+.
171
+ def columns(table_name)#:nodoc:
172
+ sql = "SELECT * FROM DBC.COLUMNS WHERE TABLENAME='#{table_name}'"
173
+ sql << " AND DATABASENAME='#{@database}'" if @database
174
+ rs = execute(sql)
175
+ rs.entries.collect do |record|
176
+ new_column(
177
+ record['ColumnName'].strip,
178
+ record['DefaultValue'],
179
+ build_sql_type(record),
180
+ record['Nullable'].strip == "Y"
181
+ )
182
+ end
183
+ end
184
+
185
+ def primary_key(table_name)
186
+ columns(table_name).select{|col| col.primary == true}[0].name rescue 'id'
187
+ end
188
+
189
+ # Overridden by the adapters to instantiate their specific Column type.
190
+ def new_column(field, default, type, null) # :nodoc:
191
+ Column.new(field, default, type, null)
192
+ end
193
+
194
+ # construct the sql type from the teradata column info
195
+ def build_sql_type(column)
196
+ field_type = get_field_type(column['ColumnType'])
197
+ case field_type
198
+ when "varchar"
199
+ "#{field_type}(#{column['ColumnLength']})"
200
+ when "decimal"
201
+ "#{field_type}(#{column['DecimalTotalDigits']},#{column['DecimalFractionalDigits']})"
202
+ else
203
+ field_type
204
+ end
205
+ end
206
+
207
+ def get_field_type(type)
208
+ case type.strip
209
+ when "I", "I1"
210
+ "int"
211
+ when "CV"
212
+ "varchar"
213
+ when "DA"
214
+ "date"
215
+ when "D"
216
+ "decimal"
217
+ when "TS"
218
+ "datetime"
219
+ else
220
+ raise "Column type #{type} not supported"
221
+ end
222
+ end
223
+
44
224
  end
45
225
  end
46
226
  end
@@ -1,5 +1,5 @@
1
1
  module Teradata
2
2
  module Ar
3
- VERSION = "0.0.3"
3
+ VERSION = "0.0.4"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: teradata-ar
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Giuseppe Privitera
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-04 00:00:00.000000000 Z
11
+ date: 2013-10-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler