Module: ActiveRecord::ConnectionAdapters::Duckdb::DatabaseStatements
- Included in:
- ActiveRecord::ConnectionAdapters::DuckdbAdapter
- Defined in:
- lib/active_record/connection_adapters/duckdb/database_statements.rb
Constant Summary collapse
- READ_QUERY_PATTERN =
SQL statements that are considered read-only (SELECT, EXPLAIN, etc.)
/\A\s*(SELECT|SHOW|DESCRIBE|EXPLAIN|PRAGMA)\b/i
Instance Method Summary collapse
-
#affected_rows(raw_result) ⇒ Integer
Returns the number of affected rows from a raw DuckDB result.
-
#begin_db_transaction ⇒ void
Begins a database transaction.
-
#cast_result(result) ⇒ ActiveRecord::Result
Casts a DuckDB result to ActiveRecord::Result format.
-
#columns_for_insert(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::Column>
Returns columns that should be included in INSERT statements.
-
#commit_db_transaction ⇒ void
Commits the current database transaction.
-
#exec_rollback_db_transaction ⇒ void
Rolls back the current database transaction.
-
#execute(sql, name = nil) ⇒ DuckDB::Result
Executes a SQL statement against the DuckDB database.
-
#last_inserted_id(result) ⇒ Object
Extracts the last inserted ID from an insert result.
-
#return_value_after_insert?(column) ⇒ Boolean
Determines if a column value should be returned after insert This is crucial - it tells Rails which columns should use RETURNING.
-
#write_query?(sql) ⇒ Boolean
Determines if a SQL query is a write operation (INSERT, UPDATE, DELETE, etc.) Used for read replica support and transaction tracking.
Instance Method Details
#affected_rows(raw_result) ⇒ Integer
Returns the number of affected rows from a raw DuckDB result. Required by Rails 8.0+ for exec_delete/exec_update via internal_execute. The base class calls affected_rows(raw_execute(...)) for DELETE/UPDATE operations.
92 93 94 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 92 def affected_rows(raw_result) raw_result.rows_changed end |
#begin_db_transaction ⇒ void
This method returns an undefined value.
Begins a database transaction.
13 14 15 16 17 18 19 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 13 def begin_db_transaction log('BEGIN', 'TRANSACTION') do with_raw_connection do |conn| conn.query('BEGIN TRANSACTION') end end end |
#cast_result(result) ⇒ ActiveRecord::Result
Casts a DuckDB result to ActiveRecord::Result format. Used by Rails 8.0+ internal_exec_query which calls cast_result(raw_execute(...)). Also called by Rails 7.2's internal_exec_query implementation in DatabaseStatementsRails72.
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 71 def cast_result(result) return ActiveRecord::Result.empty if result.nil? columns = result.columns.map do |col| if col.respond_to?(:name) col.name elsif col.respond_to?(:column_name) col.column_name else col.to_s end end ActiveRecord::Result.new(columns, result.to_a) end |
#columns_for_insert(table_name) ⇒ Array<ActiveRecord::ConnectionAdapters::Column>
Returns columns that should be included in INSERT statements
99 100 101 102 103 104 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 99 def columns_for_insert(table_name) columns(table_name).reject do |column| # Exclude columns that have a default function (like nextval) column.default_function.present? end end |
#commit_db_transaction ⇒ void
This method returns an undefined value.
Commits the current database transaction.
23 24 25 26 27 28 29 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 23 def commit_db_transaction log('COMMIT', 'TRANSACTION') do with_raw_connection do |conn| conn.query('COMMIT') end end end |
#exec_rollback_db_transaction ⇒ void
This method returns an undefined value.
Rolls back the current database transaction.
33 34 35 36 37 38 39 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 33 def exec_rollback_db_transaction log('ROLLBACK', 'TRANSACTION') do with_raw_connection do |conn| conn.query('ROLLBACK') end end end |
#execute(sql, name = nil) ⇒ DuckDB::Result
Executes a SQL statement against the DuckDB database. Used for DDL and raw SQL execution.
54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 54 def execute(sql, name = nil) # :nodoc: # Check for write queries on read-only connections (replica support) # Rails 8.1+ uses ensure_writes_are_allowed, earlier versions use check_if_write_query ensure_write_query_allowed(sql) log(sql, name) do with_raw_connection do |conn| conn.query(sql) end end end |
#last_inserted_id(result) ⇒ Object
Extracts the last inserted ID from an insert result
118 119 120 121 122 123 124 125 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 118 def last_inserted_id(result) # Handle ActiveRecord::Result from RETURNING clause if result.is_a?(ActiveRecord::Result) && result.rows.any? id_value = result.rows.first.first return id_value end super end |
#return_value_after_insert?(column) ⇒ Boolean
Determines if a column value should be returned after insert This is crucial - it tells Rails which columns should use RETURNING
110 111 112 113 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 110 def return_value_after_insert?(column) # Return true for any column with a sequence default column.default_function&.include?('nextval') || super end |
#write_query?(sql) ⇒ Boolean
Determines if a SQL query is a write operation (INSERT, UPDATE, DELETE, etc.) Used for read replica support and transaction tracking.
45 46 47 |
# File 'lib/active_record/connection_adapters/duckdb/database_statements.rb', line 45 def write_query?(sql) !READ_QUERY_PATTERN.match?(sql) end |