344 lines
No EOL
15 KiB
VB.net
344 lines
No EOL
15 KiB
VB.net
|
|
Imports System
|
|
Imports System.Data
|
|
Imports System.IO
|
|
Imports System.Configuration
|
|
Imports System.Web
|
|
Imports System.Web.Security
|
|
Imports System.Web.UI
|
|
Imports System.Web.UI.WebControls
|
|
Imports System.Web.UI.WebControls.WebParts
|
|
Imports System.Web.UI.HtmlControls
|
|
Imports System.Collections
|
|
Imports BaseClasses
|
|
Imports BaseClasses.Utils
|
|
Imports BaseClasses.Data
|
|
Imports BaseClasses.Data.SqlProvider
|
|
Imports BaseClasses.Web.UI.WebControls
|
|
|
|
Namespace Persons.UI
|
|
''' <summary>
|
|
''' Summary description for ImportDataItems
|
|
''' </summary>
|
|
Public Class ImportDataItems
|
|
Dim NumberOfRecordImported As Long = 0
|
|
Dim RowCount As Long = 1
|
|
Dim ColumnCount As Integer = 1
|
|
Private Const SEPARATOR As String = ", "
|
|
|
|
#Region "Properties"
|
|
|
|
''' <summary>
|
|
''' The path of the file from which data is to be retrieved for import.
|
|
''' </summary>
|
|
Private _fPath As String
|
|
|
|
Public Property FilePath() As String
|
|
Get
|
|
Return _fPath
|
|
End Get
|
|
Set(ByVal value As String)
|
|
_fPath = value
|
|
End Set
|
|
End Property
|
|
|
|
' <summary>
|
|
' Type of the file to be imported
|
|
' </summary>
|
|
Private _fType As Parser.FileTypes
|
|
|
|
Public Property FileType() As Parser.FileTypes
|
|
Get
|
|
Return _fType
|
|
End Get
|
|
Set(ByVal value As Parser.FileTypes)
|
|
_fType = value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' The database table to which the records from CSV file has to be imported.
|
|
''' </summary>
|
|
Private _tbl As BaseTable
|
|
|
|
Private Property DBTable() As BaseTable
|
|
Get
|
|
Return Me._tbl
|
|
End Get
|
|
Set(ByVal value As BaseTable)
|
|
Me._tbl = value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Stores the list of column names for which the data from CSV file is to be imported to database table..
|
|
''' </summary>
|
|
Private _columnNameList As ArrayList
|
|
|
|
Private Property ColumnNameList() As ArrayList
|
|
Get
|
|
Return Me._columnNameList
|
|
End Get
|
|
Set(ByVal value As ArrayList)
|
|
Me._columnNameList = value
|
|
End Set
|
|
End Property
|
|
|
|
''' <summary>
|
|
''' Stores the list of checkboxes which indicate whether corresponding column should be imported or not.
|
|
''' </summary>
|
|
Private _cbxList As ArrayList
|
|
|
|
Private Property ImportList() As ArrayList
|
|
Get
|
|
Return Me._cbxList
|
|
End Get
|
|
Set(ByVal value As ArrayList)
|
|
Me._cbxList = value
|
|
End Set
|
|
End Property
|
|
#End Region
|
|
|
|
#Region "Constructor"
|
|
Public Sub New(ByVal path As String, ByVal type As Parser.FileTypes, ByVal bTable As BaseTable, ByVal ddListSelected As ArrayList, ByVal chkBoxList As ArrayList)
|
|
MyBase.New()
|
|
'
|
|
' Add constructor logic here
|
|
'
|
|
Me.DBTable = bTable
|
|
Me.ColumnNameList = ddListSelected
|
|
Me.ImportList = chkBoxList
|
|
Me.FilePath = path
|
|
Me.FileType = type
|
|
End Sub
|
|
|
|
#End Region
|
|
|
|
|
|
|
|
#Region "Methods"
|
|
|
|
Private Sub AddSkippedRecordToList(ByRef recordsList As Generic.List(Of BaseClasses.Utils.SkippedLine), _
|
|
ByVal RowCount As Long, ByVal rowValues() As String, ByVal exMsg As String)
|
|
If Not exMsg Is Nothing AndAlso Not exMsg.Trim = "" Then
|
|
exMsg = exMsg.Replace("'", "\'")
|
|
End If
|
|
Dim skippedRecord As BaseClasses.Utils.SkippedLine = New BaseClasses.Utils.SkippedLine("", exMsg, RowCount)
|
|
For Each rv As String In rowValues
|
|
If Not rv Is Nothing AndAlso rv.Trim <> "" Then skippedRecord.LineContent &= rv & SEPARATOR
|
|
Next
|
|
If skippedRecord.LineContent.EndsWith(", ") Then
|
|
skippedRecord.LineContent = skippedRecord.LineContent.Substring(0, skippedRecord.LineContent.Length - 2)
|
|
End If
|
|
|
|
recordsList.Add(skippedRecord)
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Reads rows of values for CSV file and import it to Database.
|
|
''' </summary>
|
|
Public Function ImportRecords(ByVal isImportFirstRowChecked As Boolean, ByVal isResolvedForeignKeysChecked As Boolean) As BaseClasses.Utils.ImportedResults
|
|
Dim success As Boolean = False
|
|
Dim parsr As Parser = Nothing
|
|
Dim results As BaseClasses.Utils.ImportedResults = New BaseClasses.Utils.ImportedResults
|
|
Try
|
|
If ((Me.FilePath Is Nothing) _
|
|
OrElse ((Me.DBTable Is Nothing) _
|
|
OrElse ((Me.ColumnNameList Is Nothing) _
|
|
OrElse (Me.ImportList Is Nothing)))) Then
|
|
Return results
|
|
End If
|
|
DbUtils.StartTransaction()
|
|
parsr = Parser.GetParser(Me.FilePath, Me.FileType)
|
|
Dim rowValues() As String = parsr.GetNextRow
|
|
' get the first row
|
|
If (Not isImportFirstRowChecked _
|
|
AndAlso (Not (rowValues) Is Nothing)) Then
|
|
Try
|
|
DoImport(rowValues, isResolvedForeignKeysChecked)
|
|
RowCount += 1
|
|
|
|
Catch ex As Exception
|
|
results.NumberOfSkipped += 1
|
|
Me.AddSkippedRecordToList(results.ListOfSkipped, RowCount + results.NumberOfSkipped, rowValues, ex.Message)
|
|
End Try
|
|
|
|
|
|
End If
|
|
|
|
While (Not (rowValues) Is Nothing)
|
|
rowValues = parsr.GetNextRow
|
|
If (Not (rowValues) Is Nothing) Then
|
|
Try
|
|
DoImport(rowValues, isResolvedForeignKeysChecked)
|
|
RowCount += 1
|
|
|
|
Catch ex As Exception
|
|
results.NumberOfSkipped += 1
|
|
Me.AddSkippedRecordToList(results.ListOfSkipped, RowCount + results.NumberOfSkipped, rowValues, ex.Message)
|
|
End Try
|
|
|
|
End If
|
|
|
|
End While
|
|
DbUtils.CommitTransaction()
|
|
parsr.Close()
|
|
|
|
success = True
|
|
' turn on success only when all the rows are imported ie, saved into database.
|
|
Catch e As Exception
|
|
DbUtils.RollBackTransaction()
|
|
results.NumberOfImported = 0
|
|
parsr.Close()
|
|
Dim errorMsg As String = e.Message
|
|
If File.Exists(Me.FilePath) Then
|
|
File.Delete(Me.FilePath)
|
|
End If
|
|
errorMsg = String.Format("- " & errorMsg & Environment.NewLine & "- Import error occurred at Row = {0},Column = {1}", RowCount, ColumnCount)
|
|
Throw New Exception(errorMsg)
|
|
Finally
|
|
DbUtils.EndTransaction()
|
|
If (File.Exists(Me.FilePath)) Then
|
|
File.Delete(Me.FilePath)
|
|
End If
|
|
End Try
|
|
results.NumberOfImported = NumberOfRecordImported
|
|
Return results
|
|
End Function
|
|
|
|
''' <summary>
|
|
''' Creates a database record and calls UpdateColumnValuesInRecord to set the record values.
|
|
''' </summary>
|
|
Private Sub DoImport(ByVal rowValues() As String, ByVal isResolvedForeignKeysChecked As Boolean)
|
|
Dim r As IRecord
|
|
r = Me.DBTable.CreateRecord
|
|
If (UpdateColumnValuesInRecord(rowValues, r, isResolvedForeignKeysChecked)) Then
|
|
r.Save()
|
|
NumberOfRecordImported = NumberOfRecordImported + 1
|
|
End If
|
|
End Sub
|
|
|
|
''' <summary>
|
|
''' Sets a database record values with values retrieved from CSV file.
|
|
''' </summary>
|
|
''' <param name="rowValues"></param>
|
|
''' <param name="record"></param>
|
|
Private Function UpdateColumnValuesInRecord(ByVal rowValues() As String, ByVal record As IRecord, ByVal isResolvedForeignKeysChecked As Boolean) As Boolean
|
|
Dim j As Integer = 0
|
|
Dim isRecordUpdated As Boolean = False
|
|
ColumnCount = 1
|
|
For Each data As String In rowValues
|
|
ColumnCount = ColumnCount + 1
|
|
If j > Me.ImportList.Count - 1 Then
|
|
Return isRecordUpdated
|
|
End If
|
|
Try
|
|
|
|
|
|
If ((Me.ColumnNameList(j).ToString <> "") _
|
|
AndAlso CType(Me.ImportList(j), CheckBox).Checked) Then
|
|
Dim fkColumn As ForeignKey = Nothing
|
|
Dim currentColumn As BaseColumn = Me.DBTable.TableDefinition.ColumnList.GetByAnyName(CType(Me.ColumnNameList(j), String))
|
|
If isResolvedForeignKeysChecked Then
|
|
fkColumn = Me.DBTable.TableDefinition.GetForeignKeyByColumnName(currentColumn.InternalName)
|
|
End If
|
|
Dim colValue As String = ""
|
|
' Check if the foreign key has DFKA. If so, then check the calue from csv file agains the DFKA column in the parent/foreign key table.
|
|
' If a match is found retrieve its ID and set that as value to be insterted in the current table where you are adding records.
|
|
If (Not (fkColumn) Is Nothing) Then
|
|
Dim originalTableDef As TableDefinition = fkColumn.PrimaryKeyTableDefinition
|
|
Dim originalBaseTable As BaseTable = originalTableDef.CreateBaseTable
|
|
Dim wc As WhereClause = Nothing
|
|
Dim records As ArrayList = New ArrayList
|
|
Dim pkColumn As BaseColumn = CType(originalTableDef.PrimaryKey.Columns(0), BaseColumn)
|
|
'Index is zero because we handle only those tables which has single PK column not composite keys.
|
|
If ((Not (fkColumn.PrimaryKeyDisplayColumns) Is Nothing) _
|
|
AndAlso (fkColumn.PrimaryKeyDisplayColumns <> "") AndAlso (Not fkColumn.PrimaryKeyDisplayColumns.Trim().StartsWith("="))) Then
|
|
wc = New WhereClause(originalTableDef.ColumnList.GetByAnyName(fkColumn.PrimaryKeyDisplayColumns), BaseFilter.ComparisonOperator.EqualsTo, data)
|
|
ElseIf ((Not (fkColumn.PrimaryKeyDisplayColumns) Is Nothing) _
|
|
AndAlso (fkColumn.PrimaryKeyDisplayColumns <> "") AndAlso (fkColumn.PrimaryKeyDisplayColumns.Trim().StartsWith("="))) Then
|
|
Dim primaryKeyDisplay As String = GetDFKA(fkColumn)
|
|
If Not IsNothing(primaryKeyDisplay) Then
|
|
wc = New WhereClause(originalTableDef.ColumnList.GetByAnyName(primaryKeyDisplay), BaseFilter.ComparisonOperator.EqualsTo, data)
|
|
Else
|
|
wc = New WhereClause(pkColumn, BaseFilter.ComparisonOperator.EqualsTo, data)
|
|
End If
|
|
Else
|
|
' if the foreign key does not have DFKA then just check in the foreign key table if the id exists. If not create a record with the specified ID
|
|
' before adding to current table
|
|
wc = New WhereClause(pkColumn, BaseFilter.ComparisonOperator.EqualsTo, data)
|
|
End If
|
|
Dim join As BaseClasses.Data.BaseFilter = Nothing
|
|
records = originalBaseTable.GetRecordList(join, wc.GetFilter, Nothing, Nothing, 0, 100)
|
|
If (records.Count > 0) Then
|
|
' take the first record and retrieve its ID.
|
|
Dim rec As BaseRecord = CType(records(0), BaseRecord)
|
|
colValue = rec.GetValue(pkColumn).ToString
|
|
Else
|
|
' IF there is not match found then you have to create a record in the foreign key table with DFKA value and then retreive its ID
|
|
If ((Not (data) Is Nothing) _
|
|
And (data <> "")) Then
|
|
Dim tempRec As IRecord
|
|
If ((Not (fkColumn.PrimaryKeyDisplayColumns) Is Nothing) _
|
|
AndAlso (fkColumn.PrimaryKeyDisplayColumns <> "") AndAlso (Not fkColumn.PrimaryKeyDisplayColumns.Trim().StartsWith("="))) Then
|
|
tempRec = originalBaseTable.CreateRecord
|
|
Dim tableDef As TableDefinition = originalBaseTable.TableDefinition
|
|
For Each newCol As BaseColumn In tableDef.Columns
|
|
If fkColumn.PrimaryKeyDisplayColumns = newCol.InternalName Then
|
|
tempRec.SetValue(data, newCol.UniqueName)
|
|
End If
|
|
Next
|
|
Else
|
|
tempRec = originalBaseTable.CreateRecord(data)
|
|
End If
|
|
tempRec.Save()
|
|
colValue = tempRec.GetValue(pkColumn).ToString
|
|
End If
|
|
'colValue = data
|
|
End If
|
|
Else
|
|
colValue = data
|
|
End If
|
|
' set the table row's column for value
|
|
record.SetValue(colValue, currentColumn.UniqueName)
|
|
isRecordUpdated = True
|
|
End If
|
|
j = (j + 1)
|
|
Catch ex As Exception
|
|
Throw New Exception(ex.InnerException.Message)
|
|
End Try
|
|
|
|
Next
|
|
Return isRecordUpdated
|
|
End Function
|
|
|
|
Public Shared Function GetDFKA(ByVal fkColumn As ForeignKey) As String 'ByVal rec As BaseRecord,
|
|
Dim isDFKA As Boolean = False
|
|
If fkColumn Is Nothing Then
|
|
Return Nothing
|
|
End If
|
|
Dim _DFKA As String = fkColumn.PrimaryKeyDisplayColumns
|
|
|
|
' if the formula is in the format of "= <Primary table>.<Field name>, then pull out the data from the rec object instead of doing formula evaluation
|
|
Dim tableCodeName As String = fkColumn.PrimaryKeyTableDefinition.TableCodeName
|
|
Dim column As String = _DFKA.Trim("="c).Trim()
|
|
If column.StartsWith(tableCodeName & ".", StringComparison.InvariantCultureIgnoreCase) Then
|
|
column = column.Substring(tableCodeName.Length + 1)
|
|
End If
|
|
|
|
For Each c As BaseColumn In fkColumn.PrimaryKeyTableDefinition.Columns
|
|
If column = c.CodeName Then
|
|
isDFKA = True
|
|
Exit For
|
|
End If
|
|
Next
|
|
|
|
If isDFKA Then
|
|
Return column
|
|
Else
|
|
Return Nothing
|
|
End If
|
|
End Function
|
|
#End Region
|
|
End Class
|
|
End Namespace |