DatabaseTransactionHelpers.php 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. <?php
  2. namespace Knuckles\Scribe\Extracting;
  3. use Exception;
  4. use Knuckles\Scribe\Exceptions\DatabaseTransactionsNotSupported;
  5. use Knuckles\Scribe\Exceptions\ScribeException;
  6. use Knuckles\Scribe\Tools\ConsoleOutputUtils as c;
  7. use Knuckles\Scribe\Tools\DocumentationConfig;
  8. trait DatabaseTransactionHelpers
  9. {
  10. private function startDbTransaction()
  11. {
  12. $connections = array_keys(config('database.connections', []));
  13. foreach ($connections as $connection) {
  14. try {
  15. $driver = app('db')->connection($connection);
  16. if (self::driverSupportsTransactions($driver)) {
  17. $driver->beginTransaction();
  18. return;
  19. }
  20. $driverClassName = get_class($driver);
  21. if ($this->shouldAllowDatabasePersistence($driverClassName)) {
  22. throw DatabaseTransactionsNotSupported::create($connection, $driverClassName);
  23. }
  24. c::warn("Database driver [$driverClassName] for the connection [{$connection}] does not support transactions. Any changes made to your database will persist.");
  25. } catch (ScribeException $e) {
  26. throw $e;
  27. } catch (Exception $e) {
  28. }
  29. }
  30. }
  31. /**
  32. * @return void
  33. */
  34. private function endDbTransaction()
  35. {
  36. $connections = array_keys(config('database.connections', []));
  37. foreach ($connections as $connection) {
  38. try {
  39. $driver = app('db')->connection($connection);
  40. if (self::driverSupportsTransactions($driver)) {
  41. $driver->rollBack();
  42. return;
  43. }
  44. $driverClassName = get_class($driver);
  45. c::warn("Database driver [$driverClassName] for the connection [{$connection}] does not support transactions. Any changes made to your database have been persisted.");
  46. } catch (Exception $e) {
  47. }
  48. }
  49. }
  50. private static function driverSupportsTransactions($driver): bool
  51. {
  52. $methods = ['beginTransaction', 'rollback'];
  53. foreach ($methods as $method) {
  54. if (! method_exists($driver, $method)) {
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60. /**
  61. * Assesses whether drivers without transaction support can proceed
  62. *
  63. * @param string $driverClassName
  64. *
  65. * @return bool
  66. */
  67. private function shouldAllowDatabasePersistence(string $driverClassName): bool
  68. {
  69. $config = $this->getConfig();
  70. $whitelistedDrivers = $config->get('continue_without_database_transactions', []);
  71. return in_array($driverClassName, $whitelistedDrivers);
  72. }
  73. /**
  74. * Returns an instance of the documentation config
  75. *
  76. * @return DocumentationConfig
  77. */
  78. abstract public function getConfig();
  79. }