Class: DuckDB::Result

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/duckdb/result.rb,
ext/duckdb/result.c

Overview

The Result class encapsulates a execute result of DuckDB database.

The usage is as follows:

require 'duckdb'

db = DuckDB::Database.open # database in memory
con = db.connect

con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(30))')

con.execute("INSERT into users VALUES(1, 'Alice')")
con.execute("INSERT into users VALUES(2, 'Bob')")
con.execute("INSERT into users VALUES(3, 'Cathy')")

result = con.execute('SELECT * from users')
result.each do |row|
  p row
end

Constant Summary collapse

ToRuby =
{
  1 => :_to_boolean,
  3 => :_to_smallint,
  4 => :_to_integer,
  5 => :_to_bigint,
  10 => :_to_float,
  11 => :_to_double,
  16 => :_to_hugeint_internal,
  18 => :_to_blob,
  19 => :_to_decimal_internal
}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.use_chunk_each=(val) ⇒ Object

Raises:



45
46
47
48
49
# File 'lib/duckdb/result.rb', line 45

def self.use_chunk_each=(val)
  raise DuckDB::Error, 'chunk_each is not available. Install duckdb >= 0.8.0 and rerun `gem install duckdb`.' unless instance_methods.include?(:chunk_each)

  @use_chunk_each = val
end

.use_chunk_each?Boolean

Returns:

  • (Boolean)


51
52
53
# File 'lib/duckdb/result.rb', line 51

def self.use_chunk_each?
  !!@use_chunk_each
end

Instance Method Details

#chunk_eachObject



686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
# File 'ext/duckdb/result.c', line 686

static VALUE duckdb_result_chunk_each(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    VALUE row;
    idx_t col_count;
    idx_t row_count;
    idx_t chunk_count;
    idx_t col_idx;
    idx_t row_idx;
    idx_t chunk_idx;
    duckdb_data_chunk chunk;
    duckdb_vector vector;
    VALUE val;

    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);

    col_count = duckdb_column_count(&(ctx->result));
    chunk_count = duckdb_result_chunk_count(ctx->result);

    RETURN_ENUMERATOR(oDuckDBResult, 0, 0);

    for (chunk_idx = 0; chunk_idx < chunk_count; chunk_idx++) {
        chunk = duckdb_result_get_chunk(ctx->result, chunk_idx);
        row_count = duckdb_data_chunk_get_size(chunk);
        for (row_idx = 0; row_idx < row_count; row_idx++) {
            row = rb_ary_new2(col_count);
            for (col_idx = 0; col_idx < col_count; col_idx++) {
                vector = duckdb_data_chunk_get_vector(chunk, col_idx);
                val = vector_value(vector, row_idx);
                rb_ary_store(row, col_idx, val);
            }
            rb_yield(row);
        }
        duckdb_destroy_data_chunk(&chunk);
    }
    return Qnil;
}

#column_countInteger Also known as: column_size

Returns the column size of the result.

DuckDB::Database.open do |db|
  db.connect do |con|
    r = con.query('CREATE TABLE t2 (id INT, name VARCHAR(128))')
    r = con.query("INSERT INTO t2 VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Catherine')")
    r = con.query('SELECT id FROM t2')
    r.column_count # => 1
    r = con.query('SELECT id, name FROM t2')
    r.column_count # => 2
  end
end

Returns:

  • (Integer)


188
189
190
191
192
# File 'ext/duckdb/result.c', line 188

static VALUE duckdb_result_column_count(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    return LL2NUM(duckdb_column_count(&(ctx->result)));
}

#columnsDuckDB::Column[]

Returns the column class Lists.

Returns:



225
226
227
228
229
230
231
232
233
234
235
236
237
238
# File 'ext/duckdb/result.c', line 225

static VALUE duckdb_result_columns(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);

    idx_t col_idx;
    idx_t column_count = duckdb_column_count(&(ctx->result));

    VALUE ary = rb_ary_new2(column_count);
    for(col_idx = 0; col_idx < column_count; col_idx++) {
        VALUE column = create_column(oDuckDBResult, col_idx);
        rb_ary_store(ary, col_idx, column);
    }
    return ary;
}

#eachObject



55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/duckdb/result.rb', line 55

def each
  if self.class.use_chunk_each?
    return chunk_each unless block_given?

    chunk_each { |row| yield row }
  else
    return to_enum { row_size } unless block_given?

    row_count.times do |row_index|
      yield row(row_index)
    end
  end
end

#enum_dictionary_values(col_index) ⇒ Object



81
82
83
84
85
86
87
# File 'lib/duckdb/result.rb', line 81

def enum_dictionary_values(col_index)
  values = []
  _enum_dictionary_size(col_index).times do |i|
    values << _enum_dictionary_value(col_index, i)
  end
  values
end

#row(row_index) ⇒ Object



69
70
71
72
73
74
75
# File 'lib/duckdb/result.rb', line 69

def row(row_index)
  row = []
  column_count.times do |col_index|
    row << (_null?(row_index, col_index) ? nil : to_value(row_index, col_index))
  end
  row
end

#row_countInteger Also known as: row_size

Returns the column size of the result.

DuckDB::Database.open do |db|
  db.connect do |con|
    r = con.query('CREATE TABLE t2 (id INT, name VARCHAR(128))')
    r = con.query("INSERT INTO t2 VALUES (1, 'Alice'), (2, 'Bob'), (3, 'Catherine')")
    r = con.query('SELECT * FROM t2')
    r.row_count # => 3
    r = con.query('SELECT * FROM t2 where id = 1')
    r.row_count # => 1
  end
end

Returns:

  • (Integer)


212
213
214
215
216
# File 'ext/duckdb/result.c', line 212

static VALUE duckdb_result_row_count(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    return LL2NUM(duckdb_row_count(&(ctx->result)));
}

#rows_changedInteger

Returns the count of rows changed.

DuckDB::Database.open do |db|
  db.connect do |con|
    r = con.query('CREATE TABLE t2 (id INT)')
    r.rows_changed # => 0
    r = con.query('INSERT INTO t2 VALUES (1), (2), (3)')
    r.rows_changed # => 3
    r = con.query('UPDATE t2 SET id = id + 1 WHERE id > 1')
    r.rows_changed # => 2
    r = con.query('DELETE FROM t2 WHERE id = 0')
    r.rows_changed # => 0
    r = con.query('DELETE FROM t2 WHERE id = 4')
    r.rows_changed # => 1
  end
end

Returns:

  • (Integer)


164
165
166
167
168
# File 'ext/duckdb/result.c', line 164

static VALUE duckdb_result_rows_changed(VALUE oDuckDBResult) {
    rubyDuckDBResult *ctx;
    TypedData_Get_Struct(oDuckDBResult, rubyDuckDBResult, &result_data_type, ctx);
    return LL2NUM(duckdb_rows_changed(&(ctx->result)));
}

#to_value(row_index, col_index) ⇒ Object



77
78
79
# File 'lib/duckdb/result.rb', line 77

def to_value(row_index, col_index)
  send(ToRuby[_column_type(col_index)], row_index, col_index)
end