TypeFactory.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  5. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  6. *
  7. * Licensed under The MIT License
  8. * For full copyright and license information, please see the LICENSE.txt
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  12. * @link https://cakephp.org CakePHP(tm) Project
  13. * @since 4.0.0
  14. * @license https://opensource.org/licenses/mit-license.php MIT License
  15. */
  16. namespace Cake\Database;
  17. use InvalidArgumentException;
  18. /**
  19. * Factory for building database type classes.
  20. */
  21. class TypeFactory
  22. {
  23. /**
  24. * List of supported database types. A human readable
  25. * identifier is used as key and a complete namespaced class name as value
  26. * representing the class that will do actual type conversions.
  27. *
  28. * @var string[]
  29. */
  30. protected static $_types = [
  31. 'tinyinteger' => Type\IntegerType::class,
  32. 'smallinteger' => Type\IntegerType::class,
  33. 'integer' => Type\IntegerType::class,
  34. 'biginteger' => Type\IntegerType::class,
  35. 'binary' => Type\BinaryType::class,
  36. 'binaryuuid' => Type\BinaryUuidType::class,
  37. 'boolean' => Type\BoolType::class,
  38. 'date' => Type\DateType::class,
  39. 'datetime' => Type\DateTimeType::class,
  40. 'decimal' => Type\DecimalType::class,
  41. 'float' => Type\FloatType::class,
  42. 'json' => Type\JsonType::class,
  43. 'string' => Type\StringType::class,
  44. 'text' => Type\StringType::class,
  45. 'time' => Type\TimeType::class,
  46. 'timestamp' => Type\DateTimeType::class,
  47. 'uuid' => Type\UuidType::class,
  48. ];
  49. /**
  50. * Contains a map of type object instances to be reused if needed.
  51. *
  52. * @var \Cake\Database\TypeInterface[]
  53. */
  54. protected static $_builtTypes = [];
  55. /**
  56. * Returns a Type object capable of converting a type identified by name.
  57. *
  58. * @param string $name type identifier
  59. * @throws \InvalidArgumentException If type identifier is unknown
  60. * @return \Cake\Database\TypeInterface
  61. */
  62. public static function build(string $name): TypeInterface
  63. {
  64. if (isset(static::$_builtTypes[$name])) {
  65. return static::$_builtTypes[$name];
  66. }
  67. if (!isset(static::$_types[$name])) {
  68. throw new InvalidArgumentException(sprintf('Unknown type "%s"', $name));
  69. }
  70. /** @var \Cake\Database\TypeInterface */
  71. return static::$_builtTypes[$name] = new static::$_types[$name]($name);
  72. }
  73. /**
  74. * Returns an arrays with all the mapped type objects, indexed by name.
  75. *
  76. * @return \Cake\Database\TypeInterface[]
  77. */
  78. public static function buildAll(): array
  79. {
  80. $result = [];
  81. foreach (static::$_types as $name => $type) {
  82. $result[$name] = static::$_builtTypes[$name] ?? static::build($name);
  83. }
  84. return $result;
  85. }
  86. /**
  87. * Set TypeInterface instance capable of converting a type identified by $name
  88. *
  89. * @param string $name The type identifier you want to set.
  90. * @param \Cake\Database\TypeInterface $instance The type instance you want to set.
  91. * @return void
  92. */
  93. public static function set(string $name, TypeInterface $instance): void
  94. {
  95. static::$_builtTypes[$name] = $instance;
  96. }
  97. /**
  98. * Registers a new type identifier and maps it to a fully namespaced classname.
  99. *
  100. * @param string $type Name of type to map.
  101. * @param string $className The classname to register.
  102. * @return void
  103. */
  104. public static function map(string $type, string $className): void
  105. {
  106. static::$_types[$type] = $className;
  107. unset(static::$_builtTypes[$type]);
  108. }
  109. /**
  110. * Set type to classname mapping.
  111. *
  112. * @param string[] $map List of types to be mapped.
  113. * @return void
  114. */
  115. public static function setMap(array $map): void
  116. {
  117. static::$_types = $map;
  118. static::$_builtTypes = [];
  119. }
  120. /**
  121. * Get mapped class name for given type or map array.
  122. *
  123. * @param string|null $type Type name to get mapped class for or null to get map array.
  124. * @return array|string|null Configured class name for given $type or map array.
  125. */
  126. public static function getMap(?string $type = null)
  127. {
  128. if ($type === null) {
  129. return static::$_types;
  130. }
  131. return static::$_types[$type] ?? null;
  132. }
  133. /**
  134. * Clears out all created instances and mapped types classes, useful for testing
  135. *
  136. * @return void
  137. */
  138. public static function clear(): void
  139. {
  140. static::$_types = [];
  141. static::$_builtTypes = [];
  142. }
  143. }