odbc_adapter 4.2.3 → 5.0.0

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: 46d5813d264be7b03da6f093f5c712270310728d
4
- data.tar.gz: fbd32e5ceb9114068b1bd18bb7439581f59cab3d
3
+ metadata.gz: a82f638f836342da6b1ef70597ad205ad869e796
4
+ data.tar.gz: e2f9e57124fa42ebd816ba4e3446d68c2fc06d74
5
5
  SHA512:
6
- metadata.gz: cf045cc718248f4637b276d532632f5f882e51f57c48f9d9e5cf4b2e3b12bea8825da5ade278560de96d29c160ac1bb8acf6cf2ef18fd8927ddf6f938279c496
7
- data.tar.gz: 057f64fa0873fce5fc2581d1730ab6e538dc2439e2c9b88f635181f8212283dc7e915408f27a440aac8669ea56b1ba858df4a5893f3b88b6c58d7ba4f056d17a
6
+ metadata.gz: c1766ac63ef69f279469a25c47c18495e8e2aac3c9dce4a73c0b2ca73987446fef18fb91492231a8c60dd5b1ca30613744576c6f93ccd6dcb4dc41944bf04fe2
7
+ data.tar.gz: dc416dc3d4d359f7a6e5e5bac66fec0f08b567ffa576bbf56446d51d20dfa85836236a58cfb05811114a1d56f6fcf63ae43528d4eac4f5f697308fffea881e4a
data/Gemfile CHANGED
@@ -2,5 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'activerecord', '4.2.7.1'
5
+ gem 'activerecord', '5.0.1'
6
6
  gem 'pry', '0.10.4'
@@ -83,7 +83,6 @@ module ActiveRecord
83
83
  super(connection, logger)
84
84
  @connection = connection
85
85
  @dbms = dbms
86
- @visitor = self.class::BindSubstitution.new(self)
87
86
  end
88
87
 
89
88
  # Returns the human-readable name of the adapter. Use mixed case - one
@@ -127,10 +126,14 @@ module ActiveRecord
127
126
  @connection.disconnect if @connection.connected?
128
127
  end
129
128
 
129
+ def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, native_type = nil)
130
+ ::ODBCAdapter::Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation, native_type)
131
+ end
132
+
130
133
  protected
131
134
 
132
135
  def initialize_type_map(map)
133
- map.register_type ODBC::SQL_BIT, Type::Boolean.new
136
+ map.register_type 'boolean', Type::Boolean.new
134
137
  map.register_type ODBC::SQL_CHAR, Type::String.new
135
138
  map.register_type ODBC::SQL_LONGVARCHAR, Type::Text.new
136
139
  map.register_type ODBC::SQL_TINYINT, Type::Integer.new(limit: 4)
@@ -149,6 +152,7 @@ module ActiveRecord
149
152
  map.register_type ODBC::SQL_TIMESTAMP, Type::DateTime.new
150
153
  map.register_type ODBC::SQL_GUID, Type::String.new
151
154
 
155
+ alias_type map, ODBC::SQL_BIT, 'boolean'
152
156
  alias_type map, ODBC::SQL_VARCHAR, ODBC::SQL_CHAR
153
157
  alias_type map, ODBC::SQL_WCHAR, ODBC::SQL_CHAR
154
158
  alias_type map, ODBC::SQL_WVARCHAR, ODBC::SQL_CHAR
@@ -169,10 +173,6 @@ module ActiveRecord
169
173
  end
170
174
  end
171
175
 
172
- def new_column(name, default, cast_type, sql_type = nil, null = true, native_type = nil, scale = nil, limit = nil)
173
- ::ODBCAdapter::Column.new(name, default, cast_type, sql_type, null, native_type, scale, limit)
174
- end
175
-
176
176
  private
177
177
 
178
178
  def alias_type(map, new_type, old_type)
@@ -3,11 +3,25 @@ module ODBCAdapter
3
3
  # Overrides specific to MySQL. Mostly taken from
4
4
  # ActiveRecord::ConnectionAdapters::MySQLAdapter
5
5
  class MySQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter
6
+ PRIMARY_KEY = 'INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'.freeze
7
+
6
8
  class BindSubstitution < Arel::Visitors::MySQL
7
9
  include Arel::Visitors::BindVisitor
8
10
  end
9
11
 
10
- PRIMARY_KEY = 'INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'.freeze
12
+ def arel_visitor
13
+ BindSubstitution.new(self)
14
+ end
15
+
16
+ # Explicitly turning off prepared statements in the MySQL adapter because
17
+ # of a weird bug with SQLDescribeParam returning a string type for LIMIT
18
+ # parameters. This is blocking them from running with an error:
19
+ #
20
+ # You have an error in your SQL syntax; ...
21
+ # ... right syntax to use near ''1'' at line 1: ...
22
+ def prepared_statements
23
+ false
24
+ end
11
25
 
12
26
  def truncate(table_name, name = nil)
13
27
  execute("TRUNCATE TABLE #{quote_table_name(table_name)}", name)
@@ -3,10 +3,6 @@ module ODBCAdapter
3
3
  # Overrides specific to PostgreSQL. Mostly taken from
4
4
  # ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
5
5
  class PostgreSQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter
6
- class BindSubstitution < Arel::Visitors::PostgreSQL
7
- include Arel::Visitors::BindVisitor
8
- end
9
-
10
6
  BOOLEAN_TYPE = 'bool'.freeze
11
7
  PRIMARY_KEY = 'SERIAL PRIMARY KEY'.freeze
12
8
 
@@ -15,6 +11,10 @@ module ODBCAdapter
15
11
  @native_database_types ||= super.merge(boolean: { name: 'bool' })
16
12
  end
17
13
 
14
+ def arel_visitor
15
+ Arel::Visitors::PostgreSQL.new(self)
16
+ end
17
+
18
18
  # Filter for ODBCAdapter#tables
19
19
  # Omits table from #tables if table_filter returns true
20
20
  def table_filter(schema_name, table_type)
@@ -2,24 +2,9 @@ module ODBCAdapter
2
2
  class Column < ActiveRecord::ConnectionAdapters::Column
3
3
  attr_reader :native_type
4
4
 
5
- def initialize(name, default, cast_type, sql_type = nil, null = nil, native_type = nil, scale = nil, limit = nil)
6
- @name = name
7
- @default = default
8
- @cast_type = cast_type
9
- @sql_type = sql_type
10
- @null = null
5
+ def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, native_type = nil, default_function = nil, collation = nil)
6
+ super(name, default, sql_type_metadata, null, table_name, default_function, collation)
11
7
  @native_type = native_type
12
-
13
- if [ODBC::SQL_DECIMAL, ODBC::SQL_NUMERIC].include?(sql_type)
14
- set_numeric_params(scale, limit)
15
- end
16
- end
17
-
18
- private
19
-
20
- def set_numeric_params(scale, limit)
21
- @cast_type.instance_variable_set(:@scale, scale || 0)
22
- @cast_type.instance_variable_set(:@precision, limit)
23
8
  end
24
9
  end
25
10
  end
@@ -5,32 +5,30 @@ module ODBCAdapter
5
5
  SQL_NULLABLE = 1
6
6
  SQL_NULLABLE_UNKNOWN = 2
7
7
 
8
- # Returns an array of arrays containing the field values.
9
- # Order is the same as that returned by #columns.
10
- def select_rows(sql, name = nil)
11
- log(sql, name) do
12
- stmt = @connection.run(sql)
13
- result = stmt.fetch_all
14
- stmt.drop
15
- result
16
- end
17
- end
18
-
19
8
  # Executes the SQL statement in the context of this connection.
20
9
  # Returns the number of rows affected.
21
- # TODO: Currently ignoring binds until we can get prepared statements working.
22
10
  def execute(sql, name = nil, binds = [])
23
11
  log(sql, name) do
24
- @connection.do(sql)
12
+ if prepared_statements
13
+ @connection.do(sql, *prepared_binds(binds))
14
+ else
15
+ @connection.do(sql)
16
+ end
25
17
  end
26
18
  end
27
19
 
28
20
  # Executes +sql+ statement in the context of this connection using
29
21
  # +binds+ as the bind substitutes. +name+ is logged along with
30
22
  # the executed +sql+ statement.
31
- def exec_query(sql, name = 'SQL', binds = [])
23
+ def exec_query(sql, name = 'SQL', binds = [], prepare: false)
32
24
  log(sql, name) do
33
- stmt = @connection.run(sql)
25
+ stmt =
26
+ if prepared_statements
27
+ @connection.run(sql, *prepared_binds(binds))
28
+ else
29
+ @connection.run(sql)
30
+ end
31
+
34
32
  columns = stmt.columns
35
33
  values = stmt.to_a
36
34
  stmt.drop
@@ -81,33 +79,12 @@ module ODBCAdapter
81
79
  "#{table}_seq"
82
80
  end
83
81
 
84
- protected
85
-
86
- # Returns the last auto-generated ID from the affected table.
87
- def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
88
- begin
89
- stmt = log(sql, name) { @connection.run(sql) }
90
- table = extract_table_ref_from_insert_sql(sql)
91
-
92
- seq = sequence_name || default_sequence_name(table, pk)
93
- res = id_value || last_insert_id(table, seq, stmt)
94
- ensure
95
- stmt.drop unless stmt.nil?
96
- end
97
- res
98
- end
99
-
100
82
  private
101
83
 
102
84
  def dbms_type_cast(columns, values)
103
85
  values
104
86
  end
105
87
 
106
- def extract_table_ref_from_insert_sql(sql)
107
- sql[/into\s+([^\(]*).*values\s*\(/i]
108
- $1.strip if $1
109
- end
110
-
111
88
  # Assume received identifier is in DBMS's data dictionary case.
112
89
  def format_case(identifier)
113
90
  case dbms.field_for(ODBC::SQL_IDENTIFIER_CASE)
@@ -155,5 +132,9 @@ module ODBCAdapter
155
132
  # So force nullability of 'id' columns
156
133
  col_name == 'id' ? false : result
157
134
  end
135
+
136
+ def prepared_binds(binds)
137
+ prepare_binds_for_database(binds).map { |bind| _type_cast(bind) }
138
+ end
158
139
  end
159
140
  end
@@ -7,16 +7,6 @@ module ODBCAdapter
7
7
  @native_database_types ||= ColumnMetadata.new(self).native_database_types
8
8
  end
9
9
 
10
- # Ensure it's shorter than the maximum identifier length for the current dbms
11
- def index_name(table_name, options)
12
- maximum = dbms.field_for(ODBC::SQL_MAX_IDENTIFIER_LEN) || 255
13
- super(table_name, options)[0...maximum]
14
- end
15
-
16
- def current_database
17
- dbms.field_for(ODBC::SQL_DATABASE_NAME).strip
18
- end
19
-
20
10
  # Returns an array of table names, for database tables visible on the
21
11
  # current connection.
22
12
  def tables(_name = nil)
@@ -31,31 +21,9 @@ module ODBCAdapter
31
21
  end
32
22
  end
33
23
 
34
- # Returns an array of Column objects for the table specified by +table_name+.
35
- def columns(table_name, name = nil)
36
- stmt = @connection.columns(native_case(table_name.to_s))
37
- result = stmt.fetch_all || []
38
- stmt.drop
39
-
40
- result.each_with_object([]) do |col, cols|
41
- col_name = col[3] # SQLColumns: COLUMN_NAME
42
- col_default = col[12] # SQLColumns: COLUMN_DEF
43
- col_sql_type = col[4] # SQLColumns: DATA_TYPE
44
- col_native_type = col[5] # SQLColumns: TYPE_NAME
45
- col_limit = col[6] # SQLColumns: COLUMN_SIZE
46
- col_scale = col[8] # SQLColumns: DECIMAL_DIGITS
47
-
48
- # SQLColumns: IS_NULLABLE, SQLColumns: NULLABLE
49
- col_nullable = nullability(col_name, col[17], col[10])
50
-
51
- cast_type =
52
- if col_native_type == self.class::BOOLEAN_TYPE
53
- ActiveRecord::Type::Boolean.new
54
- else
55
- lookup_cast_type(col_sql_type)
56
- end
57
- cols << new_column(format_case(col_name), col_default, cast_type, col_sql_type, col_nullable, col_native_type, col_scale, col_limit)
58
- end
24
+ # Returns an array of view names defined in the database.
25
+ def views
26
+ []
59
27
  end
60
28
 
61
29
  # Returns an array of indexes for the given table.
@@ -88,6 +56,37 @@ module ODBCAdapter
88
56
  end
89
57
  end
90
58
 
59
+ # Returns an array of Column objects for the table specified by
60
+ # +table_name+.
61
+ def columns(table_name, name = nil)
62
+ stmt = @connection.columns(native_case(table_name.to_s))
63
+ result = stmt.fetch_all || []
64
+ stmt.drop
65
+
66
+ result.each_with_object([]) do |col, cols|
67
+ col_name = col[3] # SQLColumns: COLUMN_NAME
68
+ col_default = col[12] # SQLColumns: COLUMN_DEF
69
+ col_sql_type = col[4] # SQLColumns: DATA_TYPE
70
+ col_native_type = col[5] # SQLColumns: TYPE_NAME
71
+ col_limit = col[6] # SQLColumns: COLUMN_SIZE
72
+ col_scale = col[8] # SQLColumns: DECIMAL_DIGITS
73
+
74
+ # SQLColumns: IS_NULLABLE, SQLColumns: NULLABLE
75
+ col_nullable = nullability(col_name, col[17], col[10])
76
+
77
+ args = { sql_type: col_sql_type, type: col_sql_type, limit: col_limit }
78
+ args[:sql_type] = 'boolean' if col_native_type == self.class::BOOLEAN_TYPE
79
+
80
+ if [ODBC::SQL_DECIMAL, ODBC::SQL_NUMERIC].include?(col_sql_type)
81
+ args[:scale] = col_scale || 0
82
+ args[:precision] = col_limit
83
+ end
84
+ sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(**args)
85
+
86
+ cols << new_column(format_case(col_name), col_default, sql_type_metadata, col_nullable, table_name, col_native_type)
87
+ end
88
+ end
89
+
91
90
  # Returns just a table's primary key
92
91
  def primary_key(table_name)
93
92
  stmt = @connection.primary_keys(native_case(table_name.to_s))
@@ -95,5 +94,16 @@ module ODBCAdapter
95
94
  stmt.drop unless stmt.nil?
96
95
  result[0] && result[0][3]
97
96
  end
97
+
98
+ # Ensure it's shorter than the maximum identifier length for the current
99
+ # dbms
100
+ def index_name(table_name, options)
101
+ maximum = dbms.field_for(ODBC::SQL_MAX_IDENTIFIER_LEN) || 255
102
+ super(table_name, options)[0...maximum]
103
+ end
104
+
105
+ def current_database
106
+ dbms.field_for(ODBC::SQL_DATABASE_NAME).strip
107
+ end
98
108
  end
99
109
  end
@@ -1,3 +1,3 @@
1
1
  module ODBCAdapter
2
- VERSION = '4.2.3'
2
+ VERSION = '5.0.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: odbc_adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.2.3
4
+ version: 5.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Localytics
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-26 00:00:00.000000000 Z
11
+ date: 2017-01-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-odbc