Class: PG::Coder

Inherits:
Object
  • Object
show all
Defined in:
ext/pg_coder.c,
lib/pg/coder.rb,
ext/pg_coder.c

Overview

This is the base class for all type cast encoder and decoder classes.

It can be used for implicit type casts by a PG::TypeMap or to convert single values to/from their string representation by #encode and #decode.

Ruby nil values are not handled by encoders, but are always transmitted as SQL NULL value. Vice versa SQL NULL values are not handled by decoders, but are always returned as a nil value.

Direct Known Subclasses

CompositeCoder, CopyCoder, SimpleCoder

Defined Under Namespace

Modules: BinaryFormatting

Constant Summary collapse

TIMESTAMP_DB_UTC =

:Coder#flags=

define flags to be used with PG
TIMESTAMP_DB_LOCAL =
INT2NUM(PG_CODER_TIMESTAMP_DB_LOCAL)
TIMESTAMP_APP_UTC =
INT2NUM(PG_CODER_TIMESTAMP_APP_UTC)
TIMESTAMP_APP_LOCAL =
INT2NUM(PG_CODER_TIMESTAMP_APP_LOCAL)
FORMAT_ERROR_MASK =
INT2NUM(PG_CODER_FORMAT_ERROR_MASK)
FORMAT_ERROR_TO_RAISE =
INT2NUM(PG_CODER_FORMAT_ERROR_TO_RAISE)
FORMAT_ERROR_TO_STRING =
INT2NUM(PG_CODER_FORMAT_ERROR_TO_STRING)
FORMAT_ERROR_TO_PARTIAL =
INT2NUM(PG_CODER_FORMAT_ERROR_TO_PARTIAL)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(params = {}) ⇒ Coder

Create a new coder object based on the attribute Hash.



16
17
18
19
20
# File 'lib/pg/coder.rb', line 16

def initialize(params={})
	params.each do |key, val|
		send("#{key}=", val)
	end
end

Instance Attribute Details

#nameObject

Name of the coder or the corresponding data type.

This accessor is only used in PG::Coder#inspect .

Instance Method Details

#==(v) ⇒ Object



35
36
37
# File 'lib/pg/coder.rb', line 35

def ==(v)
	self.class == v.class && to_h == v.to_h
end

#decode(string, tuple = nil, field = nil) ⇒ Object

Decodes the given string representation into a Ruby object, without sending data to/from the database server.

A nil value is passed through and non String values are expected to have #to_str defined.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'ext/pg_coder.c', line 178

static VALUE
pg_coder_decode(int argc, VALUE *argv, VALUE self)
{
	char *val;
	int tuple = -1;
	int field = -1;
	VALUE res;
	t_pg_coder *this = DATA_PTR(self);

	if(argc < 1 || argc > 3){
		rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..3)", argc);
	}else if(argc >= 3){
		tuple = NUM2INT(argv[1]);
		field = NUM2INT(argv[2]);
	}

	if( NIL_P(argv[0]) )
		return Qnil;

	if( this->format == 0 ){
		val = StringValueCStr(argv[0]);
	}else{
		val = StringValuePtr(argv[0]);
	}
	if( !this->dec_func ){
		rb_raise(rb_eRuntimeError, "no decoder function defined");
	}

	res = this->dec_func(this, val, RSTRING_LEN(argv[0]), tuple, field, ENCODING_GET(argv[0]));
	OBJ_INFECT(res, argv[0]);

	return res;
}

#dupObject



22
23
24
# File 'lib/pg/coder.rb', line 22

def dup
	self.class.new(to_h)
end

#encode(value[, encoding]) ⇒ Object

Encodes the given Ruby object into string representation, without sending data to/from the database server.

A nil value is passed through.



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
# File 'ext/pg_coder.c', line 118

static VALUE
pg_coder_encode(int argc, VALUE *argv, VALUE self)
{
	VALUE res;
	VALUE intermediate;
	VALUE value;
	int len, len2;
	int enc_idx;
	t_pg_coder *this = DATA_PTR(self);

	if(argc < 1 || argc > 2){
		rb_raise(rb_eArgError, "wrong number of arguments (%i for 1..2)", argc);
	}else if(argc == 1){
		enc_idx = rb_ascii8bit_encindex();
	}else{
		enc_idx = rb_to_encoding_index(argv[1]);
	}
	value = argv[0];

	if( NIL_P(value) )
		return Qnil;

	if( !this->enc_func ){
		rb_raise(rb_eRuntimeError, "no encoder function defined");
	}

	len = this->enc_func( this, value, NULL, &intermediate, enc_idx );

	if( len == -1 ){
		/* The intermediate value is a String that can be used directly. */
		OBJ_INFECT(intermediate, value);
		return intermediate;
	}

	res = rb_str_new(NULL, len);
	PG_ENCODING_SET_NOCHECK(res, enc_idx);
	len2 = this->enc_func( this, value, RSTRING_PTR(res), &intermediate, enc_idx );
	if( len < len2 ){
		rb_bug("%s: result length of first encoder run (%i) is less than second run (%i)",
			rb_obj_classname( self ), len, len2 );
	}
	rb_str_set_len( res, len2 );
	OBJ_INFECT(res, value);

	RB_GC_GUARD(intermediate);

	return res;
}

#flagsInteger

Get current bitwise OR-ed coder flags.

Returns:

  • (Integer)


297
298
299
300
301
302
# File 'ext/pg_coder.c', line 297

static VALUE
pg_coder_flags_get(VALUE self)
{
	t_pg_coder *this = DATA_PTR(self);
	return INT2NUM(this->flags);
}

#flags=(Integer) ⇒ Object

Set coder specific bitwise OR-ed flags. See the particular en- or decoder description for available flags.

The default is 0.



283
284
285
286
287
288
289
# File 'ext/pg_coder.c', line 283

static VALUE
pg_coder_flags_set(VALUE self, VALUE flags)
{
	t_pg_coder *this = DATA_PTR(self);
	this->flags = NUM2INT(flags);
	return flags;
}

#formatInteger

The format code that is sent alongside with an encoded query parameter value.

Returns:

  • (Integer)


267
268
269
270
271
272
# File 'ext/pg_coder.c', line 267

static VALUE
pg_coder_format_get(VALUE self)
{
	t_pg_coder *this = DATA_PTR(self);
	return INT2NUM(this->format);
}

#format=(Integer) ⇒ Object

Specifies the format code that is sent alongside with an encoded query parameter value.

The default is 0.



252
253
254
255
256
257
258
# File 'ext/pg_coder.c', line 252

static VALUE
pg_coder_format_set(VALUE self, VALUE format)
{
	t_pg_coder *this = DATA_PTR(self);
	this->format = NUM2INT(format);
	return format;
}

#inspectObject



47
48
49
50
51
52
53
54
# File 'lib/pg/coder.rb', line 47

def inspect
	str = self.to_s
	oid_str = " oid=#{oid}" unless oid==0
	format_str = " format=#{format}" unless format==0
	name_str = " #{name.inspect}" if name
	str[-1,0] = "#{name_str} #{oid_str}#{format_str}"
	str
end

#marshal_dumpObject



39
40
41
# File 'lib/pg/coder.rb', line 39

def marshal_dump
	Marshal.dump(to_h)
end

#marshal_load(str) ⇒ Object



43
44
45
# File 'lib/pg/coder.rb', line 43

def marshal_load(str)
	initialize Marshal.load(str)
end

#oidInteger

The type OID that is sent alongside with an encoded query parameter value.

Returns:

  • (Integer)


236
237
238
239
240
241
# File 'ext/pg_coder.c', line 236

static VALUE
pg_coder_oid_get(VALUE self)
{
	t_pg_coder *this = DATA_PTR(self);
	return UINT2NUM(this->oid);
}

#oid=(Integer) ⇒ Object

Specifies the type OID that is sent alongside with an encoded query parameter value.

The default is 0.



221
222
223
224
225
226
227
# File 'ext/pg_coder.c', line 221

static VALUE
pg_coder_oid_set(VALUE self, VALUE oid)
{
	t_pg_coder *this = DATA_PTR(self);
	this->oid = NUM2UINT(oid);
	return oid;
}

#to_hObject

Returns coder attributes as Hash.



27
28
29
30
31
32
33
# File 'lib/pg/coder.rb', line 27

def to_h
	{
		oid: oid,
		format: format,
		name: name,
	}
end