File: pg_type_map.c

package info (click to toggle)
ruby-pg 1.5.6-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,264 kB
  • sloc: ansic: 8,820; ruby: 2,809; makefile: 10
file content (200 lines) | stat: -rw-r--r-- 5,036 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/*
 * pg_column_map.c - PG::ColumnMap class extension
 * $Id$
 *
 */

#include "pg.h"

void
pg_typemap_mark( void *_this )
{
	t_typemap *this = (t_typemap *)_this;
	rb_gc_mark_movable(this->default_typemap);
}

size_t
pg_typemap_memsize( const void *_this )
{
	t_typemap *this = (t_typemap *)_this;
	return sizeof(*this);
}

void
pg_typemap_compact( void *_this )
{
	t_typemap *this = (t_typemap *)_this;
	pg_gc_location(this->default_typemap);
}

const rb_data_type_t pg_typemap_type = {
	"PG::TypeMap",
	{
		pg_typemap_mark,
		RUBY_TYPED_DEFAULT_FREE,
		pg_typemap_memsize,
		pg_compact_callback(pg_typemap_compact),
	},
	0,
	0,
	RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | PG_RUBY_TYPED_FROZEN_SHAREABLE,
};

VALUE rb_cTypeMap;
VALUE rb_mDefaultTypeMappable;
static ID s_id_fit_to_query;
static ID s_id_fit_to_result;

NORETURN( VALUE
pg_typemap_fit_to_result( VALUE self, VALUE result ));
NORETURN( VALUE
pg_typemap_fit_to_query( VALUE self, VALUE params ));
NORETURN( int
pg_typemap_fit_to_copy_get( VALUE self ));
NORETURN( VALUE
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field ));
NORETURN( t_pg_coder *
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field ));
NORETURN( VALUE
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx ));

VALUE
pg_typemap_fit_to_result( VALUE self, VALUE result )
{
	rb_raise( rb_eNotImpError, "type map %s is not suitable to map result values", rb_obj_classname(self) );
}

VALUE
pg_typemap_fit_to_query( VALUE self, VALUE params )
{
	rb_raise( rb_eNotImpError, "type map %s is not suitable to map query params", rb_obj_classname(self) );
}

int
pg_typemap_fit_to_copy_get( VALUE self )
{
	rb_raise( rb_eNotImpError, "type map %s is not suitable to map get_copy_data results", rb_obj_classname(self) );
}

VALUE
pg_typemap_result_value( t_typemap *p_typemap, VALUE result, int tuple, int field )
{
	rb_raise( rb_eNotImpError, "type map is not suitable to map result values" );
}

t_pg_coder *
pg_typemap_typecast_query_param( t_typemap *p_typemap, VALUE param_value, int field )
{
	rb_raise( rb_eNotImpError, "type map is not suitable to map query params" );
}

VALUE
pg_typemap_typecast_copy_get( t_typemap *p_typemap, VALUE field_str, int fieldno, int format, int enc_idx )
{
	rb_raise( rb_eNotImpError, "type map is not suitable to map get_copy_data results" );
}

const struct pg_typemap_funcs pg_typemap_funcs = {
	pg_typemap_fit_to_result,
	pg_typemap_fit_to_query,
	pg_typemap_fit_to_copy_get,
	pg_typemap_result_value,
	pg_typemap_typecast_query_param,
	pg_typemap_typecast_copy_get
};

static VALUE
pg_typemap_s_allocate( VALUE klass )
{
	VALUE self;
	t_typemap *this;

	self = TypedData_Make_Struct( klass, t_typemap, &pg_typemap_type, this );
	this->funcs = pg_typemap_funcs;

	return self;
}

/*
 * call-seq:
 *    res.default_type_map = typemap
 *
 * Set the default TypeMap that is used for values that could not be
 * casted by this type map.
 *
 * +typemap+ must be a kind of PG::TypeMap
 *
 */
static VALUE
pg_typemap_default_type_map_set(VALUE self, VALUE typemap)
{
	t_typemap *this = RTYPEDDATA_DATA( self );
	t_typemap *tm;
	UNUSED(tm);

	rb_check_frozen(self);
	/* Check type of method param */
	TypedData_Get_Struct(typemap, t_typemap, &pg_typemap_type, tm);
	RB_OBJ_WRITE(self, &this->default_typemap, typemap);

	return typemap;
}

/*
 * call-seq:
 *    res.default_type_map -> TypeMap
 *
 * Returns the default TypeMap that is currently set for values that could not be
 * casted by this type map.
 *
 * Returns a kind of PG::TypeMap.
 *
 */
static VALUE
pg_typemap_default_type_map_get(VALUE self)
{
	t_typemap *this = RTYPEDDATA_DATA( self );

	return this->default_typemap;
}

/*
 * call-seq:
 *    res.with_default_type_map( typemap )
 *
 * Set the default TypeMap that is used for values that could not be
 * casted by this type map.
 *
 * +typemap+ must be a kind of PG::TypeMap
 *
 * Returns self.
 */
static VALUE
pg_typemap_with_default_type_map(VALUE self, VALUE typemap)
{
	pg_typemap_default_type_map_set( self, typemap );
	return self;
}

void
init_pg_type_map(void)
{
	s_id_fit_to_query = rb_intern("fit_to_query");
	s_id_fit_to_result = rb_intern("fit_to_result");

	/*
	 * Document-class: PG::TypeMap < Object
	 *
	 * This is the base class for type maps.
	 * See derived classes for implementations of different type cast strategies
	 * ( PG::TypeMapByColumn, PG::TypeMapByOid ).
	 *
	 */
	rb_cTypeMap = rb_define_class_under( rb_mPG, "TypeMap", rb_cObject );
	rb_define_alloc_func( rb_cTypeMap, pg_typemap_s_allocate );

	rb_mDefaultTypeMappable = rb_define_module_under( rb_cTypeMap, "DefaultTypeMappable");
	rb_define_method( rb_mDefaultTypeMappable, "default_type_map=", pg_typemap_default_type_map_set, 1 );
	rb_define_method( rb_mDefaultTypeMappable, "default_type_map", pg_typemap_default_type_map_get, 0 );
	rb_define_method( rb_mDefaultTypeMappable, "with_default_type_map", pg_typemap_with_default_type_map, 1 );
}