@@ -135,6 +135,7 @@ pg_composite_encoder_allocate( VALUE klass )
135135 this -> elem = NULL ;
136136 this -> needs_quotation = 1 ;
137137 this -> delimiter = ',' ;
138+ this -> dimensions = -1 ;
138139 rb_iv_set ( self , "@elements_type" , Qnil );
139140 return self ;
140141}
@@ -157,6 +158,7 @@ pg_composite_decoder_allocate( VALUE klass )
157158 this -> elem = NULL ;
158159 this -> needs_quotation = 1 ;
159160 this -> delimiter = ',' ;
161+ this -> dimensions = -1 ;
160162 rb_iv_set ( self , "@elements_type" , Qnil );
161163 return self ;
162164}
@@ -421,6 +423,49 @@ pg_coder_delimiter_get(VALUE self)
421423 return rb_str_new (& this -> delimiter , 1 );
422424}
423425
426+ /*
427+ * call-seq:
428+ * coder.dimensions = Integer
429+ * coder.dimensions = nil
430+ *
431+ * Set number of array dimensions to be encoded.
432+ *
433+ * This property ensures, that this number of dimensions is always encoded.
434+ * If less dimensions than this number are in the given value, an ArgumentError is raised.
435+ * If more dimensions than this number are in the value, the Array value is passed to the next encoder.
436+ *
437+ * Setting dimensions is especially useful, when a Record shall be encoded into an Array, since the Array encoder can not distinguish if the array shall be encoded as a higher dimension or as a record otherwise.
438+ *
439+ * The default is +nil+.
440+ *
441+ * See #dimensions
442+ */
443+ static VALUE
444+ pg_coder_dimensions_set (VALUE self , VALUE dimensions )
445+ {
446+ t_pg_composite_coder * this = RTYPEDDATA_DATA (self );
447+ rb_check_frozen (self );
448+ if (!NIL_P (dimensions ) && NUM2INT (dimensions ) < 0 )
449+ rb_raise ( rb_eArgError , "dimensions must be nil or >= 0" );
450+ this -> dimensions = NIL_P (dimensions ) ? -1 : NUM2INT (dimensions );
451+ return dimensions ;
452+ }
453+
454+ /*
455+ * call-seq:
456+ * coder.dimensions -> Integer | nil
457+ *
458+ * Get number of enforced array dimensions or +nil+ if not set.
459+ *
460+ * See #dimensions=
461+ */
462+ static VALUE
463+ pg_coder_dimensions_get (VALUE self )
464+ {
465+ t_pg_composite_coder * this = RTYPEDDATA_DATA (self );
466+ return this -> dimensions < 0 ? Qnil : INT2NUM (this -> dimensions );
467+ }
468+
424469/*
425470 * call-seq:
426471 * coder.elements_type = coder
@@ -602,6 +647,8 @@ init_pg_coder(void)
602647 *
603648 * This is the base class for all type cast classes of PostgreSQL types,
604649 * that are made up of some sub type.
650+ *
651+ * See PG::TextEncoder::Array, PG::TextDecoder::Array, PG::BinaryEncoder::Array, PG::BinaryDecoder::Array, etc.
605652 */
606653 rb_cPG_CompositeCoder = rb_define_class_under ( rb_mPG , "CompositeCoder" , rb_cPG_Coder );
607654 rb_define_method ( rb_cPG_CompositeCoder , "elements_type=" , pg_coder_elements_type_set , 1 );
@@ -610,6 +657,8 @@ init_pg_coder(void)
610657 rb_define_method ( rb_cPG_CompositeCoder , "needs_quotation?" , pg_coder_needs_quotation_get , 0 );
611658 rb_define_method ( rb_cPG_CompositeCoder , "delimiter=" , pg_coder_delimiter_set , 1 );
612659 rb_define_method ( rb_cPG_CompositeCoder , "delimiter" , pg_coder_delimiter_get , 0 );
660+ rb_define_method ( rb_cPG_CompositeCoder , "dimensions=" , pg_coder_dimensions_set , 1 );
661+ rb_define_method ( rb_cPG_CompositeCoder , "dimensions" , pg_coder_dimensions_get , 0 );
613662
614663 /* Document-class: PG::CompositeEncoder < PG::CompositeCoder */
615664 rb_cPG_CompositeEncoder = rb_define_class_under ( rb_mPG , "CompositeEncoder" , rb_cPG_CompositeCoder );
0 commit comments