Developpez.com - 4D
X

Choisissez d'abord la catégorieensuite la rubrique :


Récupération d’informations sur le 4D Server par les librairies 4D Open (Projet Windows, Projet CFM, Projet Mach-0) (2/2)

Date de publication : Septembre 2004

Par Aziz ELGHOMARI (Directeur Support Technique 4D SA)
 


I. Introduction
II. Organigramme des opérations qui peuvent être réalisées par les librairies « 4D open »
Phase 1
Phase 2
Phase 3
Phase 4
III. Explication des points d'entrées de l'API utilisés dans le code source « C »
Supprimer et ajouter des enregistrements
Rechercher un enregistrement
Trier les enregistrements
Manipuler les ensembles
Manipulation des blobs
IV. Mode d'emploi de la Note Technique
Pour les formats «Windows» et « CFM »
Ajouter et supprimer des enregistrements
Chercher un enregistrement
Trier les enregistrements
Manipuler des ensembles
Manipuler les Blobs
Pour le format «CFM »
V. Eléments fournis avec la note technique
Pour Windows
Pour Macintosh
VI. Conclusion
Avantage du Client léger
Inconvénient du Client léger
VII. Les Code source utilisés en Language "C"
Code Source Windows
Code Source Macintosh
VIII. Bases exemples


I. Introduction

La présente note technique permet de manipuler des données avec les librairies 4D Open et d'effectuer des traitements concernant les suppressions et ajouts de données, le tri et la recherche d'informations ainsi que la manipulation des ensembles et des Blobs.


Le Client 4D Open généré va réaliser les opérations suivantes :

  • Suppression et Ajout d'enregistrements ;

  • Recherche d'enregistrements ;

  • Tri des sélections d'enregistrements ;

  • Manipulation d'ensembles ;

  • Manipulation de Blobs.

II. Organigramme des opérations qui peuvent être réalisées par les librairies « 4D open »

Vous trouverez ci-dessous un résumé de tout ce que vous pouvez faire avec les librairies « 4D Open » :

Pictures 0400x0490

Phase 1

Elle correspond aux différents traitements qui peuvent être réalisés sur le 4D Server :

  • Chercher et Trier

  • Créer des sélections nommées

  • Ajouter, modifier et supprimer des enregistrements

  • Afficher utilisateurs et groupes

  • Afficher des informations sur les process etc..

Phase 2

Elle correspond aux connexions qui peuvent être ouvertes sur le même 4D Server. Avec les librairies « 4D Open », nous pouvons ouvrir plusieurs connexions sur le même 4D Server.


Phase 3

Elle correspond aux connexions simultanées avec plusieurs 4D Server. Avec les librairies « 4D open », nous pouvons ouvrir un ou plusieurs 4D Server simultanément.


Phase 4

Elle correspond au protocole utilisé avec 4D open, seul le protocole TCP peut être utilisé avec les librairies « 4D Open ».


III. Explication des points d'entrées de l'API utilisés dans le code source « C »


Supprimer et ajouter des enregistrements

Avant d'ajouter de nouveaux enregistrements, nous allons supprimer les enregistrements existants dans la base de données, nous utiliserons pour cela les routines suivantes :

   _4D_SelectAllRecords
   _4D_DeleteSelectedRecords


Les ajouts vont affecter les champs suivants : Alpha, Texte, Numérique, Entier, Entier long, Date, Heure, Booléen, Image, BLOB.

La structure contient les éléments suivants :
   typedef struct DataRec {
      DataType typ;
      byte filler;
      union {
         TE4D text; /* s_Text32K */
         st80 s; /* s_AlphaNumeric */
         Real r; /* s_Number */
         int2 b; /* s_Bool */
         int2 i; /* s_Int16 */
         int4 l; /* s_Int32 */
         int4 tim; /* s_TimeSec */
         Date4D d; /* s_Dates */
         Pict4D pic; /* s_Pictures */
         Blob4D blob; /* s_Blob */
         struct { st80 s2 ; int2 unused; } other ;
      } u;
   } DataRec;


Pour les ajouts d'enregistrements, les principales routines utilisées dans le code sont :

   _4D_CreateBuffer(ConnectHandle CIDH,int2 Targetfile)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « Targetfile »    : Correspond au numéro de fichier sur lequel, on veut créer le Buffer.

   _4D_AddToBuffer(ConnectHandle CIDH,BufferHandle Buffer, int2 FieldNumber, DataRec *Field)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4Dconnection.
      « Buffer »    : Correspond au handle retourné par la routine _4D_CreateBuffer.
      « FieldNumber » : Correspond au numéro du champ.
      « Field »    : Correspond à la valeur du champs contenu dans le DataRec.


Rechercher un enregistrement

Dans l'exemple fourni, la recherche porte sur le champ 4 de la table 1 qui est de type entier, et cherche les enregistrements dont le champ 4 est égal à 999.


La routine à utiliser est :

   _4D_Search(ConnectHandle CIDH, SearchRecordPtr What, int4 *RecordsFound)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « What »   : On lui passe un pointeur sur la structure SearchRecord
      « RecordsFound » : Elle retourne le nombre d'enregistrements trouvés.



Les structures « SearchLine » et « SerchRecord » :
   typedef struct SearchLine {
      int2 Field_Number;
      int2 File_Number;
      byte SOP; /* search operator */
      byte unused;
      DataRec Value;
      byte LOP; /* logical operator */
      byte unused2,unused3 ;
      } SearchLine;

   typedef struct SearchRecord {
      int2 NB_Lines;
      int2 TargetFile;
      SearchLine lines[1];
      } SearchRecord;

   typedef SearchRecord *SearchRecordPtr;


Dans le source de la routine de recherche, les lignes suivantes se chargent de remplir la structure :

   pSearch->NB_Lines = 1
La recherche concerne le premier niveau de recherche, dans ce cas il existe un seul niveau de recherche

   pSearch->TargetFile = 1
La recherche concerne le fichier numéro 1

   pSearch->lines[0].Field_Number = 4
La recherche concerne le champ numéro 4 de type Entier

   pSearch->lines[0].File_Number = 1
Concerne le fichier contenant le champ retenu pour la recherche

   pSearch->lines[0].SOP = Equal
L'opérateur de recherche est égal

   pSearch->lines[0].Value = data
La valeur à rechercher dans le champ entier est 999

   pSearch->lines[0].LOP = None2
L'opérateur logique est vide car il n'existe qu'une seule ligne de recherche.


Trier les enregistrements

Dans l'exemple de cette note technique, le tri s'effectuera sur le champ4 de la table1.


Les structures à remplir pour le tri sont « SortLine » et « SortRecord » :
   typedef struct SortLine {
      int2 Field_Number;
      int2 File_Number;
      byte Ascent;
      } SortLine;

   typedef struct SortRecord {
      int2 NB_Lines;
      int2 TargetFile;
      SortLine lines[1];
      } SortRecord;

   typedef SortRecord *SortRecordPtr;

La routine à utiliser est :

   _4D_Sort(hConnect, pSort)
      « hConnect »   : Correspond au Handle de connexion retourné par la routine

   _4D_Open4Dconnection.
      « pSort »    : Correspond au pointeur sur la structure « SortRecord ».


Dans le source de la routine de tri, les lignes suivantes se chargent de remplir la structure :

   pSort->NB_Lines = 1
      Correspond au numéro du niveau de tri.

   pSort->TargetFile = 1
      Correspond au numéro du fichier sur lequel porte le tri.

   pSort->lines[0].File_Number = 1
      Correspond au numéro de fichier contenant le champ.

   pSort->lines[0].Field_Number = 4
      Correspond au champ sur lequel va s'effectuer le tri, il s'agit du champ numéro 4 de type Entier.

   pSort->lines[0].Ascent = 1
      Cette ligne permet de fixer l'ordre de tri, 1 correspond au tri ascendant, 0 correspond au tri descendant.


Manipuler les ensembles

Pour l'exemple concernant la manipulation des ensembles, nous aurons besoin de créer deux ensembles : « MySet » et « MySet2 ».

   Le 1er ensemble contiendra l'enregistrement courant
   Le 2ème ensemble contiendra le résultat d'une recherche

On affiche ensuite le nombre d'éléments contenus dans les ensembles « MySet1» et « MySet2 »



Les routines qui concernent les ensembles :

   _4D_CreateEmptySet(ConnectHandle CIDH, st80 SetName, int2   Targetfile)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4Dconnection
      « SetName»    : Correspond au nom de l'ensemble vide à créer
      « Targetfile »   : Correspond à l'ID de la table

Cette commande crée un ensemble vide pour la table spécifiée


   _4D_CreateSet(ConnectHandle CIDH, st80 SetName, int2 Targetfile)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4Dconnection
      « SetName»   : Nom de l'ensemble à créer.
      « Targetfile »   : ID de la table

Cette commande crée un nouvel ensemble pour la table spécifiée et met la sélection courante dans l'ensemble spécifié


   _4D_AddToSet(ConnectHandle CIDH, st80 SetName, int2 Targetfile)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4Dconnection
      « SetName»   : Correspond au nom de l'ensemble
      « TargetName » : Correspond à l'identifiant de la table

Cette commande ajoute la sélection courante de la table spécifiée à l'ensemble spécifié


   _4D_RecordsInSet(ConnectHandle CIDH, st80 SetName, int4 *recInSet)
      « CIDH »: Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « SetName»   : Correspond au nom de l'ensemble
      « recInSet »   : Correspond au nombre d'enregistrements dans l'ensemble

Cette commande retourne dans « recInSet » le nombre d'enregistrements présents dans l'ensemble spécifié.


   _4D_ClearSet(ConnectHandle CIDH, st80 SetName)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « SetName »   : Ensemble à vider   

Cette commande libère la mémoire utilisée par l'ensemble.


Manipulation des blobs

   _4D_SelectAllRecords(ConnectHandle CIDH, int2 Targetfile)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « Targetfile»   : Correspond au numéro de la table sur laquelle on applique un « tout sélectionner ».

   _4D_GotoSelectedRecord(ConnectHandle CIDH, int2 Targetfile, int4 RecNumberInSel)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « Targetfile »   : Numéro de la table sur laquelle on sélectionne le RecNumberInSel
      « RecNumberInSel » : Détermine la position dans la sélection.

   _4D_GetFields(ConnectHandle CIDH, ReqFieldRecPtr FieldList, BufferHandle *Buffer, byte *IsLocked)
      « CIDH »    : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « FieldList »    : Correspond à la liste des champs concernés       « Buffer »    : Correspond au Handle sur les données des champs
      «IsLocked»    : Si égal à «1», l'enregistrement est verrouillé.



Pour déterminer le champ à utiliser, il faut remplir la structure suivante :
   typedef struct ReqFieldRec {
      int2 NB_Fields;
      int2 TargetFile;
      int2 Fields[1];
      } ReqFieldRec

   _4D_GetNthField(ConnectHandle CIDH,BufferHandle Buffer, int2 FieldNumber, DataRec *Field)
      « CIDH »   : Correspond au Handle de connexion retourné par la routine _4D_Open4DConnection
      « Buffer »    : Handle sur les données du champ retourné par la routine _4D_GetFields
      « FieldNumber » : Correspond au numéro de champs relatif
      « Field »    : Correspond à la valeur du champ



La structure permettant de récupérer les valeurs des champs est la suivante :
   typedef struct DataRec {
      DataType typ;
      byte filler;
      union {
         TE4D text; /* s_Text32K */
         st80 s; /* s_AlphaNumeric */
         Real r; /* s_Number */
         int2 b; /* s_Bool */
         int2 i; /* s_Int16 */
         int4 l; /* s_Int32 */
         int4 tim; /* s_TimeSec */
         Date4D d; /* s_Dates */
         Pict4D pic; /* s_Pictures */
         Blob4D blob; /* s_Blob */
         struct { st80 s2 ; int2 unused; } other ;
      } u;
   } DataRec;


Si on veut accéder à la taille du champ Blob par exemple, il faut utiliser :
data.u.blob.BlobLen

IV. Mode d'emploi de la Note Technique

Cette note technique est fournie avec deux projets :

  • Pour la partie Macintosh, nous avons un seul projet qui contient le projet «CFM» et le projet «Mach-O». Le projet a été réalisé sous Metrowerks Code Warrior 9.

  • Pour la partie Windows, le projet a été réalisé sous Microsoft Visual Studio.NET


Sous Windows, pour lancer l'exécutable « Open4D », il faut placer le fichier « 4D Open.dll » dans le dossier « Debug ».

La base doit être lancée sur le réseau, le protocole réseau utilisé est TCP :
      const short KNC = NC_TCPIP dans le code source  « C »


Pour faire fonctionner l'exemple, la base doit être ouverte par le 4D Server et doit se composer d'une table contenant des champs de types suivants :

Pictures 0354x0377



Un champ de type « Alpha », un champ de type «Texte», un champ de type «Numérique», un champ de type «Entier», un champ de type «Entier long», un champ de type «Date», un champ de type «Heure», un champ de type « Booléen», un champ de type «Image », un champ de type «BLOB ».


Pour les formats «Windows» et « CFM »

Si vous exécutez le fichier «Open4D» qui se trouve dans le dossier «Debug», vous obtenez la fenêtre « DOS » ci-dessous :

Pictures 0401x0200


Vous pouvez ensuite rentrer votre choix pour réaliser les différents traitements.


Ajouter et supprimer des enregistrements

Supprime tous les enregistrements et ajoute 3 enregistrements pour tous les champs utilisés dans la table de la base de données utilisées par le 4D Server.

Pictures 0702x0161
Résultat de l'opération si on se connecte avec le 4D Client classique

Chercher un enregistrement

Cherche dans la table numéro 1 et dans le champs numéro 4 de type «entier » la valeur 999.


Trier les enregistrements

Le tri est ascendant. Il est réalisé sur le champ numéro 1 de la table 1, le champ est de type « Alphanumérique».


Manipuler des ensembles

Permet de créer et de nommer deux ensembles :

  • Le premier va contenir l'enregistrement courant ;

  • Le deuxième contient le résultat d'un recherche (recherche dans la table numéro 1 et dans le champs numéro 4 de type «entier » la valeur 999).

Manipuler les Blobs

Permet de récupérer la nouvelle et l'ancienne taille du champs numéro 10 (qui correspond au champ Blob) de la table numéro 1.


Pour le format «CFM »

Pour le format « Mach-O », la fenêtre ne peut pas être affichée, il faut utiliser le "Terminal" Mac OsX pour afficher les différents traitements réalisés.

Au démarrage de l'exécutable «open4D », les opérations vont êtres réalisées selon le même ordre que les format « Windows » et « CFM » : Ajouter et supprimer des enregistrements, chercher un enregistrement, trier un enregistrement, Manipuler des ensembles, manipuler des Blobs.

Pictures 0398x0361
Traitements sur le 4D Server affichés par la console Mac OsX

V. Eléments fournis avec la note technique


Pour Windows

Projet4D 2003

L'exécutable «Open4D » permet d'ouvrir le 4D Server 2003 ainsi que la base de données exemple fournie.

Projet 4D2004

L'exécutable «Open4D» permet d'ouvrir le 4D Server 2004 ainsi que la base de données exemple fournie.


Pour Macintosh

L'exécutable généré par le projet « CFM » permet d'ouvrir le 4D Server 2003 ainsi que la base fournie.

L'exécutable généré par le projet « Mach-O » permet d'ouvrir le 4D Server 2004 ainsi que la base fournie.


La base de données exemple 4ème Dimension fournie se nomme «OpenLibrairies ».


VI. Conclusion

Les utilisateurs des librairies 4D open peuvent, à partir de cette note technique, construire un client "léger" pouvant manipuler les données et des sélections sur le 4D Serveur (Chercher et Trier, Créer des Sélections nommées, Ajouter, Modifier et Supprimer des enregistrements).


Avantage du Client léger

La taille du Client léger « 4Dopen » (même avec la librairie 4D Open) est beaucoup plus petite qu'un 4D Client Classique.


Inconvénient du Client léger

Il faut programmer toute la partie Interface.


VII. Les Code source utilisés en Language "C"


Code Source Windows

   #if __INTEL__
      /* #pragma once */
      /* #include "ansi_prefix.win32.h" */
      /* #include <Windows.h> */
      /* Use pre-compiled header instead */
   #elif WIN32 /* &lt;-- defined by Visual C++ */
      #include <Windows.h>
   #endif

   #if WINVER
      #undef COLOR_WINDOWFRAME
      #undef COLOR_BTNSHADOW
      #undef COLOR_BTNFACE
      #undef COLOR_BTNHIGHLIGHT
      #undef COLOR_BTNTEXT
      #undef InsertMenuItem
      #undef InsertMenu
      #undef AppendMenu
      //#include "ASIPORT.H"/*To use Altura headers (in the folder PPC_H, placed in the
         project folder)*/
   #endif

   #define Openlib 1



   #include "Open4D.h"
   #include <stdlib.h>
   #include <string.h>
   #include <stdio.h>


   const short KNC = NC_TCPIP;
   const unsigned char KStationName[32]="Intel machine\0";
   const unsigned char KUserName[32]="APIUser\0";
   const unsigned char KUserPass[32]="APIPass\0";
   const unsigned char KUserTask[32]="APITask\0";
   const unsigned char kAlphaData[256] = "Champs Alpha\0";
   const unsigned char kTexteData[256] = "Champs Texte\0";

   unsigned char kSetName1[32] = "MySet1\0";
   unsigned char kSetName2[32] = "MySet2\0";
   NetworkComponentHandle hNetworkComponent;
   NetworkLocationPtr pNetworkLocation;
   ConnectHandle hConnect;
   IDRec logRec;
   unsigned char szName[256];
   int choix;

   void Menu(void);
   void initialisation(void);
   int2 StartWSConnection(void);
   void Check(int2 myErr, char *description);
   unsigned char *SP2CSTR(unsigned char *pstr);
   void CloseWSConnection(void);
   void AddRecords(void);
   void GetBlob(void);
   void SortRecords(void);
   void SearchRecords(void);
   void Sets(void);

   int2 StartWSConnection()
   {
      int2 myErr;

      myErr =_4D_Select4DServer(szName, &pNetworkLocation, KNC, hNetworkComponent);
      if(!myErr)
      {
         _4D_Open4DConnection(&logRec, pNetworkLocation, &hConnect,KNC, hNetworkComponent);
      }
      return(myErr);

   }


   void CloseWSConnection()
   {
      _4D_Close4DConnection(hConnect);
   }

   void Check(int2 myErr, char *description)
   {
      char err[256];
      if(myErr)
      {
         sprintf(err, "%s: returns %d\n", description , myErr);
         printf(err);
         getchar();
      }
   }

   unsigned char *SP2CSTR(unsigned char *pstr)
   {
      unsigned char len = *pstr;
      memcpy(pstr, pstr+1, len);
      pstr[len] = '\0';
      return pstr;
   }

   void initialisation(void)
   {
      memcpy(&logRec.StationName[1],KStationName, strlen((char *)KStationName));
      logRec.StationName[0]=strlen((char *)KStationName);
      memcpy(&logRec.UserName[1],KUserName, strlen((char *)KUserName));
      logRec.UserName[0]=strlen((char *)KUserName);
      memcpy(&logRec.UserPass[1],KUserPass, strlen((char *)KUserPass));
      logRec.UserPass[0]=strlen((char *)KUserPass);
      memcpy(&logRec.TaskName[1],KUserTask, strlen((char *)KUserTask));
      logRec.TaskName[0]=strlen((char *)KUserTask);
   }




   // Traitement des données


   void AddRecords(void)
   {
      BufferHandle hBuffer;
      Handle4D hText, hPict, hBlob;
      char *pText, *pPict, *pBlob;
      DataRec data;
      short fNb = 1, nbRec=1;



      printf("Deleting all records of table : %d\n", fNb);
      Check(_4D_SelectAllRecords(hConnect, fNb),"_4D_SelectAllRecords\0");
      Check(_4D_DeleteSelectedRecords(hConnect, fNb),"_4D_DeleteSelectedRecords\0");


      do {

         printf("Adding records to table : %d et l'enregistrement: %d \n", fNb, nbRec);

         hBuffer = _4D_CreateBuffer(hConnect, fNb);

         data.typ = s_AlphaNumeric;
         memcpy(&data.u.s[1], kAlphaData, strlen((char *)kAlphaData));
         data.u.s[0] = strlen((char *)kAlphaData);
         Check(_4D_AddToBuffer(hConnect, hBuffer, 1, &data),"_4D_AddToBuffer\0");

         data.typ = s_Text32K;
         hText = Alloc4DHandle(strlen((char *)kTexteData));
         pText = (char *) Lock4DHandle(hText);
         memcpy(pText, &kTexteData, strlen((char *)kTexteData));
         Unlock4DHandle(hText);
         data.u.text.TextLen = strlen((char *)kTexteData);
         data.u.text.hText = hText;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 2, &data),"_4D_AddToBuffer\0");

         data.typ = s_Number;
         data.u.r.r = 999.999;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 3, &data),"_4D_AddToBuffer\0");

         data.typ = s_Int16;
         data.u.i = 999;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 4, &data),"_4D_AddToBuffer\0");

         data.typ = s_Int32;
         data.u.l = 999;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 5, &data),"_4D_AddToBuffer\0");

         data.typ = s_Dates;
         data.u.d.Day = 27;
         data.u.d.Month = 03;
         data.u.d.Year = 2000;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 6, &data),"_4D_AddToBuffer\0");

         data.typ = s_TimeSec;
         data.u.tim = 999;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 7, &data),"_4D_AddToBuffer\0");

         data.typ = s_Bools;
         data.u.b = 1;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 8, &data),"_4D_AddToBuffer\0");

         hPict = Alloc4DHandle(strlen((char *)kAlphaData));
         pPict = (char *) Lock4DHandle(hPict);
         memcpy(pPict, &kAlphaData, strlen((char *)kAlphaData));
         Unlock4DHandle(hPict);
         data.typ = s_Pictures;
         data.u.pic.PictLen = strlen((char *)kAlphaData);
         data.u.pic.hPict = hPict;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 9, &data),"_4D_AddToBuffer\0");

         hBlob = Alloc4DHandle(strlen((char *)kAlphaData));
         pBlob = (char *) Lock4DHandle(hBlob);
         memcpy(pBlob, &kAlphaData, strlen((char *)kAlphaData));
         Unlock4DHandle(hBlob);
         data.typ = s_Blob;
         data.u.blob.BlobLen = strlen((char *)kAlphaData);
         data.u.blob.hBlob = hBlob;
         Check(_4D_AddToBuffer(hConnect, hBuffer, 10, &data),"_4D_AddToBuffer\0");

         Check(_4D_NewRecord(hConnect, hBuffer),"_4D_NewRecord\0");

         Free4DHandle(hText);
         Free4DHandle(hPict);
         Free4DHandle(hBlob);
         Free4DHandle((Handle4D) hBuffer);
         nbRec ++;

      } while ( nbRec < 4 );

   }


   void GetBlob(void)
   {
      ReqFieldRecPtr pReq = (ReqFieldRecPtr) malloc(sizeof(ReqFieldRec));
      BufferHandle hBuf = 0L;
      unsigned char IsLocked;
      DataRec data;

      Check(_4D_SelectAllRecords(hConnect, 1),"_4D_SelectAllRecords\0");
      Check(_4D_GotoSelectedRecord(hConnect, 1, 1),"_4D_GotoSelectedRecord\0");
      pReq->NB_Fields = 1;
      pReq->TargetFile = 1;
      pReq->Fields[0] = 10;
      Check(_4D_GetFields(hConnect, pReq, &hBuf, &IsLocked),"_4D_GetFields\0");
      Check(_4D_GetNthField(hConnect, hBuf, 1, &data),"_4D_GetNthField\0");
      printf("Got blob field size : %ld original size was : %d\n", data.u.blob.BlobLen,
      strlen((char *) kAlphaData));
      Free4DHandle((Handle4D) data.u.blob.hBlob);
      Free4DHandle((Handle4D) hBuf);
      free(pReq);
   }

   // Sorts records in ascent order
   // if we had more than one field to sort on the server --
   // SortRecordPtr pSort = (SortRecordPtr) malloc(sizeof(SortRecord) + ( ( n - 1 ) * sizeof(SortLine) ));
   void SortRecords(void)
   {
      SortRecordPtr pSort = (SortRecordPtr) malloc(sizeof(SearchRecord));

      printf("Sorting records , field #4 in ascent order\n");
      pSort->NB_Lines = 1;
      pSort->TargetFile = 1;
      pSort->lines[0].File_Number = 1;
      pSort->lines[0].Field_Number = 4;
      pSort->lines[0].Ascent = 1;
      Check(_4D_Sort(hConnect, pSort),"_4D_Sort\0");
      free(pSort);
   }

   // Searches records where field #4 of type integer == 999
   // if we had more than one field to search on the server --
   // SortRecordPtr pSearch = (SearchRecordPtr) malloc(sizeof(SearchRecord) + ( ( n - 1 ) * sizeof(SearchLine) ));
   void SearchRecords(void)
   {
      SearchRecordPtr pSearch = (SearchRecordPtr) malloc(sizeof(SearchRecord));
      DataRec data;
      int4 nbRec;

      data.typ = s_Int16;
      data.u.i = 999;

      printf("Searching records , field #4 = 999 \n");
      pSearch->NB_Lines = 1;
      pSearch->TargetFile = 1;
      pSearch->lines[0].Field_Number = 4;
      pSearch->lines[0].File_Number = 1;
      pSearch->lines[0].SOP = Equal;
      pSearch->lines[0].Value = data;
      pSearch->lines[0].LOP = None2;
      Check(_4D_Search(hConnect, pSearch, &nbRec),"_4D_Search\0");
      free(pSearch);
      printf("found %ld records matching = 999\n", nbRec);
   }

   // Demonstrates the use of sets
   void Sets(void)
   {
      unsigned char pSetName1[32], pSetName2[32];
      int4 recIn;

      memcpy(&pSetName1[1], kSetName1, strlen((char *)kSetName1));
      pSetName1[0] = strlen((char *)kSetName1);
      memcpy(&pSetName2[1], kSetName2, strlen((char *)kSetName2));
      pSetName2[0] = strlen((char *)kSetName2);

      Check(_4D_SelectAllRecords(hConnect, 1),"_4D_SelectAllRecords\0");
      Check(_4D_CreateEmptySet(hConnect, pSetName1, 1),"_4D_CreateEmptySet\0");
      Check(_4D_AddToSet(hConnect, pSetName1, 1),"_4D_AddToSet\0");
      SearchRecords(& hConnect);
      Check(_4D_CreateSet(hConnect, pSetName2, 1),"_4D_CreateSet\0");
      Check(_4D_RecordsInSet(hConnect, pSetName1, &recIn),"_4D_RecordsInSet\0");
      printf("Set %s contains : %ld record(s)\n", SP2CSTR(pSetName1), recIn);
      Check(_4D_RecordsInSet(hConnect, pSetName2, &recIn),"_4D_RecordsInSet\0");
      printf("Set %s contains : %ld record(s)\n", SP2CSTR(pSetName2), recIn);
      Check(_4D_ClearSet(hConnect, pSetName1),"_4D_ClearSet\0");
      Check(_4D_ClearSet(hConnect, pSetName2),"_4D_ClearSet\0");
   }

   void Menu(void)
   {
      printf("\n\n1 :Ajouter et Supprimer des entregistrements ");
      printf("\n2 :Chercher un enregistrement ");
      printf("\n3 :Supprimer et Trier les enregistrements ");
      printf("\n4 :Manipuler des ensembles");
      printf("\n5 :Manipuler les Blobs");
      printf("\n0 Pour quitter le programme");

      printf("\n\n\t Entrer votre choix : ");

      scanf("%d", &choix);

      switch(choix)

      {

         case 1: AddRecords();
         break;

         case 2: SearchRecords();
         break;

         case 3: SortRecords();
         break;

         case 4: Sets();
         break;

         case 5: GetBlob();
         break;

         case 0:
         break;

         default:
         printf("\n\n Choix Incorrecte ! Appuyer sur une touche !");
         choix = getch();

      }
   }

   void main(void)
   {

      initialisation();

      _4D_Init4DWS();

      hNetworkComponent= _4D_InitNetworkComponent(KNC);

      if(hNetworkComponent)
      {
         if(!StartWSConnection())
         {

            do
               Menu();

            while(choix != 0);

            CloseWSConnection();
         }

         _4D_DeInitNetworkComponent(KNC,hNetworkComponent);
      }

      _4D_DeInit4DWS();
   }

Code Source Macintosh

   #include <stdio.h>
   #include <stdlib.h>
   #include <string.h>

   #define OpenLib 1

   #ifdef __MWERKS__
      #ifdef __INTEL__
         #define WINVER 0x0400
         #define MACVER 0
      #endif
   #else
      #define WINVER 0x0400
      #define __INTEL__
   #endif

   #include "Open4D.h"

   const short      kNC = NC_TCPIP;
                     // change nc here, if u want test with tcp/ip per example

   #ifdef __INTEL__
      const unsigned char kStationName[32] = "Intel machine\0";
   #else
      const unsigned char kStationName[32] = "Motorola machine\0";
   #endif
   const unsigned char kUserName[32] = "APIUser\0";
   const unsigned char kUserPass[32] = "APIPass\0";
   const unsigned char kUserTask[32] = "APITask\0";


   unsigned char *PversCstring(unsigned char *pstr);

   void initialisation();
   void Check(int2 myErr, char *description);
   int2 StartWSConnection(void);
   void CloseWSConnection(void);
   void DisplayServerInfo(void);
   void DisplayProcessInfo(void);
   void DisplayStructureInfo(void);


   NetworkComponentHandle hNetworkComponent;
   NetworkLocationPtr pNetworkLocation;
   ConnectHandle hConnect;
   IDRec logRec;
   unsigned char szName[256];





   // converts a pstring to a cstring
   unsigned char *PversCstring(unsigned char *pstr)
   {
      unsigned char len = *pstr;
      memmove(pstr, pstr+1, len);
      pstr[len] = '\0';
      return pstr;
   }

   // checks for errors and reports
   void Check(int2 myErr, char *description)
   {
      char err[256];

      if ( myErr ) {
         sprintf(err,"%s : returns %d\n", description, myErr);
         printf(err);
         getchar();
      }
   }

   // opens a connection with server and errors if any
   int2 StartWSConnection(void)
   {
      int2 myErr;
      myErr = _4D_Select4DServer(szName, &pNetworkLocation, kNC, hNetworkComponent);
      if ( ! myErr ) {
         myErr = _4D_Open4DConnection(&logRec, pNetworkLocation, &hConnect, kNC,
         hNetworkComponent);
      }
      return myErr;
   }

   // closes connection
   void CloseWSConnection(void)
   {
      if (hConnect)
      _4D_Close4DConnection (hConnect);
   }
   void DisplayServerInfo(void)
   {
      ServerInfoRec sInfo;
      Date4D d;
      int4 l;
      unsigned char b;

      printf("\n INFORMATIONS SUR LE 4D SERVEUR \n");

      printf("szName : %s\n", PversCstring(szName));
      Check(_4D_GetServerInfo(hConnect, &sInfo),"_4D_GetServerInfo\0");
      printf("ServerCurVers : %X\n", ((sInfo.ServerCurVers & 0xfff) << 16) );
      printf("InvertedData : %d\n", sInfo.ServerHasInvertedData);
      Check(_4D_Server_CurrentTime(hConnect, &l),"_4D_Server_CurrentTime\0");
      printf("Server_CurrentTime : %ld ticks\n", l);
      Check(_4D_Server_CurrentDate(hConnect, &d),"_4D_Server_CurrentDate\0");
      printf("Server_CurrentDate : %d/%d/%d\n", d.Day, d.Month, d.Year);
      Check(_4D_IsConnectionAsync(hConnect, (unsigned char *) &b),"_4D_IsConnectionAsync\0");
      printf("IsConnectionAsync ? : %d\n", b);
      printf("\n");
   }

   // displays running processes on server
   void DisplayProcessInfo(void)
   {
      ListProcessHandle hList = 0L;
      ListProcessPtr pList;
      int2 i;

      printf("\n INFORMATIONS SUR LES PROCESS SERVEUR \n");

      Check(_4D_GetNbUsers(hConnect, &i),"_4D_GetNbUsers\0");
      printf("GetNbUsers : %d\n", i);
      Check(_4D_GetNbUserProcesses(hConnect, &i),"_4D_GetNbUserProcesses\0");
      printf("GetNbUserProcesses : %d\n", i);
      Check(_4D_GetListProcess(hConnect, &hList),"_4D_GetListProcess\0");
      pList = (ListProcessPtr) Lock4DHandle((Handle4D)hList);

      for ( i = 0 ; i < pList->NB_Process ; i ++ ) {
         printf("GetListProcess_ProcessInfo[%d]_UserName : %s\n",
            i, PversCstring(pList->Processes[i].UserName));
         printf("GetListProcess_ProcessInfo[%d]_StationName : %s\n",
            i, PversCstring(pList->Processes[i].StationName));
         printf("GetListProcess_ProcessInfo[%d]_Taskname : %s\n",
            i, PversCstring(pList->Processes[i].Taskname));
         printf("GetListProcess_ProcessInfo[%d]_TotalTimeSpent : %ld ticks\n",
            i, pList->Processes[i].TotalTimeSpent);
         printf("GetListProcess_ProcessInfo[%d]_State : %d\n",
            i, pList->Processes[i].State);
      }
      Unlock4DHandle((Handle4D)hList);
      Free4DHandle((Handle4D)hList);
   }

   // displays structure
   void DisplayStructureInfo(void)
   {
      FileListHandle hList = 0L;
      FileListPtr pList;
      FileDefHandle hDef = 0L;
      FileDefPtr pDef;
      int2 i, f;

      printf("\n INFORMATIONS SUR LES TABLES \n");

      Check(_4D_CountFiles(hConnect, &i),"_4D_CountFiles\0");
      printf("CountFiles : %d\n", i);
      Check(_4D_GetFileList(hConnect, &hList),"_4D_GetFileList\0");
      pList = (FileListPtr) Lock4DHandle((Handle4D) hList);
      for ( f = 1; f <= pList ->nbFiles ; f ++ ) {
         Check(_4D_GetFileDefinition(hConnect, f, &hDef),"_4D_GetFileDefinition\0");
         pDef = (FileDefPtr) Lock4DHandle((Handle4D)hDef);
         printf("GetFileList : %s\n", PversCstring(pList->fileNames[f-1]));
         printf("GetFileDefinition_NB_Fields : %d\n", pDef->NB_Fields);
         printf("GetFileDefinition_Invisible : %d\n", pDef->Invisible);
         printf("GetFileDefinition_FileNum : %d\n", pDef->FileNum);
         printf("GetFileDefinition_Frame : %d/%d/%d/%d\n", pDef->Frame.left,
            pDef->Frame.top, pDef->Frame.right, pDef->Frame.bottom);
         printf("GetFileDefinition_TrigOnSavingNew : %d\n", pDef->TrigOnSavingNew);
         printf("GetFileDefinition_TrigOnSavingExisting : %d\n", pDef->TrigOnSavingExisting);
         printf("GetFileDefinition_TrigOnDeleting : %d\n", pDef->TrigOnDeleting);
         printf("GetFileDefinition_TrigOnLoading : %d\n", pDef->TrigOnLoading);
         printf("\n INFORMATIONS SUR LES CHMAPS \n");

         for ( i = 0 ; i < pDef->NB_Fields ; i ++ ) {
            printf("GetFileDefinition_Fields[%d]_Name : %s\n", i, PversCstring(pDef->Fields[i].Name));
            printf("GetFileDefinition_Fields[%d]_Typ : %d\n", i, pDef->Fields[i].Typ);
            printf("GetFileDefinition_Fields[%d]_AlphaLen : %d\n", i, pDef->Fields[i].AlphaLen);
            printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedFile : %d\n",
               i, pDef->Fields[i].u.SimpleField.RelatedFile);
            printf("GetFileDefinition_Fields[%d]_u_SimpleField_RelatedField : %d\n",
               i, pDef->Fields[i].u.SimpleField.RelatedField);
            printf("GetFileDefinition_Fields[%d]_u_SimpleField_Att : %X\n",
               i, pDef->Fields[i].u.SimpleField.Att);
            printf("GetFileDefinition_Fields[%d]_u_SimpleField_DiscriminantField : %d\n",
               i, pDef->Fields[i].u.SimpleField.DiscriminantField);
            printf("GetFileDefinition_Fields[%d]_u_PictField_PicAtt : %X\n",
               i, pDef->Fields[i].u.PictField.PicAtt);
            printf("GetFileDefinition_Fields[%d]_u_PictField_CompressDriver : %X\n",
               i, pDef->Fields[i].u.PictField.CompressDriver);
         }
         Unlock4DHandle((Handle4D)hDef);
         Free4DHandle((Handle4D)hDef);
         printf("\n");
      }
      Unlock4DHandle((Handle4D)hList);
      Free4DHandle((Handle4D)hList);
   }



   void initialisation(void)
   {
      memcpy(&logRec.StationName[1], kStationName, strlen((char *)kStationName));
      logRec.StationName[0] = strlen((char *)kStationName);
      memcpy(&logRec.UserName[1], kUserName, strlen((char *)kUserName));
      logRec.UserName[0] = strlen((char *)kUserName);
      memcpy(&logRec.UserPass[1], kUserPass, strlen((char *)kUserPass));
      logRec.UserPass[0] = strlen((char *)kUserPass);
      memcpy(&logRec.TaskName[1], kUserTask, strlen((char *)kUserTask));
      logRec.TaskName[0] = strlen((char *)kUserTask);
   }


   void main(void)
   {
      printf("GetVersionNumber : %ld\n", ( _4D_GetVersionNumber() >> 16 ));
      printf("NB_NetworkComponent : %d\n", _4D_NB_NetworkComponent());

      hNetworkComponent = _4D_InitNetworkComponent(kNC);
      if ( hNetworkComponent ) {
         if ( ! StartWSConnection()) {
            initialisation();
            DisplayServerInfo();
            DisplayProcessInfo();
            DisplayStructureInfo();
            //CloseWSConnection();
         }
         _4D_DeInitNetworkComponent(kNC, hNetworkComponent);
      }
      _4D_DeInit4DWS();
   }

VIII. Bases exemples

Téléchargez les bases exemples :

base exemple Mac

base exemple Windows

__________________________________________________
Copyright © 1985-2009 4D SA - Tous droits réservés
Tous les efforts ont été faits pour que le contenu de cette note technique présente le maximum de fiabilité possible.
Néanmoins, les différents éléments composant cette note technique, et le cas échéant, le code, sont fournis sans garantie d'aucune sorte. L'auteur et 4D S.A. déclinent donc toute responsabilité quant à l'utilisation qui pourrait être faite de ces éléments, tant à l'égard de leurs utilisateurs que des tiers.
Les informations contenues dans ce document peuvent faire l'objet de modifications sans préavis et ne sauraient en aucune manière engager 4D SA. La fourniture du logiciel décrit dans ce document est régie par un octroi de licence dont les termes sont précisés par ailleurs dans la licence électronique figurant sur le support du Logiciel et de la Documentation afférente. Le logiciel et sa documentation ne peuvent être utilisés, copiés ou reproduits sur quelque support que ce soit et de quelque manière que ce soit, que conformément aux termes de cette licence.
Aucune partie de ce document ne peut être reproduite ou recopiée de quelque manière que ce soit, électronique ou mécanique, y compris par photocopie, enregistrement, archivage ou tout autre procédé de stockage, de traitement et de récupération d'informations, pour d'autres buts que l'usage personnel de l'acheteur, et ce exclusivement aux conditions contractuelles, sans la permission explicite de 4D SA.
4D, 4D Calc, 4D Draw, 4D Write, 4D Insider, 4ème Dimension ®, 4D Server, 4D Compiler ainsi que les logos 4e Dimension, sont des marques enregistrées de 4D SA.
Windows,Windows NT,Win 32s et Microsoft sont des marques enregistrées de Microsoft Corporation.
Apple, Macintosh, Power Macintosh, LaserWriter, ImageWriter, QuickTime sont des marques enregistrées ou des noms commerciaux de Apple Computer,Inc.
Mac2Win Software Copyright © 1990-2002 est un produit de Altura Software,Inc.
4D Write contient des éléments de "MacLink Plus file translation", un produit de DataViz, Inc,55 Corporate drive,Trumbull,CT,USA.
XTND Copyright 1992-2002 © 4D SA. Tous droits réservés.
XTND Technology Copyright 1989-2002 © Claris Corporation.. Tous droits réservés ACROBAT © Copyright 1987-2002, Secret Commercial Adobe Systems Inc.Tous droits réservés. ACROBAT est une marque enregistrée d'Adobe Systems Inc.
Tous les autres noms de produits ou appellations sont des marques déposées ou des noms commerciaux appartenant à leurs propriétaires respectifs.
__________________________________________________
 



Valid XHTML 1.1!Valid CSS!

Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
Contacter le responsable de la rubrique 4D