Skip to content

Commit

Permalink
Merge pull request #795 from suketa/extracted_statements
Browse files Browse the repository at this point in the history
Extracted statements
  • Loading branch information
suketa authored Nov 4, 2024
2 parents 9000ad9 + 800b74b commit 12291c4
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
6 changes: 4 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

All notable changes to this project will be documented in this file.
# Unreleased
- add DuckDB::PreparedStatement#prepare.
- DuckDB::Connection#prepared_statement accepts block.
- add `DuckDB::ExtracteStatements#each` method.
- add `DuckDB::ExtracteStatementsImpl#destroy` method.
- add `DuckDB::PreparedStatement#prepare`.
- `DuckDB::Connection#prepared_statement` accepts block and calls `PreparedStatement#destroy` after block executed.
```ruby
con.prepared_statement('SELECT * FROM table WHERE id = ?') do |stmt|
stmt.bind(1)
Expand Down
16 changes: 14 additions & 2 deletions ext/duckdb/extracted_statements.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ static VALUE allocate(VALUE klass);
static size_t memsize(const void *p);

static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE query);
static VALUE duckdb_extracted_statements_destroy(VALUE self);
static VALUE duckdb_extracted_statements_size(VALUE self);
static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE con, VALUE index);

Expand Down Expand Up @@ -56,12 +57,22 @@ static VALUE duckdb_extracted_statements_initialize(VALUE self, VALUE con, VALUE

if (ctx->num_statements == 0) {
error = duckdb_extract_statements_error(ctx->extracted_statements);
rb_raise(eDuckDBError, "%s", error);
rb_raise(eDuckDBError, "%s", error ? error : "Failed to extract statements(Database connection closed?).");
}

return self;
}

static VALUE duckdb_extracted_statements_destroy(VALUE self) {
rubyDuckDBExtractedStatements *ctx;

TypedData_Get_Struct(self, rubyDuckDBExtractedStatements, &extract_statements_data_type, ctx);

duckdb_destroy_extracted(&(ctx->extracted_statements));

return Qnil;
}

static VALUE duckdb_extracted_statements_size(VALUE self) {
rubyDuckDBExtractedStatements *ctx;

Expand All @@ -85,10 +96,11 @@ static VALUE duckdb_extracted_statements_prepared_statement(VALUE self, VALUE co
}

void rbduckdb_init_duckdb_extracted_statements(void) {
cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatements", rb_cObject);
cDuckDBExtractedStatements = rb_define_class_under(mDuckDB, "ExtractedStatementsImpl", rb_cObject);

rb_define_alloc_func(cDuckDBExtractedStatements, allocate);
rb_define_method(cDuckDBExtractedStatements, "initialize", duckdb_extracted_statements_initialize, 2);
rb_define_method(cDuckDBExtractedStatements, "destroy", duckdb_extracted_statements_destroy, 0);
rb_define_method(cDuckDBExtractedStatements, "size", duckdb_extracted_statements_size, 0);
rb_define_method(cDuckDBExtractedStatements, "prepared_statement", duckdb_extracted_statements_prepared_statement, 2);
}
1 change: 1 addition & 0 deletions lib/duckdb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require 'duckdb/converter'
require 'duckdb/database'
require 'duckdb/connection'
require 'duckdb/extracted_statements'
require 'duckdb/result'
require 'duckdb/prepared_statement'
require 'duckdb/pending_result'
Expand Down
20 changes: 20 additions & 0 deletions lib/duckdb/extracted_statements.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# frozen_string_literal: true

module DuckDB
class ExtractedStatements < ExtractedStatementsImpl
include Enumerable

def initialize(con, sql)
@con = con
super(con, sql)
end

def each
return to_enum(__method__) { size } unless block_given?

size.times do |i|
yield prepared_statement(@con, i)
end
end
end
end
22 changes: 22 additions & 0 deletions test/duckdb_test/extracted_statements_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,28 @@ def test_prepared_statement_with_invalid_index
assert_equal 'Fail to get DuckDB::PreparedStatement object from ExtractedStatements object', ex.message
end

def test_destroy
stmts = DuckDB::ExtractedStatements.new(@con, 'SELECT 1; SELECT 2; SELECT 3')
assert_nil(stmts.destroy)
end

def test_each_without_block
stmts = DuckDB::ExtractedStatements.new(@con, 'SELECT 1; SELECT 2; SELECT 3')
enum_stmts = stmts.each
assert_instance_of(Enumerator, enum_stmts)
assert_equal(3, enum_stmts.size)
end

def test_each_with_block
stmts = DuckDB::ExtractedStatements.new(@con, 'SELECT 1; SELECT 2; SELECT 3')
i = 1
stmts.each do |stmt|
r = stmt.execute
assert_equal([[i]], r.to_a)
i += 1
end
end

def teardown
@con.close
@db.close
Expand Down

0 comments on commit 12291c4

Please sign in to comment.