See my portfolio for information on the Document Builder project that used the Query Tree component.
The Root class serves as a simple starting point for the query tree. It loads the XML file describing the query tree. The Process method then opens the connection to the database and starts processing the nodes. The caller passes in a connection string and a DbProviderFactory that allows the Root to create a Connection of the right type. The Arguments parameter passed to the Process method ultimately gets passed to the EnterRecord and LeaveRecord methods of the IEntityInstance interface implemented by the caller's objects. See the Store object for an example.
Imports System.Collections ' For access to IComparer
Imports System.Data.Common ' For access to DbProviderFactory, DbConnection
Imports System.Xml ' For access to XmlDocument
Imports NACS.Helpers.Globalization ' For access to GlobalizationHelper
Imports NACS.Helpers.Reflection ' For access to ReflectionHelper
Imports NACS.Utilities.ObjectReader ' For access to ObjectReader, Required
Namespace NACS.Data.QueryTree
Public Class Root
#Region " Member Variables and Properties "
' Public variables read from the xml file
Public Assembly As String = Nothing
Public [Namespace] As String = Nothing
Public Culture As String = Nothing
<Required()> _
Public Node As Node = Nothing
' Private member variables corresponding to public properties
Private m_oFactory As DbProviderFactory = Nothing
Private m_sConnectionString As String = Nothing
Private m_oArguments As Arguments = Nothing
' Private member variables used internally and by child entities
Private m_oComparer As IComparer = Nothing
Private m_oConnection As DbConnection = Nothing
' Private member variables used internally
Private m_bIsProcessing As Boolean = False
Public Property Factory() As DbProviderFactory
Get
Return m_oFactory
End Get
Private Set(ByVal oFactory As DbProviderFactory)
m_oFactory = oFactory
End Set
End Property
Public Property ConnectionString() As String
Get
Return m_sConnectionString
End Get
Private Set(ByVal sConnectionString As String)
m_sConnectionString = sConnectionString
End Set
End Property
Public Property Arguments() As Arguments
Get
Return m_oArguments
End Get
Private Set(ByVal oArguments As Arguments)
m_oArguments = oArguments
End Set
End Property
Friend Property Comparer() As IComparer
Get
Return m_oComparer
End Get
Private Set(ByVal oComparer As IComparer)
m_oComparer = oComparer
End Set
End Property
Friend Property Connection() As DbConnection
Get
Return m_oConnection
End Get
Private Set(ByVal oConnection As DbConnection)
m_oConnection = oConnection
End Set
End Property
Public Property IsProcessing() As Boolean
Get
Return m_bIsProcessing
End Get
Private Set(ByVal bIsProcessing As Boolean)
m_bIsProcessing = bIsProcessing
End Set
End Property
#End Region
#Region " New() Methods "
Public Sub New()
End Sub
Public Sub New(ByVal oXmlDocument As XmlDocument)
Me.Load(oXmlDocument)
End Sub
Public Sub New(ByVal sXmlFileSpec As String)
Me.Load(sXmlFileSpec)
End Sub
#End Region
#Region " Load() and Clear() Methods "
Public Sub Load(ByVal oXmlDocument As XmlDocument)
' This method does not validate the Xml document.
AssertNotProcessing()
If oXmlDocument Is Nothing Then Throw New ArgumentNullException("XmlDocument")
Me.Load(New XmlObjectReader(oXmlDocument))
End Sub
Public Sub Load(ByVal sXmlFileSpec As String)
' This method uses the schema to validate the Xml file passed in.
AssertNotProcessing()
If String.IsNullOrEmpty(sXmlFileSpec) Then Throw New ArgumentNullException("XmlFileSpec")
If Not My.Computer.FileSystem.FileExists(sXmlFileSpec) Then Throw New ArgumentException("File pointed to by XmlFileSpec does not exist.")
Me.Load(New XmlObjectReader(sXmlFileSpec, Nothing, ReflectionHelper.GetResourceStream("QueryTree.xsd")))
End Sub
Private Sub Load(ByVal oReader As XmlObjectReader)
Me.Clear()
oReader.GetValues(Me)
End Sub
Public Sub Clear()
AssertNotProcessing()
Me.Assembly = Nothing
Me.Namespace = Nothing
Me.Culture = Nothing
Me.Node = Nothing
End Sub
#End Region
#Region " Process(), Initialize() and Terminate() Methods "
Public Sub Process(ByVal oFactory As DbProviderFactory, ByVal sConnectionString As String, ByVal oArguments As Arguments)
AssertNotProcessing()
If oFactory Is Nothing Then Throw New ArgumentNullException("Factory")
If String.IsNullOrEmpty(sConnectionString) Then Throw New ArgumentNullException("ConnectionString")
Try
Me.IsProcessing = True
Me.Initialize(oFactory, sConnectionString, oArguments)
Me.Node.Process()
Finally
Me.Terminate()
Me.IsProcessing = False
End Try
End Sub
Private Sub Initialize(ByVal oFactory As DbProviderFactory, ByVal sConnectionString As String, ByVal oArguments As Arguments)
If String.IsNullOrEmpty(Me.Assembly) Then Throw New NullReferenceException("Assembly property has not been set.")
If Me.Node Is Nothing Then Throw New NullReferenceException("Node property has not been set.")
Me.Factory = oFactory
Me.ConnectionString = sConnectionString
Me.Arguments = oArguments
Me.Comparer = GlobalizationHelper.CreateCaseInsensitiveComparer(IIf(String.IsNullOrEmpty(Me.Culture), "en-US", Me.Culture))
Me.InitConnection()
Me.Node.Initialize(Me, Nothing)
End Sub
Private Sub InitConnection()
Try
Me.Connection = Me.Factory.CreateConnection()
Me.Connection.ConnectionString = Me.ConnectionString
Me.Connection.Open()
Catch oException As Exception
Throw New NoConnectionException(Me.ConnectionString, oException)
End Try
End Sub
Private Sub Terminate()
Me.Node.Terminate()
Me.TermConnection()
Me.Comparer = Nothing
Me.Arguments = Nothing
Me.ConnectionString = Nothing
Me.Factory = Nothing
End Sub
Private Sub TermConnection()
If Me.Connection IsNot Nothing Then
Me.Connection.Close()
Me.Connection.Dispose()
Me.Connection = Nothing
End If
End Sub
#End Region
#Region " Private Utility Methods "
Private Sub AssertNotProcessing()
If Me.IsProcessing Then
Throw New InvalidOperationException("Cannot perform this operation while processing data.")
End If
End Sub
#End Region
End Class
End Namespace





