Click here to Skip to main content
15,886,806 members
Articles / Programming Languages / XML

Validating data with Flat File Checker

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
30 Oct 2009GPL32 min read 43.7K   881   17  
An article on data validation with a flat file schema generated in Flat File Checker.
Imports System.Data.OleDb
Imports System.Threading
Imports System.Xml.XPath
Imports System.Xml
Public Enum CardinalityType
    NotExists = 0
    Exists = 1
    Condition = 2
End Enum

Public MustInherit Class QueryChecker
    Inherits GeneralChecker

    Private _connection As Connection
    Private _cmd As OleDbCommand
    Private _cardinality_type As CardinalityType
    Private _table As String
    Private _fields As List(Of FieldCondition)
    Private _query_template As CustomQueryTemplate
    Private _template As Template
    Protected Sub New(ByVal tableName As String)
        _fields = New List(Of FieldCondition)
        _table = tableName
        _fields = New List(Of FieldCondition)
    End Sub

    Friend Property TableName() As String
        Get
            Return _table
        End Get
        Set(ByVal value As String)
            _table = value
        End Set
    End Property
    Public Sub New(ByVal connectionName As String, ByVal templateName As String, ByVal queryName As String, ByVal parent As GeneralChecker, ByVal column As TableColumn)
        MyBase.New(column, Parent)
        _fields = New List(Of FieldCondition)
        _connection = column.Table.Datasources.Connections.Connection(connectionName)
        _template = column.Table.Datasources.Templates.Template(templateName)
        _query_template = New CustomQueryTemplate(queryName, Me)

    End Sub
 
    Public Sub AddField(ByVal queryName As String, ByVal attribute As String, ByVal value As String, ByVal cond As EnumOperator)
        _query_template.AddField(queryName, attribute, value, cond)
    End Sub

    Public ReadOnly Property Template() As Template
        Get
            Return Me._template
        End Get
    End Property
    Public Sub New(ByVal definition As IXPathNavigable, ByVal parent As GeneralChecker, ByVal column As DataColumn)
        MyBase.New(column, parent)
        _fields = New List(Of FieldCondition)
        Dim navigator As XPathNavigator = definition.CreateNavigator
        Dim connection_name As String = navigator.GetAttribute("Connection", "")
        _connection = Me.Column.Datasource.Datasources.Connections.Connection(connection_name)
        Dim template_name As String = navigator.GetAttribute("Template", "")
        If String.IsNullOrEmpty(template_name) Then
            Dim fromNavigator As XPathNavigator = navigator.CreateNavigator
            fromNavigator.MoveToChild("From", "")
            Me.TableName = fromNavigator.InnerXml
            ' Go through all fields declarations and add fields to the rule
            Dim fieldsIterator As XPathNodeIterator = navigator.Select("WhereFields/*")
            Dim fieldNavigator As XPathNavigator
            For Each fieldNavigator In fieldsIterator
                Me.AddField(fieldNavigator)
            Next
        Else ' there is a template
            Me._template = parent.Column.Datasource.Datasources.Templates(template_name)
            navigator.MoveToFirstChild()
            Me._query_template = New CustomQueryTemplate(navigator, Me)
        End If
        ' Process Field declarations here:

    End Sub
    Public Sub AddField(ByVal field As FieldCondition)

        _fields.Add(field)
    End Sub
    Friend Sub AddField(ByVal xNavigator As XPathNavigator)
        Dim navigator As XPathNavigator = xNavigator.CreateNavigator
        Select Case navigator.LocalName
            Case "ValueField"
                Me.AddField(New ValueFieldCondition(navigator, Me))
            Case "MapField"
                Me.AddField(New MappedFieldCondition(navigator, Me, Me.Column))
            Case Else ' skip this for now.
                '  Throw New NotImplementedException()
        End Select
    End Sub

    Public Overrides Function RunChecks(ByVal wait As AutoResetEvent) As Boolean
        MyBase.RunChecks(wait)

        Return Me.Evaluate()
        ' Need to close db connection(s) when application is terminated.

    End Function
    ''' <summary>
    ''' Initiates OleDb command
    ''' </summary>
    ''' <returns>Returns true if command was successfully created.</returns>
    ''' <remarks></remarks>
    Private Function InitiateCommand() As Boolean
        _cmd = New OleDbCommand
        Dim sql As String

        sql = Me.SelectClause & " FROM " & _table

        Dim is_first As Boolean = True
        Dim field As FieldCondition
        For Each field In _fields
            With field
                If is_first Then
                    sql &= " WHERE "
                    is_first = False
                Else
                    sql &= " AND "
                End If
                sql &= .ConditionText
                .AddParameters(_cmd)
            End With
        Next
        If Me.Cardinality <> CardinalityType.Condition Then
            sql &= ")"
        End If
        _cmd.CommandText = sql
        _cmd.CommandType = CommandType.Text
        _cmd.Connection = Me.Connection.Connection
    End Function

    Public Overrides Function Evaluate(ByVal row As Integer) As Boolean

        Dim now_function As String = "SYSDATE"
        Dim parameter As OleDbParameter
        Dim i As Integer = 0
        Me.CurrentValue = Me.Column(row)
        For Each parameter In _cmd.Parameters
            If _fields(i).Type = FieldConditionType.Mapping Then
                If String.IsNullOrEmpty(CurrentValue) Then
                    If Me.Column.AllowBlankValues Then
                        ' Return True
                        ' Else
                        Return False
                        ' Throw New FileFormatException("Value should be provided for column " & Me.Column.FullName & " as it is linked to the external data source.", Me.Column.File, row)
                    End If
                End If
                parameter.Value = Me.CurrentValue
            End If
            i += 1
        Next

        Return Me.CommandResult

    End Function
    Public MustOverride Property Cardinality() As CardinalityType
       
    Protected MustOverride ReadOnly Property CommandResult() As Boolean

    Public Overrides Function Clone() As Object
        Dim QueryClone As QueryChecker = CType(Me.MemberwiseClone, QueryChecker)
        Return QueryClone
    End Function

    Public Overrides Function Initiate() As Boolean
        InitiateCommand() ' Create OleDb Command
        Me.Connection.Open() ' Open connection once before processing records
        If Not Where Is Nothing AndAlso Not Where.Initiate() Then
            Return False
        End If
        Return True
    End Function
    Protected ReadOnly Property Command() As OleDbCommand
        Get
            Return Me._cmd
        End Get
    End Property
    Public ReadOnly Property Connection() As Connection
        Get
            Return _connection
        End Get
    End Property
    Public Shared Function CreateQueryCheck(ByVal xmlDefinition As XPathNavigator, ByVal parent As IDataRule, ByVal column As DataColumn) As GeneralChecker
        Dim navigator As XPathNavigator = xmlDefinition.CreateNavigator
        ' Base Query Validation
        Dim exists As String = navigator.GetAttribute("Exists", "")
        If String.IsNullOrEmpty(exists) Then
            Return New CardinalityQueryChecker(xmlDefinition, parent, column)
        Else
            Return New ExistsQueryChecker(xmlDefinition, parent, column)
        End If
    End Function
    Public Overrides ReadOnly Property Type() As FlatFileLibrary.DataRuleType
        Get
            Return DataRuleType.Query
        End Get
    End Property

    Public Overrides ReadOnly Property DataRuleMessage() As String
        Get
            If _query_template Is Nothing Then
                Return "Query rule."
            Else
                Return _query_template.DataRuleMessage
            End If
        End Get
    End Property

    ''' <summary>
    ''' Gets or sets the template of the query
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property QueryTemplate() As CustomQueryTemplate
        Get
            Return _query_template
        End Get
        Set(ByVal value As CustomQueryTemplate)
            _query_template = value
        End Set
    End Property
    Friend Overrides Function GetNode() As System.Xml.XmlNode
        Dim chkXml As XmlElement
        chkXml = Document.CreateElement("Query", "")
        Dim attrConnection As XmlAttribute = Document.CreateAttribute("Connection")
        attrConnection.Value = _connection.Name
        chkXml.Attributes.Append(attrConnection)
        AppendAttributes(chkXml)

        If _query_template Is Nothing Then
            Dim xmlFrom As XmlNode = Me.Document.CreateElement("From")

            xmlFrom.InnerText = Me.TableName

            chkXml.AppendChild(xmlFrom)
            Dim xmlWhereFields As XmlNode = Me.Document.CreateElement("WhereFields")
            chkXml.AppendChild(xmlWhereFields)
            Dim field As FieldCondition
            For Each field In Me._fields
                xmlWhereFields.AppendChild(field.GetNode())
            Next
            Me.AppendActionXml(chkXml)
            Me.AppendWhereXml(chkXml)
        Else ' Tempalte based query
            Dim attrTemplate As XmlAttribute = Me.Document.CreateAttribute("Template")
            attrTemplate.Value = _query_template.Template.Name
            chkXml.Attributes.Append(attrTemplate)
            chkXml.AppendChild(_query_template.GetNode)
        End If

        Me.AppendWhereXml(chkXml)
        Me.AppendActionXml(chkXml)

        Return chkXml
    End Function
    Public MustOverride ReadOnly Property SelectClause() As String

    Protected MustOverride Sub AppendAttributes(ByVal node As XmlNode)

    Public Overrides ReadOnly Property RuleName() As String
        Get
            Return "Query"
        End Get
    End Property

    Protected Overrides Sub Finalize()
        MyBase.Finalize()
    End Sub
End Class

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 GNU General Public License (GPLv3)


Written By
Database Developer
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions