PG::

TypeMapInRuby class

This class can be used to implement a type map in ruby, typically as a default_type_map in a type map chain.

This API is EXPERIMENTAL and could change in the future.

Public Instance Methods

fit_to_copy_get()

Check that the type map can be used for PG::Connection#get_copy_data.

This method is called, when a type map is used for decoding copy data, before the value is casted.

Should return the expected number of columns or 0 if the number of columns is unknown. This number is only used for memory pre-allocation.

static VALUE pg_tmir_fit_to_copy_get_dummy( VALUE self ){
fit_to_query( params )

Check that the type map fits to the given user values.

This method is called, when a type map is used for sending a query and for encoding of copy data, before the value is casted.

static VALUE
pg_tmir_fit_to_query( VALUE self, VALUE params )
{
        t_tmir *this = RTYPEDDATA_DATA( self );
        t_typemap *default_tm;

        if( rb_respond_to(self, s_id_fit_to_query) ){
                rb_funcall( self, s_id_fit_to_query, 1, params );
        }

        /* Ensure that the default type map fits equally. */
        default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
        default_tm->funcs.fit_to_query( this->typemap.default_typemap, params );

        return self;
}
fit_to_result( result )

Check that the type map fits to the result.

This method is called, when a type map is assigned to a result. It must return a PG::TypeMap object or raise an Exception. This can be self or some other type map that fits to the result.

static VALUE
pg_tmir_fit_to_result( VALUE self, VALUE result )
{
        t_tmir *this = RTYPEDDATA_DATA( self );
        t_typemap *default_tm;
        t_typemap *p_new_typemap;
        VALUE sub_typemap;
        VALUE new_typemap;

        if( rb_respond_to(self, s_id_fit_to_result) ){
                t_typemap *tm;
                UNUSED(tm);
                new_typemap = rb_funcall( self, s_id_fit_to_result, 1, result );

                if ( !rb_obj_is_kind_of(new_typemap, rb_cTypeMap) ) {
                        /* TypedData_Get_Struct() raises "wrong argument type", which is misleading,
                        * so we better raise our own message */
                        rb_raise( rb_eTypeError, "wrong return type from fit_to_result: %s expected kind of PG::TypeMap",
                                        rb_obj_classname( new_typemap ) );
                }
                TypedData_Get_Struct(new_typemap, t_typemap, &pg_typemap_type, tm);
        } else {
                new_typemap = self;
        }

        /* Ensure that the default type map fits equally. */
        default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
        sub_typemap = default_tm->funcs.fit_to_result( this->typemap.default_typemap, result );

        if( sub_typemap != this->typemap.default_typemap ){
                new_typemap = rb_obj_dup( new_typemap );
        }

        p_new_typemap = RTYPEDDATA_DATA(new_typemap);
        p_new_typemap->default_typemap = sub_typemap;
        return new_typemap;
}
typecast_copy_get( field_str, fieldno, format, encoding )

Cast a field string received by PG::Connection#get_copy_data.

This method implementation uses the default_type_map to cast field_str. It can be derived to change this behaviour.

Parameters:

  • field_str : The String received from the server.

  • fieldno : The field number from left to right.

  • format : The format code (0 = text, 1 = binary)

  • encoding : The encoding of the connection and encoding the returned value should get.

static VALUE
pg_tmir_typecast_copy_get( VALUE self, VALUE field_str, VALUE fieldno, VALUE format, VALUE enc )
{
        t_tmir *this = RTYPEDDATA_DATA( self );
        t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
        int enc_idx = rb_to_encoding_index( enc );

        return default_tm->funcs.typecast_copy_get( default_tm, field_str, NUM2INT(fieldno), NUM2INT(format), enc_idx );
}
typecast_query_param( param_value, field )

Cast a field string for transmission to the server.

This method implementation uses the default_type_map to cast param_value. It can be derived to change this behaviour.

Parameters:

  • param_value : The value from the user.

  • field : The field number from left to right.

static VALUE
pg_tmir_typecast_query_param( VALUE self, VALUE param_value, VALUE field )
{
        t_tmir *this = RTYPEDDATA_DATA( self );
        t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
        t_pg_coder *p_coder = default_tm->funcs.typecast_query_param( default_tm, param_value, NUM2INT(field) );

        return p_coder ? p_coder->coder_obj : Qnil;
}
typecast_result_value( result, tuple, field )

Retrieve and cast a field of the given result.

This method implementation uses the default_type_map to get the field value. It can be derived to change this behaviour.

Parameters:

  • result : The PG::Result received from the database.

  • tuple : The row number to retrieve.

  • field : The column number to retrieve.

Note: Calling any value retrieving methods of result will result in an (endless) recursion. Instead super() can be used to retrieve the value using the default_typemap.

static VALUE
pg_tmir_typecast_result_value( VALUE self, VALUE result, VALUE tuple, VALUE field )
{
        t_tmir *this = RTYPEDDATA_DATA( self );
        t_typemap *default_tm = RTYPEDDATA_DATA( this->typemap.default_typemap );
        return default_tm->funcs.typecast_result_value( default_tm, result, NUM2INT(tuple), NUM2INT(field) );
}