/// <summary> /// Creates a new connection to the Sql database. Returns connection closed. /// </summary> /// <returns></returns> private DbConnection CreateConnection(XPathDataSourceBase source, SqlProviderCommand parent) { if (null != parent) { if (string.IsNullOrEmpty(this.ConnectionName)) { this.ConnectionName = parent.ConnectionName; } if (string.IsNullOrEmpty(this.ConnectionString)) { this.ConnectionString = parent.ConnectionString; this.ConnectionProvider = parent.ConnectionProvider; } } string constr; string provider; if (!string.IsNullOrEmpty(this.ConnectionString)) { constr = this.ConnectionString; provider = this.ConnectionProvider; } else if (!string.IsNullOrEmpty(this.ConnectionName)) { System.Configuration.ConnectionStringSettings consettings = System.Configuration.ConfigurationManager.ConnectionStrings[this.ConnectionName]; if (null == consettings) { throw new NullReferenceException(string.Format(Errors.NoConnectionSettingFor, this.ConnectionName)); } constr = consettings.ConnectionString; provider = consettings.ProviderName; } else { throw new NullReferenceException(string.Format(Errors.NoConnectionDefined, this.ID, source.ID)); } DbProviderFactory fact = DbProviderFactories.GetFactory(provider); if (null == fact) { throw new NullReferenceException(string.Format(Errors.NoProviderFactoryWithName, provider)); } DbConnection con = fact.CreateConnection(); con.ConnectionString = constr; return(con); }
// // Method Loading via reflection // #region private MethodInfo AssertGetCallableMethod(PDFXPathDataSourceBase source) /// <summary> /// Finds the matching method based on the TypeName and MethodName in this ObjectProviderCommand /// </summary> /// <param name="source">The source that holds this command</param> /// <returns></returns> private MethodInfo AssertGetCallableMethod(XPathDataSourceBase source) { if (string.IsNullOrEmpty(this.TypeName)) { throw new NullReferenceException(string.Format(Errors.TypeNameNotSetOnObjectDataSource, this.ID, source.ID)); } Type foundType = this.GetTypeFromName(this.TypeName); if (null == foundType) { throw new NullReferenceException(string.Format(Errors.TypeCouldNotBeFoundForObjectData, this.TypeName, this.ID, source.ID)); } if (string.IsNullOrEmpty(this.MethodName)) { throw new NullReferenceException(string.Format(Errors.MethodNameNotSetOnObjectDataSource, this.ID, source.ID)); } MethodInfo[] meths = this.GetMethodOnType(this.MethodName, foundType); if (null == meths || meths.Length == 0) { throw new NullReferenceException(string.Format(Errors.MethodCouldNotBeFoundForObjectData, this.MethodName, this.TypeName, this.ID, source.ID)); } MethodInfo matching; if (meths.Length > 1) { matching = FindMatchMethodSignatureToParameters(meths); } else { matching = EnsureSignatureMatchesParameters(meths[0]); } if (null == matching) { throw new NullReferenceException(string.Format(Errors.MatchingMethodSignatureCouldNotBeFoundForObjectData, this.MethodName, this.TypeName, this.ID, source.ID)); } if (matching.ReturnType == null) { throw new NullReferenceException(string.Format(Errors.MatchingMethodSignatureDoesNotHaveAReturnTypeObjectData, this.MethodName, this.TypeName, this.ID, source.ID)); } return(matching); }
/// <summary> /// Main entry point to load the XPath data from a defined method on a type. /// </summary> /// <param name="source"></param> /// <param name="context"></param> /// <returns></returns> protected override void DoEnsureDataLoaded(XPathDataSourceBase source, System.Data.DataSet ds, PDFDataContext context) { MethodInfo meth = AssertGetCallableMethod(source); object instance = GetCallableInstance(meth); object[] parameters = GetInvokingParameterValues(meth); object returnValue = InvokeMethod(meth, instance, parameters); if (null != returnValue) { XPathNavigator nav = GetNavigatorFromReturnValue(returnValue, meth.ReturnType); ds.ReadXml(nav.ReadSubtree()); } }
/// <summary> /// Loads the data from this command and returns as an XPath Navigator /// </summary> /// <param name="source"></param> /// <param name="context"></param> /// <returns></returns> public void EnsureDataLoaded(XPathDataSourceBase source, System.Data.DataSet dataSet, PDFDataContext context) { try { this.DoEnsureDataLoaded(source, dataSet, context); } catch (Exception ex) { if (context.Conformance == ParserConformanceMode.Lax) { context.TraceLog.Add(TraceLevel.Error, "XPath Provider Command", ex.Message, ex); context.TraceLog.Add(TraceLevel.Error, "XPath Provider Command", string.Format("Could not load the data for command '{0}' in source '{1}'. Returning null instead.", this.ID, source.ID), ex); } else { throw; } } }
/// <summary> /// Fills the data into the dataset from the releated command, and then adds the relation constraint to the data set. /// </summary> /// <param name="rel"></param> /// <param name="ds"></param> /// <param name="source"></param> /// <param name="context"></param> protected virtual void FillRelatedData(DataRelation rel, DataSet ds, XPathDataSourceBase source, PDFDataContext context) { string cmd = rel.ChildCommand; XPathProviderCommandBase provider = source.Commands[cmd]; if (null == provider) { throw new NullReferenceException(string.Format(Errors.CommandWithNameCannotBeFound, cmd, source.ID)); } if (!(provider is IPDFDataSetProviderCommand)) { throw new InvalidCastException(string.Format(Errors.CommandForRelatedDataMustMatchType, typeof(SqlProviderCommand), typeof(SqlProviderCommand))); } IPDFDataSetProviderCommand dsProvider = (IPDFDataSetProviderCommand)provider; dsProvider.FillData(ds, source, this, context); rel.AddRelation(this, dsProvider, ds, context); }
// // abstract overrides // #region protected override System.Xml.XPath.XPathNavigator DoLoadXPathData(PDFXPathDataSourceBase source, PDFDataContext context) /// <summary> /// Main method that loads all the data (including any related commands) into a dataset and returns an XPathNavigable instance of the data representation /// </summary> /// <param name="source"></param> /// <param name="context"></param> /// <returns></returns> protected override void DoEnsureDataLoaded(XPathDataSourceBase source, DataSet ds, PDFDataContext context) { //We are always top level here so top element namespace should be the same as inner element namespace if (!string.IsNullOrEmpty(this.ElementNamespaceUri)) { ds.Namespace = this.ElementNamespaceUri; } this.FillData(ds, source, null, context); if (this.HasRelations) { foreach (DataRelation rel in this.Relations) { FillRelatedData(rel, ds, source, context); } } this.DataSet = ds; this.DataSchema = DoPopulateDataSchema(ds, context); }
// // ctor // public XPathProviderCommandList(XPathDataSourceBase parentSource) : base(((IPDFContainerComponent)parentSource).Content) { }
/// <summary> /// Abstract method that inheritors must implement to load their own data /// </summary> /// <param name="source"></param> /// <param name="context"></param> /// <returns></returns> protected abstract void DoEnsureDataLoaded(XPathDataSourceBase source, System.Data.DataSet dataSet, PDFDataContext context);
// // IPDFDataSetProvider implementation // #region public abstract void FillData(DataSet dataset, PDFXPathDataSourceBase source, IPDFDataSetProviderCommand parent, PDFDataContext context); /// <summary> /// Abstract base method that inheritors must override to populate the main data in this provider /// </summary> /// <param name="dataset"></param> /// <param name="source"></param> /// <param name="parent"></param> /// <param name="context"></param> public abstract void FillData(DataSet dataset, XPathDataSourceBase source, IPDFDataSetProviderCommand parent, PDFDataContext context);
// // support methods // #region public void FillData(DataSet ds, PDFProviderParameterValueCollection values) /// <summary> /// Loads all the required data from this commands Sql source into the dataset using the /// Sql statement and the provided parameter values that have ben explicitly set /// </summary> /// <param name="ds">the DataSet to populate</param> /// <param name="index">The index of the command</param> public override void FillData(DataSet ds, XPathDataSourceBase source, IPDFDataSetProviderCommand parent, PDFDataContext context) { bool logDebug = context.TraceLog.ShouldLog(TraceLevel.Debug); if (logDebug) { context.TraceLog.Begin(TraceLevel.Debug, SqlCommandLog, string.Format("Starting load of data for sqlCommand '{0}'", this.ID)); } DbConnection con = null; DbCommand cmd = null; try { con = this.CreateConnection(source, parent as SqlProviderCommand);//parent could be null but handled in the code if (logDebug) { context.TraceLog.Add(TraceLevel.Debug, SqlCommandLog, "Created db connection to sql database"); } cmd = this.CreateCommand(con, this.CommandType, this.Statement); if (logDebug) { context.TraceLog.Add(TraceLevel.Debug, SqlCommandLog, "Created db command for statement"); } this.PopulateParameters(cmd, context); if (logDebug) { context.TraceLog.Add(TraceLevel.Debug, SqlCommandLog, "Added " + cmd.Parameters.Count + " parameters to db command"); } con.Open(); this.PopulateData(ds, cmd); if (!string.IsNullOrEmpty(this.AsAttributes)) { ApplyAttributes(ds, this.AsAttributes, context); } if (logDebug) { context.TraceLog.Add(TraceLevel.Debug, SqlCommandLog, "Dataset populated"); } } finally { if (null != cmd) { cmd.Dispose(); } if (null != con) { con.Dispose(); } if (logDebug) { context.TraceLog.Add(TraceLevel.Debug, SqlCommandLog, string.Format("Disposed of command and connection")); } } if (logDebug) { context.TraceLog.End(TraceLevel.Debug, SqlCommandLog, string.Format("Completed load of data for sqlCommand '{0}'", this.ID)); } }