add :cast_booleans option for automatically casting tinyint(1) fields into true/false for ruby
This commit is contained in:
parent
12c022c8aa
commit
2514fafa53
@ -9,7 +9,8 @@ VALUE cBigDecimal, cDate, cDateTime;
|
||||
extern VALUE mMysql2, cMysql2Client, cMysql2Error;
|
||||
static VALUE intern_encoding_from_charset;
|
||||
static ID intern_new, intern_utc, intern_local, intern_encoding_from_charset_code;
|
||||
static ID sym_symbolize_keys, sym_as, sym_array, sym_timezone, sym_local, sym_utc;
|
||||
static ID sym_symbolize_keys, sym_as, sym_array, sym_timezone, sym_local, sym_utc,
|
||||
sym_cast_booleans;
|
||||
static ID intern_merge;
|
||||
|
||||
static void rb_mysql_result_mark(void * wrapper) {
|
||||
@ -86,7 +87,7 @@ static VALUE rb_mysql_result_fetch_field(VALUE self, unsigned int idx, short int
|
||||
return rb_field;
|
||||
}
|
||||
|
||||
static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKeys, int asArray) {
|
||||
static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKeys, int asArray, int castBool) {
|
||||
VALUE rowVal;
|
||||
mysql2_result_wrapper * wrapper;
|
||||
MYSQL_ROW row;
|
||||
@ -131,6 +132,10 @@ static VALUE rb_mysql_result_fetch_row(VALUE self, ID timezone, int symbolizeKey
|
||||
val = rb_str_new(row[i], fieldLengths[i]);
|
||||
break;
|
||||
case MYSQL_TYPE_TINY: // TINYINT field
|
||||
if (castBool && fields[i].length == 1) {
|
||||
val = *row[i] == '1' ? Qtrue : Qfalse;
|
||||
break;
|
||||
}
|
||||
case MYSQL_TYPE_SHORT: // SMALLINT field
|
||||
case MYSQL_TYPE_LONG: // INTEGER field
|
||||
case MYSQL_TYPE_INT24: // MEDIUMINT field
|
||||
@ -266,7 +271,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
||||
ID timezone;
|
||||
mysql2_result_wrapper * wrapper;
|
||||
unsigned long i;
|
||||
int symbolizeKeys = 0, asArray = 0;
|
||||
int symbolizeKeys = 0, asArray = 0, castBool = 0;
|
||||
|
||||
GetMysql2Result(self, wrapper);
|
||||
|
||||
@ -285,6 +290,10 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
||||
asArray = 1;
|
||||
}
|
||||
|
||||
if (rb_hash_aref(opts, sym_cast_booleans) == Qtrue) {
|
||||
castBool = 1;
|
||||
}
|
||||
|
||||
timezoneVal = rb_hash_aref(opts, sym_timezone);
|
||||
if (timezoneVal == sym_local) {
|
||||
timezone = intern_local;
|
||||
@ -318,7 +327,7 @@ static VALUE rb_mysql_result_each(int argc, VALUE * argv, VALUE self) {
|
||||
if (i < rowsProcessed) {
|
||||
row = rb_ary_entry(wrapper->rows, i);
|
||||
} else {
|
||||
row = rb_mysql_result_fetch_row(self, timezone, symbolizeKeys, asArray);
|
||||
row = rb_mysql_result_fetch_row(self, timezone, symbolizeKeys, asArray, castBool);
|
||||
rb_ary_store(wrapper->rows, i, row);
|
||||
wrapper->lastRowProcessed++;
|
||||
}
|
||||
@ -381,6 +390,7 @@ void init_mysql2_result() {
|
||||
sym_timezone = ID2SYM(rb_intern("timezone"));
|
||||
sym_local = ID2SYM(rb_intern("local"));
|
||||
sym_utc = ID2SYM(rb_intern("utc"));
|
||||
sym_cast_booleans = ID2SYM(rb_intern("cast_booleans"));
|
||||
|
||||
#ifdef HAVE_RUBY_ENCODING_H
|
||||
binaryEncoding = rb_enc_find("binary");
|
||||
|
@ -5,7 +5,8 @@ module Mysql2
|
||||
:symbolize_keys => false,
|
||||
:async => false,
|
||||
:as => :hash,
|
||||
:timezone => :local
|
||||
:timezone => :local,
|
||||
:cast_booleans => false
|
||||
}
|
||||
|
||||
def initialize(opts = {})
|
||||
|
@ -71,65 +71,9 @@ describe Mysql2::Result do
|
||||
context "row data type mapping" do
|
||||
before(:each) do
|
||||
@client.query "USE test"
|
||||
@client.query %[
|
||||
CREATE TABLE IF NOT EXISTS mysql2_test (
|
||||
id MEDIUMINT NOT NULL AUTO_INCREMENT,
|
||||
null_test VARCHAR(10),
|
||||
bit_test BIT(64),
|
||||
tiny_int_test TINYINT,
|
||||
small_int_test SMALLINT,
|
||||
medium_int_test MEDIUMINT,
|
||||
int_test INT,
|
||||
big_int_test BIGINT,
|
||||
float_test FLOAT(10,3),
|
||||
double_test DOUBLE(10,3),
|
||||
decimal_test DECIMAL(10,3),
|
||||
date_test DATE,
|
||||
date_time_test DATETIME,
|
||||
timestamp_test TIMESTAMP,
|
||||
time_test TIME,
|
||||
year_test YEAR(4),
|
||||
char_test CHAR(10),
|
||||
varchar_test VARCHAR(10),
|
||||
binary_test BINARY(10),
|
||||
varbinary_test VARBINARY(10),
|
||||
tiny_blob_test TINYBLOB,
|
||||
tiny_text_test TINYTEXT,
|
||||
blob_test BLOB,
|
||||
text_test TEXT,
|
||||
medium_blob_test MEDIUMBLOB,
|
||||
medium_text_test MEDIUMTEXT,
|
||||
long_blob_test LONGBLOB,
|
||||
long_text_test LONGTEXT,
|
||||
enum_test ENUM('val1', 'val2'),
|
||||
set_test SET('val1', 'val2'),
|
||||
PRIMARY KEY (id)
|
||||
)
|
||||
]
|
||||
@client.query %[
|
||||
INSERT INTO mysql2_test (
|
||||
null_test, bit_test, tiny_int_test, small_int_test, medium_int_test, int_test, big_int_test,
|
||||
float_test, double_test, decimal_test, date_test, date_time_test, timestamp_test, time_test,
|
||||
year_test, char_test, varchar_test, binary_test, varbinary_test, tiny_blob_test,
|
||||
tiny_text_test, blob_test, text_test, medium_blob_test, medium_text_test,
|
||||
long_blob_test, long_text_test, enum_test, set_test
|
||||
)
|
||||
|
||||
VALUES (
|
||||
NULL, b'101', 1, 10, 10, 10, 10,
|
||||
10.3, 10.3, 10.3, '2010-4-4', '2010-4-4 11:44:00', '2010-4-4 11:44:00', '11:44:00',
|
||||
2009, "test", "test", "test", "test", "test",
|
||||
"test", "test", "test", "test", "test",
|
||||
"test", "test", 'val1', 'val1,val2'
|
||||
)
|
||||
]
|
||||
@test_result = @client.query("SELECT * FROM mysql2_test ORDER BY id DESC LIMIT 1").first
|
||||
end
|
||||
|
||||
after(:all) do
|
||||
@client.query("DELETE FROM mysql2_test WHERE id=#{@test_result['id']}")
|
||||
end
|
||||
|
||||
it "should return nil for a NULL value" do
|
||||
@test_result['null_test'].class.should eql(NilClass)
|
||||
@test_result['null_test'].should eql(nil)
|
||||
@ -145,6 +89,20 @@ describe Mysql2::Result do
|
||||
@test_result['tiny_int_test'].should eql(1)
|
||||
end
|
||||
|
||||
it "should return TrueClass or FalseClass for a TINYINT value if :cast_booleans is enabled" do
|
||||
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (1)'
|
||||
id1 = @client.last_id
|
||||
@client.query 'INSERT INTO mysql2_test (bool_cast_test) VALUES (0)'
|
||||
id2 = @client.last_id
|
||||
|
||||
result1 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 1 LIMIT 1', :cast_booleans => true
|
||||
result2 = @client.query 'SELECT bool_cast_test FROM mysql2_test WHERE bool_cast_test = 0 LIMIT 1', :cast_booleans => true
|
||||
result1.first['bool_cast_test'].should be_true
|
||||
result2.first['bool_cast_test'].should be_false
|
||||
|
||||
@client.query "DELETE from mysql2_test WHERE id IN(#{id1},#{id2})"
|
||||
end
|
||||
|
||||
it "should return Fixnum for a SMALLINT value" do
|
||||
[Fixnum, Bignum].should include(@test_result['small_int_test'].class)
|
||||
@test_result['small_int_test'].should eql(10)
|
||||
|
@ -3,3 +3,62 @@ $LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/..')
|
||||
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + '/../lib')
|
||||
|
||||
require 'mysql2'
|
||||
|
||||
Spec::Runner.configure do |config|
|
||||
config.before(:all) do
|
||||
client = Mysql2::Client.new :database => 'test'
|
||||
client.query %[
|
||||
CREATE TABLE IF NOT EXISTS mysql2_test (
|
||||
id MEDIUMINT NOT NULL AUTO_INCREMENT,
|
||||
null_test VARCHAR(10),
|
||||
bit_test BIT(64),
|
||||
tiny_int_test TINYINT,
|
||||
bool_cast_test TINYINT(1),
|
||||
small_int_test SMALLINT,
|
||||
medium_int_test MEDIUMINT,
|
||||
int_test INT,
|
||||
big_int_test BIGINT,
|
||||
float_test FLOAT(10,3),
|
||||
double_test DOUBLE(10,3),
|
||||
decimal_test DECIMAL(10,3),
|
||||
date_test DATE,
|
||||
date_time_test DATETIME,
|
||||
timestamp_test TIMESTAMP,
|
||||
time_test TIME,
|
||||
year_test YEAR(4),
|
||||
char_test CHAR(10),
|
||||
varchar_test VARCHAR(10),
|
||||
binary_test BINARY(10),
|
||||
varbinary_test VARBINARY(10),
|
||||
tiny_blob_test TINYBLOB,
|
||||
tiny_text_test TINYTEXT,
|
||||
blob_test BLOB,
|
||||
text_test TEXT,
|
||||
medium_blob_test MEDIUMBLOB,
|
||||
medium_text_test MEDIUMTEXT,
|
||||
long_blob_test LONGBLOB,
|
||||
long_text_test LONGTEXT,
|
||||
enum_test ENUM('val1', 'val2'),
|
||||
set_test SET('val1', 'val2'),
|
||||
PRIMARY KEY (id)
|
||||
)
|
||||
]
|
||||
client.query %[
|
||||
INSERT INTO mysql2_test (
|
||||
null_test, bit_test, tiny_int_test, bool_cast_test, small_int_test, medium_int_test, int_test, big_int_test,
|
||||
float_test, double_test, decimal_test, date_test, date_time_test, timestamp_test, time_test,
|
||||
year_test, char_test, varchar_test, binary_test, varbinary_test, tiny_blob_test,
|
||||
tiny_text_test, blob_test, text_test, medium_blob_test, medium_text_test,
|
||||
long_blob_test, long_text_test, enum_test, set_test
|
||||
)
|
||||
|
||||
VALUES (
|
||||
NULL, b'101', 1, 1, 10, 10, 10, 10,
|
||||
10.3, 10.3, 10.3, '2010-4-4', '2010-4-4 11:44:00', '2010-4-4 11:44:00', '11:44:00',
|
||||
2009, "test", "test", "test", "test", "test",
|
||||
"test", "test", "test", "test", "test",
|
||||
"test", "test", 'val1', 'val1,val2'
|
||||
)
|
||||
]
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user