NOVINKA - Online rekvalifikační kurz Java programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: Nechat v databází pouze nejnovější zprávy | Doctrine 2

Aktivity
Avatar
Petra Nováčková:2.11.2017 21:31

Ahojte, mám jednoduchý chat, kde se zobrazuje pouze nejnovějších 50 zpráv. Tak mi příjde zbytečné nechávat v databázi všechny zprávy. Mám entitu MainMessage:

class MainMessage extends BaseEntity
{
    /**
     * @var User
     * @ORM\ManyToOne(targetEntity="User")
     * @ORM\JoinColumn(name="user", referencedColumnName="id")
     */
    public $user;

    /**
     * @var string
     * @ORM\Column(type="string", length=2500)
     */
    public $content;

    /**
     * @ORM\Column(type="datetime")
     */
    public $time;
}

Jelikož administrátor může zprávy mazat, tak bych si jich v databázi nechala tak 200 (pro jistotu).
Zkoušela jsem to následovně:

$this->em->createQuery('
    DELETE
    FROM App\Model\Entities\MainMessage m
    WHERE m.id < (SELECT a.id FROM App\Model\Entities\MainMessage a ORDER BY a.id DESC OFFSET 200)

, ale vyhodilo mi to chybu s tím OFFSET.
Mohli byste mi prosím napsat DQL dotaz, který by smazal všechny zprávy a nechal v databázi pouze 200 nejnovějších ?
Díky ;-)

 
Odpovědět
2.11.2017 21:31
Avatar
Odpovídá na Petra Nováčková
Martin Konečný (pavelco1998):2.11.2017 21:53

Ahoj,
jelikož jde v zásadě jen o SQL dotaz, který nijak přímo nepracuje s entitami, navrhuji toto neřešit přes DQL, ale přímo přes SQL.

$this->em->getConnection()->executeQuery("
        DELETE FROM `message`
        WHERE `id` IN (
                SELECT `id`
                FROM `message`
                ORDER BY `id` DESC
                OFFSET 200
        )
");

Druhá varianta by mohla být, že se jedním DQL dotazem vyhledají všechny entity, které se mají smazat (v příkladu ten subselect) a do druhého dotazu se do operátoru IN předají.

$entities = $this->em->createQuery("
        SELECT m
        FROM App\Model\Entities\MainMessage m
        ORDER BY m.id DESC
")
        ->setFirstResult(200)
        ->getResult();

$ids = array();
foreach ($entities as $entity) {
        $ids[] = $entity->id;
}

$this->em->createQuery("
        DELETE FROM App\Model\Entities\MainMessage m
        WHERE m.id IN (:ids)
")
        ->setParameter("ids", $ids)
        ->getResult();

Nejsem si z hlavy jistý, zda by operátor IN() v DQL uměl pobrat i celou entitu, nebo se to musí řešit přes ta ID.

Editováno 2.11.2017 21:55
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
2.11.2017 21:53
Aktuálně připravuji browser RPG, FB stránka - https://www.facebook.com/AlteiraCZ
Avatar
Petra Nováčková:2.11.2017 22:00

Díky :)

 
Nahoru Odpovědět
2.11.2017 22:00
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 3 zpráv z 3.