1010use Imi \Db \Exception \DbException ;
1111use Imi \Db \Statement \StatementManager ;
1212use Imi \Db \Transaction \Transaction ;
13- use Imi \Pgsql \Db \Contract \IPgsqlDb ;
1413use Imi \Pgsql \Db \Contract \IPgsqlStatement ;
1514use Imi \Pgsql \Db \PgsqlBase ;
1615use Imi \Pgsql \Db \Util \SqlUtil ;
2120 *
2221 * @Bean("PdoPgsqlDriver")
2322 */
24- class Driver extends PgsqlBase implements IPgsqlDb
23+ class Driver extends PgsqlBase
2524{
2625 /**
2726 * 连接对象
@@ -104,14 +103,30 @@ public function isConnected(): bool
104103 */
105104 public function ping (): bool
106105 {
106+ $ instance = $ this ->instance ;
107+ if (!$ instance )
108+ {
109+ return false ;
110+ }
107111 try
108112 {
109- $ instance = $ this ->instance ;
113+ if ($ instance ->query ('select 1 ' ))
114+ {
115+ return true ;
116+ }
117+ if ($ this ->checkCodeIsOffline ($ instance ->errorInfo ()[0 ] ?? '' ))
118+ {
119+ $ this ->close ();
120+ }
110121
111- return $ instance && false !== $ instance -> query ( ' select 1 ' ) ;
122+ return false ;
112123 }
113- catch (\Throwable $ e )
124+ catch (\PDOException $ e )
114125 {
126+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
127+ {
128+ $ this ->close ();
129+ }
115130 }
116131
117132 return false ;
@@ -140,12 +155,13 @@ public function close(): void
140155 $ this ->lastStmt = null ;
141156 }
142157 $ this ->instance = null ;
158+ $ this ->transaction ->init ();
143159 }
144160
145161 /**
146162 * {@inheritDoc}
147163 */
148- public function getInstance (): PDO
164+ public function getInstance (): ? PDO
149165 {
150166 return $ this ->instance ;
151167 }
@@ -155,12 +171,28 @@ public function getInstance(): PDO
155171 */
156172 public function beginTransaction (): bool
157173 {
158- if (! $ this -> inTransaction () && ! $ this -> instance -> beginTransaction ())
174+ try
159175 {
160- return false ;
176+ if (!$ this ->inTransaction () && !$ this ->instance ->beginTransaction ())
177+ {
178+ if ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
179+ {
180+ $ this ->close ();
181+ }
182+
183+ return false ;
184+ }
185+ $ this ->exec ('SAVEPOINT P ' . $ this ->getTransactionLevels ());
186+ $ this ->transaction ->beginTransaction ();
187+ }
188+ catch (\PDOException $ e )
189+ {
190+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
191+ {
192+ $ this ->close ();
193+ }
194+ throw $ e ;
161195 }
162- $ this ->exec ('SAVEPOINT P ' . $ this ->getTransactionLevels ());
163- $ this ->transaction ->beginTransaction ();
164196
165197 return true ;
166198 }
@@ -170,7 +202,28 @@ public function beginTransaction(): bool
170202 */
171203 public function commit (): bool
172204 {
173- return $ this ->instance ->commit () && $ this ->transaction ->commit ();
205+ try
206+ {
207+ if (!$ this ->instance ->commit ())
208+ {
209+ if ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
210+ {
211+ $ this ->close ();
212+ }
213+
214+ return false ;
215+ }
216+ }
217+ catch (\PDOException $ e )
218+ {
219+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
220+ {
221+ $ this ->close ();
222+ }
223+ throw $ e ;
224+ }
225+
226+ return $ this ->transaction ->commit ();
174227 }
175228
176229 /**
@@ -180,7 +233,18 @@ public function rollBack(?int $levels = null): bool
180233 {
181234 if (null === $ levels )
182235 {
183- $ result = $ this ->instance ->rollback ();
236+ try
237+ {
238+ $ result = $ this ->instance ->rollback ();
239+ }
240+ catch (\PDOException $ e )
241+ {
242+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
243+ {
244+ $ this ->close ();
245+ }
246+ throw $ e ;
247+ }
184248 }
185249 else
186250 {
@@ -191,6 +255,10 @@ public function rollBack(?int $levels = null): bool
191255 {
192256 $ this ->transaction ->rollBack ($ levels );
193257 }
258+ elseif ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
259+ {
260+ $ this ->close ();
261+ }
194262
195263 return $ result ;
196264 }
@@ -261,11 +329,29 @@ public function lastSql(): string
261329 public function exec (string $ sql ): int
262330 {
263331 $ this ->lastSql = $ sql ;
332+ $ this ->lastStmt = null ;
264333
265- $ result = $ this ->instance ->exec ($ sql );
266- if (false === $ result )
334+ try
267335 {
268- throw new DbException ('SQL prepare error [ ' . $ this ->errorCode () . '] ' . $ this ->errorInfo () . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
336+ $ result = $ this ->instance ->exec ($ sql );
337+ if (false === $ result )
338+ {
339+ $ errorCode = $ this ->errorCode ();
340+ $ errorInfo = $ this ->errorInfo ();
341+ if ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
342+ {
343+ $ this ->close ();
344+ }
345+ throw new DbException ('SQL exec error [ ' . $ errorCode . '] ' . $ errorInfo . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
346+ }
347+ }
348+ catch (\PDOException $ e )
349+ {
350+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
351+ {
352+ $ this ->close ();
353+ }
354+ throw $ e ;
269355 }
270356
271357 return $ result ;
@@ -330,17 +416,34 @@ public function prepare(string $sql, array $driverOptions = []): IPgsqlStatement
330416 }
331417 else
332418 {
333- $ this ->lastSql = $ sql ;
334- $ lastStmt = $ this ->lastStmt = $ this ->instance ->prepare ($ sql , $ driverOptions );
335- // @phpstan-ignore-next-line
336- if (false === $ lastStmt )
419+ try
337420 {
338- throw new DbException ('SQL prepare error [ ' . $ this ->errorCode () . '] ' . $ this ->errorInfo () . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
421+ $ this ->lastSql = $ sql ;
422+ $ lastStmt = $ this ->lastStmt = $ this ->instance ->prepare ($ sql , $ driverOptions );
423+ // @phpstan-ignore-next-line
424+ if (false === $ lastStmt )
425+ {
426+ $ errorCode = $ this ->errorCode ();
427+ $ errorInfo = $ this ->errorInfo ();
428+ if ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
429+ {
430+ $ this ->close ();
431+ }
432+ throw new DbException ('SQL prepare error [ ' . $ errorCode . '] ' . $ errorInfo . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
433+ }
434+ $ stmt = App::getBean (Statement::class, $ this , $ lastStmt );
435+ if ($ this ->isCacheStatement && !isset ($ stmtCache ))
436+ {
437+ StatementManager::setNX ($ stmt , true );
438+ }
339439 }
340- $ stmt = App::getBean (Statement::class, $ this , $ lastStmt );
341- if ($ this ->isCacheStatement && !isset ($ stmtCache ))
440+ catch (\PDOException $ e )
342441 {
343- StatementManager::setNX ($ stmt , true );
442+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
443+ {
444+ $ this ->close ();
445+ }
446+ throw $ e ;
344447 }
345448 }
346449
@@ -352,11 +455,28 @@ public function prepare(string $sql, array $driverOptions = []): IPgsqlStatement
352455 */
353456 public function query (string $ sql ): IPgsqlStatement
354457 {
355- $ this ->lastSql = $ sql ;
356- $ this ->lastStmt = $ lastStmt = $ this ->instance ->query ($ sql );
357- if (false === $ lastStmt )
458+ try
358459 {
359- throw new DbException ('SQL query error: [ ' . $ this ->errorCode () . '] ' . $ this ->errorInfo () . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
460+ $ this ->lastSql = $ sql ;
461+ $ this ->lastStmt = $ lastStmt = $ this ->instance ->query ($ sql );
462+ if (false === $ lastStmt )
463+ {
464+ $ errorCode = $ this ->errorCode ();
465+ $ errorInfo = $ this ->errorInfo ();
466+ if ($ this ->checkCodeIsOffline ($ this ->instance ->errorInfo ()[0 ] ?? '' ))
467+ {
468+ $ this ->close ();
469+ }
470+ throw new DbException ('SQL query error [ ' . $ errorCode . '] ' . $ errorInfo . \PHP_EOL . 'sql: ' . $ sql . \PHP_EOL );
471+ }
472+ }
473+ catch (\PDOException $ e )
474+ {
475+ if ($ this ->checkCodeIsOffline ($ e ->errorInfo [0 ]))
476+ {
477+ $ this ->close ();
478+ }
479+ throw $ e ;
360480 }
361481
362482 return App::getBean (Statement::class, $ this , $ lastStmt );
0 commit comments