lib/pg_conn.rb in pg_conn-0.26.0 vs lib/pg_conn.rb in pg_conn-0.26.1
- old
+ new
@@ -313,45 +313,25 @@
def quote_tuples(tuples, elem_types: nil)
tuples.map { |tuple| "(#{quote_tuple(tuple, elem_types: elem_types)})" }.join(", ")
end
# Quote a record and cast it into the given type, the type can also be a
- # table or view. 'data' is a hash or struct representation of the record
+ # table or view. 'data' is an array, hash, or struct representation of the
+ # record
#
# Note that the fields are retrived from the database so this method is not
# as fast as the other quote-methods. It is however very convenient when
# you're testing and need a composite type because record-quoting can
# easily become unwieldly
- def quote_record(schema_name = nil, type, data, elem_types: nil)
- qual_name = [schema_name, type].compact .join('.')
-
- fields = self.values(%(
- select attname
- from pg_attribute
- where
- attrelid = '#{qual_name}'::regclass
- and attnum > 0
- and not attisdropped
- order by attnum
- )).map(&:to_sym)
-
- values =
- case data
- when Hash; fields.map { |f| data[f] }
- when OpenStruct; fields.map { |f| data.send(f) }
- when Array; data
- else
- raise Error, "Illegal value #{data.inspect}"
- end
-
- "(#{quote_tuple(values, elem_types: elem_types)})::#{qual_name}"
+ def quote_record(data, schema_name = nil, type, elem_types: nil)
+ quote_record_impl(data, schema_name, type, elem_types: elem_types, array: false)
end
- def quote_records(schema_name = nil, type, datas, elem_types: nil)
- qual_name = [schema_name, type].compact .join('.') + "[]"
- records = datas.map { |data| quote_record(schema_name, type, data, elem_types: elem_types) }
- "array[#{records.join(", ")}]::#{qual_name}"
+ # Quote an array of records. The type is the record type, not the type of
+ # the enclosing array
+ def quote_records(data, schema_name = nil, type, elem_types: nil)
+ quote_record_impl(data, schema_name, type, elem_types: elem_types, array: true)
end
# :call-seq:
# exist?(query)
# exist?(table, id)
@@ -975,9 +955,45 @@
Process::Sys.seteuid 0
Process::Sys.setguid 0
end
else
PG::Connection.new *args, **opts
+ end
+ end
+
+ # Common implementation for #quote_record and #quote_records that avoids
+ # query the database multiple times while not duplication the code. the
+ # :array flag controls the mode
+ def quote_record_impl(datas, schema_name = nil, type, elem_types: nil, array: nil)
+ pg_type = [schema_name, type].compact.join('.')
+ fields = self.values(%(
+ select attname
+ from pg_attribute
+ where
+ attrelid = '#{pg_type}'::regclass
+ and attnum > 0
+ and not attisdropped
+ order by attnum
+ )).map(&:to_sym)
+
+ datas = [datas] if !array
+
+ literals = datas.map { |data|
+ values =
+ case data
+ when Hash; fields.map { |f| data[f] }
+ when OpenStruct; fields.map { |f| data.send(f) }
+ when Array; data
+ else
+ raise Error, "Illegal value #{data.inspect}"
+ end
+ "(#{quote_tuple(values, elem_types: elem_types)})::#{pg_type}"
+ }
+
+ if array
+ "array[#{literals.join(', ')}]::#{pg_type}[]"
+ else
+ literals.first
end
end
# :call-seq:
# pg_exec(string)