1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
# frozen-string-literal: true
Sequel::JDBC.load_driver('org.sqlite.JDBC', :SQLite3)
require_relative '../shared/sqlite'
module Sequel
module JDBC
Sequel.synchronize do
DATABASE_SETUP[:sqlite] = proc do |db|
db.extend(Sequel::JDBC::SQLite::DatabaseMethods)
db.extend_datasets Sequel::SQLite::DatasetMethods
db.set_integer_booleans
org.sqlite.JDBC
end
end
module SQLite
module ForeignKeyListPragmaConvertorFix
# For the use of the convertor for String, working around a bug
# in jdbc-sqlite3 that reports fields are of type
# java.sql.types.NUMERIC even though they contain non-numeric data.
def type_convertor(_, _, _, i)
i > 2 ? TypeConvertor::CONVERTORS[:String] : super
end
end
module TableInfoPragmaConvertorFix
# For the use of the convertor for String, working around a bug
# in jdbc-sqlite3 that reports dflt_value field is of type
# java.sql.types.NUMERIC even though they contain string data.
def type_convertor(_, _, _, i)
i == 5 ? TypeConvertor::CONVERTORS[:String] : super
end
end
module DatabaseMethods
include Sequel::SQLite::DatabaseMethods
# Swallow pointless exceptions when the foreign key list pragma
# doesn't return any rows.
def foreign_key_list(table, opts=OPTS)
super
rescue Sequel::DatabaseError => e
raise unless foreign_key_error?(e)
[]
end
# Swallow pointless exceptions when the index list pragma
# doesn't return any rows.
def indexes(table, opts=OPTS)
super
rescue Sequel::DatabaseError => e
raise unless foreign_key_error?(e)
{}
end
private
# Add workaround for bug when running foreign_key_list pragma
def _foreign_key_list_ds(_)
super.with_extend(ForeignKeyListPragmaConvertorFix)
end
# Add workaround for bug when running table_info pragma
def _parse_pragma_ds(_, _)
super.with_extend(TableInfoPragmaConvertorFix)
end
DATABASE_ERROR_REGEXPS = Sequel::SQLite::DatabaseMethods::DATABASE_ERROR_REGEXPS.merge(/Abort due to constraint violation/ => ConstraintViolation).freeze
def database_error_regexps
DATABASE_ERROR_REGEXPS
end
# Use last_insert_rowid() to get the last inserted id.
def last_insert_id(conn, opts=OPTS)
statement(conn) do |stmt|
rs = stmt.executeQuery('SELECT last_insert_rowid()')
rs.next
rs.getLong(1)
end
end
# Default to a single connection for a memory database.
def connection_pool_default_options
o = super
uri == 'jdbc:sqlite::memory:' ? o.merge(:max_connections=>1) : o
end
# Execute the connection pragmas on the connection.
def setup_connection(conn)
conn = super(conn)
statement(conn) do |stmt|
connection_pragmas.each{|s| log_connection_yield(s, conn){stmt.execute(s)}}
end
conn
end
# Whether the given exception is due to a foreign key error.
def foreign_key_error?(exception)
exception.message =~ /query does not return ResultSet/
end
# Use getLong instead of getInt for converting integers on SQLite, since SQLite does not enforce a limit of 2**32.
# Work around regressions in jdbc-sqlite 3.8.7 for date and blob types.
def setup_type_convertor_map
super
@type_convertor_map[Java::JavaSQL::Types::INTEGER] = @type_convertor_map[Java::JavaSQL::Types::BIGINT]
@basic_type_convertor_map[Java::JavaSQL::Types::INTEGER] = @basic_type_convertor_map[Java::JavaSQL::Types::BIGINT]
x = @type_convertor_map[Java::JavaSQL::Types::DATE] = Object.new
def x.call(r, i)
if v = r.getString(i)
Sequel.string_to_date(v)
end
end
x = @type_convertor_map[Java::JavaSQL::Types::BLOB] = Object.new
def x.call(r, i)
if v = r.getBytes(i)
Sequel::SQL::Blob.new(String.from_java_bytes(v))
elsif !r.wasNull
Sequel::SQL::Blob.new('')
end
end
end
# The result code for the exception, if the jdbc driver supports result codes for exceptions.
def sqlite_error_code(exception)
exception.resultCode.code if exception.respond_to?(:resultCode)
end
end
end
end
end
|