Quelle über C# öffnen

In rimacon omniSuite werden die am häufigsten genutzten Quellen wie CVS, XLS, XLSX direkt unterstützt (out-of-the-box). Für alle anderen Quellen besteht die Möglichkeit, die Quelle über C#-Scripte anzubinden.

Einsatzbereiche

Diese Anleitung gilt für:

Life-Cycle

Jede C#-Quelle muss fünf Funktionen implementieren:

Die Funktionen werden in folgender Reihenfolge aufgerufen:
  1. Open
    Die Quelle wird geöffnet. Beispielsweise wird eine Connection zur XY-Datenbank und gleichzeitig ein Recordset geöffnet, aber die Daten werden noch nicht ausgelesen.
    Bei einem Fehler sollte diese Funktion die Fehlermeldung als Zeichenfolge zurückgeben. Ansonsten wird eine leere Zeichenfolge zurückgegeben.
  2. Fields
    Diese Funktion gibt die Informationen über die ausgelesenen Spalten zurück. Beispiel:
    return new FieldInfo[] { 
        new FieldInfo() { Name="Name", OriginalTypeAsString="string", CmdbType=19, CmdbLength=-1, CmdbScale=0 }, 
        new FieldInfo() { Name="Anzahl", OriginalTypeAsString="int", CmdbType=8 } 
        };
    Liste von CmdbType-n:
    Typ CmdbType CmdbLength CmdbScale
    Nummer (Gleitkommadaten) 0 0 0
    Zeichenfolge 1 > 0 oder -1 wenn unbegrentzt 0
    Datum 2 automatisch 20 0
    Zeichenfolge (mehrzeilig) 4 > 0 oder -1 wenn unbegrentzt 0
    Nummer (ganzzahlig) 8 0 0
    Link 10 automatisch 256 0
    Dezimal 14 1-38 1-38
    Datum und Zeit 15 0 0
    HTML (direkt) 17 1-8000 0
    Nummer (ganzzahlig 8-Byte) 18 0 0
    Zeichenfolge (Unicode) 19 > 0 oder -1 wenn unbegrentzt 0
    Zeichenfolge (mehrzeilig,Unicode) 20 > 0 oder -1 wenn unbegrentzt 0
  3. Read / GetData
    In einer Schleife wird die Funktion Read aufgerufen.
    Solange diese den booleschen Wert true zurückgibt, wird die Funktion GetData für jede Spalte (Parameter index ist 0-basiert) aufgerufen.
    Wenn die Funktion den booleschen Wert False zurückgibt, wird das Auslesen von Daten gestoppt.
  4. Fields
    Diese Funktion wird am Ende nochmal aufgerufen. Dies ermöglicht es, die Informationen über die Spalten zu verfeinern.
    Wenn die Routine die realen Daten nicht analysiert, geben sie einfach die Informationen aus Schritt 2 zurück.
  5. Close
    Zum Schluss wird die Funktion Close aufgerufen. Gibt alle Ressourcen frei.
Im Praxis werden die Quellen auf zwei Arten geöffnet und verwaltet:
  1. Sequentiell
    Die Logik entspricht dem Life-Cycle. Es sind z.B. Quellen aus Datenbanken.
  2. Bei Open wird alles auf einmal ausgelesen und dann sequentiell zurückgegeben
    Das sind Quellen, bei denen das Ergebnis auf einmal kommt (z.B. Webservices) oder wo es sinnvoller bzw. einfacher ist, alles auf einmal auszulesen und dann über die fünf Funktionen sequentiell zurückzugeben.

Beispiel - Quelle sequentiell auslesen

Als Beispiel führen wir ein einfaches SQL-Select gegen die aktuelle rimacon-Datenbank aus.
Hinweis: Dies dient nur zur Demonstration. Natürlich ist es für solche Quellen besser, Direkt-SQL zu nutzen.

Hier die einzelnen Code-Sektionen:

Referenzen

System.Data.dll

Usings

rimacon.cmdb.ExternalDataSet
System.Data.SqlClient

Interne Definitionen

System.Data.SqlClient.SqlConnection m_Conn = null;
System.Data.SqlClient.SqlDataReader m_Reader = null;

Open

string cs = "Data Source=!!!ANPASSEN!!!;Initial Catalog=rimacon;Trusted_Connection=yes;";
try {

    m_Conn = new System.Data.SqlClient.SqlConnection(cs);
    m_Conn.Open();
    
    System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("select top 10 ANW_ID, ANW_Name1, ANW_Name2 from ANW order by ANW_ID", m_Conn);
    m_Reader = cmd.ExecuteReader();
    
    return ""; // Fehlermeldung
}
catch(System.Exception e) {
    m_Reader = null;
    if (m_Conn != null) m_Conn.Close();
    m_Conn = null;
    return e.Message; // Fehlermeldung
}

Fields

if (m_Conn == null) return new FieldInfo[0];

return new FieldInfo[] {
    new FieldInfo() { Name = m_Reader.GetName(0), OriginalTypeAsString = m_Reader.GetFieldType(0).ToString(), CmdbType = 8 },
    new FieldInfo() { Name = m_Reader.GetName(1), OriginalTypeAsString = m_Reader.GetFieldType(1).ToString(), CmdbType = 19, CmdbLength = 256 },
    new FieldInfo() { Name = m_Reader.GetName(2), OriginalTypeAsString = m_Reader.GetFieldType(2).ToString(), CmdbType = 19, CmdbLength = 256 }
};    

Read

if (m_Reader == null) return false;
return m_Reader.Read();

GetData

errmsg = "";
if (m_Reader == null) return null;
return m_Reader[index];    

Close

if (m_Reader != null) m_Reader.Close();
if (m_Conn != null) m_Conn.Close();

m_Reader = null;
m_Conn = null;

Test

Button "Vorschau" anklicken.

Beispiel - Bei Open alles auf einmal auslesen und dann sequentiell zurückgeben

Die Quelle simulieren wir über einen fixen Datensatz.

Usings

rimacon.cmdb.ExternalDataSet

Interne Definitionen

class Row {
    public string Country;
    public string Capital;
    public Row(string country, string capital) { 
        Country = country;
        Capital = capital; 
    }
}

List<Row> m_AllData = null;
FieldInfo[] m_AllFields = null;
int m_RowIndex = -1;    

Open

m_AllData = new List<Row>();

m_AllData.Add( new Row("Australia", "Canberra") );
m_AllData.Add( new Row("Austria", "Vienna") );
m_AllData.Add( new Row("Denmark", "Copenhagen") );
m_AllData.Add( new Row("Egypt", "Cairo") );
m_AllData.Add( new Row("Finland", "Helsinki") );
m_AllData.Add( new Row("Germany", "Berlin") );
m_AllData.Add( new Row("Italy", "Rome") );
m_AllData.Add( new Row("Japan", "Tokyo") );

m_AllFields = new FieldInfo[] {
    new FieldInfo() { Name = "Country", OriginalTypeAsString = "string", CmdbType = 19, CmdbLength = 100 },
    new FieldInfo() { Name = "Capital", OriginalTypeAsString = "string", CmdbType = 19, CmdbLength = 100 }
};   

m_RowIndex = -1;

return ""; // Fehlermeldung    

Fields

return m_AllFields;    

Read

if (m_AllData == null || m_RowIndex + 1 >= m_AllData.Count) return false;
m_RowIndex++;
return true;    

GetData

errmsg= "";

if (m_AllData == null || index < 0 || index >= 2) return null;

if (index == 0) return m_AllData[m_RowIndex].Country;
if (index == 1) return m_AllData[m_RowIndex].Capital;

return null;    

Close

if (m_AllData != null) m_AllData.Clear();
m_AllData = null;    

Test

Button "Vorschau" anklicken.