Share via


How to: Create Data Source Providers

Data source providers connect to a data source, access its data, and then return query results. Data source providers reside on the computers that are running PerformancePoint Monitoring Server and Windows SharePoint Services 3.0 or Microsoft Office SharePoint Server 2007 in the PerformancePoint Monitoring system.

You can create a custom data source provider to access a data source that is not supported by Monitoring Server. Data source providers must implement the IDataSourceProvider interface, either directly or indirectly. All native Monitoring Server data source providers also implement the IDataSourceMetadata interface.

Because Monitoring Server fully supports ADOMD and ODBC data sources, custom data source providers typically implement the TabularDataSourceProvider class, which inherits from the CustomDataSourceProvider base class.

Note

Monitoring Server provides native support for the following tabular data sources: Microsoft Office Excel 2007 and Excel Services worksheets, Windows SharePoint Services 3.0 and Microsoft Office SharePoint Server 2007 lists, and Microsoft SQL Server 2005 and Microsoft SQL Server 2000 tables.

To determine which class your extension should inherit from, review the built-in data source providers and choose the one that best matches your needs. Your custom implementation will typically return hard-coded values for many of the overridden methods. For information about native data source providers, see Microsoft.PerformancePoint.Scorecards.DataSourceProviders and Microsoft.PerformancePoint.Scorecards.Extensions.

This topic assumes that your provider inherits from TabularDataSourceProvider.

Note

To download a code sample of a data source extension that uses a Live Search Web service as a data source, see PerformancePoint Monitoring Server SDK: Custom Data Connector and Report View Code Samples from the Microsoft PerformancePoint Team Blog.

Implementing TabularDataSourceProvider

The main function of TabularDataSourceProvider is to create and populate a Dataset object with data from the data source. It also provides support for the following features:

  • Multidimensional mapping, which converts tabular data into a fully qualified multidimensional data structure by defining column data as fact, dimension, or date data. This mapping is used for Time Intelligence features and for multidimensional navigation, such as drilling down on members.

  • Data set filtering, in which the data source provider accepts parameters and then filters the dataset by using the RunQuery method.

Note

CustomDataSourceProvider does not support these features. If you inherit from it directly and want to support these features, you must create similar functionality in your data source provider.

To create the SimpleTabularDataSourceProvider data source provider

The following procedure provides steps for creating the data source provider in the Example section. This example does not contain code for the data source designer component, but it assumes that the designer component sets the UseConnectionString property to true and allows a user to provide a connection string that is a path to a text file. It also supports letting users specify the list separator to use in the CustomData property, which can store information for the data source that is not defined in another property.

  1. Create the SimpleTabularDataSourceProvider class in the Extensions.Dashboard namespace.

  2. Add the following assembly references to your project:

    • Microsoft.PerformancePoint.Scorecards.Client.dll

    • Microsoft.PerformancePoint.Scorecards.DataSourceProviders.Standard.dll

    These references apply to the provider component of this custom data source extension. The functionality of your extension determines the references that you add to your project. The default path for Monitoring Server DLLs is drive:\Program Files\Microsoft Office PerformancePoint Server\3.0\Monitoring\Assemblies.

  3. Add the following using directives.

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.IO;
    using System.Text;
    using Microsoft.PerformancePoint.Scorecards.DataSourceProviders;
    using Microsoft.PerformancePoint.Scorecards;
    
  4. Inherit from TabularDataSourceProvider.

  5. To indicate whether the connection string for the data source stores sensitive information, override the IsConnectionStringSecure property.

    This example returns false. If your extension stores sensitive information in the connection string such as a user name or password, return true. If the data source does not use a connection string, return false.

  6. To return the identifier for your data source provider, override the GetId method. This must return the same string as the SourceName property in the data source designer class factory.

  7. To create a Dataset object to store the data from the data source, override the GetDataSet method.

    Note

    If you implement GetDataSet, you do not need to implement the following four abstract methods: GetDatabaseNames GetCubeNames GetCubeNameInfos GetCubeMetaData

    This example throws a "Not implemented" exception for the four abstract methods. However, you can use them to provide information about your data source for Dashboard Designer editing controls. For example, to let users select a data source from a set of files, you could return a path to a file share in GetDatabaseNames and the list of available files in GetCubeNames.

  8. To return the names of the available databases from the data source, override the GetDatabaseNames method.

  9. To return the names of the available cubes from the data source, override the GetCubeNames method.

  10. To return the unique name, display name, and description for each available cube, override the GetCubeNameInfos method.

  11. To return information about the data, such as member names and hierarchy structure, override the GetCubeMetaData method.

  12. To validate your data source provider, override the Validate method.

Example

The class in the following code example creates a data source provider that uses a text file as a data source.

Prerequisites

Before you compile the code example, ensure you have met the following prerequisites:

  • Install Monitoring Server.

  • Create a text file to use as the data source. The file should contain a few lines of comma-separated values, as follows.

    09/5/2008,7,Redmond Washington
    01/20/2009,1,Boise Idaho
    02/18/2009,2,Santa Fe New Mexico
    
  • Create a data source designer component that does the following:

    • Sets the UseConnectionString property of the data source object to true.

    • Allows a user to provide a path to a text file to use as a connection string. Alternatively, you can set the ConnectionString property to a hard-coded path in the designer component.

    • (Optional) Allows a user to set the CustomData property to specify the list separator value. The code example sets a comma as the default value, which will work with the text file data source described in the previous item without requiring a user-defined setting. If you do implement CustomData in the designer component, you can modify the data source to use a different list separator.

  • Be prepared to sign your DLL with a strong name. In addition, ensure that all assemblies referenced by your DLL have strong names. For information about how to sign an assembly with a strong name and how to create a public/private key pair, see How to: Create a Public/Private KeyPair.

The following code example defines a simple tabular data source provider that creates a dataset and then populates it with the contents of a text file.

using System;
using System.Collections.Generic;
using System.Data;
using System.IO; 
using System.Text;
using Microsoft.PerformancePoint.Scorecards.DataSourceProviders;
using Microsoft.PerformancePoint.Scorecards;

namespace Extensions.Dashboard
{
    public class CustomTabularDataSourceProvider : TabularDataSourceProvider
    {

        // Return true if your provider stores sensitive information
        // in the connection string, such as user names and passwords.
        // This example does not, so it returns false. 
        public override bool IsConnectionStringSecure
        {
            get { return false; }
        }

        // The source name for your data source. Used internally.
        public override string GetId()
        {
            return "SimpleTabularDataSource";
        }

        // Get the data from the data source.
        // In this example, GetDataSet contains all the logic for the provider.
        public override DataSet GetDataSet()
        {
            
            // Create a dataset and a data table to store the data. 
            DataSet resultsSet = new DataSet();
            DataTable resultsTable = resultsSet.Tables.Add();

            // Define column names and the type of data they contain. 
            resultsTable.Columns.Add("Date", typeof(DateTime));
            resultsTable.Columns.Add("Count", typeof(int));
            resultsTable.Columns.Add("GeoDimension", typeof(string));

            // Get the data from the data source and use it to populate the dataset.
            // The data source in this example is a local text file that is 
            // specified by the data source object's connection string.
            // The text file contains three comma-separated values on each line.
            // Example line: 09/05/2008,7,Redmond Washington
            using (StreamReader sr = File.OpenText(dataSource.ConnectionString))
            {
                string s = "";
                while ((s = sr.ReadLine()) != null)
                {

                    // Split the line of data into its three values,
                    // using the list separator specified in the CustomData
                    // property in Dashboard Designer. Use "," by default.
                    string[] separator = { string.IsNullOrEmpty(dataSource.CustomData) ? "," : dataSource.CustomData };
                    string[] csv = s.Split(separator, StringSplitOptions.None);


                    // Create a row, assign the values to each column,
                    // and then add the row to the dataset.
                    DataRow row = resultsTable.NewRow();
                    row["Date"] = csv[0];
                    row["Count"] = csv[1];
                    row["GeoDimension"] = csv[2];
                    resultsTable.Rows.Add(row);
                }
            }
            return resultsSet;
        }

        #region Overridden abstract methods that are not implemented.

        // Get the names of available databases from 
        // the data source.
        // This example does not implement GetDatabaseNames.
        public override string[] GetDatabaseNames()
        {
            throw new NotImplementedException();
        }

        // Get the names of available cubes from the
        // data source. 
        // This example does not implement GetCubeNames.
        public override string[] GetCubeNames()
        {
            throw new NotImplementedException();
        }

        // Get the unique name, display name, and description
        // of the cube.
        // This example does not implement GetCubeNameInfos. 
        public override NameInfoCollection GetCubeNameInfos()
        {
            throw new NotImplementedException();
        }

        // Get information about your data, such as member names 
        // and hierarchy structures.
        // This example does not implement GetCubeMetaData.
        public override Cube GetCubeMetaData()
        {
            throw new NotImplementedException();
        }
        
        #endregion

        // Validate the data source.
        public override void Validate()
        {
            File.ReadAllText(dataSource.ConnectionString);
        }
    }
}

Remarks for Creating Data Source Providers

The following considerations might be useful when you create or debug your custom data source provider:

  • Although the names of many methods in CustomDataSourceProvider are based on ADOMD.NET objects such as cubes and dimensions, they can be used against any data source. For example, the SPListDataSourceProvider class treats lists as cubes.

  • Data source providers are accessed through report views and KPIs, but not from the PmService Web service. Therefore, to see the result set that is returned by your data source when debugging or testing, call a report or KPI that consumes your data source.

See Also

Tasks

How to: Install Data Source Provider Extensions

Concepts

How to: Create Data Source Designers

Other Resources

Data Sources