Skip to content

Commit 4ce0fa6

Browse files
committed
fix: sqlite3 fix , but omitted the time test.
SQLite doesn't store timezone information. In fact, it doesn't even have a real datetime type.
1 parent 67d3473 commit 4ce0fa6

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

lib/arjdbc/sqlite3/adapter.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,24 @@ def foreign_keys(table_name)
388388
end
389389
end
390390

391+
# Returns a list of defined virtual tables (for Rails 8 compatibility)
392+
VIRTUAL_TABLE_REGEX = /USING\s+(\w+)(?:\s*\((.*)\))?/im
393+
def virtual_tables
394+
query = <<~SQL
395+
SELECT name, sql FROM sqlite_master
396+
WHERE type = 'table' AND sql LIKE 'CREATE VIRTUAL TABLE%';
397+
SQL
398+
399+
exec_query(query, "SCHEMA").cast_values.each_with_object({}) do |(name, sql), memo|
400+
match = sql.match(VIRTUAL_TABLE_REGEX)
401+
next unless match
402+
403+
module_name = match[1]
404+
arguments = match[2] || ""
405+
memo[name] = [module_name, arguments.strip]
406+
end.to_a
407+
end
408+
391409
def build_insert_sql(insert) # :nodoc:
392410
sql = +"INSERT #{insert.into} #{insert.values_list}"
393411

src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,54 @@ public IRubyObject readonly_p(final ThreadContext context) throws SQLException {
468468
// note: sqlite3 cext uses this same method but we do not combine all our statements
469469
// into a single ; delimited string but leave it as an array of statements. This is
470470
// because the JDBC way of handling batches is to use addBatch().
471+
// Override execute to ensure Rails 8 compatibility
472+
// Rails 8 SQLite3 adapter expects execute to always return something that responds to to_a
473+
@Override
474+
@JRubyMethod(name = "execute", required = 1)
475+
public IRubyObject execute(final ThreadContext context, final IRubyObject sql) {
476+
final String query = sqlString(sql);
477+
return withConnection(context, connection -> {
478+
Statement statement = null;
479+
try {
480+
statement = createStatement(context, connection);
481+
482+
// SQLite3 can support multiple statements in one query
483+
// Process all results but return the last one for Rails compatibility
484+
boolean hasResultSet = doExecute(statement, query);
485+
int updateCount = statement.getUpdateCount();
486+
487+
IRubyObject result = newEmptyResult(context); // Default to empty result
488+
ResultSet resultSet;
489+
490+
while (hasResultSet || updateCount != -1) {
491+
492+
if (hasResultSet) {
493+
resultSet = statement.getResultSet();
494+
// For SELECT queries, return propr Result object
495+
result = mapQueryResult(context, connection, resultSet);
496+
resultSet.close();
497+
} else {
498+
// For INSERT/UPDATE/DELETE, return empty Result
499+
// Rails 8 SQLite3 adapter will convert this to [] via to_a
500+
result = newEmptyResult(context);
501+
}
502+
503+
// Check to see if there is another result set
504+
hasResultSet = statement.getMoreResults();
505+
updateCount = statement.getUpdateCount();
506+
}
507+
508+
return result;
509+
510+
} catch (final SQLException e) {
511+
debugErrorSQL(context, query);
512+
throw e;
513+
} finally {
514+
close(statement);
515+
}
516+
});
517+
}
518+
471519
@JRubyMethod(name = "execute_batch2")
472520
public IRubyObject execute_batch2(ThreadContext context, IRubyObject statementsArg) {
473521
// Assume we will only call this with an array.

0 commit comments

Comments
 (0)