IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++Builder Discussion :

Programmer historique de mise a jour


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut Programmer historique de mise a jour
    Bonjour ,

    J'affiche des données depuis un cache via un IBClientDataSet dans un DgbGrid
    Je fais des modifications(ajout,suppression,modification) dans le cache .

    Je voudrais synchroniser le tout quant utilisateur clique sur le bouton "enregistrer" d'où mon idée de programmer un historique.
    Cela me permettrais de savoir quel enregistrement a été modifié, supprimé ajouter...

    Je risque d'avoir plusieurs contrôles en cache (dgbgrid ou autre ) avec des type de champ divers (int ,blob,String,etc.....)

    Avez vous un idée pour développer ceci ?
    Qui a déjà développé ceci ?


    Je vous remercie par avance
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Le TClientDataSet (en tout cas celui de Delphi), inclu des Logs, as-tu la propriété LogChanges à True
    Normal un ApplyUpdates devrait appliquer le modification au Provider sous-jacent !

    Tu dois pouvoir intercepter les actions BeforeApplyUpdates et AfterApplyUpdates !

    Sinon, il te faut te connecter sur le BeforePost et AfterPost, et constitué ton propre log séparé (avec la propriété Modified et OldValue), tu peux très bien utilisé un autre ClientDataSet pour stocker les modifications (5 colonnes, Nom de Table, Nom de Champ, Action, Valeur, Nouvelle Valeur)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour,

    Effectivement j'ai la propriété LogChanges sous bcb6 pro

    aurait tu un exemple de code même si c'est en delphi
    je ne vois pas comment on peut lire les modification

    Comment cela va appeler le différentes procédures stockées sous FireBird 2.1 ?

    merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Je n'ai pas de code pour lire le ChangeLog
    Pour les BeforeApplyUpdates et AfterApplyUpdates, c'est un tableau de variant !
    Cela peut être un délicat à coder !

    Sinon la solution via BeforePost, BeforeDelete pour stocker manuellement les opérations, ce n'est pas très complexe en soit, c'est juste un peu fastidieux !

    Pour les Procédures stockées, reste l'utilisation de Trigger associé à des Modifications de Table pour les lancer automatiquement !

    A mon avis, tu prends le problème à l'envers, le mieux serait d'avoir un ensemble d'objet qui représente la couche business de ton application qui modifie la base de données, ensuite tout ce qui DBGrid, Edit, ... utilise la couche Objet pour effectuer ses modifications (vu que tu utilise déjà des TClientDataSet), tu peux connaitre les lignes déjà en base (celle avec le colonne ID rempli donc UPDATE), celle inseré (sans ID), celle supprimé (tu stockes dans une Liste ou alors tu utilise un statut pour indiquer la suppression au lieu de supprimer réellement)

    Perso, j'ai développé cela en PHP5 qui dans une appli Web (un générateur de formulaire, entre Google App et Drupal)
    le serveur emet un XML de données et un Layout le tout traduit en JSON
    le client (bcp de JavaScript) modifie ses objets en fonction des actions user et envoie un JSON contenant les données (avec des attributs liés au modification)
    le serveur reçoit le JSON et le parse pour générer les requêtes d'INSERT et UPDATE selon une structure de table dynamique elle même décrite en XML, le tout avec gestion de droits et de cohérence des données)
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    rebonjour
    je vais inspirer de ce que tu as dis et je te remercie,
    en faisant de recherche je me suis inspiré de ceci:

    http://www.developpez.net/forums/d74...r/#post4335116

    (le huitième message)

    j'ai essaye ce code pour lire la propriété Delta
    j'ai retranscrit le code Delphi en Cbuilder

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    TIBClientDataSet *pCdsTemp=new TIBClientDataSet(IbSgbd->IBClientDataSet);
                   //  pCdsTemp=IbSgbd->IBClientDataSet;
                     pCdsTemp->Data= IbSgbd->IBClientDataSet->Delta; //plantage ici
                     pCdsTemp->First();
     
                     while(!pCdsTemp->Eof){
     
                      ShowMessage(pCdsTemp->FieldByName("ID")->AsString);
                      pCdsTemp->Next();
     
                     }
     
    delete pCdsTemp;


    j'ai ce message d'erreur :

    ---------------------------
    Notification d'une exception du débogueur
    ---------------------------
    Le projet TestConectionFirebird4.exe a provoqué une classe d'exception EIBClientError avec le message 'Base de données non affectée'. Processus stoppé. Utilisez Pas-à-pas ou Exécuter pour continuer.
    ---------------------------
    OK Aide
    ---------------------------

    pourtant j'affiche bien mes données dans le cache et dans le grille

    ou est mon erreur a votre avis ?

    encore merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  6. #6
    Membre éclairé
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    573
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 573
    Points : 713
    Points
    713
    Par défaut
    Tu pourrais par exemple inclure un nouveau champ qui serait un int et qui représenterait le niveau dans l historique

    Ou des stringlist créer dynamiquement

    Au choix tout çà

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Je creuse la piste du LogChange et du Delta , cependant je galere pas mal
    et il y a peu de pages qui en parle....

    1 apres avoir charge le cache en memoire j'ai fait :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    IbSgbd->IBClientDataSet->LogChanges=true;


    J'ai ressayé la séance de code comme ceci en m'ispirant toujours de la même page :
    http://www.developpez.net/forums/d74...r/#post4335116


    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    TIBClientDataSet *pCdsDelta=new TIBClientDataSet(NULL);
     
    // la connection
    pCdsDelta->DBConnection=  IbSgbd->IBClientDataSet->DBConnection;
     
    //essaye de récupérer un paquet de l'historique des données modifiées
    // dans l'ensemble de données client 
     
    // plantage ici
    pCdsDelta->Data= IbSgbd->IBClientDataSet->Delta;

    avec le message d'erreur
    EIBClientError avec le message 'Instruction SQL vide'.
    Qui a un idée ?
    Comment récupérer le contenu de Delta(historique) ?

    Cela plante aussi sur le meme ligne indiquée plus haut en changeant le parametre de mon constructeur
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    TIBClientDataSet *pCdsDelta=new TIBClientDataSet(IbSgbd->IBClientDataSet);

    Merci bien encore d'aider un débutant.
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour,
    j'ai un peu avancé.....

    je recherche a écrire une procédure me permettant d'avoir l'historique de mise a jour.

    après avoir chargé les données dans le TIBClientDataSet je mets ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    IbSgbd->IBClientDataSet->LogChanges=true;
    Par la suite ,je fais des motifs ( ajout modif ,supp )dans mon contrôle (DbGrid)qui contient en cache mes domées (TIBClientDataSet).De ce cote la tous est ok ,tout s'actualise.

    J'ai écris une procédure CheckEnreg( TDataSet *DataSet)
    qui me donne l'état de mon enregistrement courant.
    C'est cette même fonction qui me pose problème

    Voici comment je procède :

    Ajout:
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     IbSgbd->IBClientDataSet->AppendRecord(ARRAYOFCONST((NULL,Edit1->Text,
                                                  Edit2->Text,
                                                  Edit3->Text,
                                                  Edit4->Text
     
                                               )));
    CheckEnreg(IbSgbd->IBClientDataSet); // test de l'etat de mon enreg Usmodified.....etc

    Modif :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    IbSgbd->IBClientDataSet->SetFields(
                                       ARRAYOFCONST((DBGridCache->DataSource->DataSet->FieldByName("ID")->AsString,
                                                     Edit1->Text,
                                                     Edit2->Text,
                                                     Edit3->Text,
                                                     Edit4->Text
                                                     )));
    CheckEnreg(IbSgbd->IBClientDataSet);

    Suppression :
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
     IbSgbd->IBClientDataSet->Delete();
    CheckEnreg(IbSgbd->IBClientDataSet);

    Voici le code de la procédure pour voir l'état d'un enregistrement courant

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    void __fastcall TForm1::CheckEnreg( TDataSet *DataSet)
    {
            //teste si on a modifie insere ou supprime
     
          switch (DataSet->UpdateStatus()) {
     
          case usUnmodified:
                ShowMessage("pas de modif");
                break; 
     
          case usInserted:
                ShowMessage("ajout");
                break;
     
          case usModified :
               ShowMessage("modif");
               break;
     
          case usDeleted:
                ShowMessage("suppression");
                break;   
      }
     
    }

    Le problème est que je suis toujours en mode ajout (usInserted) malgré la création , modification et suppression de données par la suite dans le cache

    je ne vois pas ou est le problème ? Pouvez vous m'aider ?
    je vous remercie par avance....
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  9. #9
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    o_live, ben voilà, je savais bien que j'avais déjà vu cela quelque part ! J'avais déjà répondu sur le forum Delphi à la même question !

    Pour récupérer le Variant, ce n'est pas via TIBClientDataSet mais du TClientDataSet normal qu'il faut utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    TClientDataSet *pCdsDelta = new TClientDataSet(IbSgbd->IBClientDataSet);
     
    pCdsDelta->Data= IbSgbd->IBClientDataSet->Delta;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Bonjour et merci de ta réponse,
    le problème est toujours identique je suis toujours en mode ajout usInserted malgré de suppression , modif (réussies et affichées dans un dbGrid) par contre cela compile sans pb et s'exécute sans exceptions

    *Faut- il jouer avec la propriété StatusFilter ?

    *Faut- il mettre quelque chose en plus dans les procédure de suppression , modif,ajout pour faire modifier le mode de fonctionnement afin que la méthode UpdateStatus() renvoie autre chose que usInserted ?

    (Veuillez regardez ici pour les procédures ,merci)

    voici ce que je fais :

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    void __fastcall TForm1::BtSynchroniserClick(TObject *Sender)
    {
    //IbSgbd->IBClientDataSet->
     
    TClientDataSet *pCdsDelta = new TClientDataSet(IbSgbd->IBClientDataSet);
     
    pCdsDelta->Data= IbSgbd->IBClientDataSet->Delta;
     
    pCdsDelta->First();
     
                       while(!pCdsDelta->Eof) {
     
                        // TUpdateStatusS Status=pCdsDelta->StatusFilter;
                        // pCdsDelta->StatusFilter=(TUpdateStatusSet)usDeleted;
                          switch(pCdsDelta->UpdateStatus())  {
     
                              case usUnmodified:{
                              ShowMessage("pas de modif");
                              break;
                              }
     
                              case usInserted: {
                              ShowMessage("ajout");
                              break;
                              }
                              case usModified :{
                              ShowMessage("modif");
                              break;
                              }
                              case usDeleted: {
                              ShowMessage("suppression");
                              break;
                              }
     
                          }
                        pCdsDelta->Next();
     
     
     
                       }
     
       delete pCdsDelta;
     
     
     
     
    }

    En changeant le parametre du constructeur , j'ai toujours le même problème
    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
     TClientDataSet *pCdsDelta = new TClientDataSet(NULL);

    Que faut il faire ?

    merci bien encore d'aider un débutant
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Juin 2002
    Messages
    218
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2002
    Messages : 218
    Points : 91
    Points
    91
    Par défaut
    Qui a une idée ?
    A votre avis pourquoi je reste toujours en mode ajout (Veuillez regardez le post précédent ,merci)

    Comment on manipule la propriété StatusFilter ?(lecture /ecriture/comparaison)



    merci
    Outils utilisés : FireBird 2.1 - IbExert Free - C++ Builder 6 Pro Update 4- Windows Xp pro Sp3

Discussions similaires

  1. mise a jour impossible de mes programmes
    Par interhossa007 dans le forum Windows XP
    Réponses: 15
    Dernier message: 29/09/2008, 08h52
  2. Réponses: 1
    Dernier message: 23/12/2007, 20h08
  3. Historique des mises à jour (Réinstallation XP)
    Par Winsam01 dans le forum Windows XP
    Réponses: 2
    Dernier message: 15/10/2007, 09h58
  4. Mise a jour programme
    Par Poulain dans le forum Windows Forms
    Réponses: 3
    Dernier message: 23/09/2007, 17h43
  5. Comment effectuer la mise a jour d'un programme ?
    Par Velociraptor dans le forum Langage
    Réponses: 2
    Dernier message: 22/09/2005, 21h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo