How to use the type in the Mysql::Field object?


#1

I’m trying to do something like this (not really, I want to use the type
info instead of just displaying it…):

fields = $db.list_fields(tablename).fetch_fields
fields.each do |field|
puts “Type = #{field.type} (#{field.type.class})”
end

Result:
Type = 1 (Fixnum)
Type = 253 (Fixnum)
Type = 2 (Fixnum)
Type = 254 (Fixnum)
etc.

How can I translate the first part to something presentable? I cannot
find any information on how to translate the integer values to something
like FLOAT, SMALLINT, TIMESTAMP, etc.

Does anybody have some information about this?


#2

Patrick P. wrote:

I’m trying to do something like this (not really, I want to use the type
info instead of just displaying it…):

fields = $db.list_fields(tablename).fetch_fields
fields.each do |field|
puts “Type = #{field.type} (#{field.type.class})”
end

Result:
Type = 1 (Fixnum)
Type = 253 (Fixnum)
Type = 2 (Fixnum)
Type = 254 (Fixnum)

These constants are defined in some MySQL header file (And perhaps
MySQL’s manual lists their numerical values in its C API section, I
don’t know). That Ruby extension you’re using exports them as Ruby
constants as well; e.g. Mysql::Field::TYPE_SHORT,
Mysql::Field::TYPE_FLOAT, etc.

Note that there are numerous Mysql Ruby extensions: DBI’s, DataMapper’s,
ActiveRecord’s.

If you look at do_mysql’s ‘do_mysql_ext.c’ (That’s DataObjects’s, which
is DataMapper’s), you’ll find a useful infer_ruby_type() with a big case
statemnt. Here it is:

// Figures out what we should cast a given mysql field type to
static VALUE infer_ruby_type(MYSQL_FIELD *field) {

char* ruby_type;

switch(field->type) {
case MYSQL_TYPE_NULL: {
ruby_type = NULL;
break;
}
case MYSQL_TYPE_TINY: {
ruby_type = “TrueClass”;
break;
}
case MYSQL_TYPE_BIT:
case MYSQL_TYPE_SHORT:
case MYSQL_TYPE_LONG:
case MYSQL_TYPE_INT24:
case MYSQL_TYPE_LONGLONG:
case MYSQL_TYPE_YEAR: {
ruby_type = “Fixnum”;
break;
}
case MYSQL_TYPE_DECIMAL:
case MYSQL_TYPE_NEWDECIMAL: {
ruby_type = “BigDecimal”;
break;
}
case MYSQL_TYPE_FLOAT:
case MYSQL_TYPE_DOUBLE: {
ruby_type = “Float”;
break;
}
case MYSQL_TYPE_TIMESTAMP:
case MYSQL_TYPE_DATETIME: {
ruby_type = “DateTime”;
break;
}
case MYSQL_TYPE_TIME: {
ruby_type = “DateTime”;
break;
}
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_NEWDATE: {
ruby_type = “Date”;
break;
}
default: {
ruby_type = “String”;
break;
}
}

return rb_str_new2(ruby_type);
}

Maybe your extension has a similar funcion. Look in its .c file. E.g.,
search for “_TYPE_DOUBLE” to arrive at the relevant places.


#3

Thank you Alby!

Inspired by your reaction I’ve found the MYSQL_TYPES:

http://sequel.rubyforge.org/rdoc/classes/Mysql/Result.html

I have to admit I could not find a file like mysql.c on my system… :frowning:
It’s Fedora Core 5. I remember that I had to add this library because it
was not in the standard installation.

My problem is solved however.


#4

Albert S. wrote:

Patrick P. wrote:

I have to admit I could not find a file like mysql.c on my system… :frowning:

I was refering to your Ruby extension’s .c code. On my system it’s:

/usr/lib/ruby/gems/1.8/gems/mysql-2.7/mysql.c

And by “these constants are defined in some MySQL header file” I was
refering to MySQL’s own header files. The constants are defined in:

/usr/include/mysql/mysql_com.h


#5

Patrick P. wrote:

I have to admit I could not find a file like mysql.c on my system… :frowning:

I was refering to your Ruby extension’s .c code. On my system it’s:

/usr/lib/ruby/gems/1.8/gems/mysql-2.7/mysql.c