Kam správně uložit předponu tabulek v db

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

Používám Nette\Database. Zatím mám předponu uloženou ve třídě Model, chtěl bych ji ale načítat z konfiguračního souboru, kde by byla napsána spolu s konfigurací databáze. Nějaká chytrá rada jak to elegantně udělat?

Pavel Kouřil
Člen | 128
+
0
-

(Následující rada předpokládá, že máš kód podobný nebo shodný tomu, jak je ukázán v QuickStartu.)

Udělal bych následující úpravy:

  • Konstruktoru bych přidal parametr, kterým se do třídy předá ta předpona pro tabulku a ten si jej uloží do nějakého privátního fieldu.
  • V metodě getTable() bych upravil řádek, který volá $this->connection->table() tak, že bych do volání table přidal i ten prefix.
  • V configu bych těm jednotlivým třídám pracujícím s databází začal předávat i ten prefix.

Ale předpokládám, že bude existovat ještě nějaké elegantnější řešení; tak si možná radši počkej na něj. :)

castamir
Člen | 629
+
0
-

Ve verzi 2.1dev jsem zahlédl nějaké mapování přímo v configu (viz config.neon ze sandboxu). Podrobnosti jsem ale zatím nehledal a tohle mapování doposud nezkoušel.

danielseek
Člen | 42
+
0
-

Pajka napsal(a):

(Následující rada předpokládá, že máš kód podobný nebo shodný tomu, jak je ukázán v QuickStartu.)

  • Konstruktoru bych přidal parametr, kterým se do třídy předá ta předpona pro tabulku a ten si jej uloží do nějakého privátního fieldu.

Ano, odhadl jsi správně, že jsem se řídil podle tohto článku. Toto řešení mě napadlo, přijde mi ale trochu otravné podobné věci všem Modelům přenášet v konstruktoru.

drahos
Člen | 18
+
0
-

Řešení co napsal Pajka je asi lepší, ale napadá mě ještě vytvořit si vlastní SelectionFactory a v konfiguračním souboru (příp. v rozšíření) tam ten prefix zaregistrovat. Vytvořit si něco jako:

class PrefixSelectionFactory extends \Nette\Database\Table\SelectionFactory
{

	/** @var string */
	private $prefix;

	public function __construct($prefix = '', Connection $connection, IReflection $reflection = NULL, IStorage $cacheStorage = NULL)
	{
		parent::__construct($connection, $reflection, $cacheStorage);
		$this->prefix = $prefix;
	}

	/**
	 * @param string $table
	 * @return \Nette\Database\Table\Selection
	 */
	public function create($table)
	{
		return parent::create($this->prefix . $table);
	}

}

a pak to zaregistrovat v config.neon třeba jako:

selectionFactory: PrefixSelectionFactory(%database.prefix%, ...)
connection:
	class: Nette\Database\Connection
        arguments: ['%database.driver%:host=%database.host%;dbname=%database.name%', %database.user%, %database.password%]
        setup:
            - setSelectionFactory(@selectionFactory)

To ale počítá s tím, že všechny tabulky, se kterými budeš pracovat, budeš taky mít prefixované stejně.

castamir napsal(a):

Ve verzi 2.1dev jsem zahlédl nějaké mapování přímo v configu (viz config.neon ze sandboxu). Podrobnosti jsem ale zatím nehledal a tohle mapování doposud nezkoušel.

To mapování se týká jmenných prostorů.

Editoval drahos (29. 1. 2013 0:17)

Ja
Člen | 260
+
0
-

Byl tady nejaky posun v teto veci? Elegantnejsi reseni by neskodilo :)

Zax
Člen | 370
+
0
-

Hehe něco podobného jsem před pár dny řešil s YetORM a já teda resignoval na předávání prefixu do modelu v konstruktoru (ono to jinak nešlo, když název tabulky se definuje v anotacích repozitáře a nechci tam mít nikde natvrdo prefix):

parameters:
    # Předpona pro názvy tabulek
    tablePrefix: web_
    dalsiTablePrefix: cokoliv_

services:
    # YetORM repozitář bere jako první parametr Nette\Database\Context
    - Model\Repository\UserRepository( ..., %tablePrefix% )
    - Model\Service\UserService

    - Model\Repository\LocalizationRepository( ..., %dalsiTablePrefix% )
    - Model\Service\LocalizationService

    # ...

Sice je to dost copy&pastování pokud používáte jen jeden prefix, ale výhody podle mě převažují.

Akorát celkem škoda, že YetORM má dost metod nastavených jako private, takže pokud tohle chcete zkusit a nechcete zasahovat do zdrojáků YetORM, připravte se že to bude trochu opruz. Ale to asi nevadí, co jsem se tak díval, tak tu YetORM používám akorát já, možná ještě snad pár dalších lidí :D

Obecně bych určitě doporučil házet prefix spíš do modelu než do connection. Podle mě je beztak blbost používat jeden prefix v celé aplikaci, k čemu ty prefixy pak jsou?