OIDs numériques (framework)

De Wiki1000
(Différences entre les versions)
(Page créée avec « ===Revue de code=== * Query broker * Curseurs category:Latest category:Version810 Category:Framework »)
 
 
(20 révisions intermédiaires par un utilisateur sont masquées)
Ligne 1 : Ligne 1 :
===Revue de code===
+
{{version900}}
* Query broker
+
  
* Curseurs
+
Une base en OIDs numériques stocke les OID en entier 64 bits au lieu de les stocker en chaîne de caractères.
  
 +
Les avantages sont :
  
 +
* Gain de taille, la taille d'un oid numérique est de 8 octets alors que la taille d'un oid caractère est de 32 octets
 +
* Gain de performance, le serveur SQL est plus performant dans la manipulation d'entier.
 +
* Gain réseau, le volume de données échangé est réduit.
  
[[category:Latest]]
+
{{tip|Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne}}
[[category:Version810]]
+
 
 +
===Struture interne===
 +
 
 +
{|class="wikitable"
 +
|-
 +
!nom
 +
!taille
 +
!Remarque
 +
|-
 +
|LID
 +
|16 bits
 +
|Local OID, incrément propre à chaque client
 +
|-
 +
|GID
 +
|32 bits
 +
|Root OID, stocké dans la séquence RootOID, incrémenté par chaque client à la connexion
 +
|-
 +
|OTP
 +
|16 bits
 +
|identifie la classe, grâce à la table sysOTPs
 +
|}
 +
 
 +
===Revue de code métier===
 +
Les éléments suivants doivent être revue pour s'assurer que le code métier est correctement implémenté :
 +
 
 +
* Queries brokers
 +
* Curseurs utilisant une construction SQL
 +
 
 +
Les points à vérifier sont :
 +
 
 +
* Utilisation de dbOutOID() pour encoder les OIDs dans les requêtes
 +
 
 +
'''Support de l'encodage d'OID par translateur :'''
 +
 
 +
{|class="wikitable"
 +
|-
 +
!Fonction
 +
!Supporte l'encodage d'OID
 +
!Remarque
 +
|-
 +
|dboutOID()
 +
|Oui
 +
|
 +
|-
 +
|dbOutStr()
 +
|Non
 +
|
 +
|-
 +
|dbOutVariant()
 +
|Non
 +
|
 +
|-
 +
|dbOutWhereString('oidXXX','=',' ')
 +
|Oui
 +
| oidXXX is NULL
 +
|-
 +
|dbOutWhereString('oidXXX','<>',' ')
 +
|Oui
 +
| oidXXX is NOT NULL
 +
|-
 +
|dbOutWhereString('oidXXX','=',aOID)
 +
|Oui
 +
|
 +
|-
 +
|dbOutWhereString('oidXXX','=',dbOutStr(aOID))
 +
|non
 +
|
 +
|-
 +
|dbOutWhereVariant('oidXXX','=',aOID)
 +
|oui
 +
|
 +
|}
 +
 
 +
 
 +
 
 +
Exemples :
 +
 
 +
<source lang=delphi>
 +
//Procedure TestQueryBroker;
 +
var vQuery:TQuery; aOID,xOID:TOID; inst:WFClasseA; ctn:Integer;
 +
begin
 +
//find first instance
 +
inst := WFClasseA.Find('','',True,[]);
 +
if not Assigned(inst) then Exit;
 +
aOID := inst.OID;
 +
 
 +
vQuery := QueryBroker(''{URL},'Test','WFClasseA');
 +
vQuery.Sql.Add('SELECT oid FROM '+ClassManager.FindClassTableName('WFClasseA'));
 +
vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)])); //!! Important use dbOutOID() to encode oid
 +
//
 +
ctn := 0;
 +
vQuery.Open;
 +
vQuery.First;
 +
while not vQuery.Eof do
 +
  begin
 +
    ctn  := ctn+1;
 +
    xOID := vQuery.Fields[0].AsVariant; // OK, Fields[] return the OID in char format
 +
    vQuery.Next;
 +
  end;
 +
vQuery.Close;
 +
//
 +
if (ctn=1) and (aOID=xOID)
 +
  then showMessage('success')
 +
  else showMessage(Format('failed :%d, %s / %s',[ctn,aoid,xoid]));
 +
end;
 +
</source>
 +
 
 +
<source lang="delphi">
 +
begin
 +
  // OK
 +
 +
  // Equality test
 +
  aOID := inst.OID;
 +
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)]));
 +
 
 +
  // Null test
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','NULL')]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','NULL')]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','')]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','')]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=',aOID)]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNull('oid')]));
 +
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNotNull('oid')]));
 +
 
 +
  // In test
 +
  aWhereIn := '('''+aOID+'')';
 +
  vQuery.SQL.Add(Format('WHERE oid in %s',[vQuery.translator.dbOutOID(aWhereIn)]);
 +
end;
 +
</source>
 +
 
 +
<source lang="delphi">
 +
begin
 +
  // NOT OK
 +
 +
  // Equality test
 +
  aOID := inst.OID;
 +
  vQuery.SQL.Add(Format('WHERE oid=''%s''',[aOID]));
 +
  vQuery.SQL.Add(Format('WHERE oid='''+aOID+''',[]));
 +
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutStr(aOID)]));
 +
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutVariant(aOID)]));
 +
 
 +
 
 +
  // In test
 +
  aWhereIn := '('''+aOID+'')';
 +
  vQuery.SQL.Add(Format('WHERE oid in %s',[aWhereIn]);
 +
end;
 +
</source>
 +
 
 +
{{tip|Il est recommandé de ne pas utiliser de Query broker ni de curseur avec du code SQL. En général, ceux-ci peuvent être remplacés par des sélecteurs ou des vues locales.}} 
 +
 
 +
===Fonctions spécifiques SQL===
 +
Dans certain cas il peut être nécessaire de convertir des OIDs numériques et alphanumériques dans des requêtes SQL
 +
 
 +
Il existe deux fonctions SQL pour réaliser ces conversions
 +
 
 +
* OIDToNumeric ( iOIDChar : CHAR_(12) )
 +
: Retourne la valeur numérique d'un OID caractère
 +
 
 +
* NumericToOID (iDatabasePrefix : CHAR_(16),  iOIDInt:BigInt )
 +
: Retourne la valeur alphanumérique d'un OID numérique
 +
 
 +
{{tip|N'utiliser pas ces fonctions dans le script métier, il n'est jamais nécessaire de gérer le format des OIDs dans le code métier}}
 +
 
 +
Voir aussi:
 +
* [[Translateurs_SQL_(tech)|Translateur]]
 +
* [[Selecteur_(tech)|Sélecteurs]]
 +
* [[Vue_locale_(langage)|Vues locales]]
 +
 
 +
[[category:Version900]]
 +
[[Category:Base de données]]
 
[[Category:Framework]]
 
[[Category:Framework]]

Version actuelle en date du 9 septembre 2022 à 14:52

version900-32x32.png

Une base en OIDs numériques stocke les OID en entier 64 bits au lieu de les stocker en chaîne de caractères.

Les avantages sont :

  • Gain de taille, la taille d'un oid numérique est de 8 octets alors que la taille d'un oid caractère est de 32 octets
  • Gain de performance, le serveur SQL est plus performant dans la manipulation d'entier.
  • Gain réseau, le volume de données échangé est réduit.
Tip-20px.png Tip : Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne

Struture interne

nom taille Remarque
LID 16 bits Local OID, incrément propre à chaque client
GID 32 bits Root OID, stocké dans la séquence RootOID, incrémenté par chaque client à la connexion
OTP 16 bits identifie la classe, grâce à la table sysOTPs

Revue de code métier

Les éléments suivants doivent être revue pour s'assurer que le code métier est correctement implémenté :

  • Queries brokers
  • Curseurs utilisant une construction SQL

Les points à vérifier sont :

  • Utilisation de dbOutOID() pour encoder les OIDs dans les requêtes

Support de l'encodage d'OID par translateur :

Fonction Supporte l'encodage d'OID Remarque
dboutOID() Oui
dbOutStr() Non
dbOutVariant() Non
dbOutWhereString('oidXXX','=',' ') Oui oidXXX is NULL
dbOutWhereString('oidXXX','<>',' ') Oui oidXXX is NOT NULL
dbOutWhereString('oidXXX','=',aOID) Oui
dbOutWhereString('oidXXX','=',dbOutStr(aOID)) non
dbOutWhereVariant('oidXXX','=',aOID) oui


Exemples :

//Procedure TestQueryBroker;
var vQuery:TQuery; aOID,xOID:TOID; inst:WFClasseA; ctn:Integer;
begin
 //find first instance 
 inst := WFClasseA.Find('','',True,[]); 
 if not Assigned(inst) then Exit;
 aOID := inst.OID; 
 
 vQuery := QueryBroker(''{URL},'Test','WFClasseA');
 vQuery.Sql.Add('SELECT oid FROM '+ClassManager.FindClassTableName('WFClasseA'));
 vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)])); //!! Important use dbOutOID() to encode oid
 //
 ctn := 0; 
 vQuery.Open;
 vQuery.First;
 while not vQuery.Eof do
  begin
    ctn  := ctn+1;
    xOID := vQuery.Fields[0].AsVariant; // OK, Fields[] return the OID in char format
    vQuery.Next;
  end;
 vQuery.Close;
 //
 if (ctn=1) and (aOID=xOID) 
  then showMessage('success')
  else showMessage(Format('failed :%d, %s / %s',[ctn,aoid,xoid])); 
end;
begin
  // OK
 
  // Equality test
  aOID := inst.OID;
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutOID(aOID)]));
 
  // Null test
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','NULL')]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','NULL')]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=','')]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','<>','')]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereString('oid','=',aOID)]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNull('oid')]));
  vQuery.SQL.Add(Format('AND %s',[vQuery.translator.dbOutWhereNotNull('oid')]));
 
  // In test
  aWhereIn := '('''+aOID+'')';
  vQuery.SQL.Add(Format('WHERE oid in %s',[vQuery.translator.dbOutOID(aWhereIn)]);
end;
begin
  // NOT OK
 
  // Equality test
  aOID := inst.OID;
  vQuery.SQL.Add(Format('WHERE oid=''%s''',[aOID]));
  vQuery.SQL.Add(Format('WHERE oid='''+aOID+''',[]));
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutStr(aOID)]));
  vQuery.SQL.Add(Format('WHERE oid=%s',[vQuery.translator.dbOutVariant(aOID)]));
 
 
  // In test
  aWhereIn := '('''+aOID+'')';
  vQuery.SQL.Add(Format('WHERE oid in %s',[aWhereIn]);
end;
Tip-20px.png Tip : Il est recommandé de ne pas utiliser de Query broker ni de curseur avec du code SQL. En général, ceux-ci peuvent être remplacés par des sélecteurs ou des vues locales.

Fonctions spécifiques SQL

Dans certain cas il peut être nécessaire de convertir des OIDs numériques et alphanumériques dans des requêtes SQL

Il existe deux fonctions SQL pour réaliser ces conversions

  • OIDToNumeric ( iOIDChar : CHAR_(12) )
Retourne la valeur numérique d'un OID caractère
  • NumericToOID (iDatabasePrefix : CHAR_(16), iOIDInt:BigInt )
Retourne la valeur alphanumérique d'un OID numérique
Tip-20px.png Tip : N'utiliser pas ces fonctions dans le script métier, il n'est jamais nécessaire de gérer le format des OIDs dans le code métier

Voir aussi:

Outils personnels