[mysql/php] mod edit user. trigger versie db aanvullen

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 19:03
Goedendag,

een goeie titel voor deze vraag is moeilijk te vinden dus excuus hiervoor:

Ik ben bezig met een mod systeem in mn huidige usersysteem. Ik wil dus dat als een user wordt bewerkt door zichzelf of door een mod dat er een version getriggert wordt (dus een oude kopie wordt gemaakt in users_versions). Maar aan deze users_version wil ik graag data aanvullen. Zoals het IP en het userid door wie deze actie is uitgevoerd. En als de actie uitgevoerd word door een admin of mod dat er ook een notie gemaakt kan worden met de reden van deze actie.

Is zoiets wel mogelijk dmv een trigger. Aangezien een trigger automatisch start naar een update/delete etc. Of zijn er nog andere mogelijkheden dat je alsnog de data kan aanpassen ?

-
Ik heb wel een manier in gedachten om het alsnog voor elkaar te krijgen maar weet niet of dit een netter manier is:
Als een mod een user bewerkt in een aparte table (user_edit_by_mod) de user_id van mod in opslaan, notitie en userId

Dit bij de trigger uitlaten lezen en met deze data de version aanvullen en daarna deze row weer verwijderen?

[ Voor 19% gewijzigd door Jboy1991 op 19-07-2017 19:26 ]

Alle reacties


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Een trigger in je DB? Kan vast wel, maar triggers gebruiken voor dit soort dingen is niet handig...

Je kan wel een framework gebruiken met event-support (Symfony bijvoorbeeld) of een ORM met lifecycle events waar je op kan pluggen (Doctrine bijvoorbeeld).

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 19:03
NMe schreef op woensdag 19 juli 2017 @ 20:40:
Een trigger in je DB? Kan vast wel, maar triggers gebruiken voor dit soort dingen is niet handig...

Je kan wel een framework gebruiken met event-support (Symfony bijvoorbeeld) of een ORM met lifecycle events waar je op kan pluggen (Doctrine bijvoorbeeld).
Waarom zijn triggers niet handig? Ik dacht juist dat het wel handig was voor zoiets aangezien je dan een oude kopie krijg van de geupdate gegevens. Waardoor je dus bij een fout makkelijk een oude data terug kan plaatsen?

Maar ik dacht een oplossing te hebben:
De huidige users db heeft elke row een version kolom. Deze version kolom update ik telkens met +1 als er een update plaats vindt. Vervolgens door de trigger word de oude gegevens incl huidige version opgesloten in users_old

Nu ga ik een trigger doen op insert in users_old en update ik de notie kolom en edit_by_userid kolom met data uit een andere tabel (edit_action_notes).

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Jboy1991 schreef op woensdag 19 juli 2017 @ 20:56:
[...]

Waarom zijn triggers niet handig? Ik dacht juist dat het wel handig was voor zoiets aangezien je dan een oude kopie krijg van de geupdate gegevens. Waardoor je dus bij een fout makkelijk een oude data terug kan plaatsen?

Maar ik dacht een oplossing te hebben:
De huidige users db heeft elke row een version kolom. Deze version kolom update ik telkens met +1 als er een update plaats vindt. Vervolgens door de trigger word de oude gegevens incl huidige version opgesloten in users_old

Nu ga ik een trigger doen op insert in users_old en update ik de notie kolom en edit_by_userid kolom met data uit een andere tabel (edit_action_notes).
Met triggers gooi je deel van je applicatielogica in je database, waar 'ie niet thuishoort.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 19:03
NMe schreef op woensdag 19 juli 2017 @ 21:02:
[...]

Met triggers gooi je deel van je applicatielogica in je database, waar 'ie niet thuishoort.
Ik volg je even niet. Waarom hoort het daar niet thuis en welke logica ?
Ik hou op deze manier dan toch juist netjes bij door wie en eventueel waarom er een Edit gedaan wordt zodat bij evt klachten het makkelijk terug gevonden kan worden en evt herstelt kan worden. Aangezien een een compleet kopie word gemaakt met aanvullende notie

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Niet iedereen zal het met me eens zijn op dit punt maar ik vind dat audit logging in de applicatie zelf hoort waar je ook veel beter in de gelegenheid bent om de data te verrijken. Juist als je een goed framework gebruikt is dat verder ook nul extra moeite.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Merethil
  • Registratie: December 2008
  • Laatst online: 22:15
NMe schreef op woensdag 19 juli 2017 @ 21:19:
Niet iedereen zal het met me eens zijn op dit punt maar ik vind dat audit logging in de applicatie zelf hoort waar je ook veel beter in de gelegenheid bent om de data te verrijken. Juist als je een goed framework gebruikt is dat verder ook nul extra moeite.
Dit. Daarnaast zorgt het scheiden van die logica naar de database voor een probleem aan portability van je applicatie; je kan niet even over naar een andere database-manufacturer want stel die heeft een andere manier van triggers e.d.

Ik zou het lekker in je repository doen, kan je het naast je queries om ze uit te lezen zetten (welke je toch al nodig hebt, waarom zou je het anders bijhouden?)

Acties:
  • 0 Henk 'm!

  • Jboy1991
  • Registratie: September 2012
  • Laatst online: 19:03
Uiteraard kan ik dit ook via php gewoon laten uitvoeren. Maar ik begreep dat juist triggers hiervoor bedoelt is.

Maar als jullie aangeven dat het beter is om dit zelf te programmeren en via een querie te doen dan doe ik dat. Wil natuurlijk niet dat wanneer een hosting veranderd of André mysql versie gebruikt etc dat Mn triggers niet meer werken

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Dat kan heel elegant verder, al betekent dat wel een soort van eventqueue implementeren/includen als je geen framework gebruikt dat 'm al heeft, tenzij je handmatig een call wil doen om spul te loggen. Ik heb bijvoorbeeld in een recent project zo'n beetje elke method afgesloten met het triggeren van een event:

PHP:
1
2
3
        $this->eventDispatcher->dispatch(TournamentEvent::ENTRY_CREATE,
            new TournamentEvent(TournamentEvent::ENTRY_CREATE, $tournament, $user)
        );

...of...
PHP:
1
2
3
4
            $this->eventDispatcher->dispatch(MatchEvent::WIN,
                new MatchEvent(MatchEvent::WIN, $match, $winner));
            $this->eventDispatcher->dispatch(MatchEvent::LOSE,
                new MatchEvent(MatchEvent::LOSE, $match, $loser));

Die events had ik dus al voor andere zaken geïmplementeerd en ik had zelfs een aantal events toegevoegd die nog niet meteen nut hadden. Toen kwam de klant vlak voordat het project opgeleverd zou worden ineens met de wens om audit logging in te bouwen zodat hij van elke user kon zien wat die wanneer gedaan heeft. Dit is letterlijk alle code die ik daarvoor toen nog moest schrijven:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
namespace AppBundle\Event\Subscriber;

use AppBundle\Entity\AuditLog;
use AppBundle\Event\BaseEvent;
use AppBundle\Event\MatchEvent;
use AppBundle\Event\PayoutRequestEvent;
use AppBundle\Event\TournamentEvent;
use AppBundle\Event\UserAwareEventInterface;
use AppBundle\Event\UserEvent;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\ORM\EntityManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class AuditLogSubscriber implements EventSubscriberInterface
{
    /** @var RequestStack */
    protected $requestStack;

    /** @var Registry */
    protected $registry;

    /** @var EntityManager */
    protected $em;

    public function __construct(RequestStack $requestStack, Registry $registry)
    {
        $this->requestStack = $requestStack;
        $this->registry = $registry;
        $this->em = $registry->getManager();
    }

    public static function getSubscribedEvents()
    {
        return array_fill_keys([
            UserEvent::REGISTER,
            UserEvent::ACTIVATE,
            UserEvent::LOGIN,
            UserEvent::LOGOUT,
            UserEvent::CREDIT_PURCHASE,
            MatchEvent::WIN,
            MatchEvent::DRAW,
            MatchEvent::LOSE,
            MatchEvent::SCORES_CONFIRMED,
            TournamentEvent::WIN,
            TournamentEvent::SECOND,
            TournamentEvent::LOSE,
            TournamentEvent::TOP_8,
            TournamentEvent::ENTRY_CREATE,
            TournamentEvent::ENTRY_DELETE,
            PayoutRequestEvent::CREDIT_PAYOUT_REQUEST,
        ], 'onTriggerEvent');
    }

    public function onTriggerEvent(BaseEvent $event)
    {
        /** @var UserAwareEventInterface $event */
        if (!($event instanceof UserAwareEventInterface)) {
            return;
        }

        $auditLog = new AuditLog();
        $auditLog->setUser($event->getUser());
        $auditLog->setAction($event->getType());
        $auditLog->setIp($this->requestStack->getCurrentRequest()->getClientIp());

        $this->em->persist($auditLog);
        $this->em->flush();
    }
}

...en toen werd ineens álles dat zinnig was om te loggen gelogd. ;)

[ Voor 3% gewijzigd door NMe op 20-07-2017 01:41 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Harrie_
  • Registratie: Juli 2003
  • Niet online

Harrie_

⠀                  🔴 🔴 🔴 🔴 🔴

Jboy1991 schreef op woensdag 19 juli 2017 @ 21:30:
Uiteraard kan ik dit ook via php gewoon laten uitvoeren. Maar ik begreep dat juist triggers hiervoor bedoelt is.

Maar als jullie aangeven dat het beter is om dit zelf te programmeren en via een querie te doen dan doe ik dat. Wil natuurlijk niet dat wanneer een hosting veranderd of André mysql versie gebruikt etc dat Mn triggers niet meer werken
Use of database triggers

• To drive column values automatically.
• To enforce complex integrity constraints.
• To enforce complex business rules.
• To customize complex security authorizations.
• To maintain replicate tables.
• To audit data modification.
Jij doelt op punt 6. Zoals @NMe al aangaf kun je dat beter vanuit je applicatie/script doen. Wijzigingen bijhouden via een trigger is handig als je database-user gelijk is aan de applicatie-user. In dat geval heb je dus alle info (en de juiste user) in de database al bij de hand, vanuit je PHP script verbind je (ga ik vanuit) 1 user met de database. Triggeren is dan erg omslachtig omdat de database maar 1 user kent terwijl in jouw (web)applicatie gewoon bekend is welke user er is ingelogd. :Y

Hoeder van het Noord-Meierijse dialect

Pagina: 1