/vendor/laravel/framework/src/Illuminate/Database/DatabaseManager.php

https://gitlab.com/milton2913/myBlog · PHP · 319 lines · 130 code · 44 blank · 145 comment · 10 complexity · bd3a52c8918b34b88c0669396489e42e MD5 · raw file

  1. <?php
  2. namespace Illuminate\Database;
  3. use PDO;
  4. use Illuminate\Support\Arr;
  5. use Illuminate\Support\Str;
  6. use InvalidArgumentException;
  7. use Illuminate\Database\Connectors\ConnectionFactory;
  8. class DatabaseManager implements ConnectionResolverInterface
  9. {
  10. /**
  11. * The application instance.
  12. *
  13. * @var \Illuminate\Foundation\Application
  14. */
  15. protected $app;
  16. /**
  17. * The database connection factory instance.
  18. *
  19. * @var \Illuminate\Database\Connectors\ConnectionFactory
  20. */
  21. protected $factory;
  22. /**
  23. * The active connection instances.
  24. *
  25. * @var array
  26. */
  27. protected $connections = [];
  28. /**
  29. * The custom connection resolvers.
  30. *
  31. * @var array
  32. */
  33. protected $extensions = [];
  34. /**
  35. * Create a new database manager instance.
  36. *
  37. * @param \Illuminate\Foundation\Application $app
  38. * @param \Illuminate\Database\Connectors\ConnectionFactory $factory
  39. * @return void
  40. */
  41. public function __construct($app, ConnectionFactory $factory)
  42. {
  43. $this->app = $app;
  44. $this->factory = $factory;
  45. }
  46. /**
  47. * Get a database connection instance.
  48. *
  49. * @param string $name
  50. * @return \Illuminate\Database\Connection
  51. */
  52. public function connection($name = null)
  53. {
  54. list($name, $type) = $this->parseConnectionName($name);
  55. // If we haven't created this connection, we'll create it based on the config
  56. // provided in the application. Once we've created the connections we will
  57. // set the "fetch mode" for PDO which determines the query return types.
  58. if (! isset($this->connections[$name])) {
  59. $connection = $this->makeConnection($name);
  60. $this->setPdoForType($connection, $type);
  61. $this->connections[$name] = $this->prepare($connection);
  62. }
  63. return $this->connections[$name];
  64. }
  65. /**
  66. * Parse the connection into an array of the name and read / write type.
  67. *
  68. * @param string $name
  69. * @return array
  70. */
  71. protected function parseConnectionName($name)
  72. {
  73. $name = $name ?: $this->getDefaultConnection();
  74. return Str::endsWith($name, ['::read', '::write'])
  75. ? explode('::', $name, 2) : [$name, null];
  76. }
  77. /**
  78. * Disconnect from the given database and remove from local cache.
  79. *
  80. * @param string $name
  81. * @return void
  82. */
  83. public function purge($name = null)
  84. {
  85. $this->disconnect($name);
  86. unset($this->connections[$name]);
  87. }
  88. /**
  89. * Disconnect from the given database.
  90. *
  91. * @param string $name
  92. * @return void
  93. */
  94. public function disconnect($name = null)
  95. {
  96. if (isset($this->connections[$name = $name ?: $this->getDefaultConnection()])) {
  97. $this->connections[$name]->disconnect();
  98. }
  99. }
  100. /**
  101. * Reconnect to the given database.
  102. *
  103. * @param string $name
  104. * @return \Illuminate\Database\Connection
  105. */
  106. public function reconnect($name = null)
  107. {
  108. $this->disconnect($name = $name ?: $this->getDefaultConnection());
  109. if (! isset($this->connections[$name])) {
  110. return $this->connection($name);
  111. }
  112. return $this->refreshPdoConnections($name);
  113. }
  114. /**
  115. * Refresh the PDO connections on a given connection.
  116. *
  117. * @param string $name
  118. * @return \Illuminate\Database\Connection
  119. */
  120. protected function refreshPdoConnections($name)
  121. {
  122. $fresh = $this->makeConnection($name);
  123. return $this->connections[$name]
  124. ->setPdo($fresh->getPdo())
  125. ->setReadPdo($fresh->getReadPdo());
  126. }
  127. /**
  128. * Make the database connection instance.
  129. *
  130. * @param string $name
  131. * @return \Illuminate\Database\Connection
  132. */
  133. protected function makeConnection($name)
  134. {
  135. $config = $this->getConfig($name);
  136. // First we will check by the connection name to see if an extension has been
  137. // registered specifically for that connection. If it has we will call the
  138. // Closure and pass it the config allowing it to resolve the connection.
  139. if (isset($this->extensions[$name])) {
  140. return call_user_func($this->extensions[$name], $config, $name);
  141. }
  142. $driver = $config['driver'];
  143. // Next we will check to see if an extension has been registered for a driver
  144. // and will call the Closure if so, which allows us to have a more generic
  145. // resolver for the drivers themselves which applies to all connections.
  146. if (isset($this->extensions[$driver])) {
  147. return call_user_func($this->extensions[$driver], $config, $name);
  148. }
  149. return $this->factory->make($config, $name);
  150. }
  151. /**
  152. * Prepare the database connection instance.
  153. *
  154. * @param \Illuminate\Database\Connection $connection
  155. * @return \Illuminate\Database\Connection
  156. */
  157. protected function prepare(Connection $connection)
  158. {
  159. $connection->setFetchMode($this->app['config']['database.fetch']);
  160. if ($this->app->bound('events')) {
  161. $connection->setEventDispatcher($this->app['events']);
  162. }
  163. // Here we'll set a reconnector callback. This reconnector can be any callable
  164. // so we will set a Closure to reconnect from this manager with the name of
  165. // the connection, which will allow us to reconnect from the connections.
  166. $connection->setReconnector(function ($connection) {
  167. $this->reconnect($connection->getName());
  168. });
  169. return $connection;
  170. }
  171. /**
  172. * Prepare the read write mode for database connection instance.
  173. *
  174. * @param \Illuminate\Database\Connection $connection
  175. * @param string $type
  176. * @return \Illuminate\Database\Connection
  177. */
  178. protected function setPdoForType(Connection $connection, $type = null)
  179. {
  180. if ($type == 'read') {
  181. $connection->setPdo($connection->getReadPdo());
  182. } elseif ($type == 'write') {
  183. $connection->setReadPdo($connection->getPdo());
  184. }
  185. return $connection;
  186. }
  187. /**
  188. * Get the configuration for a connection.
  189. *
  190. * @param string $name
  191. * @return array
  192. *
  193. * @throws \InvalidArgumentException
  194. */
  195. protected function getConfig($name)
  196. {
  197. $name = $name ?: $this->getDefaultConnection();
  198. // To get the database connection configuration, we will just pull each of the
  199. // connection configurations and get the configurations for the given name.
  200. // If the configuration doesn't exist, we'll throw an exception and bail.
  201. $connections = $this->app['config']['database.connections'];
  202. if (is_null($config = Arr::get($connections, $name))) {
  203. throw new InvalidArgumentException("Database [$name] not configured.");
  204. }
  205. return $config;
  206. }
  207. /**
  208. * Get the default connection name.
  209. *
  210. * @return string
  211. */
  212. public function getDefaultConnection()
  213. {
  214. return $this->app['config']['database.default'];
  215. }
  216. /**
  217. * Set the default connection name.
  218. *
  219. * @param string $name
  220. * @return void
  221. */
  222. public function setDefaultConnection($name)
  223. {
  224. $this->app['config']['database.default'] = $name;
  225. }
  226. /**
  227. * Get all of the support drivers.
  228. *
  229. * @return array
  230. */
  231. public function supportedDrivers()
  232. {
  233. return ['mysql', 'pgsql', 'sqlite', 'sqlsrv'];
  234. }
  235. /**
  236. * Get all of the drivers that are actually available.
  237. *
  238. * @return array
  239. */
  240. public function availableDrivers()
  241. {
  242. return array_intersect($this->supportedDrivers(), str_replace('dblib', 'sqlsrv', PDO::getAvailableDrivers()));
  243. }
  244. /**
  245. * Register an extension connection resolver.
  246. *
  247. * @param string $name
  248. * @param callable $resolver
  249. * @return void
  250. */
  251. public function extend($name, callable $resolver)
  252. {
  253. $this->extensions[$name] = $resolver;
  254. }
  255. /**
  256. * Return all of the created connections.
  257. *
  258. * @return array
  259. */
  260. public function getConnections()
  261. {
  262. return $this->connections;
  263. }
  264. /**
  265. * Dynamically pass methods to the default connection.
  266. *
  267. * @param string $method
  268. * @param array $parameters
  269. * @return mixed
  270. */
  271. public function __call($method, $parameters)
  272. {
  273. return $this->connection()->$method(...$parameters);
  274. }
  275. }