@@ -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 = /\s WHERE\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