Unifikace spojení Dibi/Doctrine

Robin Martinez
Člen | 89
+
0
-

Ahoj, měl bych dotaz – kdysi jsem dělal na ne-nette aplikaci, kde měli dva zdroje db – dibi a PDO, takže se všude připojovali 2×. Tam jsem udělal úpravu, aby dibi používala to existující PDO pro ušetření prostředků. Super. Tam to bylo ale čistý PHP, teď dělám na podobné nette aplikaci, kde je dibi a doctrine.

Zkusil jsem nastavení nejdříve takto:

services:
	pdo:
		create: PDO(%database.dsn%, %database.user%, %database.password%)
		setup:
			- setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT)
		autowired: PDO

dbal:
	connection:
		driver: pdo_mysql
		pdo: @pdo

dibi:
	driver: pdo
	resource: @pdo
	lazy: true

Tady jsou 2 „problémy“
Dibi vadí, že „PDO connection in exception or warning error mode is not supported.“ i když ho na silent vyše nastavuji
doctrine řve, že předání vlastního PDO je deprecated, kde jsem přišel na to,že to potenciálně jde nastavit takto:
dbal:
	connection:
		port: %database.port%
		host: %database.host%
		driver: pdo_mysql
		user: %database.user%
		password: %database.password%
		dbname: %database.dbname%

dibi:
	driver: pdo
	resource: @dbal.connection::getWrappedConnection()
	lazy: true

což bude asi čistší, ale dibi mi stále ječí to samé. Když nedejbože tu exception dám z dibi dočasně pryč, vše vypadá ok.

Mohl by mne tedy prosím, někdo nasměrovat, jestli a případně jak jdou tato spojení nějak unifikovat?

díky moc

Editoval Robin Martinez (21. 2. 12:38)

Robin Martinez
Člen | 89
+
0
-

Bump… Nikdo netuší?

Pepino
Člen | 256
+
+1
-

Čekni kontejner jestli se tam volá na službě PDO setAttribute a potom ověř přes getAttribute jestli je ten attribute opravdu nastavené.

Robin Martinez
Člen | 89
+
0
-

Ano, to jsem otestoval. V DIC se zavolá, naopak getAttribute pak vrací, že je to nastavené na PDO::ERRMODE_EXCEPTION. Takže to asi nějak přenastaví doctrine mezitím?

Pepino
Člen | 256
+
+1
-

Vypadá to tak.

Zkus místo @dbal.connection::getWrappedConnection() svojí službu co bude vracet PDO s nastaveným PDO::ERRMODE_SILENT. To by asi mohlo fungovat.

final class MyPdo {
	public function __construct(private PDO $pdo) {
	}

	public function getConnection(): PDO {
		$pdo = $this->pdo;
		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
		return $pdo;
	}
}
Robin Martinez
Člen | 89
+
0
-

Pepino napsal(a):

Vypadá to tak.

Zkus místo @dbal.connection::getWrappedConnection() svojí službu co bude vracet PDO s nastaveným PDO::ERRMODE_SILENT. To by asi mohlo fungovat.

final class MyPdo {
	public function __construct(private PDO $pdo) {
	}

	public function getConnection(): PDO {
		$pdo = $this->pdo;
		$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT);
		return $pdo;
	}
}

to vyzkouším, moc díky!

Robin Martinez
Člen | 89
+
0
-

Vypadá funkčně. Ještě jednou moc díky!

Robin Martinez
Člen | 89
+
0
-

Vracím se ještě s jedním dotazem. Vše vypadá, že funguje, nicméně v testech nám teď u dibi při insertu PDO hází chybu:

[TypeError] Doctrine\DBAL\Driver\PDOConnection::doQuery(): Return value must be of type PDOStatement, false returned

Před unifikací vše probíhá ok. Nemohl by někdo tušit, co to může být? Díky

Editoval Robin Martinez (12. 3. 16:33)

Robin Martinez
Člen | 89
+
0
-

Pohrabal jsem se v doctrině a hodil si tam u PDO dump erroru. Jedná se o duplikaci klíče v db, takže PDO „spadne“. Nicméně u toho dotazu u dibi testujeme UniqueConstraintViolationException, jen ji dibi asi nějak nevyhazuje.

Takže se tam asi poprvé pošle správné PDO s ERRMODE = silent, ale doctrine si to patrně někde nastaví zpět na své warning nebo exception, se kterým dibi neumí pracovat? Pokud to tak je, lze to nějak vůbec řešit?

BTW: hodiny na fóru jsou o hodinu posunuté nebo to dělá jen mně?

Editoval Robin Martinez (12. 3. 17:35)

Pepino
Člen | 256
+
0
-

https://github.com/…nnection.php#L45

Asi bude jediná možnost si napsat svůj driver pro doctrine. Ale nevím co to pak ovlivní, když tam bude errmode silent.

Robin Martinez
Člen | 89
+
0
-

Na to jsem taky koukal, ale to je ale stejně v konstruktoru „Doctriny“, takže by se to mělo zavolat jako první, nastavit na exception a teprve po předání dibi nastavit na silent, pokud to chápu.

Nicméně co koukám do kódu dibi i doctrine, obě pracují přesně s opačnou verzí ERRMODE. Takže to asi nepůjde :(

Editoval Robin Martinez (12. 3. 17:29)