Skip to content

Commit

Permalink
Merge pull request #169 from jimflood/sqlite3_result_blob
Browse files Browse the repository at this point in the history
BLOB function result when ASCII-8BIT encoding
  • Loading branch information
tenderlove committed Feb 7, 2016
2 parents 99aa5aa + 220c194 commit 7dc8122
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 7 deletions.
32 changes: 26 additions & 6 deletions ext/sqlite3/database.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,14 @@ static VALUE sqlite3val2rb(sqlite3_value * val)
which is what we want, as blobs are binary
*/
int len = sqlite3_value_bytes(val);
#ifdef HAVE_RUBY_ENCODING_H
return rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
#else
/* When encoding is not available, make it class SQLite3::Blob. */
VALUE strargv[1];
strargv[0] = rb_tainted_str_new((const char *)sqlite3_value_blob(val), len);
return rb_class_new_instance(1, strargv, cSqlite3Blob);
#endif
break;
}
case SQLITE_NULL:
Expand Down Expand Up @@ -322,12 +329,25 @@ static void set_sqlite3_func_result(sqlite3_context * ctx, VALUE result)
sqlite3_result_double(ctx, NUM2DBL(result));
break;
case T_STRING:
sqlite3_result_text(
ctx,
(const char *)StringValuePtr(result),
(int)RSTRING_LEN(result),
SQLITE_TRANSIENT
);
if(CLASS_OF(result) == cSqlite3Blob
#ifdef HAVE_RUBY_ENCODING_H
|| rb_enc_get_index(result) == rb_ascii8bit_encindex()
#endif
) {
sqlite3_result_blob(
ctx,
(const void *)StringValuePtr(result),
(int)RSTRING_LEN(result),
SQLITE_TRANSIENT
);
} else {
sqlite3_result_text(
ctx,
(const char *)StringValuePtr(result),
(int)RSTRING_LEN(result),
SQLITE_TRANSIENT
);
}
break;
default:
rb_raise(rb_eRuntimeError, "can't return %s",
Expand Down
9 changes: 8 additions & 1 deletion test/test_database.rb
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,19 @@ def test_function_return
end

def test_function_return_types
[10, 2.2, nil, "foo"].each do |thing|
[10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
@db.define_function("hello") { |a| thing }
assert_equal [thing], @db.execute("select hello('world')").first
end
end

def test_function_return_type_round_trip
[10, 2.2, nil, "foo", Blob.new("foo\0bar")].each do |thing|
@db.define_function("hello") { |a| a }
assert_equal [thing], @db.execute("select hello(hello(?))", [thing]).first
end
end

def test_define_function_closed
@db.close
assert_raise(SQLite3::Exception) do
Expand Down

0 comments on commit 7dc8122

Please sign in to comment.