Skip to content

DefaultTypeConverterFactory

Alexey Borzov edited this page Jul 19, 2020 · 2 revisions

DefaultTypeConverterFactory class

This is the default implementation of TypeConverterFactory interface. Its instance is automatically added to a Connection unless setTypeConverterFactory() is explicitly used.

In addition to methods defined in the above interface, the following public methods are available:

  • registerConverter(string|callable|TypeConverter $converter, string|array $type, string $schema = 'pg_catalog') - this registers a new converter for a base type. $converter argument is either a class name, a callable returning TypeConverter instance or an object implementing TypeConverter that will be used as a prototype for cloning.
  • setCompositeTypesCaching(bool $caching): $this / getCompositeTypesCaching(): bool - this controls whether structure of composite (row) types will be stored in the cache. If the cached list of columns is used to convert the composite value with different columns the conversion will obviously fail, so that should be set to false if you:
    • Use composite types in the application;
    • Expect changes to those types.
  • registerClassMapping(string $className, string $type, string $schema = 'pg_catalog') - registers a mapping from PHP class to a database type name. If you pass an instance of this class to getConverterForPHPValue() it will return a converter for this type.

Note that it is only needed to register converters for base types, proper converters for arrays / composites / ranges over these base types will be built automatically:

$factory->registerConverter('BlahConverter', 'blah', 'blah');
$factory->getConverter('blah.blah[]');

will return

new ArrayConverter(new BlahConverter());

getConverterForTypeSpecification() arguments

DefaultTypeConverterFactory::getConverterForTypeSpecification() method accepts the following type specifications:

  • Type name as a string. A minimal parser is implemented, so schema-qualified names like 'pg_catalog.int4', double-quoted identifiers like '"CamelCaseType"', SQL standard names like 'CHARACTER VARYING' will be understood.
  • TypeConverter instance. Its properties will be updated from current Connection object if needed (e.g. date and time converters will use DateStyle setting of connected database).
  • Composite type specification as an array 'column' => 'column type specification'

If no converter is found for a base type referenced by name, an InvalidArgumentException will be thrown. Reasoning here is that type names are provided manually, so there is an error on user's part (a typo in the name or converter not registered).

Database lookups and caching

DefaultTypeConverterFactory is pre-populated with info on PostgreSQL's built-in data types. If you use only these types, then there will be no need to query database.

If, however, your database has some custom types (ENUMs count), then the class will load type info from the database, and can later store it in the cache implementation set via Connection::setMetadataCache().

Using some sort of cache is highly recommended in production to prevent database lookups on each page request. Note though that while the class is smart enough to reload metadata when OID is not found (i.e. a new type was added) it is unable to handle changes in composite type structure, so either disable caching of that or invalidate the cache manually.