[ROZŠÍŘENÍ] Díl 5.: Databáze (migrace)

Odpovědět
Uživatelský avatar
Otakar Pěnkava
Administrátor
Administrátor
Příspěvky: 544
Registrován: sob 25. říj 2008 16:17:14
Kontaktovat uživatele:

[ROZŠÍŘENÍ] Díl 5.: Databáze (migrace)

Příspěvek od Otakar Pěnkava » čtv 15. úno 2018 22:43:20

Ahoj uživatelé,
v minulých dílech jsme si ukázali jak tvořit vlastní podstránky. Tvoříme aukční systém a tam budeme potřeba ukládat data do databází.
Proto si nyní vysvětlíme jak tvořit migrace, protože ručně to tvořit skrze phpMyAdmin je nepraktické a pokud chcete plugin používat na více místech, neobejdete se bez toho.

Co to tedy migrace je?
Migrace jsou ve stručnosti seznam instrukcí, které se mají provést k databázi. Instrukce může být úprava hodnoty v tabulce, tvorba nové tabulky, přidání dat do tabulky a další... V podstatě to, co můžete udělat ručně v phpMyAdminu/Admineru, ale ve strojovém formátu. Migrace slouží pro vytvoření struktury a případně naplnění dat, dané změny se provádí pouze při instalaci nebo odinstalaci rozšíření.

Tvorba migrace
Migrace mají v rozšíření složku migrations (ROOT/ext/webdeal/auctions/migrations). Řekněme proto, že máme svoji verzi 1.0.0, pro kterou chceme vytvořit tabulku phpbb_auctions se sloupci:

Kód: Vybrat vše

auction_id, user_id, auction_name, auction_text, auction_start_price, auction_price, auction_bids, auction_leader_id, auction_time, auction_end
Založíme si proto ve složce migrations soubor release_1_0_0.php s obsahem níže:

Kód: Vybrat vše

<?php
/**
 *
 * This file is part of the phpBB Forum Software package.
 *
 * @copyright (c) phpBB Limited <https://www.phpbb.com>
 * @license GNU General Public License, version 2 (GPL-2.0)
 *
 * For full copyright and license information, please see
 * the docs/CREDITS.txt file.
 *
 */

namespace webdeal\auctions\migrations;

class release_1_0_0 extends \phpbb\db\migration\migration
{
    public function effectively_installed()
    {
      return version_compare($this->config['webdeal_auctions_version'], '>=', '1.0.0');
    }

    public function update_data()
    {
        return array(
            array('config.add', array('webdeal_auctions_version', '1.0.0')),
        );
    }

    public function update_schema()
  	{
  		return array(
  			'add_tables'		=> array(
  				$this->table_prefix . 'auctions'	=> array(
  					'COLUMNS'	=> array(
  						'auction_id'		=> array('UINT', null, 'auto_increment'),
  						'user_id'		=> array('UINT'),
  						'auction_name'   => array('VCHAR:100'),
  						'auction_text'	=> array('TEXT', ''),
  						'auction_start_price'   => array('UINT:8', 0),
  						'auction_price'   	=> array('UINT:8', 0),  						  						
  						'auction_leader_id'   	=> array('UINT', 0),
  						'auction_bids'   	=> array('UINT:4', 0),  						
  						'auction_time'		=> array('UINT:10', 0),
						'auction_end'		=> array('UINT:10', 0),  						
  					),
  					'PRIMARY_KEY'	=> 'auction_id',
  				),
        )
      );
    }

    public function revert_schema()
  	{
  		return array(
  			'drop_tables' =>  array(
  				$this->table_prefix . 'auctions',
  			),
  		);
  	}
}
Nyní si to rozebereme:
Funkce effectively_installed() slouží k tomu, aby phpBB poznalo, že je migrace už nainstalovaná a už ji znovu neinstalovalo.
Funkce update_data() slouží k úpravě dat v tabulce, například přidání, úprava nebo smazání řádku v tabulce.
Funkce update_schema() slouží k manipulaci s celými tabulkami, například přidání, úpravě nebo mazání celé tabulky nebo více tabulek.
Funkce revert_schema() se jako jedinná zavolá při odinstalování rozšíření (ty předchozí se volají pouze při instalaci) a má za úkol uklidit po sobě.

Stručně řečeno v této migraci:
  • přidáme do phpbb_config řádek s webdeal_auctions_version a hodnotou 1.0.0 (bude nám sloužit při práci s migrací, samotné phpBB si verzi vezme z composer.json)
  • tabulku phpbb_auctions se sloupci, které jsme si definovali výše
  • při odinstalaci plugin smaže tabulku phpbb_auctions (a také řádek v configu - dělá to automaticky)
Tabulka phpbb_auctions bude mít sloupce s hodnotou:
  • auction_id: nastavena vlastnost autoincrement (při novém záznamu se automaticky vloží nejvyšší hodnota+1, takže čísla aukcí půjdou popořadě, vše se bude dít automaticky, ve skriptu nebudete muset zjišťovat pod jakým ID jej přidělit)
  • user_id: sloupec máme, abychom poznali, kdo aukci založil a znali prodejce. Sloupec má nastaven číselný typ (jdou do něj vložit pouze čísla) a nemá definovanou výchozí hodnotu. Jednoduše, user_id vždy budeme znát = nikdy se nepoužije výchozí hodnota.
  • auction_name: název aukce, nastaven typ sloupce, který podporuje jak čísla, tak písmena; maximální délka 100 znaků.
  • auction_text: oproti názvu, zde může být text delší a VCHAR podporuje max. 255 znaků, proto použijeme textový sloupec, který umožňuje až 65000 znaků (= asi 36 stran textu = dostačující).
  • auction_start_price: uložíme si původní cenu, abychom ji znali a měli přehled; zase číselný typ sloupce, tentokrát o max. délce 8 znaků a s výchozí hodnotou 0
  • auction_price: viz auction_start_price
  • auction_leader_id: uložíme si aktuálního "výherce", s příhozy se aktuální výherce bude měnit
  • auction_time: začátek aukce
  • auction_end: konec aukce
Daný soubor v migracích by vždy měl pokrývat změnu v jedné verzi, aby jste v tom neměli zmatek. Pokud v dané verzi není žádná změna, nemusíte pro novou verzi vydávat novou (prázdnou) migraci.

Jak řešit aktualizace na další verzi?
V předchozí migraci jsme vytvořili tabulku phpbb_auctions (prefix tabulky se vždy může lišit dle nastavení phpBB, proto v migracích nepíšeme napevno phpbb_, ale $this->table_prefix). Nicméně k aukcím potřebujeme i historii příhozů (bids), proto si vytvoříme další soubor s migrací (aka verze 1.0.1), kde si vytvoříme tabulku phpbb_bids.

Ve složce migrations vytvoříme soubor release_1_0_1.php s obsahem:

Kód: Vybrat vše

<?php
/**
 *
 * This file is part of the phpBB Forum Software package.
 *
 * @copyright (c) phpBB Limited <https://www.phpbb.com>
 * @license GNU General Public License, version 2 (GPL-2.0)
 *
 * For full copyright and license information, please see
 * the docs/CREDITS.txt file.
 *
 */

namespace webdeal\auctions\migrations;

class release_1_0_0 extends \phpbb\db\migration\migration
{
    public function effectively_installed()
    {
      return version_compare($this->config['webdeal_auctions_version'], '>=', '1.0.1');
    }

    static public function depends_on()
  	{
  		return array('\webdeal\auctions\migrations\release_1_0_0');
  	}

    public function update_data()
    {
        return array(
            array('config.update', array('webdeal_auctions_version', '1.0.1')),
        );
    }

    public function update_schema()
  	{
  		return array(
  			'add_tables'		=> array(
  				$this->table_prefix . 'bids'	=> array(
  					'COLUMNS'	=> array(
  						'bid_id'		=> array('UINT', null, 'auto_increment'),
  						'auction_id'	=> array('UINT'),
  						'user_id'		=> array('UINT'),
  						'bid_price'   	=> array('UINT:8', 0),
  						'bid_time'		=> array('UINT:10', 0),
  					),
  					'PRIMARY_KEY'	=> 'bid_id',
  				),
        )
      );
    }

    public function revert_schema()
  	{
  		return array(
  			'drop_tables' =>  array(
  				$this->table_prefix . 'bids',
  			),
  		);
  	}
}
Kromě úpravy verze ve funkci effectively_installed() je potřeba upravit i ve funkci update_data() řádek:

Kód: Vybrat vše

            array('config.add', array('webdeal_auctions_version', '1.0.1')),
Na:

Kód: Vybrat vše

            array('config.update', array('webdeal_auctions_version', '1.0.1')),
A to z důvodu, že už nepřidáváme nový řádek, ten nám přidala předchozí migrace a my tak proto chceme pouze upravit hodnotu. Kdybychom tam nechali přidání, pravděpodobně by to skončilo chybou = daný řádek totiž už v phpbb_config existuje.

Zároveň, aby v migracích byl přehledný pořádek, přibyla funkce depends_on(), která říká phpBB, že než vykoná tuto migraci, musí nainstalovat migraci release_1_0_0.
Přílohy
dil_5.zip
(6.33 KiB) Staženo 30 x
Starám se o projekt phpBB.cz od doby, kdy jsem jej zachránil před zaniknutím. Pomůžete mi a dostaneme jej zase nahoru?
Přes soukromé zprávy ani Facebook neposkytuji podporu.

Odpovědět