Skip to content

Commit 3201df4

Browse files
committed
[sqlite] pre.support for latest JDBC 3.8 (work-around needed - might go away in 3.8.8)
1 parent 74eb264 commit 3201df4

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

lib/arjdbc/sqlite3/adapter.rb

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,38 @@ def primary_key(table_name)
367367
column && column['name']
368368
end
369369

370+
# NOTE: do not override indexes without testing support for 3.7.2 & 3.8.7 !
371+
# @override
372+
def indexes(table_name, name = nil)
373+
# on JDBC 3.7 we'll simply do super since it can not handle "PRAGMA index_info"
374+
return @connection.indexes(table_name, name) if sqlite_version < '3.8' # super
375+
376+
name ||= 'SCHEMA'
377+
exec_query_raw("PRAGMA index_list(#{quote_table_name(table_name)})", name).map do |row|
378+
index_name = row['name']
379+
sql = "SELECT sql FROM sqlite_master"
380+
sql << " WHERE name=#{quote(index_name)} AND type='index'"
381+
sql << " UNION ALL "
382+
sql << "SELECT sql FROM sqlite_temp_master"
383+
sql << " WHERE name=#{quote(index_name)} AND type='index'"
384+
where = nil
385+
exec_query_raw(sql, name) do |index_sql|
386+
match = /\sWHERE\s+(.+)$/i.match(index_sql)
387+
where = match[1] if match
388+
end
389+
begin
390+
columns = exec_query_raw("PRAGMA index_info('#{index_name}')", name).map { |col| col['name'] }
391+
rescue => e
392+
# NOTE: JDBC <= 3.8.7 bug work-around :
393+
if e.message && e.message.index('[SQLITE_ERROR] SQL error or missing database')
394+
columns = []
395+
end
396+
raise e
397+
end
398+
new_index_definition(table_name, index_name, row['unique'] != 0, columns, nil, nil, where)
399+
end
400+
end
401+
370402
# @override
371403
def remove_index!(table_name, index_name)
372404
execute "DROP INDEX #{quote_column_name(index_name)}"
@@ -488,12 +520,17 @@ def last_inserted_id(result)
488520
end
489521

490522
def translate_exception(exception, message)
491-
case exception.message
492-
when /column(s)? .* (is|are) not unique/
493-
ActiveRecord::RecordNotUnique.new(message, exception)
494-
else
495-
super
523+
if msg = exception.message
524+
# SQLite 3.8.2 returns a newly formatted error message:
525+
# UNIQUE constraint failed: *table_name*.*column_name*
526+
# Older versions of SQLite return:
527+
# column *column_name* is not unique
528+
if msg.index('UNIQUE constraint failed: ') ||
529+
msg =~ /column(s)? .* (is|are) not unique/
530+
return RecordNotUnique.new(message, exception)
531+
end
496532
end
533+
super
497534
end
498535

499536
# @private available in native adapter way back to AR-2.3

0 commit comments

Comments
 (0)