teradata-ar 0.0.3 → 0.0.4

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.
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