Class: DuckDB::PendingResult

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

Overview

The DuckDB::PendingResult encapsulates connection with DuckDB pending result. PendingResult provides methods to execute SQL asynchronousely and check if the result is ready and to get the result.

require 'duckdb'

DuckDB::Result.use_chunk_each = true

db = DuckDB::Database.open
con = db.connect
stmt = con.prepared_statement(VERY_SLOW_QUERY)
pending_result = stmt.pending_prepared
while pending_result.state == :not_ready
  print '.'
  sleep(0.01)
  pending_result.execute_task
end
result = pending_result.execute_pending

Constant Summary collapse

STATES =
%i[ready not_ready error no_tasks].freeze

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Object



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
# File 'ext/duckdb/pending_result.c', line 37

static VALUE duckdb_pending_result_initialize(int argc, VALUE *argv, VALUE self) {
    VALUE oDuckDBPreparedStatement;
    VALUE streaming_p = Qfalse;
    duckdb_state state;

    /*
     * FIXME: The 2nd argument is deprecated and will be removed in the future.
     * The behavior will be same as streaming.
    if (argc == 2) {
        rb_warn("The 2nd argument is deprecated and will be removed in the future.");
    }
    */
    rb_scan_args(argc, argv, "11", &oDuckDBPreparedStatement, &streaming_p);

    if (rb_obj_is_kind_of(oDuckDBPreparedStatement, cDuckDBPreparedStatement) != Qtrue) {
        rb_raise(rb_eTypeError, "1st argument must be DuckDB::PreparedStatement");
    }

    rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
    rubyDuckDBPreparedStatement *stmt = get_struct_prepared_statement(oDuckDBPreparedStatement);

#ifdef DUCKDB_API_NO_DEPRECATED
    state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
#else
    /*
     * FIXME: streaming_p check will be removed in the future.
     *
     * state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
     */
    if (!NIL_P(streaming_p) && streaming_p == Qtrue) {
        state = duckdb_pending_prepared_streaming(stmt->prepared_statement, &(ctx->pending_result));
    } else {
        state = duckdb_pending_prepared(stmt->prepared_statement, &(ctx->pending_result));
    }
#endif

    if (state == DuckDBError) {
        rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
    }
    return self;
}

Instance Method Details

#execute_pendingDuckDB::Result

Get DuckDB::Result object after query execution finished.

db = DuckDB::Database.open
conn = db.connect
pending_result = conn.async_query("slow query")
pending_result.execute_task while pending_result.state != :ready
result = pending_result.execute_pending # => DuckDB::Result

Returns:



113
114
115
116
117
118
119
120
121
122
123
124
# File 'ext/duckdb/pending_result.c', line 113

static VALUE duckdb_pending_result_execute_pending(VALUE self) {
    rubyDuckDBPendingResult *ctx;
    rubyDuckDBResult *ctxr;
    VALUE result = rbduckdb_create_result();

    TypedData_Get_Struct(self, rubyDuckDBPendingResult, &pending_result_data_type, ctx);
    ctxr = get_struct_result(result);
    if (duckdb_execute_pending(ctx->pending_result, &(ctxr->result)) == DuckDBError) {
        rb_raise(eDuckDBError, "%s", duckdb_pending_error(ctx->pending_result));
    }
    return result;
}

#execute_tasknil

Executes the task in the pending result.

db = DuckDB::Database.open
conn = db.connect
pending_result = conn.async_query("slow query")
pending_result.execute_task

Returns:

  • (nil)


90
91
92
93
94
# File 'ext/duckdb/pending_result.c', line 90

static VALUE duckdb_pending_result_execute_task(VALUE self) {
    rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
    ctx->state = duckdb_pending_execute_task(ctx->pending_result);
    return Qnil;
}

#execution_finished?Boolean

Returns:

  • (Boolean)


96
97
98
99
# File 'ext/duckdb/pending_result.c', line 96

static VALUE duckdb_pending_result_execution_finished_p(VALUE self) {
    rubyDuckDBPendingResult *ctx = get_struct_pending_result(self);
    return duckdb_pending_execution_is_finished(ctx->state) ? Qtrue : Qfalse;
}

#stateSymbol

returns the state of the pending result. The result can be :ready, :not_ready, :error, :no_tasks. (:no_tasks is available only with duckdb 0.9.0 or later.)

:ready means the result is ready to be fetched, and you can call ‘execute_pending` to get the result.

:not_ready means the result is not ready yet, so you need to call ‘execute_task`.

Returns:

  • (Symbol)

    :ready, :not_ready, :error, :no_tasks



37
38
39
# File 'lib/duckdb/pending_result.rb', line 37

def state
  STATES[_state]
end