Class: DuckDB::Appender

Inherits:
Object
  • Object
show all
Includes:
Converter, TableNameParser
Defined in:
lib/duckdb/appender.rb,
ext/duckdb/appender.c

Overview

The DuckDB::Appender encapsulates DuckDB Appender.

The table argument (2nd positional argument) supports dot-notation and quoting:

  • 'schema.table' — interpreted as schema-qualified (deprecated; use schema: instead)

  • '"schema.table"' or "'schema.table'" — treated as a literal table name containing a dot

    require ‘duckdb’ db = DuckDB::Database.open con = db.connect con.query(‘CREATE TABLE users (id INTEGER, name VARCHAR)’) appender = con.appender(‘users’) appender.append_row(1, ‘Alice’)

Constant Summary

Constants included from Converter

Converter::EPOCH, Converter::EPOCH_UTC, Converter::HALF_HUGEINT, Converter::HALF_HUGEINT_BIT, Converter::LOWER_HUGEINT_MASK, Converter::RANGE_DECIMAL_WIDTH, Converter::RANGE_HUGEINT, Converter::RANGE_INT16, Converter::RANGE_INT32, Converter::RANGE_INT64, Converter::RANGE_INT8, Converter::RANGE_UHUGEINT, Converter::RANGE_UINT16, Converter::RANGE_UINT32, Converter::RANGE_UINT64, Converter::RANGE_UINT8

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Converter

_decimal_to_unscaled, _decimal_width, _hugeint_lower, _hugeint_upper, _parse_date, _parse_deciaml, _parse_time, _to_date, _to_decimal_from_hugeint, _to_decimal_from_value, _to_hugeint_from_vector, _to_infinity, _to_interval_from_vector, _to_query_progress, _to_time, _to_time_from_duckdb_time, _to_time_from_duckdb_time_ns, _to_time_from_duckdb_time_tz, _to_time_from_duckdb_timestamp_ms, _to_time_from_duckdb_timestamp_ns, _to_time_from_duckdb_timestamp_s, _to_time_from_duckdb_timestamp_tz, decimal_to_hugeint, default_timezone_utc?, format_timestamp_with_micro, format_timezone_offset, integer_to_hugeint

Constructor Details

#initialize(con, table_or_schema, table = nil, schema: nil, catalog: nil) ⇒ Appender

Returns a new instance of Appender.



29
30
31
32
33
34
35
36
# File 'lib/duckdb/appender.rb', line 29

def initialize(con, table_or_schema, table = nil, schema: nil, catalog: nil)
  if table
    warn_deprecated_3arg
    _initialize(con, table_or_schema, table)
  else
    initialize_with_parsed_table(con, table_or_schema, schema: schema, catalog: catalog)
  end
end

Class Method Details

.DuckDB::Appender.create_queryDuckDB::Appender Also known as: from_query

Returns a new Appender instance created from a query.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
query = 'INSERT OR REPLACE INTO users SELECT i, val FROM my_appended_data'
types = [DuckDB::LogicalType::INTEGER, DuckDB::LogicalType::VARCHAR]
appender = DuckDB::Appender.create_query(con, query, types, 'my_appended_data', %w[i val])

Returns:



87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'ext/duckdb/appender.c', line 87

static VALUE appender_s_create_query(VALUE klass, VALUE con, VALUE query, VALUE types, VALUE table, VALUE columns) {
    rubyDuckDBConnection *ctxcon;
    rubyDuckDBAppender *ctx;
    char *query_str = StringValuePtr(query);
    char *table_name = NULL;
    const char **column_names = NULL;
    idx_t column_count = 0;
    duckdb_logical_type *type_array = NULL;
    VALUE appender = Qnil;

    if (!rb_obj_is_kind_of(con, cDuckDBConnection)) {
        rb_raise(rb_eTypeError, "1st argument should be instance of DackDB::Connection");
    }
    if (rb_obj_is_kind_of(types, rb_cArray) == Qfalse) {
        rb_raise(rb_eTypeError, "2nd argument should be an Array");
    }
    column_count = RARRAY_LEN(types);
    type_array = ALLOCA_N(duckdb_logical_type, (size_t)column_count);
    for (idx_t i = 0; i < column_count; i++) {
        VALUE type_val = rb_ary_entry(types, i);
        rubyDuckDBLogicalType *type_ctx = rbduckdb_get_struct_logical_type(type_val);
        type_array[i] = type_ctx->logical_type;
    }

    if (table != Qnil) {
        table_name = StringValuePtr(table);
    }
    if (columns != Qnil) {
        if (rb_obj_is_kind_of(columns, rb_cArray) == Qfalse) {
            rb_raise(rb_eTypeError, "4th argument should be an Array or nil");
        }
        idx_t col_count = RARRAY_LEN(columns);
        column_names = ALLOCA_N(const char *, (size_t)col_count);
        for (idx_t i = 0; i < col_count; i++) {
            VALUE col_name_val = rb_ary_entry(columns, i);
            column_names[i] = StringValuePtr(col_name_val);
        }
    }
    ctxcon = rbduckdb_get_struct_connection(con);
    appender = allocate(klass);
    TypedData_Get_Struct(appender, rubyDuckDBAppender, &appender_data_type, ctx);
    if (duckdb_appender_create_query(ctxcon->con, query_str, column_count, type_array, table_name, column_names, &ctx->appender) == DuckDBError) {
        rb_raise(eDuckDBError, "failed to create appender from query");
    }

    return appender;
}

Instance Method Details

#add_column(column) ⇒ Object

:call-seq:

appender.add_column(column_name) -> self

Specifies a column to append to, allowing selective column insertion. Columns not added will use their default values or be computed from generated column expressions. Raises DuckDB::Error if the column does not exist in the table.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE t (id UUID PRIMARY KEY DEFAULT uuidv4(), name VARCHAR)')
appender = con.appender('t')
appender.add_column('name')
appender
  .append_varchar('Alice')
  .end_row
  .flush


129
130
131
132
133
# File 'lib/duckdb/appender.rb', line 129

def add_column(column)
  return self if _add_column(column)

  raise_appender_error('failed to add_column')
end

#append(value) ⇒ Object

appends value.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender.append(1)
appender.append('Alice')
appender.end_row

rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength



740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
# File 'lib/duckdb/appender.rb', line 740

def append(value)
  case value
  when NilClass
    append_null
  when Float
    append_double(value)
  when Integer
    append_integer_value(value)
  when String
    append_string_value(value)
  when TrueClass, FalseClass
    append_bool(value)
  when Time
    append_timestamp(value)
  when Date
    append_date(value)
  when DuckDB::Interval
    append_interval(value)
  else
    raise(DuckDB::Error, "not supported type #{value} (#{value.class})")
  end
end

#append_blob(value) ⇒ Object

call-seq:

appender.append_blob(val) -> self

Appends a varchar value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE values (value BLOB)')
appender = con.appender('values')
appender
  .append('\0\1\2\3\4\5'.encode(Encoding::BINARY))
  .end_row
  .flush


469
470
471
472
473
# File 'lib/duckdb/appender.rb', line 469

def append_blob(value)
  return self if _append_blob(value)

  raise_appender_error('failed to append_blob')
end

#append_bool(value) ⇒ Object

call-seq:

appender.append_bool(val) -> self

Appends a boolean value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, active BOOLEAN)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_bool(true)
  .end_row
  .flush


200
201
202
203
204
# File 'lib/duckdb/appender.rb', line 200

def append_bool(value)
  return self if _append_bool(value)

  raise_appender_error('failed to append_bool')
end

#append_data_chunk(chunk) ⇒ Object

call-seq:

appender.append_data_chunk(chunk) -> self

Appends a pre-filled DuckDB::DataChunk to the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
chunk = DuckDB::DataChunk.new([DuckDB::LogicalType::INTEGER, DuckDB::LogicalType::VARCHAR])
chunk.set_value(0, 0, 1)
chunk.set_value(1, 0, 'Alice')
chunk.size = 1
appender.append_data_chunk(chunk)
appender.flush

Raises:

  • (ArgumentError)


693
694
695
696
697
698
699
# File 'lib/duckdb/appender.rb', line 693

def append_data_chunk(chunk)
  raise ArgumentError, "expected DuckDB::DataChunk, got #{chunk.class}" unless chunk.is_a?(DuckDB::DataChunk)

  return self if _append_data_chunk(chunk)

  raise_appender_error('failed to append_data_chunk')
end

#append_date(value) ⇒ Object

call-seq:

appender.append_date(val) -> self

Appends a date value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE dates (date_value DATE)')
appender = con.appender('dates')
appender.append_date(Date.today)
# or
# appender.append_date(Time.now)
# appender.append_date('2021-10-10')
appender.end_row
appender.flush


577
578
579
580
581
582
583
# File 'lib/duckdb/appender.rb', line 577

def append_date(value)
  date = _parse_date(value)

  return self if _append_date(date.year, date.month, date.day)

  raise_appender_error('failed to append_date')
end

#append_defaultObject

call-seq:

appender.append_default -> self

Appends a default value to the current row in the appender. If the column does not have a default value, this method appends a NULL value.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE values (value INTEGER DEFAULT 1)')
appender = con.appender('values')
appender
  .append_default
  .end_row
  .flush


511
512
513
514
515
# File 'lib/duckdb/appender.rb', line 511

def append_default
  return self if _append_default

  raise_appender_error('failed to append_default')
end

#append_default_to_chunk(chunk, col, row) ⇒ Object

call-seq:

appender.append_default_to_chunk(chunk, col, row) -> self

Appends the DEFAULT value for the column at col and row in chunk. If no DEFAULT is defined for the column, NULL is used. Call this before appending the chunk via #append_data_chunk.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (name VARCHAR, enabled BOOLEAN DEFAULT TRUE)')
appender = con.appender('users')
chunk = DuckDB::DataChunk.new([DuckDB::LogicalType::VARCHAR, DuckDB::LogicalType::BOOLEAN])
appender.append_default_to_chunk(chunk, 1, 0)  # enabled DEFAULT for row 0
appender.append_default_to_chunk(chunk, 1, 1)  # enabled DEFAULT for row 1
chunk.set_value(0, 0, 'Alice')
chunk.set_value(0, 1, 'Bob')
chunk.size = 2
appender.append_data_chunk(chunk)
appender.flush

Raises:

  • (ArgumentError)


721
722
723
724
725
726
727
# File 'lib/duckdb/appender.rb', line 721

def append_default_to_chunk(chunk, col, row)
  raise ArgumentError, "expected DuckDB::DataChunk, got #{chunk.class}" unless chunk.is_a?(DuckDB::DataChunk)

  return self if _append_default_to_chunk(chunk, col, row)

  raise_appender_error('failed to append_default_to_chunk')
end

#append_double(value) ⇒ Object

call-seq:

appender.append_double(val) -> self

Appends a double value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE numbers (num DOUBLE)')
appender = con.appender('numbers')
appender
  .append_double(1.23)
  .end_row
  .flush


409
410
411
412
413
# File 'lib/duckdb/appender.rb', line 409

def append_double(value)
  return self if _append_double(value)

  raise_appender_error('failed to append_double')
end

#append_float(value) ⇒ Object

call-seq:

appender.append_float(val) -> self

Appends a float value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE numbers (num FLOAT)')
appender = con.appender('numbers')
appender
  .append_float(1.23)
  .end_row
  .flush


389
390
391
392
393
# File 'lib/duckdb/appender.rb', line 389

def append_float(value)
  return self if _append_float(value)

  raise_appender_error('failed to append_float')
end

#append_hugeint(value) ⇒ Object

call-seq:

appender.append_hugeint(val) -> self

Appends a huge int value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE numbers (num HUGEINT)')
appender = con.appender('numbers')
appender
  .append_hugeint(-170_141_183_460_469_231_731_687_303_715_884_105_727)
  .end_row
  .flush


531
532
533
534
535
536
537
# File 'lib/duckdb/appender.rb', line 531

def append_hugeint(value)
  lower, upper = integer_to_hugeint(value)

  return self if _append_hugeint(lower, upper)

  raise_appender_error('failed to append_hugeint')
end

#append_int16(value) ⇒ Object

call-seq:

appender.append_int16(val) -> self

Appends an int16(SMALLINT) value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age SMALLINT)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_int16(20)
  .end_row
  .flush


243
244
245
246
247
# File 'lib/duckdb/appender.rb', line 243

def append_int16(value)
  return self if _append_int16(value)

  raise_appender_error('failed to append_int16')
end

#append_int32(value) ⇒ Object

call-seq:

appender.append_int32(val) -> self

Appends an int32(INTEGER) value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age INTEGER)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_int32(20)
  .end_row
  .flush


264
265
266
267
268
# File 'lib/duckdb/appender.rb', line 264

def append_int32(value)
  return self if _append_int32(value)

  raise_appender_error('failed to append_int32')
end

#append_int64(value) ⇒ Object

call-seq:

appender.append_int64(val) -> self

Appends an int64(BIGINT) value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age BIGINT)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_int64(20)
  .end_row
  .flush


285
286
287
288
289
# File 'lib/duckdb/appender.rb', line 285

def append_int64(value)
  return self if _append_int64(value)

  raise_appender_error('failed to append_int64')
end

#append_int8(value) ⇒ Object

call-seq:

appender.append_int8(val) -> self

Appends an int8(TINYINT) value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age TINYINT)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_int8(20)
  .end_row
  .flush


222
223
224
225
226
# File 'lib/duckdb/appender.rb', line 222

def append_int8(value)
  return self if _append_int8(value)

  raise_appender_error('failed to append_int8')
end

#append_interval(value) ⇒ Object

call-seq:

appender.append_interval(val) -> self

Appends an interval value to the current row in the appender. The argument must be ISO8601 duration format.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE intervals (interval_value INTERVAL)')
appender = con.appender('intervals')
appender
  .append_interval('P1Y2D') # => append 1 year 2 days interval.
  .end_row
  .flush


647
648
649
650
651
652
653
# File 'lib/duckdb/appender.rb', line 647

def append_interval(value)
  value = Interval.to_interval(value)

  return self if _append_interval(value.interval_months, value.interval_days, value.interval_micros)

  raise_appender_error('failed to append_interval')
end

#append_nullObject

call-seq:

appender.append_null -> self

Appends a NULL value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE values (value INTEGER)')
appender = con.appender('values')
appender
  .append_null
  .end_row
  .flush


489
490
491
492
493
# File 'lib/duckdb/appender.rb', line 489

def append_null
  return self if _append_null

  raise_appender_error('failed to append_null')
end

#append_row(*args) ⇒ Object

append a row.

appender.append_row(1, 'Alice')

is same as:

appender.append(2)
appender.append('Alice')
appender.end_row


773
774
775
776
777
778
# File 'lib/duckdb/appender.rb', line 773

def append_row(*args)
  args.each do |arg|
    append(arg)
  end
  end_row
end

#append_time(value) ⇒ Object

call-seq:

appender.append_time(val) -> self

Appends a time value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE times (time_value TIME)')
appender = con.appender('times')
appender.append_time(Time.now)
# or
# appender.append_time('01:01:01')
appender.end_row
appender.flush


600
601
602
603
604
605
606
# File 'lib/duckdb/appender.rb', line 600

def append_time(value)
  time = _parse_time(value)

  return self if _append_time(time.hour, time.min, time.sec, time.usec)

  raise_appender_error('failed to append_time')
end

#append_timestamp(value) ⇒ Object

call-seq:

appender.append_timestamp(val) -> self

Appends a timestamp value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE timestamps (timestamp_value TIMESTAMP)')
appender = con.appender('timestamps')
appender.append_time(Time.now)
# or
# appender.append_time(Date.today)
# appender.append_time('2021-08-01 01:01:01')
appender.end_row
appender.flush


624
625
626
627
628
629
630
# File 'lib/duckdb/appender.rb', line 624

def append_timestamp(value)
  time = to_time(value)

  return self if _append_timestamp(time.year, time.month, time.day, time.hour, time.min, time.sec, time.nsec / 1000)

  raise_appender_error('failed to append_timestamp')
end

#append_uhugeint(value) ⇒ Object

call-seq:

appender.append_uhugeint(val) -> self

Appends an unsigned huge int value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE numbers (num UHUGEINT)')
appender = con.appender('numbers')
appender
  .append_hugeint(340_282_366_920_938_463_463_374_607_431_768_211_455)
  .end_row
  .flush


553
554
555
556
557
558
559
# File 'lib/duckdb/appender.rb', line 553

def append_uhugeint(value)
  lower, upper = integer_to_hugeint(value)

  return self if _append_uhugeint(lower, upper)

  raise_appender_error('failed to append_uhugeint')
end

#append_uint16(value) ⇒ Object

call-seq:

appender.append_uint16(val) -> self

Appends an uint16 value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age USMALLINT)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_uint16(20)
  .end_row
  .flush


327
328
329
330
331
# File 'lib/duckdb/appender.rb', line 327

def append_uint16(value)
  return self if _append_uint16(value)

  raise_appender_error('failed to append_uint16')
end

#append_uint32(value) ⇒ Object

call-seq:

appender.append_uint32(val) -> self

Appends an uint32 value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age UINTEGER)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_uint32(20)
  .end_row
  .flush


348
349
350
351
352
# File 'lib/duckdb/appender.rb', line 348

def append_uint32(value)
  return self if _append_uint32(value)

  raise_appender_error('failed to append_uint32')
end

#append_uint64(value) ⇒ Object

call-seq:

appender.append_uint64(val) -> self

Appends an uint64 value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age UBIGINT)')
appender = con.appender('users')
Appender
  .append_int32(1)
  .append_uint64(20)
  .end_row
  .flush


369
370
371
372
373
# File 'lib/duckdb/appender.rb', line 369

def append_uint64(value)
  return self if _append_uint64(value)

  raise_appender_error('failed to append_uint64')
end

#append_uint8(value) ⇒ Object

call-seq:

appender.append_uint8(val) -> self

Appends an uint8 value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, age UTINYINT)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_uint8(20)
  .end_row
  .flush


306
307
308
309
310
# File 'lib/duckdb/appender.rb', line 306

def append_uint8(value)
  return self if _append_uint8(value)

  raise_appender_error('failed to append_uint8')
end

#append_value(value) ⇒ Object

call-seq:

appender.append_value(val) -> self

Appends a DuckDB::Value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE numbers (num INTEGER)')
appender = con.appender('numbers')
appender
  .append_value(DuckDB::Value.create_int32(42))
  .end_row
  .flush

Raises:

  • (ArgumentError)


669
670
671
672
673
674
675
# File 'lib/duckdb/appender.rb', line 669

def append_value(value)
  raise ArgumentError, "expected DuckDB::Value, got #{value.class}" unless value.is_a?(DuckDB::Value)

  return self if _append_value(value)

  raise_appender_error('failed to append_value')
end

#append_varchar(value) ⇒ Object

call-seq:

appender.append_varchar(val) -> self

Appends a varchar value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE names (name VARCHAR)')
appender = con.appender('names')
appender
  .append_varchar('Alice')
  .end_row
  .flush


429
430
431
432
433
# File 'lib/duckdb/appender.rb', line 429

def append_varchar(value)
  return self if _append_varchar(value)

  raise_appender_error('failed to append_varchar')
end

#append_varchar_length(value, length) ⇒ Object

call-seq:

appender.append_varchar_length(val, len) -> self

Appends a varchar value to the current row in the appender.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE names (name VARCHAR)')
appender = con.appender('names')
appender
  .append_varchar_length('Alice', 5)
  .end_row
  .flush


449
450
451
452
453
# File 'lib/duckdb/appender.rb', line 449

def append_varchar_length(value, length)
  return self if _append_varchar_length(value, length)

  raise_appender_error('failed to append_varchar_length')
end

#begin_rowObject

:call-seq:

appender.begin_row -> self

A nop method, provided for backwards compatibility reasons. Does nothing. Only ‘end_row` is required.



42
43
44
# File 'lib/duckdb/appender.rb', line 42

def begin_row
  self
end

#clearObject

:call-seq:

appender.clear -> self

Clears all unflushed data from the appender, discarding any appended rows that have not yet been flushed to the table.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_varchar('Alice')
  .end_row
  .clear # discards the row above without flushing to the table


178
179
180
181
182
# File 'lib/duckdb/appender.rb', line 178

def clear
  return self if _clear

  raise_appender_error('failed to clear')
end

#clear_columnsObject

:call-seq:

appender.clear_columns -> self

Clears the list of columns previously set by #add_column, so that all columns of the table become active again. Any previously appended rows are flushed before the column list is reset; if the flush fails (e.g. a constraint violation), this method raises DuckDB::Error.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE t (id UUID PRIMARY KEY DEFAULT uuidv4(), name VARCHAR)')
appender = con.appender('t')
appender.add_column('name')
appender
  .append_varchar('Alice')
  .end_row
  .flush
appender.clear_columns
# all table columns are active again


155
156
157
158
159
# File 'lib/duckdb/appender.rb', line 155

def clear_columns
  return self if _clear_columns

  raise_appender_error('failed to clear_columns')
end

#closeObject

:call-seq:

appender.close -> self

Closes the appender by flushing all intermediate states and closing it for further appends. If flushing the data triggers a constraint violation or any other error, then all data is invalidated, and this method raises DuckDB::Error.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_varchar('Alice')
  .end_row
  .close


105
106
107
108
109
# File 'lib/duckdb/appender.rb', line 105

def close
  return self if _close

  raise_appender_error('failed to close')
end

#end_rowObject

call-seq:

appender.end_row -> self

Finish the current row of appends. After end_row is called, the next row can be appended.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_varchar('Alice')
  .end_row


59
60
61
62
63
# File 'lib/duckdb/appender.rb', line 59

def end_row
  return self if _end_row

  raise_appender_error('failed to end_row')
end

#error_messageString

Returns the error message of the appender. If there is no error, then it returns nil.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender.error_message # => nil

Returns:

  • (String)


196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'ext/duckdb/appender.c', line 196

static VALUE appender_error_message(VALUE self) {
    rubyDuckDBAppender *ctx;
    duckdb_error_data error_data;
    const char *msg = NULL;
    VALUE rb_msg = Qnil;
    TypedData_Get_Struct(self, rubyDuckDBAppender, &appender_data_type, ctx);

    error_data = duckdb_appender_error_data(ctx->appender);
    if (duckdb_error_data_has_error(error_data)) {
        msg = duckdb_error_data_message(error_data);
        rb_msg = rb_str_new2(msg);
    }
    duckdb_destroy_error_data(&error_data);
    return rb_msg;
}

#flushObject

:call-seq:

appender.flush -> self

Flushes the appender to the table, forcing the cache of the appender to be cleared. If flushing the data triggers a constraint violation or any other error, then all data is invalidated, and this method raises DuckDB::Error.

require 'duckdb'
db = DuckDB::Database.open
con = db.connect
con.query('CREATE TABLE users (id INTEGER, name VARCHAR)')
appender = con.appender('users')
appender
  .append_int32(1)
  .append_varchar('Alice')
  .end_row
  .flush


82
83
84
85
86
# File 'lib/duckdb/appender.rb', line 82

def flush
  return self if _flush

  raise_appender_error('failed to flush')
end