odbc_adapter 4.2.3 → 5.0.0

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