summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlsces <lester@lsces.co.uk>2026-03-03 19:19:01 +0000
committerlsces <lester@lsces.co.uk>2026-03-03 19:19:01 +0000
commit4931fcca9be66faf1b7ce6e50652d0a6640c8920 (patch)
tree366e63bf9be68146ecb737ac777177195c067263
parenta069223605c3449a9d1c20dd71c12a69caaa8f36 (diff)
downloadilluminate-firebird-4931fcca9be66faf1b7ce6e50652d0a6640c8920.tar.gz
illuminate-firebird-4931fcca9be66faf1b7ce6e50652d0a6640c8920.tar.bz2
illuminate-firebird-4931fcca9be66faf1b7ce6e50652d0a6640c8920.zip
In the absence of autoload, dropping this file into /vendor/illuminate/database/Connectors will bypass the missing autoload of this as an extra driver.
-rwxr-xr-xextra/ConnectionFactory.php287
1 files changed, 287 insertions, 0 deletions
diff --git a/extra/ConnectionFactory.php b/extra/ConnectionFactory.php
new file mode 100755
index 0000000..b2d19dc
--- /dev/null
+++ b/extra/ConnectionFactory.php
@@ -0,0 +1,287 @@
+<?php
+
+namespace Illuminate\Database\Connectors;
+
+use Illuminate\Contracts\Container\Container;
+use Illuminate\Database\Connection;
+use Illuminate\Database\MariaDbConnection;
+use Illuminate\Database\MySqlConnection;
+use Illuminate\Database\PostgresConnection;
+use Illuminate\Database\SQLiteConnection;
+use Illuminate\Database\SqlServerConnection;
+use Illuminate\Support\Arr;
+use InvalidArgumentException;
+use PDOException;
+use Xgrz\Firebird\FirebirdConnection;
+use Xgrz\Firebird\FirebirdConnector;
+
+class ConnectionFactory
+{
+ /**
+ * The IoC container instance.
+ *
+ * @var \Illuminate\Contracts\Container\Container
+ */
+ protected $container;
+
+ /**
+ * Create a new connection factory instance.
+ *
+ * @param \Illuminate\Contracts\Container\Container $container
+ */
+ public function __construct(Container $container)
+ {
+ $this->container = $container;
+ }
+
+ /**
+ * Establish a PDO connection based on the configuration.
+ *
+ * @param array $config
+ * @param string|null $name
+ * @return \Illuminate\Database\Connection
+ */
+ public function make(array $config, $name = null)
+ {
+ $config = $this->parseConfig($config, $name);
+
+ if (isset($config['read'])) {
+ return $this->createReadWriteConnection($config);
+ }
+
+ return $this->createSingleConnection($config);
+ }
+
+ /**
+ * Parse and prepare the database configuration.
+ *
+ * @param array $config
+ * @param string $name
+ * @return array
+ */
+ protected function parseConfig(array $config, $name)
+ {
+ return Arr::add(Arr::add($config, 'prefix', ''), 'name', $name);
+ }
+
+ /**
+ * Create a single database connection instance.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ */
+ protected function createSingleConnection(array $config)
+ {
+ $pdo = $this->createPdoResolver($config);
+
+ return $this->createConnection(
+ $config['driver'], $pdo, $config['database'], $config['prefix'], $config
+ );
+ }
+
+ /**
+ * Create a read / write database connection instance.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ */
+ protected function createReadWriteConnection(array $config)
+ {
+ $connection = $this->createSingleConnection($this->getWriteConfig($config));
+
+ return $connection
+ ->setReadPdo($this->createReadPdo($config))
+ ->setReadPdoConfig($this->getReadConfig($config));
+ }
+
+ /**
+ * Create a new PDO instance for reading.
+ *
+ * @param array $config
+ * @return \Closure
+ */
+ protected function createReadPdo(array $config)
+ {
+ return $this->createPdoResolver($this->getReadConfig($config));
+ }
+
+ /**
+ * Get the read configuration for a read / write connection.
+ *
+ * @param array $config
+ * @return array
+ */
+ protected function getReadConfig(array $config)
+ {
+ return $this->mergeReadWriteConfig(
+ $config, $this->getReadWriteConfig($config, 'read')
+ );
+ }
+
+ /**
+ * Get the write configuration for a read / write connection.
+ *
+ * @param array $config
+ * @return array
+ */
+ protected function getWriteConfig(array $config)
+ {
+ return $this->mergeReadWriteConfig(
+ $config, $this->getReadWriteConfig($config, 'write')
+ );
+ }
+
+ /**
+ * Get a read / write level configuration.
+ *
+ * @param array $config
+ * @param string $type
+ * @return array
+ */
+ protected function getReadWriteConfig(array $config, $type)
+ {
+ return isset($config[$type][0])
+ ? Arr::random($config[$type])
+ : $config[$type];
+ }
+
+ /**
+ * Merge a configuration for a read / write connection.
+ *
+ * @param array $config
+ * @param array $merge
+ * @return array
+ */
+ protected function mergeReadWriteConfig(array $config, array $merge)
+ {
+ return Arr::except(array_merge($config, $merge), ['read', 'write']);
+ }
+
+ /**
+ * Create a new Closure that resolves to a PDO instance.
+ *
+ * @param array $config
+ * @return \Closure
+ */
+ protected function createPdoResolver(array $config)
+ {
+ return array_key_exists('host', $config)
+ ? $this->createPdoResolverWithHosts($config)
+ : $this->createPdoResolverWithoutHosts($config);
+ }
+
+ /**
+ * Create a new Closure that resolves to a PDO instance with a specific host or an array of hosts.
+ *
+ * @param array $config
+ * @return \Closure
+ *
+ * @throws \PDOException
+ */
+ protected function createPdoResolverWithHosts(array $config)
+ {
+ return function () use ($config) {
+ foreach (Arr::shuffle($this->parseHosts($config)) as $host) {
+ $config['host'] = $host;
+
+ try {
+ return $this->createConnector($config)->connect($config);
+ } catch (PDOException $e) {
+ continue;
+ }
+ }
+
+ if (isset($e)) {
+ throw $e;
+ }
+ };
+ }
+
+ /**
+ * Parse the hosts configuration item into an array.
+ *
+ * @param array $config
+ * @return array
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function parseHosts(array $config)
+ {
+ $hosts = Arr::wrap($config['host']);
+
+ if (empty($hosts)) {
+ throw new InvalidArgumentException('Database hosts array is empty.');
+ }
+
+ return $hosts;
+ }
+
+ /**
+ * Create a new Closure that resolves to a PDO instance where there is no configured host.
+ *
+ * @param array $config
+ * @return \Closure
+ */
+ protected function createPdoResolverWithoutHosts(array $config)
+ {
+ return fn () => $this->createConnector($config)->connect($config);
+ }
+
+ /**
+ * Create a connector instance based on the configuration.
+ *
+ * @param array $config
+ * @return \Illuminate\Database\Connectors\ConnectorInterface
+ *
+ * @throws \InvalidArgumentException
+ */
+ public function createConnector(array $config)
+ {
+ if (! isset($config['driver'])) {
+ throw new InvalidArgumentException('A driver must be specified.');
+ }
+
+ if ($this->container->bound($key = "db.connector.{$config['driver']}")) {
+ return $this->container->make($key);
+ }
+
+ return match ($config['driver']) {
+ 'mysql' => new MySqlConnector,
+ 'mariadb' => new MariaDbConnector,
+ 'pgsql' => new PostgresConnector,
+ 'sqlite' => new SQLiteConnector,
+ 'sqlsrv' => new SqlServerConnector,
+ 'firebird' => new FirebirdConnector,
+ default => throw new InvalidArgumentException("Unsupported driver [{$config['driver']}]."),
+ };
+ }
+
+ /**
+ * Create a new connection instance.
+ *
+ * @param string $driver
+ * @param \PDO|\Closure $connection
+ * @param string $database
+ * @param string $prefix
+ * @param array $config
+ * @return \Illuminate\Database\Connection
+ *
+ * @throws \InvalidArgumentException
+ */
+ protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
+ {
+ if ($resolver = Connection::getResolver($driver)) {
+ return $resolver($connection, $database, $prefix, $config);
+ }
+
+ return match ($driver) {
+ 'mysql' => new MySqlConnection($connection, $database, $prefix, $config),
+ 'mariadb' => new MariaDbConnection($connection, $database, $prefix, $config),
+ 'pgsql' => new PostgresConnection($connection, $database, $prefix, $config),
+ 'sqlite' => new SQLiteConnection($connection, $database, $prefix, $config),
+ 'sqlsrv' => new SqlServerConnection($connection, $database, $prefix, $config),
+ 'firebird' => new FirebirdConnection($connection, $database, $prefix, $config),
+ default => throw new InvalidArgumentException("Unsupported driver [{$driver}]."),
+ };
+ }
+}