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 : | ||
− | + | {{version900}} | |
− | + | ||
− | + | 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|Seul le stockage est différent, le framework et le code métier utilisent toujours des OIDs au format caractère en interne}} |
− | [[category: | + | |
+ | ===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
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 : 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 : 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: