Click here to Skip to main content
15,886,362 members
Articles / Database Development / SQL Server

Overview of XQuiSoft Data Using the Provider Pattern (Open Source)

Rate me:
Please Sign up or sign in to vote.
3.59/5 (12 votes)
16 Jun 2009BSD8 min read 40.7K   77   28  
A data abstraction layer for .NET applications. Write your application code to be database neutral. Swap out the type of database your application uses without updating or even recompiling your business components.
/*
Copyright (c) 2006, XQuiSoft LLC
All rights reserved.
Redistribution and use in source and binary forms, with or without modification
are permitted provided that the following conditions are met:
�	Redistributions of source code must retain the above copyright notice, this
	list of conditions and the following disclaimer.
�	Redistributions in binary form must reproduce the above copyright notice,
	this list of conditions and the following disclaimer in the documentation
	and/or other materials provided with the distribution.
�	Neither the name of XQuiSoft LLC nor the names of its contributors may be
	used to endorse or promote products derived from this software without
	specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Data;
using System.Collections;
using System.Collections.Specialized;

using XQuiSoft.Installation;
using XQuiSoft.Provider;
using XQuiSoft.Reflection;

namespace XQuiSoft.Data.Demo.Data
{
	/// <summary>
	/// Summary description for DbEmployeeProvider.
	/// </summary>
	public class DbEmployeeProvider: EmployeeProvider
	{
		#region Fields
		private string connectionName_ = string.Empty;
		private DataProvider dataProvider_ = null;
		private string cachedDataSourceVersion_ = null;
		#endregion Fields

		#region Constructors
		/// <summary>
		/// Creates a new instance of DbEmployeeProvider.
		/// </summary>
        public DbEmployeeProvider() :base() { }
		#endregion Constructors

		#region Properties
		/// <summary>
		/// The name of the connection the provider will use.
		/// </summary>
		public virtual string ConnectionName
		{
			get {return this.connectionName_;}
		}
		/// <summary>
		/// The version of the datamodel for this API installed in the
		/// datasource that this provider manipulates.
		/// </summary>
		public override string DataSourceVersion
		{
			get
			{
				if (cachedDataSourceVersion_ != null)
					return cachedDataSourceVersion_;

				string script = InternalResource.GetResourceString(this
					, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Installer.DbEmployeeProviderVersionCheck.sql", true);

				string ver = dataProvider_.ExecuteScalar(script).ToString().Trim();
				if (ver.StartsWith("*"))
				{	//replace * with current version number
					ver = ComponentVersion + ver.Substring(1);
				}
				cachedDataSourceVersion_ = ver;
				return ver;
			}
		}
		#endregion Properties

		#region Methods
		/// <summary>
		/// Initializes the provider with the specified values.
		/// </summary>
		/// <param name="name">The name of the provider.</param>
		/// <param name="configValue">Provider specific attributes.</param>
		public override void Initialize(string name, NameValueCollection configValue)
		{
			base.Initialize(name, configValue);

			connectionName_ = ProvidersHelper.GetStringValue
				(configValue, "connectionName", connectionName_);
			if (connectionName_ != null && connectionName_.Trim().Length > 0)
				dataProvider_ = DataManager.Providers[connectionName_];
			else
				dataProvider_ = DataManager.Providers.Default;
			if (dataProvider_ == null)
				throw new ArgumentException("ConnectionName does not exist in the configuration.");
		}
		/// <summary>
		/// Installs the required datamodel for this provider into
		/// the datasource.
		/// </summary>
		public override ExecutionResults Install()
		{
			cachedDataSourceVersion_ = null;
			ExecutionResults result = new ExecutionResults();

			try
			{
				if (this.Feature.TargetFeatureLevel == InstallLevel.Unspecified)
					return result;
				else if (this.Feature.TargetFeatureLevel == InstallLevel.NotAvailable)
				{   //un-install
					result.AppendInfo("Uninstall started.");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Installer.DEmployeeProviderUnInstall.sql"));
					this.Feature.FeatureLevel = InstallLevel.NotAvailable;
				}
				else //install
				{
					//tables
					result.AppendInfo("Updating tables.");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Tables.Demo_Employee.sql"));
					result.AppendInfo("  Demo_Employee OK");
					this.Feature.FeatureLevel = InstallLevel.Partial;

					//procedures
					result.AppendInfo("Updating procedures.");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Procs.Demo_DeleteEmployee.sql"));
					result.AppendInfo("  Demo_DeleteEmployee OK");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Procs.Demo_GetEmployee.sql"));
					result.AppendInfo("  Demo_GetEmployee OK");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Procs.Demo_GetEmployeeSubordinates.sql"));
					result.AppendInfo("  Demo_GetEmployeeSubordinates OK");
					dataProvider_.ExecuteNonQuery(InternalResource.GetResourceString(this
						, "XQuiSoft.Data.Demo.Data.Scripts.SQL.Procs.Demo_SaveEmployee.sql"));
					result.AppendInfo("  Demo_SaveEmployee OK");
					this.Feature.FeatureLevel = InstallLevel.Complete;
				}
				result.AppendInfo("Completed Successfully!");
			}
			catch (Exception ex)
			{
				result.AppendError(ex.ToString());
			}	//do not throw, just return last message as a failure.
			return result;
		}
		/// <summary>
		/// Gets an instance of an employee with the specified id.
		/// </summary>
		/// <param name="id">The employee's unique identity.</param>
		/// <returns>A new Employee instance.</returns>
		public override Employee GetEmployee(int id)
        {
            Procedure proc = new Procedure("Demo_GetEmployee");
            proc.AddInputParameter("EmployeeID", DbType.Int32, id);
            
            DataFactoryDelegate builder = new DataFactoryDelegate(this.AddEmployee);
            EmployeeCollection col = new EmployeeCollection();
            dataProvider_.Execute(proc, builder, col);

            if (col.Count > 0)
                return col[0];
            else
                return null;
		}
		/// <summary>
		/// Gets all the subordinate employees for a given manager.
		/// </summary>
		/// <param name="managerID">The identity of the manager.</param>
		/// <returns>A collection of the employees</returns>
		public override EmployeeCollection GetSubOrdinates(int managerID)
        {
            Procedure proc = new Procedure("Demo_GetEmployeeSubordinates");
            proc.AddInputParameter("ManagerID", DbType.Int32, managerID);

            DataFactoryDelegate builder = new DataFactoryDelegate(this.AddEmployee);
            EmployeeCollection col = new EmployeeCollection();
            dataProvider_.Execute(proc, builder, col);
            return col;
		}
		/// <summary>
		/// Saves an employee instance.
		/// </summary>
		/// <param name="item">The instance data to save.</param>
		public override bool SaveEmployee(Employee item)
		{
            Procedure proc = new Procedure("Demo_SaveEmployee");
            proc.AddParameter("EmployeeID", DbType.Int32, ParameterDirection.InputOutput, item.ID);
            proc.AddInputParameter("ManagerID", DbType.Int32, item.ManagerID);
            proc.AddInputParameter("FirstName", DbType.AnsiString, item.FirstName);
            proc.AddInputParameter("LastName", DbType.AnsiString, item.LastName);

            int rows = dataProvider_.ExecuteNonQuery(proc);

            Parameter prmID = proc.Parameters.Find("EmployeeID");
            item.ID = dataProvider_.GetInt32(prmID.Value);
            return (rows > 0);
		}
		/// <summary>
		/// Deletes an employee from the datastore with the specified id.
		/// </summary>
		/// <param name="id">The employee's unique identity.</param>
		public override bool DeleteEmployee(int id)
        {
            Procedure proc = new Procedure("Demo_DeleteEmployee");
            proc.AddInputParameter("EmployeeID", DbType.Int32, id);

            int rows = dataProvider_.ExecuteNonQuery(proc);
            return (rows > 0);
		}

        /// <summary>
        /// Adds a source for a given record to a list.
        /// </summary>
        /// <param name="target">The target list.</param>
        /// <param name="record">The record.</param>
        protected virtual void AddEmployee(IList target, IDataRecord record)
        {
            Employee item = new Employee();
            item.ID = dataProvider_.GetInt32(record, "EmployeeID", -1);
            item.ManagerID = dataProvider_.GetInt32(record, "ManagerID", -1);
            item.FirstName = dataProvider_.GetString(record, "FirstName");
            item.LastName = dataProvider_.GetString(record, "LastName");
            target.Add(item);
        }
		#endregion Methods
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The BSD License


Written By
Web Developer Nexul Software LLC
United States United States
Mike has worked in the .Net platform since the beta 2 release of version 1.0. Before that he worked on VB6 windows forms applications automating other applications such as AutoCAD and "Intent".

Mike has released a number of open source applications in javascript and C#.Net. Most of them can be found on github.
github/michael-lang

You can find older .Net open source projects on sourceforge at:
http://sourceforge.net/users/versat1474/

Mike is currently blogging at candordeveloper.com

Comments and Discussions