NotORM nad Nette\Database

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
petr.pavel
Člen | 535
+
0
-

Chápu, že to je šílený, ale omylem se mi podařilo naroubovat NotORM na Nette\Database (NTDB).
Pozitivní výsledek je, že při dotazu přes NotORM se mi zobrazí debug bar z NTDB.
http://ukaz.at/28t/full

Napadá vás nějaký negativní následek?
Mě zatím napadlo jen to, že se bude cacheovat dvakrát (viz moje konfigurace níže). To se fakt děje.

A teď, jak se mi to „podařilo“.
config.neon

common:
	parameters:
		database:
			driver: mysql
			atd...

		dbconvention:
			primary: id
			atd...

	nette:
		database:
			default:
				dsn: '%database.driver%:host=%database.host%;dbname=%database.dbname%'
				atd...

	services:
		dbcache:
			class: NotORM_Cache_Include
			arguments: ["%tempDir%/notorm.cache"]

		dbconvention:
			class: NotORM_Structure_Convention
			arguments: [%dbconvention.primary%, %dbconvention.foreign%, %dbconvention.table%, %dbconvention.prefix%]

		pdo: @\PDO

		notorm:
			class: NotORM(@pdo, @dbconvention, @dbcache)

Mám za to, že řádka pdo: @\PDO způsobí, že Nette zavolá nějakou službu, která PDO vrací – což je „shodou okolností“ NTDB. A tak se NotORM přilepí nad PDO i s NTDB.

juzna.cz
Člen | 248
+
0
-

A ma to nejake prinosy, krome ukazky „ninja-programovani“? Debug panel je i primo pro NotORM.

Tomáš Votruba
Moderator | 1114
+
0
-

juzna.cz napsal(a):

A ma to nejake prinosy, krome ukazky „ninja-programovani“? Debug panel je i primo pro NotORM.

Co je „ninja-programování“?

Důležitým přínosem je zobrazení délky dotazů pro případnou optimalizaci, které NotORM panel bohužel nedá (vyžadovalo by to asi náročnější zásahy do struktury původní třídy).

EDIT: Pro jistotu jsem ověřil logování všech SQL dotazů a provedou se pouze jednou.

Editoval Schmutzka (26. 3. 2012 16:29)

juzna.cz
Člen | 248
+
0
-

Schmutzka napsal(a):

Co je „ninja-programování“?

Termin „programming ninja“ pouziva Douglas Crockford a popisuje tim situace, kdy nekdo udela nejakej akrobatickej kousek a pouzije kod uplne proti puvodnimu ucelu a konvencim. Viz sada prednasek Crockford on JavaScript.

Důležitým přínosem je zobrazení délky dotazů pro případnou optimalizaci, které NotORM panel bohužel nedá (vyžadovalo by to asi náročnější zásahy do struktury původní třídy).

Aha, sorry to sem nevedel ze to neumi. Porad se mi to zda ale jako „nepekny“ hack (tzn ze ja bych to tak nepouzil, ale to je jen muj nazor).

David Grudl
Nette Core | 8227
+
0
-

Proč nepoužiješ rovnou notorm: NotORM(@\PDO, @dbconvention, @dbcache) ?

Vyki
Člen | 388
+
0
-

Také to používám již delší dobu. Je to dobré v development režimu. Na žádný problém jsem nenarazil.

Tomáš Votruba
Moderator | 1114
+
0
-

Vyki napsal(a):

Také to používám již delší dobu. Je to dobré v development režimu. Na žádný problém jsem nenarazil.

Můžeš poslat ukázku configu? Rád bych bral verzi zkušenějšího.

petr.pavel
Člen | 535
+
0
-

Pro ty, kterým tohle „ninja programování“ ;-) nevadí, posílám patch ConnectionPanel.php, který v debug baru začne zobrazovat skutečné názvy souborů/řádky volajícího kódu. Bez patche se všude zobrazuje ...\libs\NotORM\Result.php, což člověku moc nepomůže :-)

Jde o to přidat jedinou řádku – tu s tím in_array(). Používám verzi 2.0.3 s prefixy, proto NStatement.

--- original ConnectionPanel.php
+++ modified ConnectionPanel.php
@@ -51,4 +51,5 @@
  if (isset($row['function']) && strpos($row['function'], 'call_user_func') === 0) continue;
  if (isset($row['class']) && is_subclass_of($row['class'], '\\Nette\\Database\\Connection')) continue;
+ if (isset($row['class']) && in_array($row['class'], array('NStatement', 'NotORM_Result', 'NotORM', 'NotORM_Row'))) continue;
  $source = array($row['file'], (int) $row['line']);
  break;

Už se těším, až se do mě puristi pustí ;-)

EDIT: Safra, koukám, že to bude chtít ještě poladit, někdy to ukazuje příliš vysoko, ne bezprostředně volajícího.

Editoval petr.pavel (26. 4. 2012 23:43)

petr.pavel
Člen | 535
+
0
-

Tak další pokus, tentokrát detekce přes cestu k adresáři s NotORM.
Do bootstrap.php si přidejte

define('NOTORM_DIR', realpath(LIBS_DIR . DIRECTORY_SEPARATOR . 'NotORM'));

A ConnectionPanel.php změňte takto:

--- original ConnectionPanel.php
+++ modified ConnectionPanel.php
@@ -49,4 +49,5 @@
foreach (PHP_VERSION_ID < 50205 ? debug_backtrace() :debug_backtrace(FALSE) as $row) {
  if (isset($row['file']) && is_file($row['file']) && strpos($row['file'], NETTE_DIR . DIRECTORY_SEPARATOR) !== 0) {
+ if (strpos($row['file'], NOTORM_DIR . DIRECTORY_SEPARATOR) === 0) continue;
  if (isset($row['function']) && strpos($row['function'], 'call_user_func') === 0) continue;
  if (isset($row['class']) && is_subclass_of($row['class'], '\\Nette\\Database\\Connection')) continue;

Měl jsem to takhle udělat rovnou, holt už je půlnoc, no.

Editoval petr.pavel (27. 4. 2012 10:30)

Tomáš Votruba
Moderator | 1114
+
0
-

Díky za tip. Škoda, že nejde Nette Database „vnutit“ vlastní panel, který by od ConnectionPanel mohl dědit.

Poslední věch zjednodušil (1. řádek) a vylepšil o přímé linkování dotazů, tedy ne modely, ale třídy, kde jsou modely volány (2. řádek, spíše individuální):

if (strpos($row['file'], "NotORM") != 0) continue;
if (strpos($row['file'], "Model") != 0) continue;
petr.pavel
Člen | 535
+
0
-

A ještě úprava bluescreen.phtml v libs/Nette/Diagnostics/templates:

--- bluescreen.phtml
+++ bluescreen.phtml.bak
@@ -39,5 +39,5 @@
 $title = ($exception instanceof FatalErrorException && isset($errorTypes[$exception->getSeverity()])) ? $errorTypes[$exception->getSeverity()] : get_class($exception);

-$expandPath = realpath(LIBS_DIR . DIRECTORY_SEPARATOR);
+$expandPath = NETTE_DIR . DIRECTORY_SEPARATOR; // . 'Utils' . DIRECTORY_SEPARATOR . 'Object';
 $counter = 0;

Způsobí, že při PDOException vám Laděnka ukáže váš soubor – a ne zdroják NotORM. Nette 2.0.3 s prefixy.

Tomáš Votruba
Moderator | 1114
+
0
-

Tak nakonec vnutit jde:

services:
	nette.database.defaultConnectionPanel: MyConnectionPanel
	// "default" ve stylu database:default: ...