From 18a24f87929c591ef11c5d3d5c489a04e1bd1c80 Mon Sep 17 00:00:00 2001 From: Dirkjan Bussink Date: Thu, 12 Nov 2009 20:41:26 +0100 Subject: [PATCH] Fix default encoding on sqlite3 and add specs for it --- .../lib/data_objects/spec/encoding_spec.rb | 59 ++++++++++++++++++- .../spec/typecast/byte_array_spec.rb | 4 +- do_derby/spec/encoding_spec.rb | 2 +- do_h2/spec/encoding_spec.rb | 2 +- do_hsqldb/spec/encoding_spec.rb | 2 +- do_mysql/spec/encoding_spec.rb | 3 +- do_oracle/spec/encoding_spec.rb | 2 +- do_postgres/spec/encoding_spec.rb | 3 +- .../ext/do_sqlite3_ext/do_sqlite3_ext.c | 15 +++++ do_sqlite3/spec/spec_helper.rb | 2 +- do_sqlite3/spec/typecast/byte_array_spec.rb | 3 +- do_sqlserver/spec/encoding_spec.rb | 2 +- 12 files changed, 86 insertions(+), 13 deletions(-) diff --git a/data_objects/lib/data_objects/spec/encoding_spec.rb b/data_objects/lib/data_objects/spec/encoding_spec.rb index 4b14e17d..4c223691 100644 --- a/data_objects/lib/data_objects/spec/encoding_spec.rb +++ b/data_objects/lib/data_objects/spec/encoding_spec.rb @@ -1,4 +1,4 @@ -share_examples_for 'a driver supporting encodings' do +share_examples_for 'a driver supporting different encodings' do before :each do @connection = DataObjects::Connection.new(CONFIG.uri) @@ -37,7 +37,64 @@ it { @latin1_connection.character_set.should == 'UTF-8' } end + end +end + +share_examples_for 'returning correctly encoded strings for the default encoding' do + + include DataObjectsSpecHelpers + + before :all do + setup_test_environment + end + before :each do + @connection = DataObjects::Connection.new(CONFIG.uri) + end + after :each do + @connection.close end + + if defined?(::Encoding) + describe 'with encoded string support' do + + describe 'reading a String' do + before do + @reader = @connection.create_command("SELECT name FROM widgets WHERE ad_description = ?").execute_reader('Buy this product now!') + @reader.next! + @values = @reader.values + end + + after do + @reader.close + end + + it 'should return UTF-8 encoded String' do + @values.first.should be_kind_of(String) + @values.first.encoding.name.should == 'UTF-8' + end + end + + describe 'reading a ByteArray' do + before do + @command = @connection.create_command("SELECT ad_image FROM widgets WHERE ad_description = ?") + @command.set_types(Extlib::ByteArray) + @reader = @command.execute_reader('Buy this product now!') + @reader.next! + @values = @reader.values + end + + after do + @reader.close + end + + it 'should return ASCII-8BIT encoded ByteArray' do + @values.first.should be_kind_of(::Extlib::ByteArray) + @values.first.encoding.name.should == 'ASCII-8BIT' + end + end + end + end + end diff --git a/data_objects/lib/data_objects/spec/typecast/byte_array_spec.rb b/data_objects/lib/data_objects/spec/typecast/byte_array_spec.rb index d3033a63..50114428 100644 --- a/data_objects/lib/data_objects/spec/typecast/byte_array_spec.rb +++ b/data_objects/lib/data_objects/spec/typecast/byte_array_spec.rb @@ -67,7 +67,7 @@ describe 'writing a ByteArray' do before do - @reader = @connection.create_command("SELECT id FROM widgets WHERE id = ?").execute_reader(::Extlib::ByteArray.new("2")) + @reader = @connection.create_command("SELECT ad_description FROM widgets WHERE cad_drawing = ?").execute_reader(::Extlib::ByteArray.new("CAD \001 \000 DRAWING")) @reader.next! @values = @reader.values end @@ -78,7 +78,7 @@ it 'should return the correct entry' do #Some of the drivers starts autoincrementation from 0 not 1 - @values.first.should satisfy { |val| val == 2 or val == 1 } + @values.first.should == 'Buy this product now!' end end diff --git a/do_derby/spec/encoding_spec.rb b/do_derby/spec/encoding_spec.rb index d79aff0a..f2d1769b 100644 --- a/do_derby/spec/encoding_spec.rb +++ b/do_derby/spec/encoding_spec.rb @@ -4,5 +4,5 @@ require 'data_objects/spec/encoding_spec' describe DataObjects::Derby::Connection do -# it_should_behave_like 'a driver supporting encodings' +# it_should_behave_like 'a driver supporting different encodings' end diff --git a/do_h2/spec/encoding_spec.rb b/do_h2/spec/encoding_spec.rb index e8ff7bfe..ac8dbada 100644 --- a/do_h2/spec/encoding_spec.rb +++ b/do_h2/spec/encoding_spec.rb @@ -4,5 +4,5 @@ require 'data_objects/spec/encoding_spec' describe DataObjects::H2::Connection do - #it_should_behave_like 'a driver supporting encodings' + #it_should_behave_like 'a driver supporting different encodings' end diff --git a/do_hsqldb/spec/encoding_spec.rb b/do_hsqldb/spec/encoding_spec.rb index 51f713bc..8b595716 100644 --- a/do_hsqldb/spec/encoding_spec.rb +++ b/do_hsqldb/spec/encoding_spec.rb @@ -4,5 +4,5 @@ require 'data_objects/spec/encoding_spec' describe DataObjects::Hsqldb::Connection do - # it_should_behave_like 'a driver supporting encodings' + # it_should_behave_like 'a driver supporting different encodings' end diff --git a/do_mysql/spec/encoding_spec.rb b/do_mysql/spec/encoding_spec.rb index 3d33074d..0349d482 100644 --- a/do_mysql/spec/encoding_spec.rb +++ b/do_mysql/spec/encoding_spec.rb @@ -4,5 +4,6 @@ require 'data_objects/spec/encoding_spec' describe DataObjects::Mysql::Connection do - it_should_behave_like 'a driver supporting encodings' + it_should_behave_like 'a driver supporting different encodings' + it_should_behave_like 'returning correctly encoded strings for the default encoding' end diff --git a/do_oracle/spec/encoding_spec.rb b/do_oracle/spec/encoding_spec.rb index d1f12650..561aba3f 100644 --- a/do_oracle/spec/encoding_spec.rb +++ b/do_oracle/spec/encoding_spec.rb @@ -4,7 +4,7 @@ # require 'data_objects/spec/encoding_spec' # # describe DataObjects::Oracle::Connection do -# it_should_behave_like 'a driver supporting encodings' +# it_should_behave_like 'a driver supporting different encodings' # end diff --git a/do_postgres/spec/encoding_spec.rb b/do_postgres/spec/encoding_spec.rb index 43408a70..70ceff22 100644 --- a/do_postgres/spec/encoding_spec.rb +++ b/do_postgres/spec/encoding_spec.rb @@ -14,6 +14,7 @@ # handles setting the internal client_encoding setting appropriately. It # can be overridden -- but for now, we won't support doing this. # - it_should_behave_like 'a driver supporting encodings' + it_should_behave_like 'a driver supporting different encodings' + it_should_behave_like 'returning correctly encoded strings for the default encoding' end end diff --git a/do_sqlite3/ext/do_sqlite3_ext/do_sqlite3_ext.c b/do_sqlite3/ext/do_sqlite3_ext/do_sqlite3_ext.c index 55430878..b95e2032 100755 --- a/do_sqlite3/ext/do_sqlite3_ext/do_sqlite3_ext.c +++ b/do_sqlite3/ext/do_sqlite3_ext/do_sqlite3_ext.c @@ -534,6 +534,18 @@ static VALUE cConnection_quote_string(VALUE self, VALUE string) { return result; } +static VALUE cConnection_quote_byte_array(VALUE self, VALUE string) { + VALUE source = StringValue(string); + VALUE array = rb_funcall(source, rb_intern("unpack"), 1, rb_str_new2("H*")); + rb_ary_unshift(array, rb_str_new2("X'")); + rb_ary_push(array, rb_str_new2("'")); + return rb_ary_join(array, Qnil); +} + +static VALUE cConnection_character_set(VALUE self) { + return rb_iv_get(self, "@encoding"); +} + static VALUE build_query_from_args(VALUE klass, int count, VALUE *args) { VALUE query = rb_iv_get(klass, "@text"); int i; @@ -604,6 +616,7 @@ static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, sqlite3_reader)); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); + rb_iv_set(reader, "@connection", conn_obj); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); @@ -752,6 +765,8 @@ void Init_do_sqlite3_ext() { rb_define_method(cConnection, "dispose", cConnection_dispose, 0); rb_define_method(cConnection, "quote_boolean", cConnection_quote_boolean, 1); rb_define_method(cConnection, "quote_string", cConnection_quote_string, 1); + rb_define_method(cConnection, "quote_byte_array", cConnection_quote_byte_array, 1); + rb_define_method(cConnection, "character_set", cConnection_character_set, 0); cCommand = SQLITE3_CLASS("Command", cDO_Command); rb_define_method(cCommand, "set_types", cCommand_set_types, -1); diff --git a/do_sqlite3/spec/spec_helper.rb b/do_sqlite3/spec/spec_helper.rb index ede0e045..ae6a85c1 100644 --- a/do_sqlite3/spec/spec_helper.rb +++ b/do_sqlite3/spec/spec_helper.rb @@ -111,7 +111,7 @@ def setup_test_environment 1.upto(16) do |n| conn.create_command(<<-EOF).execute_non_query - insert into widgets(code, name, shelf_location, description, image_data, ad_description, ad_image, whitepaper_text, cad_drawing, super_number, weight) VALUES ('W#{n.to_s.rjust(7,"0")}', 'Widget #{n}', 'A14', 'This is a description', 'IMAGE DATA', 'Buy this product now!', 'AD IMAGE DATA', 'String', 'CAD DRAWING', 1234, 13.4); + insert into widgets(code, name, shelf_location, description, image_data, ad_description, ad_image, whitepaper_text, cad_drawing, super_number, weight) VALUES ('W#{n.to_s.rjust(7,"0")}', 'Widget #{n}', 'A14', 'This is a description', 'IMAGE DATA', 'Buy this product now!', 'AD IMAGE DATA', 'String', X'434144200120002044524157494e47', 1234, 13.4); EOF end diff --git a/do_sqlite3/spec/typecast/byte_array_spec.rb b/do_sqlite3/spec/typecast/byte_array_spec.rb index 08f4b0f0..819f2de9 100644 --- a/do_sqlite3/spec/typecast/byte_array_spec.rb +++ b/do_sqlite3/spec/typecast/byte_array_spec.rb @@ -4,6 +4,5 @@ require 'data_objects/spec/typecast/byte_array_spec' describe 'DataObjects::Sqlite3 with ByteArray' do - # We need to switch to using parameter binding for this to work with Sqlite3 - # it_should_behave_like 'supporting ByteArray' + it_should_behave_like 'supporting ByteArray' end diff --git a/do_sqlserver/spec/encoding_spec.rb b/do_sqlserver/spec/encoding_spec.rb index 3027ffcf..06f513a2 100644 --- a/do_sqlserver/spec/encoding_spec.rb +++ b/do_sqlserver/spec/encoding_spec.rb @@ -4,5 +4,5 @@ require 'data_objects/spec/encoding_spec' describe DataObjects::SqlServer::Connection do - it_should_behave_like 'a driver supporting encodings' + it_should_behave_like 'a driver supporting different encodings' end