class DuckDB::PreparedStatement

stmt.execute
stmt.bind(1, ‘email@example.com’)
stmt = PreparedStatement.new(con, sql)
sql =‘SELECT name, email FROM users WHERE email = ?’
con = db.connect
db = DuckDB::Database.open(‘duckdb_database’)
require ‘duckdb’
statement.
The DuckDB::PreparedStatement encapsulates connection with DuckDB prepared

def bind(index, value)

stmt.bind(1, 'email@example.com')
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name, email FROM users WHERE email = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

The second argument value is the value of prepared statement parameter.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind(index, value)
  case index
  when Integer
    bind_with_index(index, value)
  when String
    bind_with_name(index, value)
  when Symbol
    bind_with_name(index.to_s, value)
  else
    raise(ArgumentError, "1st argument `#{index}` must be Integer or String or Symbol.")
  end
end

def bind_args(*args, **kwargs)

# stmt.bind_args(id: 1)
# or
stmt.bind_args([1])
stmt = PreparedStatement.new(con, sql)
# sql ='SELECT name FROM users WHERE id = $id'
# or
sql ='SELECT name FROM users WHERE id = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

binds all parameters with SQL prepared statement.
def bind_args(*args, **kwargs)
  args.each.with_index(1) do |arg, i|
    bind(i, arg)
  end
  kwargs.each do |key, value|
    bind(key, value)
  end
end

def bind_date(index, value)

# stmt.bind(1, '2021-02-23')
# or you can specify date string.
stmt.bind(1, Date.today)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE birth_day = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

The second argument value is to expected date.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_date(index, value)
  date = _parse_date(value)
  _bind_date(index, date.year, date.month, date.day)
end

def bind_decimal(index, value)

stmt.bind_decimal(1, BigDecimal('987654.321'))
stmt = PreparedStatement.new(con, sql)
sql ='SELECT value FROM decimals WHERE decimal = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

that can be parsed into a BigDecimal.
The second argument value is to expected BigDecimal value or any value
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_decimal(index, value)
  decimal = _parse_deciaml(value)
  lower, upper = decimal_to_hugeint(decimal)
  width = decimal.to_s('F').gsub(/[^0-9]/, '').length
  _bind_decimal(index, lower, upper, width, decimal.scale)
end

def bind_hugeint(index, value)

stmt.bind_hugeint(1, 1_234_567_890_123_456_789_012_345)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE bigint_col = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

This method uses bind_varchar internally.
The second argument value is to expected Integer value.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_hugeint(index, value)
  case value
  when Integer
    bind_varchar(index, value.to_s)
  else
    raise(ArgumentError, "2nd argument `#{value}` must be Integer.")
  end
end

def bind_hugeint_internal(index, value)

stmt.bind_hugeint_internal(1, 1_234_567_890_123_456_789_012_345)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE hugeint_col = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

This method uses duckdb_bind_hugeint internally.
The second argument value must be Integer value.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_hugeint_internal(index, value)
  lower, upper = integer_to_hugeint(value)
  _bind_hugeint(index, lower, upper)
end

def bind_interval(index, value)

stmt.bind(1, 'P1Y2D')
stmt = PreparedStatement.new(con, sql)
sql ='SELECT value FROM intervals WHERE interval = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

The second argument value is to expected ISO8601 time interval string.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_interval(index, value)
  value = Interval.to_interval(value)
  _bind_interval(index, value.interval_months, value.interval_days, value.interval_micros)
end

def bind_time(index, value)

# stmt.bind(1, '07:39:45')
# or you can specify time string.
stmt.bind(1, Time.now)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE birth_time = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

The second argument value is to expected time value.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_time(index, value)
  time = _parse_time(value)
  _bind_time(index, time.hour, time.min, time.sec, time.usec)
end

def bind_timestamp(index, value)

# stmt.bind(1, '2022-02-23 07:39:45')
# or you can specify timestamp string.
stmt.bind(1, Time.now)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE created_at = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

The second argument value is to expected time value.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_timestamp(index, value)
  time = _parse_time(value)
  _bind_timestamp(index, time.year, time.month, time.day, time.hour, time.min, time.sec, time.usec)
end

def bind_uhugeint(index, value)

stmt.bind_uhugeint(1, (2**128) - 1)
stmt = PreparedStatement.new(con, sql)
sql ='SELECT name FROM users WHERE uhugeint_col = ?'
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

This method uses duckdb_bind_uhugeint internally.
The second argument value must be Integer value.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_uhugeint(index, value)
  lower, upper = integer_to_hugeint(value)
  _bind_uhugeint(index, lower, upper)
end

def bind_uint16(index, val)

The second argument value is to expected Integer value between 0 to 65535.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_uint16(index, val)
  return _bind_uint16(index, val) if val.between?(0, 65_535)
  raise DuckDB::Error, "can't bind uint16(bind_uint16) to `#{val}`. The `#{val}` is out of range 0..65535."
end

def bind_uint32(index, val)

The second argument value is to expected Integer value between 0 to 4294967295.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_uint32(index, val)
  return _bind_uint32(index, val) if val.between?(0, 4_294_967_295)
  raise DuckDB::Error, "can't bind uint32(bind_uint32) to `#{val}`. The `#{val}` is out of range 0..4294967295."
end

def bind_uint64(index, val)

The second argument value is to expected Integer value between 0 to 18446744073709551615.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_uint64(index, val)
  return _bind_uint64(index, val) if val.between?(0, 18_446_744_073_709_551_615)
  raise DuckDB::Error, "can't bind uint64(bind_uint64) to `#{val}`. The `#{val}` is out of range 0..18446744073709551615."
end

def bind_uint8(index, val)

The second argument value is to expected Integer value between 0 to 255.
The index of first parameter is 1 not 0.
The first argument is index of parameter.
binds i-th parameter with SQL prepared statement.
def bind_uint8(index, val)
  return _bind_uint8(index, val) if val.between?(0, 255)
  raise DuckDB::Error, "can't bind uint8(bind_uint8) to `#{val}`. The `#{val}` is out of range 0..255."
end

def bind_with_index(index, value)

def bind_with_index(index, value)
  case value
  when NilClass
    bind_null(index)
  when Float
    bind_double(index, value)
  when Integer
    case value
    when RANGE_INT64
      bind_int64(index, value)
    else
      bind_varchar(index, value.to_s)
    end
  when String
    blob?(value) ? bind_blob(index, value) : bind_varchar(index, value)
  when TrueClass, FalseClass
    bind_bool(index, value)
  when Time
    bind_varchar(index, value.strftime('%Y-%m-%d %H:%M:%S.%N'))
  when Date
    bind_varchar(index, value.strftime('%Y-%m-%d'))
  when BigDecimal
    bind_decimal(index, value)
  else
    raise(DuckDB::Error, "not supported type `#{value}` (#{value.class})")
  end
end

def bind_with_name(name, value)

def bind_with_name(name, value)
  raise DuckDB::Error, 'not supported binding with name' unless respond_to?(:bind_parameter_index)
  i = bind_parameter_index(name)
  bind_with_index(i, value)
end

def blob?(value)

def blob?(value)
  value.instance_of?(DuckDB::Blob) || value.encoding == Encoding::BINARY
end

def param_type(index)

stmt.param_type(1) # => :integer
stmt = con.prepared_statement('SELECT * FROM users WHERE id = ?')
con.execute('CREATE TABLE users (id INTEGER, name VARCHAR(255))')
con = db.connect
db = DuckDB::Database.open
require 'duckdb'

returns parameter type. The argument must be index of parameter.
def param_type(index)
  i = _param_type(index)
  Converter::IntToSym.type_to_sym(i)
end

def pending_prepared

def pending_prepared
  PendingResult.new(self)
end

def pending_prepared_stream

def pending_prepared_stream
  warn("`#{self.class}##{__method__}` will be deprecated. use `#{self.class}#pending_prepared` instead")
  pending_prepared
end

def prepare(con, sql)

end
stmt.execute
stmt.bind(1, 1)
DuckDB::PreparedStatement.prepare(con, 'SELECT * FROM users WHERE id = ?') do |stmt|
con = db.connection
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

If block is given, the block is executed and the statement is destroyed.
The second argument is SQL string.
The first argument is DuckDB::Connection object.
return DuckDB::PreparedStatement object.
def prepare(con, sql)
  stmt = new(con, sql)
  return stmt unless block_given?
  begin
    yield stmt
  ensure
    stmt.destroy
  end
end

def statement_type

stmt.statement_type # => :select
stmt = con.prepared_statement('SELECT * FROM users')
con = db.connect
db = DuckDB::Database.open('duckdb_database')
require 'duckdb'

:logical_plan, :attach, :detach, :multi
:drop, :export, :pragma, :vacuum, :call, :set, :load, :relation, :extension,
:execute, :alter, :transaction, :copy, :analyze, :variable_set, :create_func,
:invalid, :select, :insert, :update, :explain, :delete, :prepare, :create,
returns statement type. The return value is one of the following symbols:
def statement_type
  i = _statement_type
  Converter::IntToSym.statement_type_to_sym(i)
end