Exemples Tcl

Exemple 1 :

Lorsqu'il est placé dans un fichier de contrôle global, ce fragment de fichier de contrôle utilise les hooks de début/fin de conversion pour que les heures de début et de fin de conversion soient écrites en sortie.

FME_BEGIN_TCL set gTranslationStartTime [clock format [clock seconds]]

FME_END_TCL puts \”Translation started time: $gTranslationStartTime  \nTranslation end time: [clock format [clock seconds]]\”

Exemple 2 :

Lorsqu'il est placé dans un fichier de contrôle global, ce fragment de fichier de contrôle utilise le hook de fin de conversion et la variable globale FME_Status pour produire un message de succès ou d'échec de la conversion.

Pour information, cela définit en premier lieu une procédure qui fera ce test et produira ce message, puis la procédure lancera le travail.

FME_END_TCL proc finally {} {                      \
       global FME_Status;                          \
       if {$FME_Status == "1"} {                   \
          puts \"Translation was successful\";     \
       } else {                                    \
          puts \"Translation was NOT successful\"; \
       };                                          \
    };                                             \
    finally

Le même exemple peut aussi être écrit sans utiliser de procédure :

FME_END_TCL if {$FME_Status == "1"} {                        \
                    puts \"Translation was successful\";     \
                 } else {                                    \
                    puts \"Translation was NOT successful\"; \
                 }

Exemple 3 :

Cet exemple montre comment les macros utilisées par le fichier de mappage peuvent être passées dans un script de début ou de fin comme argument d'une procédure. Cette procédure peut être utilisée pour déplacer, copier, envoyer par e-mail, sauvegarder ou post-traiter les jeux de données de destination.  Dans cet exemple, le jeu de données de destination est sauvegardé avant le début de la traduction afin de préserver tout fichier de sortie existant qui serait normalement écrasé.

Le fragment du fichier de contrôle est :

# La macro utilisée dans ce fichier de contrôle pour définir la destination 
# dataset directory is DestDataset.  
DWG_DATASET "$(DestDataset)"
# Source dans le script Tcl à exécuter à la conclusion de cette
# conversion.  Le script est stocké dans le même répertoire que
# ce fichier de contrôle.
FME_BEGIN_TCL source {$(FME_MF_DIR_UNIX)/backup.tcl}; backup {$(DestDataset)}

Le contenu du fichier “backup.tcl” est :

proc backup {filename} {
    if {[file exists $filename]} {
        file copy -force $filename $filename.bak
    }
}

Exemple 4 :

Cet exemple montre comment la FME_END_TCL peut être utilisée pour enchaîner les traductions, en fonction des résultats d'une traduction particulière. Dans cet exemple, si la traduction originale échoue, une autre session FME sera lancée.

Notez que dans le fichier Tcl, le 2> NUL: dirige les messages de log et d'erreur vers le système "null", qui les ignorera.

Le fragment du fichier de contrôle est :

# Source dans le script Tcl à exécuter à la conclusion de cette
# conversion.  Le script est stocké dans le même répertoire que
# ce fichier de contrôle.
FME_END_TCL source {$(FME_MF_DIR_UNIX)/tryAnother.tcl}

Le contenu du fichier “tryAnother.tcl” est :

set outputFile [open c:/temp/status.txt w+] 
if { $FME_Status == "1" } {
   puts $outputFile "Translation was successful"
} else {
   puts $outputFile "Translation failed -- running alternate translation"
   exec fme.exe alternateTranslation.fme 2> NUL:
}
close $outputFile

Exemple 5 :

Cet exemple utilise un script externe pour produire un jeu complet de statistiques de conversion dans un fichier résumé à la fin de la conversion.

Le fragment du fichier de contrôle est :

# Définit un id de fichier de contrôle afin que la procédure de finalisation  Tcl "sache" quel 
# fichier de contrôle est exécuté
MAPPING_FILE_ID Shape to AutoCAD
# Logger tous les numéros de messages pour pouvoir par la suite prendre ceux
# qui nous intéressent.
LOG_MESSAGE_NUMBERS yes
# Source dans le script Tcl à exécuter à la conclusion de cette
# conversion.  Le script est stocké dans le même répertoire que
# ce fichier de contrôle.
FME_END_TCL source {$(FME_MF_DIR_UNIX)/tclFinalization.tcl}

Le contenu du fichier “tclFinalization.tcl” est :

# Ouvrir un fichier pour écrire les statistiques de conversion
set outputFile [open c:/temp/stats_out.txt w+]
# Vérifier le statut de la conversion et produire le message souhaité
if { $FME_Status == "1" } {
   puts $outputFile "Translation was successful"
} else {
   puts $outputFile "Translation failed"
   puts $outputFile "Error message was: $FME_FailureMessage"
};
puts $outputFile ""
# Output the unique Mapping file identifier set in the mapping file using MAPPING_FILE_ID
puts $outputFile "Translation summary for $FME_MappingFileId"
# Output the number of features read\written per feature type.
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile "                         Features read summary                                 "
puts $outputFile "---------------------------------------------------------------------------"
# Loop through a sorted listed of the feature types that were read, and output the
# résultat pour chacune d'entre elles
set formatSpec "%-65s: %12s"
foreach featType [lsort [array names FME_FeaturesRead]] {
    puts $outputFile [format $formatSpec $featType $FME_FeaturesRead($featType)]
}
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile [format $formatSpec "Total Features Read" $FME_TotalFeaturesRead];
puts $outputFile "---------------------------------------------------------------------------"   
puts $outputFile ""
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile "                         Features Written summary                              "
puts $outputFile "---------------------------------------------------------------------------"
# Loop through a sorted listed of the feature types that were written, and output the
# résultat pour chacune d'entre elles
foreach featType [lsort [array names FME_FeaturesWritten]] {
    puts $outputFile [format $formatSpec $featType $FME_FeaturesWritten($featType)]
}
puts $outputFile ""
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile [format $formatSpec "Total Features Written" $FME_TotalFeaturesWritten]
puts $outputFile [format $formatSpec "Total Coordinates Written" $FME_TotalCoordinates]
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile ""
# Chercher les lignes qui dans le fichier de log étaient des avertissements, et en faire le compte
# dans le fichier résumé.  Vérifier également la présence de "unexpected input remover"
# dans la ligne de statistiques et signaler s'il y en a (cela peut arriver
# quand les fichiers de contrôle Workbench sont exécutés contre des jeux de données en entrée
# avec des types d'entités différents de ceux attendus
# De même, il faut trouver le message de log sur l'état du système (#246014) et le copier
# dans le fichier produit
set logFileExists [file exists $FME_LogFileName]
set warnings 0
if {$logFileExists} {
   set logFile [open $FME_LogFileName r]
   while {[gets $logFile line] >= 0} {
      if {[regexp {WARN} $line]} {
         incr warnings
      } elseif {[regexp {#246014} $line]} {
        puts $outputFile "-------------------------------------------------------------------"
        puts $outputFile $line
        puts $outputFile "-------------------------------------------------------------------"
        puts $outputFile ""
      } elseif {[regexp {Unexpected Input Remover} $line]} {
          set totalFeatures 0
          set acceptedFeatures 0
          set rejectedFeatures 0
          set line [regsub {^.*Unexpected} $line {Unexpected}]
          catch {scan $line "Unexpected Input Remover(TestFactory): Tested %d input features -- %d features passed, %d features failed." totalFeatures acceptedFeatures rejectedFeatures}
          if {$rejectedFeatures > 0} {
            puts $outputFile "---------------------------------------------------------------"
            puts $outputFile [format $formatSpec "Features with Unexpected Feature Types" $rejectedFeatures]
            puts $outputFile "---------------------------------------------------------------"
            puts $outputFile ""
          }
      }
   }
   close $logFile
}
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile [format $formatSpec "Logfile $FME_LogFileName Warnings" $warnings]
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile ""
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile [format $formatSpec "Total Elapsed Time (seconds)" $FME_ElapsedTime]
puts $outputFile [format $formatSpec "Total CPU Time (seconds)" $FME_CPUTime]
puts $outputFile "---------------------------------------------------------------------------"
puts $outputFile ""
# Et fermer le fichier
close $outputFile

Exemple 6 : Installation de TclODBC

Cet exemple utilise un script externe pour insérer un enregistrement de l'activité de la conversion dans une base de données à l'aide du package TclODBC. Dans cet exemple, une base de données Access est créée (si nécessaire) et alimentée avec une ligne pour chaque traduction terminée.

Pour utiliser TclODBC dans FME, procéder ainsi :

En savoir plus sur le package TclODBC sur http://wiki.tcl.tk/2151

Télécharger le package TclODBC sur http://sourceforge.net/projects/tclodbc

Dézipper le résultat

Editer le setup.tcl fourni pour changer :

if [string match *lib $i] { 
to
       if [string match *lib* $i] {

Dans une invite de commande, dans le dossier contenant setup.tcl, exécutez "fme setup.tcl". Ceci installera le paquetage TclODBC dans l'environnement Tcl de FME.

S'assurer que tous les scripts qui ont besoin du package TclODBC commencent ainsi :

      package require tclodbc

Pour appeler le script type qui effectue l'insertion dans la base de données, le fichier de contrôle contient cette ligne-ci :

 FME_END_TCL source {$(FME_MF_DIR_UNIX)/recordTranslationODBC.tcl}

 The contents of the “recordTranslationODBC.tcl” file are:
#=====================================================================
#
# recordTranslationODBC.tcl
#
# Ce script enregistre l'exécution d'une conversion utilisant
# le package TclODBC.  Cet exemple inclut la création des
# base de données et table Access pour enregistrer les résultats de la conversion.
# Une ligne pour chaque conversion exécutée est insérée dans la table.
# Notez que pour un système de production réglé les déclarations "puts"
# seront supprimées.
package require tclodbc
#=====================================================================
#
# Installer certaines variables qui sont utilisées pour créer et connecter
# à la base de données via ODBC
set driver "Microsoft Access Driver (*.mdb)"
set dbfile c:/translations.mdb
set dsn XLATION
#=====================================================================
# Créer la base de données si elle n'est pas déjà là. Nous ne ferions pas cela si le
# base de données était basée sur le serveur, mais pour cet exemple nous utilisons Access.
if {![file exists $dbfile]} {
    puts "Creating database $dbfile"

database configure config_dsn $driver [list "CREATE_DB=\"$dbfile\" General"]    } else {
    puts "Using existing database $dbfile"
}
#=====================================================================
# Créer une source de données ODBC pour cette base de données, et s'y connecter
# En premier lieu, toujours supprimer le DSN s'il y a lieu.  Si l'on utilisait
# ODBC pour se connecter à une base de données "réelle", on supposerait
# que le DSN est déjà valide
catch {database configure remove_dsn $driver "DSN=$dsn"}
database configure add_dsn $driver [list "DSN=$dsn" "DBQ=$dbfile"]
database db $dsn
#=====================================================================
#  Créer la table que l'on souhaite insérer si elle n'y est pas encore
if {[llength [db tables XLATION_RESULTS]] == 0} {
  puts "Creating XLATION_RESULTS table in database $dbfile"
  db "CREATE TABLE XLATION_RESULTS (
      MappingFileID VARCHAR(50),
      StartTime TIMESTAMP,
      EndTime TIMESTAMP,
      CpuTime DOUBLE,
      Successful CHAR(3),
      NumFeatures INTEGER)"
} else {
  puts "XLATION_RESULTS table present in database $dbfile"
}
#=====================================================================
# Tout ceci n'était que de l'installation ; nous pouvons à présent insérer notre ligne,
# l'engager, et déconnecter de la source des données
set Success yes
if {$FME_Status == 0} {set Success no}
db "INSERT INTO XLATION_RESULTS
       (MappingFileID, StartTime, EndTime, CpuTime, Successful, NumFeatures)
       VALUES ('$FME_MappingFileId', \{ts '$FME_StartingTimeStamp'\},
               \{ts '$FME_EndingTimeStamp'\},
               $FME_CPUTime, '$Success', $FME_TotalFeaturesWritten)"
       
db commit
db disconnect
#=====================================================================
# Si vous étiez connecté à une base de données basée sur un serveur, vous voudriez
# ne supprimerait PAS le DSN ODBC à la fin. Mais comme nous étions basés sur des fichiers
#nous allons le supprimer
database configure remove_dsn $driver "DSN=$dsn"