@@ 3-139 (lines=137) @@ | ||
1 | <?php |
|
2 | ||
3 | class DatabaseConnection |
|
4 | { |
|
5 | /** |
|
6 | * [$instance description] |
|
7 | * @var [type] |
|
8 | */ |
|
9 | private static $instance; |
|
10 | ||
11 | /** |
|
12 | * [$databaseConnection description] |
|
13 | * @var [type] |
|
14 | */ |
|
15 | public $databaseConnection; |
|
16 | ||
17 | /** |
|
18 | * The default PDO connection options. |
|
19 | * |
|
20 | * @var array |
|
21 | */ |
|
22 | protected $options = [ |
|
23 | PDO::ATTR_CASE => PDO::CASE_NATURAL, |
|
24 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
|
25 | PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, |
|
26 | PDO::ATTR_STRINGIFY_FETCHES => false, |
|
27 | PDO::ATTR_EMULATE_PREPARES => false, |
|
28 | ]; |
|
29 | ||
30 | /** |
|
31 | * Singleton Class: |
|
32 | * Constructor reads database config file and creates connection. |
|
33 | */ |
|
34 | private function __construct(DatabaseConnectionStringFactoryInterface $dbConnStringFactory) |
|
35 | { |
|
36 | //Read config file |
|
37 | $this->config = parse_ini_file('config.ini'); |
|
38 | $dsn = $dbConnStringFactory->createDatabaseSourceString($this->config); |
|
39 | $this->databaseConnection = $this->createConnection($dsn, $this->options); |
|
40 | } |
|
41 | ||
42 | public static function getInstance() |
|
43 | { |
|
44 | if (self::$instance === null) { |
|
45 | self::$instance = new self(new DatabaseConnectionStringFactory); |
|
46 | } |
|
47 | return self::$instance; |
|
48 | } |
|
49 | ||
50 | ||
51 | /** |
|
52 | * Create a new PDO connection. |
|
53 | * |
|
54 | * @param string $dsn |
|
55 | * @param array $config |
|
56 | * @return \PDO |
|
57 | */ |
|
58 | public function createConnection($dsn, array $config) |
|
59 | { |
|
60 | $username = $this->config['USERNAME']; |
|
61 | ||
62 | $password = $this->config['PASSWORD']; |
|
63 | ||
64 | ||
65 | try { |
|
66 | $pdo = new PDO($dsn, $username, $password, $this->options); |
|
67 | } catch (Exception $e) { |
|
68 | $pdo = $this->tryAgainIfCausedByLostConnection( |
|
69 | $e, $dsn, $username, $password, $options |
|
70 | ); |
|
71 | } |
|
72 | ||
73 | return $pdo; |
|
74 | } |
|
75 | ||
76 | /** |
|
77 | * Get the default PDO connection options. |
|
78 | * |
|
79 | * @return array |
|
80 | */ |
|
81 | public function getDefaultOptions() |
|
82 | { |
|
83 | return $this->options; |
|
84 | } |
|
85 | ||
86 | /** |
|
87 | * Set the default PDO connection options. |
|
88 | * |
|
89 | * @param array $options |
|
90 | * @return void |
|
91 | */ |
|
92 | public function setDefaultOptions(array $options) |
|
93 | { |
|
94 | $this->options = $options; |
|
95 | } |
|
96 | ||
97 | /** |
|
98 | * Handle a exception that occurred during connect execution. |
|
99 | * |
|
100 | * @param \Exception $e |
|
101 | * @param string $dsn |
|
102 | * @param string $username |
|
103 | * @param string $password |
|
104 | * @param array $options |
|
105 | * @return \PDO |
|
106 | * |
|
107 | * @throws \Exception |
|
108 | */ |
|
109 | protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options) |
|
110 | { |
|
111 | if ($this->causedByLostConnection($e)) { |
|
112 | return new PDO($dsn, $username, $password, $options); |
|
113 | } |
|
114 | ||
115 | throw $e; |
|
116 | } |
|
117 | ||
118 | /** |
|
119 | * Determine if the given exception was caused by a lost connection. |
|
120 | * |
|
121 | * @param \Exception $e |
|
122 | * @return bool |
|
123 | */ |
|
124 | protected function causedByLostConnection(Exception $e) |
|
125 | { |
|
126 | $message = $e->getMessage(); |
|
127 | ||
128 | return Helpers::contains($message, [ |
|
129 | 'server has gone away', |
|
130 | 'no connection to the server', |
|
131 | 'Lost connection', |
|
132 | 'is dead or not enabled', |
|
133 | 'Error while sending', |
|
134 | 'decryption failed or bad record mac', |
|
135 | 'SSL connection has been closed unexpectedly', |
|
136 | 'Deadlock found when trying to get lock', |
|
137 | ]); |
|
138 | } |
|
139 | } |
|
140 | ||
141 | abstract class Model implements ModelInterface |
|
142 | { |
@@ 9-153 (lines=145) @@ | ||
6 | use Pyjac\ORM\DatabaseConnectionStringFactoryInterface; |
|
7 | use Pyjac\ORM\DatabaseConnectionStringFactory; |
|
8 | ||
9 | class DatabaseConnection |
|
10 | { |
|
11 | /** |
|
12 | * The instance of this class. |
|
13 | * |
|
14 | * @var Pyjac\ORM\DatabaseConnection. |
|
15 | */ |
|
16 | private static $instance; |
|
17 | ||
18 | /** |
|
19 | * The PDO database connection in use. |
|
20 | * |
|
21 | * @var \PDO |
|
22 | */ |
|
23 | public $databaseConnection; |
|
24 | ||
25 | /** |
|
26 | * The default PDO connection options. |
|
27 | * |
|
28 | * @var array |
|
29 | */ |
|
30 | protected $options = [ |
|
31 | PDO::ATTR_CASE => PDO::CASE_NATURAL, |
|
32 | PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, |
|
33 | PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL, |
|
34 | PDO::ATTR_STRINGIFY_FETCHES => false, |
|
35 | PDO::ATTR_EMULATE_PREPARES => false, |
|
36 | ]; |
|
37 | ||
38 | /** |
|
39 | * Create a new Database Connection. |
|
40 | * |
|
41 | * @param DatabaseConnectionStringFactoryInterface $dbConnStringFactory |
|
42 | */ |
|
43 | private function __construct(DatabaseConnectionStringFactoryInterface $dbConnStringFactory) |
|
44 | { |
|
45 | //Read config file |
|
46 | $this->config = parse_ini_file('config.ini'); |
|
47 | $dsn = $dbConnStringFactory->createDatabaseSourceString($this->config); |
|
48 | $this->databaseConnection = $this->createConnection($dsn, $this->options); |
|
49 | } |
|
50 | ||
51 | /** |
|
52 | * Get the instance of the class. |
|
53 | * |
|
54 | * @return Pyjac\ORM\DatabaseConnection |
|
55 | */ |
|
56 | public static function getInstance() |
|
57 | { |
|
58 | if (self::$instance === null) { |
|
59 | self::$instance = new self(new DatabaseConnectionStringFactory); |
|
60 | } |
|
61 | return self::$instance; |
|
62 | } |
|
63 | ||
64 | ||
65 | /** |
|
66 | * Create a new PDO connection. |
|
67 | * |
|
68 | * @param string $dsn |
|
69 | * @param array $config |
|
70 | * @return \PDO |
|
71 | */ |
|
72 | public function createConnection($dsn, array $config) |
|
73 | { |
|
74 | $username = $this->config['USERNAME']; |
|
75 | ||
76 | $password = $this->config['PASSWORD']; |
|
77 | ||
78 | ||
79 | try { |
|
80 | $pdo = new PDO($dsn, $username, $password, $this->options); |
|
81 | } catch (\Exception $e) { |
|
82 | $pdo = $this->tryAgainIfCausedByLostConnection( |
|
83 | $e, $dsn, $username, $password, $options |
|
84 | ); |
|
85 | } |
|
86 | ||
87 | return $pdo; |
|
88 | } |
|
89 | ||
90 | /** |
|
91 | * Get the default PDO connection options. |
|
92 | * |
|
93 | * @return array |
|
94 | */ |
|
95 | public function getDefaultOptions() |
|
96 | { |
|
97 | return $this->options; |
|
98 | } |
|
99 | ||
100 | /** |
|
101 | * Set the default PDO connection options. |
|
102 | * |
|
103 | * @param array $options |
|
104 | * @return void |
|
105 | */ |
|
106 | public function setDefaultOptions(array $options) |
|
107 | { |
|
108 | $this->options = $options; |
|
109 | } |
|
110 | ||
111 | /** |
|
112 | * Handle a exception that occurred during connect execution. |
|
113 | * |
|
114 | * @param \Exception $e |
|
115 | * @param string $dsn |
|
116 | * @param string $username |
|
117 | * @param string $password |
|
118 | * @param array $options |
|
119 | * @return \PDO |
|
120 | * |
|
121 | * @throws \Exception |
|
122 | */ |
|
123 | protected function tryAgainIfCausedByLostConnection(Exception $e, $dsn, $username, $password, $options) |
|
124 | { |
|
125 | if ($this->causedByLostConnection($e)) { |
|
126 | return new PDO($dsn, $username, $password, $options); |
|
127 | } |
|
128 | ||
129 | throw $e; |
|
130 | } |
|
131 | ||
132 | /** |
|
133 | * Determine if the given exception was caused by a lost connection. |
|
134 | * |
|
135 | * @param \Exception $e |
|
136 | * @return bool |
|
137 | */ |
|
138 | protected function causedByLostConnection(Exception $e) |
|
139 | { |
|
140 | $message = $e->getMessage(); |
|
141 | ||
142 | return Helpers::contains($message, [ |
|
143 | 'server has gone away', |
|
144 | 'no connection to the server', |
|
145 | 'Lost connection', |
|
146 | 'is dead or not enabled', |
|
147 | 'Error while sending', |
|
148 | 'decryption failed or bad record mac', |
|
149 | 'SSL connection has been closed unexpectedly', |
|
150 | 'Deadlock found when trying to get lock', |
|
151 | ]); |
|
152 | } |
|
153 | } |
|
154 |