activerecord-jdbc-adapter 0.9.1 → 0.9.2
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.
- data/History.txt +33 -0
- data/Manifest.txt +17 -0
- data/README.txt +48 -20
- data/Rakefile +2 -169
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +11 -5
- data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +12 -0
- data/lib/jdbc_adapter.rb +1 -1
- data/lib/jdbc_adapter/jdbc.rake +43 -30
- data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
- data/lib/jdbc_adapter/jdbc_db2.rb +2 -2
- data/lib/jdbc_adapter/jdbc_derby.rb +11 -0
- data/lib/jdbc_adapter/jdbc_hsqldb.rb +6 -1
- data/lib/jdbc_adapter/jdbc_mimer.rb +14 -7
- data/lib/jdbc_adapter/jdbc_mssql.rb +18 -2
- data/lib/jdbc_adapter/jdbc_mysql.rb +3 -0
- data/lib/jdbc_adapter/jdbc_oracle.rb +24 -14
- data/lib/jdbc_adapter/jdbc_postgre.rb +38 -18
- data/lib/jdbc_adapter/jdbc_sqlite3.rb +96 -26
- data/lib/jdbc_adapter/missing_functionality_helper.rb +40 -34
- data/lib/jdbc_adapter/rake_tasks.rb +1 -1
- data/lib/jdbc_adapter/tsql_helper.rb +1 -0
- data/lib/jdbc_adapter/version.rb +1 -1
- data/lib/pg.rb +4 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/jdbc.rake +8 -0
- data/rails_generators/templates/jdbc.rb +7 -0
- data/rakelib/compile.rake +23 -0
- data/rakelib/package.rake +85 -0
- data/rakelib/rails.rake +41 -0
- data/rakelib/test.rake +71 -0
- data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +1 -0
- data/src/java/jdbc_adapter/JdbcDerbySpec.java +11 -46
- data/src/java/jdbc_adapter/JdbcMySQLSpec.java +3 -2
- data/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java +71 -0
- data/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +24 -4
- data/src/java/jdbc_adapter/RubyJdbcConnection.java +57 -44
- data/test/abstract_db_create.rb +45 -0
- data/test/db/mysql.rb +2 -2
- data/test/db/postgres.rb +2 -2
- data/test/helper.rb +5 -0
- data/test/jdbc_adapter/jdbc_db2_test.rb +5 -0
- data/test/jdbc_common.rb +2 -0
- data/test/models/entry.rb +3 -0
- data/test/models/validates_uniqueness_of_string.rb +19 -0
- data/test/mysql_db_create_test.rb +25 -0
- data/test/mysql_nonstandard_primary_key_test.rb +42 -0
- data/test/mysql_simple_test.rb +5 -0
- data/test/postgres_db_create_test.rb +21 -0
- data/test/postgres_nonseq_pkey_test.rb +40 -0
- data/test/simple.rb +62 -1
- data/test/sqlite3_simple_test.rb +153 -10
- metadata +26 -5
Binary file
|
@@ -2,7 +2,7 @@ module JdbcSpec
|
|
2
2
|
module DB2
|
3
3
|
def self.adapter_matcher(name, config)
|
4
4
|
if name =~ /db2/i
|
5
|
-
return
|
5
|
+
return config[:url] =~ /^jdbc:derby:net:/ ? ::JdbcSpec::Derby : self
|
6
6
|
end
|
7
7
|
false
|
8
8
|
end
|
@@ -50,7 +50,7 @@ module JdbcSpec
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def modify_types(tp)
|
53
|
-
tp[:primary_key] = 'int generated by default as identity (start with
|
53
|
+
tp[:primary_key] = 'int not null generated by default as identity (start with 1) primary key'
|
54
54
|
tp[:string][:limit] = 255
|
55
55
|
tp[:integer][:limit] = nil
|
56
56
|
tp[:boolean][:limit] = nil
|
@@ -3,6 +3,7 @@ require 'jdbc_adapter/missing_functionality_helper'
|
|
3
3
|
module ::JdbcSpec
|
4
4
|
module ActiveRecordExtensions
|
5
5
|
def derby_connection(config)
|
6
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/derby_adapter"
|
6
7
|
config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
|
7
8
|
config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
|
8
9
|
embedded_driver(config)
|
@@ -400,6 +401,16 @@ module ::JdbcSpec
|
|
400
401
|
'0'
|
401
402
|
end
|
402
403
|
|
404
|
+
def add_limit_offset!(sql, options) #:nodoc:
|
405
|
+
if options[:offset]
|
406
|
+
sql << " OFFSET #{options[:offset]} ROWS"
|
407
|
+
end
|
408
|
+
if options[:limit]
|
409
|
+
#ROWS/ROW and FIRST/NEXT mean the same
|
410
|
+
sql << " FETCH FIRST #{options[:limit]} ROWS ONLY"
|
411
|
+
end
|
412
|
+
end
|
413
|
+
|
403
414
|
private
|
404
415
|
# Derby appears to define schemas using the username
|
405
416
|
def derby_schema
|
@@ -1,12 +1,14 @@
|
|
1
1
|
module ::JdbcSpec
|
2
2
|
module ActiveRecordExtensions
|
3
3
|
def hsqldb_connection(config)
|
4
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/hsqldb_adapter"
|
4
5
|
config[:url] ||= "jdbc:hsqldb:#{config[:database]}"
|
5
6
|
config[:driver] ||= "org.hsqldb.jdbcDriver"
|
6
7
|
embedded_driver(config)
|
7
8
|
end
|
8
9
|
|
9
10
|
def h2_connection(config)
|
11
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/h2_adapter"
|
10
12
|
config[:url] ||= "jdbc:h2:#{config[:database]}"
|
11
13
|
config[:driver] ||= "org.h2.Driver"
|
12
14
|
embedded_driver(config)
|
@@ -82,10 +84,13 @@ module ::JdbcSpec
|
|
82
84
|
"''"
|
83
85
|
elsif column && column.type == :binary
|
84
86
|
"'#{value.unpack("H*")}'"
|
87
|
+
elsif column.respond_to?(:primary) && column.primary
|
88
|
+
value.to_i.to_s
|
85
89
|
else
|
86
90
|
"'#{quote_string(value)}'"
|
87
91
|
end
|
88
|
-
else
|
92
|
+
else
|
93
|
+
super
|
89
94
|
end
|
90
95
|
end
|
91
96
|
|
@@ -73,13 +73,20 @@ module JdbcSpec
|
|
73
73
|
return "X'#{quote_string(value.unpack("C*").collect {|v| v.to_s(16)}.join)}'"
|
74
74
|
end
|
75
75
|
case value
|
76
|
-
when String
|
77
|
-
|
78
|
-
when
|
79
|
-
|
80
|
-
when
|
81
|
-
|
82
|
-
|
76
|
+
when String
|
77
|
+
%Q{'#{quote_string(value)}'}
|
78
|
+
when NilClass
|
79
|
+
'NULL'
|
80
|
+
when TrueClass
|
81
|
+
'1'
|
82
|
+
when FalseClass
|
83
|
+
'0'
|
84
|
+
when Numeric
|
85
|
+
value.to_s
|
86
|
+
when Date, Time
|
87
|
+
%Q{TIMESTAMP '#{value.strftime("%Y-%m-%d %H:%M:%S")}'}
|
88
|
+
else
|
89
|
+
%Q{'#{quote_string(value.to_yaml)}'}
|
83
90
|
end
|
84
91
|
end
|
85
92
|
|
@@ -31,6 +31,10 @@ module ::JdbcSpec
|
|
31
31
|
[/sqlserver|tds/i, lambda {|cfg,col| col.extend(::JdbcSpec::MsSQL::Column)}]
|
32
32
|
end
|
33
33
|
|
34
|
+
def self.jdbc_connection_class
|
35
|
+
::ActiveRecord::ConnectionAdapters::MssqlJdbcConnection
|
36
|
+
end
|
37
|
+
|
34
38
|
module Column
|
35
39
|
attr_accessor :identity, :is_special
|
36
40
|
|
@@ -69,7 +73,7 @@ module ::JdbcSpec
|
|
69
73
|
|
70
74
|
# JRUBY-2011: Match balanced quotes and parenthesis - 'text',('text') or (text)
|
71
75
|
def unquote_string(value)
|
72
|
-
value.sub(/^\((.*)\)$/,'\1').sub(/^'(.*)'$/,'\1')
|
76
|
+
value.to_s.sub(/^\((.*)\)$/,'\1').sub(/^'(.*)'$/,'\1')
|
73
77
|
end
|
74
78
|
|
75
79
|
def unquote(value)
|
@@ -116,7 +120,7 @@ module ::JdbcSpec
|
|
116
120
|
value = column.type == :integer ? value.to_i : value.to_f
|
117
121
|
value.to_s
|
118
122
|
else
|
119
|
-
"'#{quote_string(value)}'" # ' (for ruby-mode)
|
123
|
+
"N'#{quote_string(value)}'" # ' (for ruby-mode)
|
120
124
|
end
|
121
125
|
when TrueClass then '1'
|
122
126
|
when FalseClass then '0'
|
@@ -138,6 +142,14 @@ module ::JdbcSpec
|
|
138
142
|
"[#{name}]"
|
139
143
|
end
|
140
144
|
|
145
|
+
def quoted_true
|
146
|
+
quote true
|
147
|
+
end
|
148
|
+
|
149
|
+
def quoted_false
|
150
|
+
quote false
|
151
|
+
end
|
152
|
+
|
141
153
|
def change_order_direction(order)
|
142
154
|
order.split(",").collect {|fragment|
|
143
155
|
case fragment
|
@@ -249,6 +261,10 @@ module ::JdbcSpec
|
|
249
261
|
end
|
250
262
|
end
|
251
263
|
|
264
|
+
#SELECT .. FOR UPDATE is not supported on Microsoft SQL Server
|
265
|
+
def add_lock!(sql, options)
|
266
|
+
sql
|
267
|
+
end
|
252
268
|
|
253
269
|
private
|
254
270
|
# Turns IDENTITY_INSERT ON for table during execution of the block
|
@@ -5,7 +5,10 @@ module ::JdbcSpec
|
|
5
5
|
$LOADED_FEATURES << "active_record/connection_adapters/mysql_adapter.rb"
|
6
6
|
|
7
7
|
module ActiveRecordExtensions
|
8
|
+
add_method_to_remove_from_ar_base(:mysql_connection)
|
9
|
+
|
8
10
|
def mysql_connection(config)
|
11
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/mysql_adapter"
|
9
12
|
config[:port] ||= 3306
|
10
13
|
url_options = "zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=false&useUnicode=true&characterEncoding="
|
11
14
|
url_options << (config[:encoding] || 'utf8')
|
@@ -26,6 +26,9 @@ module ::JdbcSpec
|
|
26
26
|
ActiveRecord::Base.after_save :after_save_with_oracle_lob
|
27
27
|
@lob_callback_added = true
|
28
28
|
end
|
29
|
+
mod.class_eval do
|
30
|
+
alias_chained_method :insert, :query_dirty, :jdbc_oracle_insert
|
31
|
+
end
|
29
32
|
end
|
30
33
|
|
31
34
|
def self.adapter_matcher(name, *)
|
@@ -67,14 +70,14 @@ module ::JdbcSpec
|
|
67
70
|
private
|
68
71
|
def simplified_type(field_type)
|
69
72
|
case field_type
|
70
|
-
when /^number\(1\)$/i
|
71
|
-
when /char/i
|
72
|
-
when /float|double/i
|
73
|
-
when /int/i
|
74
|
-
when /num|dec|real/i
|
75
|
-
when /date|time/i
|
76
|
-
when /clob/i
|
77
|
-
when /blob/i
|
73
|
+
when /^number\(1\)$/i then :boolean
|
74
|
+
when /char/i then :string
|
75
|
+
when /float|double/i then :float
|
76
|
+
when /int/i then :integer
|
77
|
+
when /num|dec|real/i then @scale == 0 ? :integer : :decimal
|
78
|
+
when /date|time/i then :datetime
|
79
|
+
when /clob/i then :text
|
80
|
+
when /blob/i then :binary
|
78
81
|
end
|
79
82
|
end
|
80
83
|
|
@@ -87,6 +90,9 @@ module ::JdbcSpec
|
|
87
90
|
|
88
91
|
return nil if value == "null"
|
89
92
|
|
93
|
+
# sysdate default should be treated like a null value
|
94
|
+
return nil if value.downcase == "sysdate"
|
95
|
+
|
90
96
|
# jdbc returns column default strings with actual single quotes around the value.
|
91
97
|
return $1 if value =~ /^'(.*)'$/
|
92
98
|
|
@@ -132,8 +138,8 @@ module ::JdbcSpec
|
|
132
138
|
recreate_database(name)
|
133
139
|
end
|
134
140
|
|
135
|
-
def
|
136
|
-
if id_value # Pre-assigned id
|
141
|
+
def jdbc_oracle_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
142
|
+
if id_value || pk.nil? # Pre-assigned id or table without a primary key
|
137
143
|
execute sql, name
|
138
144
|
else # Assume the sql contains a bind-variable for the id
|
139
145
|
# Extract the table from the insert sql. Yuck.
|
@@ -153,7 +159,7 @@ module ::JdbcSpec
|
|
153
159
|
|
154
160
|
def _execute(sql, name = nil)
|
155
161
|
case sql.strip
|
156
|
-
when /\A\(?\s*(select|show)/i
|
162
|
+
when /\A\(?\s*(select|show)/i then
|
157
163
|
@connection.execute_query(sql)
|
158
164
|
else
|
159
165
|
@connection.execute_update(sql)
|
@@ -308,13 +314,13 @@ module ::JdbcSpec
|
|
308
314
|
# see: abstract/quoting.rb
|
309
315
|
|
310
316
|
# Camelcase column names need to be quoted.
|
311
|
-
# Nonquoted identifiers can contain only alphanumeric characters from your
|
317
|
+
# Nonquoted identifiers can contain only alphanumeric characters from your
|
312
318
|
# database character set and the underscore (_), dollar sign ($), and pound sign (#).
|
313
319
|
# Database links can also contain periods (.) and "at" signs (@).
|
314
320
|
# Oracle strongly discourages you from using $ and # in nonquoted identifiers.
|
315
321
|
# Source: http://download.oracle.com/docs/cd/B28359_01/server.111/b28286/sql_elements008.htm
|
316
322
|
def quote_column_name(name) #:nodoc:
|
317
|
-
name.to_s =~ /^[a-
|
323
|
+
name.to_s =~ /^[a-z0-9_$#]+$/ ? name.to_s : "\"#{name}\""
|
318
324
|
end
|
319
325
|
|
320
326
|
def quote_string(string) #:nodoc:
|
@@ -329,6 +335,9 @@ module ::JdbcSpec
|
|
329
335
|
%Q{empty_#{ column.sql_type.downcase rescue 'blob' }()}
|
330
336
|
end
|
331
337
|
else
|
338
|
+
if column.respond_to?(:primary) && column.primary
|
339
|
+
return value.to_i.to_s
|
340
|
+
end
|
332
341
|
quoted = super
|
333
342
|
if value.acts_like?(:date) || value.acts_like?(:time)
|
334
343
|
quoted = "#{quoted_date(value)}"
|
@@ -353,7 +362,7 @@ module ::JdbcSpec
|
|
353
362
|
# In Oracle, schemas are created under your username:
|
354
363
|
# http://www.oracle.com/technology/obe/2day_dba/schema/schema.htm
|
355
364
|
def oracle_schema
|
356
|
-
@config[:username].to_s
|
365
|
+
@config[:username].to_s if @config[:username]
|
357
366
|
end
|
358
367
|
|
359
368
|
def select(sql, name=nil)
|
@@ -365,3 +374,4 @@ module ::JdbcSpec
|
|
365
374
|
end
|
366
375
|
end
|
367
376
|
end
|
377
|
+
|
@@ -4,7 +4,10 @@ module ::JdbcSpec
|
|
4
4
|
$LOADED_FEATURES << "active_record/connection_adapters/postgresql_adapter.rb"
|
5
5
|
|
6
6
|
module ActiveRecordExtensions
|
7
|
+
add_method_to_remove_from_ar_base(:postgresql_connection)
|
8
|
+
|
7
9
|
def postgresql_connection(config)
|
10
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/postgresql_adapter"
|
8
11
|
config[:host] ||= "localhost"
|
9
12
|
config[:port] ||= 5432
|
10
13
|
config[:url] ||= "jdbc:postgresql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
|
@@ -87,10 +90,12 @@ module ::JdbcSpec
|
|
87
90
|
def postgresql_version
|
88
91
|
@postgresql_version ||=
|
89
92
|
begin
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
93
|
+
value = select_value('SELECT version()')
|
94
|
+
if value =~ /PostgreSQL (\d+)\.(\d+)\.(\d+)/
|
95
|
+
($1.to_i * 10000) + ($2.to_i * 100) + $3.to_i
|
96
|
+
else
|
97
|
+
0
|
98
|
+
end
|
94
99
|
end
|
95
100
|
end
|
96
101
|
|
@@ -217,28 +222,36 @@ module ::JdbcSpec
|
|
217
222
|
table = sql.split(" ", 4)[2].gsub('"', '')
|
218
223
|
|
219
224
|
# Try an insert with 'returning id' if available (PG >= 8.2)
|
220
|
-
if supports_insert_with_returning?
|
225
|
+
if supports_insert_with_returning? && id_value.nil? && false # FIXME:
|
226
|
+
# Disabled, as it causes:
|
227
|
+
# ActiveRecord::ActiveRecordError: A result was returned when none was expected
|
228
|
+
# This was previously disabled because postgresql_version returned 0
|
221
229
|
pk, sequence_name = *pk_and_sequence_for(table) unless pk
|
222
230
|
if pk
|
223
|
-
|
224
|
-
clear_query_cache
|
225
|
-
return
|
231
|
+
id_value = select_value("#{sql} RETURNING #{quote_column_name(pk)}")
|
232
|
+
clear_query_cache #FIXME: Why now?
|
233
|
+
return id_value
|
226
234
|
end
|
227
235
|
end
|
228
236
|
|
229
|
-
# Otherwise, insert
|
237
|
+
# Otherwise, plain insert
|
230
238
|
execute(sql, name)
|
231
239
|
|
232
|
-
#
|
233
|
-
|
234
|
-
|
235
|
-
|
240
|
+
# Don't need to look up id_value if we already have it.
|
241
|
+
# (and can't in case of non-sequence PK)
|
242
|
+
unless id_value
|
243
|
+
# If neither pk nor sequence name is given, look them up.
|
244
|
+
unless pk || sequence_name
|
245
|
+
pk, sequence_name = *pk_and_sequence_for(table)
|
246
|
+
end
|
236
247
|
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
248
|
+
# If a pk is given, fallback to default sequence name.
|
249
|
+
# Don't fetch last insert id for a table without a pk.
|
250
|
+
if pk && sequence_name ||= default_sequence_name(table, pk)
|
251
|
+
id_value = last_insert_id(table, sequence_name)
|
252
|
+
end
|
241
253
|
end
|
254
|
+
id_value
|
242
255
|
end
|
243
256
|
|
244
257
|
def columns(table_name, name=nil)
|
@@ -332,7 +345,7 @@ module ::JdbcSpec
|
|
332
345
|
|
333
346
|
def _execute(sql, name = nil)
|
334
347
|
case sql.strip
|
335
|
-
when /\A\(?\s*(select|show)/i
|
348
|
+
when /\A\(?\s*(select|show)/i then
|
336
349
|
@connection.execute_query(sql)
|
337
350
|
else
|
338
351
|
@connection.execute_update(sql)
|
@@ -445,6 +458,13 @@ module ::JdbcSpec
|
|
445
458
|
execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DEFAULT '#{default}'"
|
446
459
|
end
|
447
460
|
|
461
|
+
def change_column_null(table_name, column_name, null, default = nil)
|
462
|
+
unless null || default.nil?
|
463
|
+
execute("UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote(default)} WHERE #{quote_column_name(column_name)} IS NULL")
|
464
|
+
end
|
465
|
+
execute("ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} #{null ? 'DROP' : 'SET'} NOT NULL")
|
466
|
+
end
|
467
|
+
|
448
468
|
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
449
469
|
execute "ALTER TABLE #{quote_table_name(table_name)} RENAME COLUMN #{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
|
450
470
|
end
|
@@ -1,6 +1,13 @@
|
|
1
1
|
module ::JdbcSpec
|
2
|
+
# Don't need to load native postgres adapter
|
3
|
+
$LOADED_FEATURES << "active_record/connection_adapters/sqlite3_adapter.rb"
|
4
|
+
|
2
5
|
module ActiveRecordExtensions
|
6
|
+
add_method_to_remove_from_ar_base(:sqlite3_connection)
|
7
|
+
|
3
8
|
def sqlite3_connection(config)
|
9
|
+
require File.dirname(__FILE__) + "/../active_record/connection_adapters/sqlite3_adapter"
|
10
|
+
|
4
11
|
parse_sqlite3_config!(config)
|
5
12
|
|
6
13
|
config[:url] ||= "jdbc:sqlite:#{config[:database]}"
|
@@ -34,12 +41,15 @@ module ::JdbcSpec
|
|
34
41
|
end
|
35
42
|
|
36
43
|
module Column
|
44
|
+
def init_column(name, default, *args)
|
45
|
+
@default = '' if default =~ /NULL/
|
46
|
+
end
|
37
47
|
|
38
48
|
def type_cast(value)
|
39
49
|
return nil if value.nil?
|
40
50
|
case type
|
41
51
|
when :string then value
|
42
|
-
when :integer then
|
52
|
+
when :integer then JdbcSpec::SQLite3::Column.cast_to_integer(value)
|
43
53
|
when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
44
54
|
when :float then value.to_f
|
45
55
|
when :datetime then JdbcSpec::SQLite3::Column.cast_to_date_or_time(value)
|
@@ -51,11 +61,23 @@ module ::JdbcSpec
|
|
51
61
|
end
|
52
62
|
end
|
53
63
|
|
64
|
+
def type_cast_code(var_name)
|
65
|
+
case type
|
66
|
+
when :integer then "JdbcSpec::SQLite3::Column.cast_to_integer(#{var_name})"
|
67
|
+
when :datetime then "JdbcSpec::SQLite3::Column.cast_to_date_or_time(#{var_name})"
|
68
|
+
when :date then "JdbcSpec::SQLite3::Column.cast_to_date_or_time(#{var_name})"
|
69
|
+
when :time then "JdbcSpec::SQLite3::Column.cast_to_time(#{var_name})"
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
54
75
|
private
|
55
76
|
def simplified_type(field_type)
|
56
77
|
case field_type
|
57
78
|
when /boolean/i then :boolean
|
58
|
-
when /text/i then :
|
79
|
+
when /text/i then :text
|
80
|
+
when /varchar/i then :string
|
59
81
|
when /int/i then :integer
|
60
82
|
when /float/i then :float
|
61
83
|
when /real/i then @scale == 0 ? :integer : :decimal
|
@@ -89,6 +111,11 @@ module ::JdbcSpec
|
|
89
111
|
value
|
90
112
|
end
|
91
113
|
|
114
|
+
def self.cast_to_integer(value)
|
115
|
+
return nil if value =~ /NULL/ or value.to_s.empty? or value.nil?
|
116
|
+
return (value.to_i) ? value.to_i : (value ? 1 : 0)
|
117
|
+
end
|
118
|
+
|
92
119
|
def self.cast_to_date_or_time(value)
|
93
120
|
return value if value.is_a? Date
|
94
121
|
return nil if value.blank?
|
@@ -125,7 +152,8 @@ module ::JdbcSpec
|
|
125
152
|
end
|
126
153
|
|
127
154
|
def modify_types(tp)
|
128
|
-
tp[:primary_key] = "INTEGER PRIMARY KEY AUTOINCREMENT"
|
155
|
+
tp[:primary_key] = "INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL"
|
156
|
+
tp[:string] = { :name => "VARCHAR", :limit => 255 }
|
129
157
|
tp[:float] = { :name => "REAL" }
|
130
158
|
tp[:decimal] = { :name => "REAL" }
|
131
159
|
tp[:datetime] = { :name => "DATETIME" }
|
@@ -142,6 +170,10 @@ module ::JdbcSpec
|
|
142
170
|
when String
|
143
171
|
if column && column.type == :binary
|
144
172
|
"'#{quote_string(column.class.string_to_binary(value))}'"
|
173
|
+
elsif column && [:integer, :float].include?(column.type)
|
174
|
+
(column.type == :integer ? value.to_i : value.to_f).to_s
|
175
|
+
elsif column && column.respond_to?(:primary) && column.primary
|
176
|
+
value.to_i.to_s
|
145
177
|
else
|
146
178
|
"'#{quote_string(value)}'"
|
147
179
|
end
|
@@ -184,34 +216,38 @@ module ::JdbcSpec
|
|
184
216
|
end
|
185
217
|
end
|
186
218
|
|
187
|
-
def remove_column(table_name,
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
@connection.begin
|
194
|
-
|
195
|
-
execute "CREATE TEMPORARY TABLE #{table_backup}(#{cols})"
|
196
|
-
insert "INSERT INTO #{table_backup} SELECT #{cols} FROM #{table_name}"
|
197
|
-
execute "DROP TABLE #{table_name}"
|
198
|
-
execute "CREATE TABLE #{table_name}(#{cols})"
|
199
|
-
insert "INSERT INTO #{table_name} SELECT #{cols} FROM #{table_backup}"
|
200
|
-
execute "DROP TABLE #{table_backup}"
|
201
|
-
|
202
|
-
@connection.commit
|
219
|
+
def remove_column(table_name, *column_names) #:nodoc:
|
220
|
+
column_names.flatten.each do |column_name|
|
221
|
+
alter_table(table_name) do |definition|
|
222
|
+
definition.columns.delete(definition[column_name])
|
223
|
+
end
|
224
|
+
end
|
203
225
|
end
|
226
|
+
alias :remove_columns :remove_column
|
204
227
|
|
205
228
|
def change_column(table_name, column_name, type, options = {}) #:nodoc:
|
206
|
-
|
229
|
+
alter_table(table_name) do |definition|
|
230
|
+
include_default = options_include_default?(options)
|
231
|
+
definition[column_name].instance_eval do
|
232
|
+
self.type = type
|
233
|
+
self.limit = options[:limit] if options.include?(:limit)
|
234
|
+
self.default = options[:default] if include_default
|
235
|
+
self.null = options[:null] if options.include?(:null)
|
236
|
+
end
|
237
|
+
end
|
207
238
|
end
|
208
239
|
|
209
240
|
def change_column_default(table_name, column_name, default) #:nodoc:
|
210
|
-
|
241
|
+
alter_table(table_name) do |definition|
|
242
|
+
definition[column_name].default = default
|
243
|
+
end
|
211
244
|
end
|
212
245
|
|
213
246
|
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
214
|
-
|
247
|
+
unless columns(table_name).detect{|c| c.name == column_name.to_s }
|
248
|
+
raise ActiveRecord::ActiveRecordError, "Missing column #{table_name}.#{column_name}"
|
249
|
+
end
|
250
|
+
alter_table(table_name, :rename => {column_name.to_s => new_column_name.to_s})
|
215
251
|
end
|
216
252
|
|
217
253
|
def rename_table(name, new_name)
|
@@ -221,6 +257,7 @@ module ::JdbcSpec
|
|
221
257
|
def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) #:nodoc:
|
222
258
|
log(sql,name) do
|
223
259
|
@connection.execute_update(sql)
|
260
|
+
clear_query_cache
|
224
261
|
end
|
225
262
|
table = sql.split(" ", 4)[2]
|
226
263
|
id_value || last_insert_id(table, nil)
|
@@ -237,8 +274,16 @@ module ::JdbcSpec
|
|
237
274
|
end
|
238
275
|
end
|
239
276
|
|
240
|
-
def tables
|
241
|
-
|
277
|
+
def tables(name = nil) #:nodoc:
|
278
|
+
sql = <<-SQL
|
279
|
+
SELECT name
|
280
|
+
FROM sqlite_master
|
281
|
+
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
|
282
|
+
SQL
|
283
|
+
|
284
|
+
select_rows(sql, name).map do |row|
|
285
|
+
row[0]
|
286
|
+
end
|
242
287
|
end
|
243
288
|
|
244
289
|
def remove_index(table_name, options = {})
|
@@ -256,6 +301,11 @@ module ::JdbcSpec
|
|
256
301
|
::ActiveRecord::ConnectionAdapters::IndexDefinition.new(table_name, name, unique, cols)
|
257
302
|
end
|
258
303
|
end
|
304
|
+
|
305
|
+
def primary_key(table_name) #:nodoc:
|
306
|
+
column = table_structure(table_name).find {|field| field['pk'].to_i == 1}
|
307
|
+
column ? column['name'] : nil
|
308
|
+
end
|
259
309
|
|
260
310
|
def recreate_database(name)
|
261
311
|
tables.each{ |table| drop_table(table) }
|
@@ -269,7 +319,19 @@ module ::JdbcSpec
|
|
269
319
|
ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql) ? last_insert_id(sql.split(" ", 4)[2], nil) : affected_rows
|
270
320
|
end
|
271
321
|
end
|
272
|
-
|
322
|
+
|
323
|
+
def select(sql, name=nil)
|
324
|
+
execute(sql, name).map do |row|
|
325
|
+
record = {}
|
326
|
+
row.each_key do |key|
|
327
|
+
if key.is_a?(String)
|
328
|
+
record[key.sub(/^"?\w+"?\./, '')] = row[key]
|
329
|
+
end
|
330
|
+
end
|
331
|
+
record
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
273
335
|
def table_structure(table_name)
|
274
336
|
returning structure = @connection.execute_query("PRAGMA table_info(#{quote_table_name(table_name)})") do
|
275
337
|
raise(ActiveRecord::StatementInvalid, "Could not find table '#{table_name}'") if structure.empty?
|
@@ -278,9 +340,17 @@ module ::JdbcSpec
|
|
278
340
|
|
279
341
|
def columns(table_name, name = nil) #:nodoc:
|
280
342
|
table_structure(table_name).map do |field|
|
281
|
-
::ActiveRecord::ConnectionAdapters::JdbcColumn.new(@config, field['name'], field['dflt_value'], field['type'], field['notnull'] ==
|
343
|
+
::ActiveRecord::ConnectionAdapters::JdbcColumn.new(@config, field['name'], field['dflt_value'], field['type'], field['notnull'] == 0)
|
282
344
|
end
|
283
345
|
end
|
346
|
+
|
347
|
+
# SELECT ... FOR UPDATE is redundant since the table is locked.
|
348
|
+
def add_lock!(sql, options) #:nodoc:
|
349
|
+
sql
|
350
|
+
end
|
351
|
+
|
352
|
+
protected
|
353
|
+
include JdbcSpec::MissingFunctionalityHelper
|
284
354
|
end
|
285
355
|
end
|
286
356
|
|