Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions ext/sqlite3/statement.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,36 @@ bind_parameter_count(VALUE self)
return INT2NUM(sqlite3_bind_parameter_count(ctx->st));
}

/** call-seq: stmt.named_params
*
* Return the list of named parameters in the statement.
*/
static VALUE
named_params(VALUE self)
{
sqlite3StmtRubyPtr ctx;
TypedData_Get_Struct(self, sqlite3StmtRuby, &statement_type, ctx);

REQUIRE_LIVE_DB(ctx);
REQUIRE_OPEN_STMT(ctx);

int param_count = sqlite3_bind_parameter_count(ctx->st);
VALUE params = rb_ary_new2(param_count);

// The first host parameter has an index of 1, not 0.
for (int i = 1; i <= param_count; i++) {
const char *name = sqlite3_bind_parameter_name(ctx->st, i);
// If parameters of the ?NNN form are used, there may be gaps in the list.
if (name) {
VALUE rb_name = interned_utf8_cstr(name);
// The initial ":" or "$" or "@" or "?" is included as part of the name.
rb_name = rb_str_substr(rb_name, 1, RSTRING_LEN(rb_name) - 1);
rb_ary_push(params, rb_name);
}
}
return rb_obj_freeze(params);
}

enum stmt_stat_sym {
stmt_stat_sym_fullscan_steps,
stmt_stat_sym_sorts,
Expand Down Expand Up @@ -689,6 +719,7 @@ init_sqlite3_statement(void)
rb_define_method(cSqlite3Statement, "column_name", column_name, 1);
rb_define_method(cSqlite3Statement, "column_decltype", column_decltype, 1);
rb_define_method(cSqlite3Statement, "bind_parameter_count", bind_parameter_count, 0);
rb_define_method(cSqlite3Statement, "named_params", named_params, 0);
rb_define_method(cSqlite3Statement, "sql", get_sql, 0);
rb_define_method(cSqlite3Statement, "expanded_sql", get_expanded_sql, 0);
#ifdef HAVE_SQLITE3_COLUMN_DATABASE_NAME
Expand Down
8 changes: 8 additions & 0 deletions test/test_statement.rb
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,14 @@ def test_named_bind_not_found
stmt.close
end

def test_named_params
assert_empty @stmt.named_params

stmt = SQLite3::Statement.new(@db, "select :foo, $bar, @zed")
assert_equal ["foo", "bar", "zed"], stmt.named_params
stmt.close
end

def test_each
r = nil
@stmt.each do |row|
Expand Down
Loading