SSIS API #3 : ConnectionManager & OLEDB Data source

Publié le par Renaud Harduin

Dans le précédent article, j'ai créé mon package et lui ajoutais un data flow (MainPipe).

Nous allons maintenant aborder l'aspect accès aux données dans ce billet. Au sein de l'ETL Microsoft, nous définissons des ConnectionManager dont l'objet est centraliser, de manière générique, les définitions et l'accès aux sources de données (et donc réduire la redondance de paramétrage)

(Tout le code source est disponible sur CodePlex : www.codeplex.com/BILAB, dans l'onglet source, répertoire POC/BILABHistory, solution BIHistory.sln. La classe concernée est MulticastExport.cs dans le sous projet BILAB.Technical.History.PackageBuilder)

Ajout des Gestionnaires de Connexion

Les gestionnaires de connexion (ConnectionManager) font l'objet d'une collection _p.Connections au sein de package. Vous pouvez en ajouter comme suit :

private runtime.ConnectionManager _sourceCM;

 

private void addSourceCM()

{

    _sourceCM = _p.Connections.Add("OLEDB");

    _sourceCM.Name = "AdventureDWSource";

    _sourceCM.ConnectionString = @"Provider=SQLOLEDB.1;Password=myuser;Persist Security Info=True;User ID=myuser;Initial Catalog=AdventureWorksDW;Data Source=localhost";

}


Les sources peuvent être FLATFILE, ADO, ODBC... fonction du besoin.

Ajout de la source au sein du DataFlow

Définir une connexion ne suffit pas en tant que tel à accéder aux données, il faut ajouter une source au sein de notre DataFlow, plus précisément au MainPipe :

private wrapper.IDTSComponentMetaData100 _oledbDatasource;

private wrapper.CManagedComponentWrapper _sourceInstance;

 

private void addSourceConnection()

   {

       _oledbDatasource = _mainpipe.ComponentMetaDataCollection.New();           

       _oledbDatasource.ComponentClassID = "DTSAdapter.OLEDBSource";

<…/>


Le pipeline SSIS est en fait composé d'objets de type ComponentMetadata qui représente chacune des tâches que vous vous pouvez glisser sur le designer SSIS.
Ce type vous permet d'accéder aux propriétés génériques (Commons) des tâches. Nous le "typons" en utilisant à nouveau les CLSID. 

Vous trouverez ici la référence des API Communes à toutes les tâches :

http://msdn.microsoft.com/en-us/library/ms136001.aspx

Plus précisément : http://msdn.microsoft.com/en-us/library/ms135950.aspx

 

Dans le modèle SSIS, nous devons aussi créer une instance de type « source OLE DB » (et non, ce n'est toujours pas fait...) avec la méthode _oleDbSource.Instanciate qui nous renvoie CManagedComponentWrapper qui comme son nom l'indique est un wrapper vers l'objet (COM encore) sous jacent :

<…/>

 

// Instanciate an OleDB source Instance for design time based on OleDB Source

_sourceInstance = _oledbDatasource.Instantiate();

// ProvideComponentProperties acts as a kind of constructor and build input, output ...//

_sourceInstance.ProvideComponentProperties();

 

<…/>

Si je refais un détour sur le développement de composants SSIS, je vous avais proposé il ya quelques temps une destination XML (qui ne passait pas par du DOM, mais par un XMLWriter) :

http://www.techheadbrothers.com/Articles.aspx/developpement-composant-integration-services-ssis

Et c'est en surchargeant la méthode ProvideComponentProperties que j'ajoutais les propriétés dynamiquement à mon composant.

http://www.techheadbrothers.com/Articles.aspx/developpement-composant-integration-services-ssis-page-3

Il faut donc bien comprendre que la méthode ProvideComponentProperties agit comme un véritable constructeur sur l'instance. Dès lors, nous aurons accès aux propriétés propres au PipelineComponent, et notamment lui la possibilité de lier notre source un connectionManager.

<…/>

// Relink runtime oledb component with the package connection manager defined before

            _oledbDatasource.RuntimeConnectionCollection[0].ConnectionManagerID = _sourceCM.ID;

            _oledbDatasource.RuntimeConnectionCollection[0].ConnectionManager

                            = runtime.DtsConvert.GetExtendedInterface(_sourceCM);

<…/>

Nous pouvons aussi spécifier le mode d'accès aux données ainsi que la requête (propriétés spécifiques):

<…/>

_sourceInstance.SetComponentProperty("AccessMode", 2);

_sourceInstance.SetComponentProperty("SqlCommand", "Select * from FactInternetSales");

   

_oledbDatasource.Name = "OLE select from Fact InternetSales";

_oledbDatasource.Description = "OLE select from Fact InternetSales";

<…/>

En complément au lien MSDN sur les propriétés communes, vous trouverez sur le lien suivant les propriétés propres à la source OLE DB :

http://msdn.microsoft.com/en-us/library/ms135923.aspx

Comme dernière étape à notre processus, nous allons faire en sorte que notre composant se connecte à sa source de données pour la valider et récupérer la liste des colonnes à extraire de la source comme suit:

<…/>

   _sourceInstance.AcquireConnections(null);

    _sourceInstance.ReinitializeMetaData();

    _sourceInstance.ReleaseConnections();

   

}

<…>

 

MulticastExport en action …

Enfin si je replace le tout dans l'appel :

public void Export()

        {

            _p = new runtime.Package();

            _p.Name = "MulticastExport";

            _p.CreatorComputerName = System.Environment.MachineName;

            _p.CreatorName = System.Environment.UserName;

   

            this.addDataflow();

            this.addSourceCM();

            this.addSourceConnection();

            //this.addMulticast();

            //this.addPdtSource();

            //this.addSort();

            //this.addMerge();

            //this.addFactDestination();

   

            runtime.Application a = new Microsoft.SqlServer.Dts.Runtime.Application();

            a.SaveToXml("ZBILAB.History.dtsx", _p, null);

        }

 

Nous retrouvons notre package avec une Connexion :


Et une source dans le dataflow :


Les propriétés « populées » avec nos paramètres :


Le vecteur colonne préparé suite à la validation de la source :

La suite …

A partir de cette source nous allons continuer à construire notre flux et ajouter un multicast qui nous permettra de faire un flux vers un fichier texte, et un flux vers une tâche Merge Join.

 

Publié dans API SSIS

Pour être informé des derniers articles, inscrivez vous :
Commenter cet article