EDMI: UpdateFile WIP

This commit is contained in:
Jonathan Jenne 2022-01-25 16:29:20 +01:00
parent 0fa654bda0
commit 884c9d4546
18 changed files with 460 additions and 338 deletions

View File

@ -119,26 +119,36 @@ Namespace DocumentResultList
Private Sub FileOpenTimer_Elapsed() Handles FileOpenTimer.Elapsed Private Sub FileOpenTimer_Elapsed() Handles FileOpenTimer.Elapsed
Try Try
For Each oOpenFile In OpenFiles For Each oOpenFile In OpenFiles
' All files that are currently processe/updated on the outside,
' will not be checked again.
If oOpenFile.CurrentlyProcessing = False Then If oOpenFile.CurrentlyProcessing = False Then
Continue For Continue For
End If End If
' Check if the file is currently in use, and skip if it is.
Dim oIsLocked = FileEx.TestFileIsLocked(oOpenFile.FilePath) Dim oIsLocked = FileEx.TestFileIsLocked(oOpenFile.FilePath)
If oIsLocked Then If oIsLocked Then
Continue For Continue For
End If End If
' If this point is reached, we assume the file was closed again after opening it.
' ------
' Compute the current hash of the file and compare it with the one
' in the database.
Dim oOldHash = oOpenFile.Document.FileHash Dim oOldHash = oOpenFile.Document.FileHash
Dim oNewHash = FileEx.GetChecksum(oOpenFile.FilePath) Dim oNewHash = FileEx.GetChecksum(oOpenFile.FilePath)
If oNewHash.Equals(oOldHash) = False Then ' If the the file did not change, remove it from the watch list
' File changed If oNewHash.Equals(oOldHash) Then
RaiseEvent FileChanged(Me, New FileChangedArgs() With {.File = oOpenFile})
oOpenFile.CurrentlyProcessing = True
Else
OpenFiles.Remove(oOpenFile) OpenFiles.Remove(oOpenFile)
Continue For
End If End If
' The File changed, so mark the file as being processed/updated
' and notify any listeners of the FileChanged event
oOpenFile.CurrentlyProcessing = True
RaiseEvent FileChanged(Me, New FileChangedArgs() With {.File = oOpenFile})
Next Next
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)

View File

@ -236,7 +236,13 @@ Public Class frmDocumentResultList
End Sub End Sub
Public Sub Watcher_FileChanged(sender As Object, e As DocumentResultList.Watcher.FileChangedArgs) Handles Watcher.FileChanged Public Sub Watcher_FileChanged(sender As Object, e As DocumentResultList.Watcher.FileChangedArgs) Handles Watcher.FileChanged
Try
Catch ex As Exception
Finally
e.File.CurrentlyProcessing = False
End Try
End Sub End Sub

View File

@ -9,7 +9,7 @@ Imports DigitalData.Modules.Logging
Public Class Client Public Class Client
' Constants ' Constants
Private Const UPDATE_INTERVAL_IN_MINUTES As Integer = 1 Private Const UPDATE_INTERVAL_IN_MINUTES As Integer = 1
Public Const INVALID_OBEJCT_ID As Long = 0
Private Const KIND_TYPE_DOC = "DOC" Private Const KIND_TYPE_DOC = "DOC"
' Helper Classes ' Helper Classes
@ -188,58 +188,11 @@ Public Class Client
''' <returns>The ObjectId of the newly generated filesystem object</returns> ''' <returns>The ObjectId of the newly generated filesystem object</returns>
Public Async Function NewFileAsync(pFilePath As String, pObjectStoreName As String, pObjectKind As String, pBusinessEntity As String, Optional pImportOptions As Options.NewFileOptions = Nothing) As Task(Of Long) Public Async Function NewFileAsync(pFilePath As String, pObjectStoreName As String, pObjectKind As String, pBusinessEntity As String, Optional pImportOptions As Options.NewFileOptions = Nothing) As Task(Of Long)
Try Try
' Set default options Dim oNewFile As New Modules.IDB.NewFile(LogConfig, Channel)
If pImportOptions Is Nothing Then Return Await oNewFile.RunAsync(pFilePath, pObjectStoreName, pObjectKind, pBusinessEntity, pImportOptions)
pImportOptions = New Options.NewFileOptions()
End If
' Check if file exists
If File.Exists(pFilePath) = False Then
Throw New FileNotFoundException("Path does not exist")
End If
Dim oFileInfo As New FileInfo(pFilePath)
Dim oExtension As String = oFileInfo.Extension
Dim oFileName As String = oFileInfo.Name
Dim oFileCreatedAt As Date = oFileInfo?.CreationTime
Dim oFileModifiedAt As Date = oFileInfo?.LastWriteTime
Dim oFileHash As String = FileEx.GetChecksum(oFileInfo.FullName)
' Importing the file now
Using oFileStream As New FileStream(pFilePath, FileMode.Open, FileAccess.Read)
Using oMemoryStream As New MemoryStream()
oFileStream.CopyTo(oMemoryStream)
Dim oContents = oMemoryStream.ToArray()
Dim oFileImportResponse = Await Channel.NewFileAsync(New NewFileRequest With {
.BusinessEntity = pBusinessEntity,
.File = New FileProperties With {
.FileName = oFileInfo.Name,
.FileCreatedAt = oFileCreatedAt,
.FileChangedAt = oFileModifiedAt,
.FileContents = oContents,
.FileImportedAt = pImportOptions.DateImported,
.FileChecksum = oFileHash
},
.KindType = pObjectKind,
.StoreName = pObjectStoreName,
.User = New UserState With {
.Language = pImportOptions.Language,
.UserName = pImportOptions.Username
}
})
If oFileImportResponse.OK = False Then
Throw New ApplicationException("Could not Import File Contents!")
End If
Return oFileImportResponse.ObjectId
End Using
End Using
Catch ex As Exception Catch ex As Exception
Logger.Error(ex) Logger.Error(ex)
Return INVALID_OBEJCT_ID Return Nothing
End Try End Try
End Function End Function

View File

@ -25,6 +25,15 @@
Public Property DateImported As Date = Date.Now Public Property DateImported As Date = Date.Now
End Class End Class
Public Class UpdateFileOptions
Inherits BaseOptions
''' <summary>
''' Should the changes in the file result in a new version? Otherwise the old file will be overridden.
''' </summary>
Public Property CreateNewFileVersion As Boolean = False
End Class
Public Class ImportFileOptions Public Class ImportFileOptions
Inherits BaseOptions Inherits BaseOptions

View File

@ -1,5 +1,6 @@
Public Class Constants Public Class Constants
Public Const DEFAULT_SERVICE_PORT = 9000 Public Const DEFAULT_SERVICE_PORT = 9000
Public Const INVALID_OBEJCT_ID As Long = 0
Public Enum DatabaseType Public Enum DatabaseType
ECM ECM

View File

@ -78,6 +78,9 @@
<Compile Include="Client\Channel.vb" /> <Compile Include="Client\Channel.vb" />
<Compile Include="Modules\BaseMethod.vb" /> <Compile Include="Modules\BaseMethod.vb" />
<Compile Include="Modules\Globix\ImportFile.vb" /> <Compile Include="Modules\Globix\ImportFile.vb" />
<Compile Include="Helpers.vb" />
<Compile Include="Modules\IDB\NewFile.vb" />
<Compile Include="Modules\IDB\UpdateFile.vb" />
<Compile Include="Modules\ZooFlow\GetFileObject.vb" /> <Compile Include="Modules\ZooFlow\GetFileObject.vb" />
<Compile Include="Connected Services\EDMIServiceReference\Reference.vb"> <Compile Include="Connected Services\EDMIServiceReference\Reference.vb">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>

View File

@ -0,0 +1,41 @@
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports DigitalData.Modules.Logging
Public Class Helpers
Private ReadOnly LogConfig As LogConfig
Private ReadOnly Logger As Logger
Private ReadOnly FileEx As Filesystem.File
Public Sub New(pLogConfig As LogConfig)
LogConfig = pLogConfig
Logger = pLogConfig.GetLogger()
FileEx = New Filesystem.File(pLogConfig)
End Sub
Public Function GetFileProperties(pFilePath As String, pDateImportedAt As Date) As FileProperties
Using oFileStream As New IO.FileStream(pFilePath, IO.FileMode.Open, IO.FileAccess.Read)
Using oMemoryStream As New IO.MemoryStream()
oFileStream.CopyTo(oMemoryStream)
Dim oContents = oMemoryStream.ToArray()
Dim oFileInfo As New IO.FileInfo(pFilePath)
Dim oExtension As String = oFileInfo.Extension
Dim oFileName As String = oFileInfo.Name
Dim oFileCreatedAt As Date = oFileInfo?.CreationTime
Dim oFileModifiedAt As Date = oFileInfo?.LastWriteTime
Dim oFileHash As String = FileEx.GetChecksum(oFileInfo.FullName)
Return New FileProperties With {
.FileName = oFileInfo.Name,
.FileCreatedAt = oFileCreatedAt,
.FileChangedAt = oFileModifiedAt,
.FileContents = oContents,
.FileImportedAt = pDateImportedAt,
.FileChecksum = oFileHash
}
End Using
End Using
End Function
End Class

View File

@ -6,11 +6,15 @@ Namespace Modules
Friend ReadOnly LogConfig As LogConfig Friend ReadOnly LogConfig As LogConfig
Friend ReadOnly Logger As Logger Friend ReadOnly Logger As Logger
Friend ReadOnly Channel As IEDMIServiceChannel Friend ReadOnly Channel As IEDMIServiceChannel
Friend ReadOnly FileEx As Filesystem.File
Friend ReadOnly Helpers As Helpers
Public Sub New(pLogConfig As LogConfig, pChannel As IEDMIServiceChannel) Public Sub New(pLogConfig As LogConfig, pChannel As IEDMIServiceChannel)
LogConfig = pLogConfig LogConfig = pLogConfig
Logger = pLogConfig.GetLogger() Logger = pLogConfig.GetLogger()
Channel = pChannel Channel = pChannel
FileEx = New Filesystem.File(pLogConfig)
Helpers = New Helpers(pLogConfig)
End Sub End Sub
End Class End Class

View File

@ -0,0 +1,49 @@
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports DigitalData.Modules.Logging
Imports DigitalData.Modules.Filesystem
Namespace Modules.IDB
Public Class NewFile
Inherits BaseMethod
Public Sub New(pLogConfig As LogConfig, pChannel As IEDMIServiceChannel)
MyBase.New(pLogConfig, pChannel)
End Sub
Public Async Function RunAsync(pFilePath As String, pObjectStoreName As String, pObjectKind As String, pBusinessEntity As String, Optional pOptions As Options.NewFileOptions = Nothing) As Task(Of Long)
Try
' Set default options
If pOptions Is Nothing Then
pOptions = New Options.NewFileOptions()
End If
' Check if file exists
If IO.File.Exists(pFilePath) = False Then
Throw New IO.FileNotFoundException("Path does not exist")
End If
' Importing the file now
Dim oFileProperties = Helpers.GetFileProperties(pFilePath, pOptions.DateImported)
Dim oFileImportResponse = Await Channel.NewFileAsync(New NewFileRequest With {
.BusinessEntity = pBusinessEntity,
.File = oFileProperties,
.KindType = pObjectKind,
.StoreName = pObjectStoreName,
.User = New UserState With {
.Language = pOptions.Language,
.UserName = pOptions.Username
}
})
If oFileImportResponse.OK = False Then
Throw New ApplicationException("Could not Import File Contents!")
End If
Return oFileImportResponse.ObjectId
Catch ex As Exception
Logger.Error(ex)
Return Constants.INVALID_OBEJCT_ID
End Try
End Function
End Class
End Namespace

View File

@ -0,0 +1,39 @@
Imports DigitalData.Modules.EDMI.API.EDMIServiceReference
Imports DigitalData.Modules.EDMI.API.Options
Imports DigitalData.Modules.Logging
Namespace Modules.IDB
Public Class UpdateFile
Inherits BaseMethod
Public Sub New(pLogConfig As LogConfig, pChannel As IEDMIServiceChannel)
MyBase.New(pLogConfig, pChannel)
End Sub
Public Async Function RunAsync(pFilePath As String, pObjectId As Long, Optional pOptions As UpdateFileOptions = Nothing) As Task
' Set default options
If pOptions Is Nothing Then
pOptions = New UpdateFileOptions()
End If
' Check if file exists
If IO.File.Exists(pFilePath) = False Then
Throw New IO.FileNotFoundException("Path does not exist")
End If
' Importing the file now
Dim oFileProperties = Helpers.GetFileProperties(pFilePath, Date.Now)
'Dim oFileImportResponse = Await Channel.(New NewFileRequest With {
' .BusinessEntity = pBusinessEntity,
' .File = oFileProperties,
' .KindType = pObjectKind,
' .StoreName = pObjectStoreName,
' .User = New UserState With {
' .Language = pOptions.Language,
' .UserName = pOptions.Username
' }
'})
End Function
End Class
End Namespace

View File

@ -80,9 +80,9 @@ Public Class EDMIService
Return oNewFile.Run(Data) Return oNewFile.Run(Data)
End Function End Function
Public Function VersionFile(Data As VersionFile.VersionFileRequest) As VersionFile.VersionFileResponse Implements IEDMIService.VersionFile Public Function UpdateFile(Data As UpdateFile.UpdateFileRequest) As UpdateFile.UpdateFileResponse Implements IEDMIService.UpdateFile
_Logger.Debug("Start of Method [VersionFile]") _Logger.Debug("Start of Method [VersionFile]")
Dim oVersionFile As New VersionFile.VersionFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState) Dim oVersionFile As New UpdateFile.UpdateFileMethod(LogConfig, MSSQL_IDB, MSSQL_ECM, GlobalState)
Return oVersionFile.Run(Data) Return oVersionFile.Run(Data)
End Function End Function

View File

@ -181,9 +181,9 @@
<Compile Include="Messages\DatabaseResult.vb" /> <Compile Include="Messages\DatabaseResult.vb" />
<Compile Include="EDMIService.vb" /> <Compile Include="EDMIService.vb" />
<Compile Include="Methods\IDB\AttributeValue.vb" /> <Compile Include="Methods\IDB\AttributeValue.vb" />
<Compile Include="Methods\IDB\VersionFile\VersionFileMethod.vb" /> <Compile Include="Methods\IDB\UpdateFile\UpdateFileMethod.vb" />
<Compile Include="Methods\IDB\VersionFile\VersionFileRequest.vb" /> <Compile Include="Methods\IDB\UpdateFile\UpdateFileRequest.vb" />
<Compile Include="Methods\IDB\VersionFile\VersionFileResponse.vb" /> <Compile Include="Methods\IDB\UpdateFile\UpdateFileResponse.vb" />
<Compile Include="Scheduler\Scheduler.vb" /> <Compile Include="Scheduler\Scheduler.vb" />
<Compile Include="Scheduler\DatatableJob.vb" /> <Compile Include="Scheduler\DatatableJob.vb" />
<Compile Include="Scheduler\JobListener.vb" /> <Compile Include="Scheduler\JobListener.vb" />

View File

@ -84,7 +84,7 @@ Interface IEDMIService
Function NewFile(Data As NewFile.NewFileRequest) As NewFile.NewFileResponse Function NewFile(Data As NewFile.NewFileRequest) As NewFile.NewFileResponse
<OperationContract> <OperationContract>
Function VersionFile(Data As VersionFile.VersionFileRequest) As VersionFile.VersionFileResponse Function UpdateFile(Data As UpdateFile.UpdateFileRequest) As UpdateFile.UpdateFileResponse
<OperationContract> <OperationContract>
Function SetAttributeValue(Data As SetAttributeValue.SetAttributeValueRequest) As SetAttributeValue.SetAttributeValueResponse Function SetAttributeValue(Data As SetAttributeValue.SetAttributeValueRequest) As SetAttributeValue.SetAttributeValueResponse

View File

@ -0,0 +1,254 @@
Imports System.Data.SqlClient
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Database.MSSQLServer.TransactionMode
Imports DigitalData.Modules.Logging
Imports DigitalData.Services.EDMIService.Methods
Imports DigitalData.Services.EDMIService.GlobalState
Namespace Methods.IDB.UpdateFile
Public Class UpdateFileMethod
Inherits BaseMethod
Private ReadOnly Connection As SqlConnection
Private ReadOnly Transaction As SqlTransaction
Public Sub New(pLogConfig As LogConfig, pDatabaseIDB As MSSQLServer, pDatabaseECM As MSSQLServer, pGlobalState As GlobalState)
MyBase.New(pLogConfig, pDatabaseIDB, pDatabaseECM, pGlobalState)
Connection = DatabaseIDB.GetConnection()
Transaction = Connection.BeginTransaction()
End Sub
Public Function Run(pData As UpdateFileRequest) As UpdateFileResponse
' TODO: Update file object
If Helpers.TestObjectIdExists(pData.ObjectId) = False Then
LogAndThrow("ObjectId does not exist!")
End If
'TODO: Create a view that collects all information about an idb object
If pData.CreateNewVersion = False Then
Else
End If
Return New UpdateFileResponse(pData.ObjectId)
'Dim oFilePath As String = Nothing
'
'Dim oExistingObjectId = TestFileChecksumExists(pData.File.FileChecksum)
'If oExistingObjectId > 0 Then
' Return New UpdateFileResponse(oExistingObjectId)
'End If
'Try
' Dim oObjectId = NewObjectId(pData.KindType, pData.BusinessEntity, pData.User.UserName)
' If oObjectId = 0 Then
' LogAndThrow("Could not create new ObjectId!")
' End If
' ' Find ObjectStore by Title
' Logger.Debug("Checking for DataStore [{0}].", pData.StoreName)
' Dim oStore = GlobalState.ObjectStores.
' Where(Function(store) store.Title.Equals(pData.StoreName, StringComparison.OrdinalIgnoreCase)).
'SingleOrDefault()
' If oStore Is Nothing Then
' LogAndThrow($"DataStore [{pData.StoreName}] does not exist. Exiting.")
' End If
' ' Get Store base path
' Dim oBasePath As String = oStore.Path
' Logger.Debug("Store BasePath is [{0}]", oBasePath)
' ' Get directory by DateImported or, if not supplied, by current date
' Dim oSubDirectory As String
' If IsNothing(pData.File.FileImportedAt) Then
' oSubDirectory = GetDateSubDirectory(Now)
' Else
' oSubDirectory = GetDateSubDirectory(pData.File.FileImportedAt)
' End If
' Logger.Debug("Subdirectory is [{0}]", oSubDirectory)
' ' Check and create final path, if necessary
' Dim oFinalPath = IO.Path.Combine(oBasePath, oSubDirectory)
' If Not IO.Directory.Exists(oFinalPath) Then
' Try
' Logger.Debug("Path does not exist, creating: [{0}]", oFinalPath)
' IO.Directory.CreateDirectory(oFinalPath)
' Logger.Debug("Created folder [{0}]", oFinalPath)
' Catch ex As Exception
' LogAndThrow(ex, $"Store Directory [{oFinalPath}] could not be created!")
' End Try
' End If
' Logger.Debug("Final Directory is [{0}]", oFinalPath)
' ' Get filename
' Dim oKeepFileName As Boolean = False
' If oStore.IsArchive Then
' Logger.Debug("Object Store is an archive: [{0}]", oStore.IsArchive)
' oKeepFileName = True
' End If
' Dim oFileName As String = GetFileObjectFileName(oObjectId, pData.File.FileName, oKeepFileName)
' Logger.Debug("Filename is [{0}]", oFileName)
' oFilePath = IO.Path.Combine(oFinalPath, oFileName)
' Dim oFileObjectInfo As IO.FileInfo = New IO.FileInfo(oFilePath)
' Dim oFileObjectSize As Long = pData.File.FileContents.Length
' Dim oFileObjectName As String = oFileObjectInfo.Name
' Dim oOriginalExtension As String = pData.File.FileInfoRaw.Extension.Substring(1)
' Logger.Debug("File Information for [{0}]:", oFileObjectName)
' Logger.Debug("Size: [{0}]", oFileObjectSize)
' Logger.Debug("Original Extension: [{0}]", oOriginalExtension)
' Logger.Debug("Checksum: [{0}]", pData.File.FileChecksum)
' Try
' Using oStream = New IO.FileStream(oFilePath, IO.FileMode.Create, IO.FileAccess.Write)
' Logger.Info("Saving file to path [{0}]", oFilePath)
' oStream.Write(pData.File.FileContents, 0, oFileObjectSize)
' oStream.Flush(True)
' oStream.Close()
' End Using
' Catch ex As Exception
' LogAndThrow(ex, $"Could not write file [{oFilePath}] to disk!")
' End Try
' '---------------------------------------------------------------------------
' Logger.Info("Creating IDB FileObject for ObjectId [{0}].", oObjectId)
' ' Insert into DB
' Dim oSQL As String = $"EXEC PRIDB_NEW_IDBFO
' '{oFinalPath}',
' '{oFileObjectName}',
' '{oOriginalExtension}',
' {oFileObjectSize},
' '{pData.File.FileChecksum}' ,
' '{pData.User.UserName}',
' '{oObjectId}',
' {oStore.Id}"
' Dim oResult As Boolean = DatabaseIDB.ExecuteNonQueryWithConnectionObject(oSQL, Connection, ExternalTransaction, Transaction)
' If oResult = False Then
' LogAndThrow("IDB FileObject could not be created!")
' End If
' '---------------------------------------------------------------------------
' 'TODO: File dates in try catch
' Dim oSystemAttributes As New Dictionary(Of String, Object) From {
' {"OriginFileName", pData.File.FileName},
' {"OriginCreationDatetime", pData.File.FileCreatedAt},
' {"OriginChangedDatetime", pData.File.FileChangedAt}
'}
' For Each oAttribute As KeyValuePair(Of String, Object) In oSystemAttributes
' Try
' ' Dont write empty attributes
' If oAttribute.Value Is Nothing Then
' Continue For
' End If
' Dim oSuccess = Helpers.SetAttributeValue(Connection, Transaction, oObjectId, oAttribute.Key, oAttribute.Value, pData.User.Language, pData.User.UserName)
' If oSuccess Then
' Logger.Debug("System Attribute [{0}] written with value [{1}]", oAttribute.Key, oAttribute.Value)
' Else
' Logger.Warn("System attribute value could not be written")
' End If
' Catch ex As Exception
' LogAndThrow(ex, $"System attribute [{oAttribute.Key}] could not be written!")
' End Try
' Next
' '---------------------------------------------------------------------------
' ' Finally, commit the transaction
' Transaction?.Commit()
' Return New UpdateFileResponse(oObjectId)
'Catch ex As Exception
' Logger.Warn("Error occurred while creating file!")
' Logger.Error(ex)
' Logger.Info("Cleaning up files.")
' If Not IsNothing(oFilePath) AndAlso IO.File.Exists(oFilePath) Then
' Try
' IO.File.Delete(oFilePath)
' Catch exInner As Exception
' Logger.Warn("Error while cleaning up files.")
' Logger.Error(exInner)
' End Try
' End If
' Logger.Info("Rolling back transaction.")
' Transaction?.Rollback()
' Return New UpdateFileResponse(ex)
'End Try
End Function
Private Function TestFileChecksumExists(pChecksum As String) As Long
Try
Dim oChecksumSQL = $"SELECT IDB_OBJ_ID FROM TBIDB_FILE_OBJECT WHERE FILE_HASH = '{pChecksum}'"
Dim oExistingObjectId As Long = DatabaseIDB.GetScalarValue(oChecksumSQL)
If oExistingObjectId > 0 Then
Logger.Info("Returning early with ObjectId [{0}] because Checksum [{1}] already exists.", oExistingObjectId, pChecksum)
Return oExistingObjectId
End If
Return Nothing
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function NewObjectId(pKindType As String, pBusinessEntity As String, pWho As String) As Long
Try
Dim oNewObjectIdSQL = $"DECLARE @NEW_IDB_OBJ_ID BIGINT
EXEC PRIDB_NEW_OBJECT '{pKindType}','{pWho}','{pBusinessEntity}',0, @IDB_OBJ_ID = @NEW_IDB_OBJ_ID OUTPUT;
SELECT @NEW_IDB_OBJ_ID"
Dim oObjectId As Long = DatabaseIDB.GetScalarValueWithConnectionObject(oNewObjectIdSQL, Connection, ExternalTransaction, Transaction)
Logger.Info("New Object with Id [{0}] created!", oObjectId)
If IsNothing(oObjectId) Then
LogAndThrow("Could not create new ObjectId!")
End If
Return oObjectId
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function GetFileObjectFileName(IDB_OBJ_ID As Long, pFilename As String, pKeepFilename As Boolean) As String
' TODO: save actual extensions
If pKeepFilename Then
Return pFilename
Else
Return $"{IDB_OBJ_ID}.ddfo"
End If
End Function
Private Function GetDateSubDirectory(pDate As Date) As String
Return IO.Path.Combine(pDate.ToString("yyyy"), pDate.ToString("MM"), pDate.ToString("dd"))
End Function
End Class
End Namespace

View File

@ -0,0 +1,26 @@
Imports System.Runtime.Serialization
Imports DigitalData.Modules.ZooFlow.State
Namespace Methods.IDB.UpdateFile
<Serializable>
<DataContract>
Public Class UpdateFileRequest
<DataMember>
Public Property ObjectId As Long
<DataMember>
Public Property File As FileProperties
<DataMember>
Public Property CreateNewVersion As Boolean
''' <summary>
''' User Importing the file
''' </summary>
''' <returns></returns>
<DataMember>
Public Property User As UserState
End Class
End Namespace

View File

@ -1,9 +1,9 @@
Imports System.Runtime.Serialization Imports System.Runtime.Serialization
Namespace Methods.IDB.VersionFile Namespace Methods.IDB.UpdateFile
<Serializable> <Serializable>
<DataContract> <DataContract>
Public Class VersionFileResponse Public Class UpdateFileResponse
Inherits Messages.BaseResponse Inherits Messages.BaseResponse
<DataMember> <DataMember>

View File

@ -1,235 +0,0 @@
Imports System.Data.SqlClient
Imports DigitalData.Modules.Database
Imports DigitalData.Modules.Database.MSSQLServer.TransactionMode
Imports DigitalData.Modules.Logging
Imports DigitalData.Services.EDMIService.Methods
Imports DigitalData.Services.EDMIService.GlobalState
Namespace Methods.IDB.VersionFile
Public Class VersionFileMethod
Inherits BaseMethod
Private ReadOnly Connection As SqlConnection
Private ReadOnly Transaction As SqlTransaction
Public Sub New(pLogConfig As LogConfig, pDatabaseIDB As MSSQLServer, pDatabaseECM As MSSQLServer, pGlobalState As GlobalState)
MyBase.New(pLogConfig, pDatabaseIDB, pDatabaseECM, pGlobalState)
Connection = DatabaseIDB.GetConnection()
Transaction = Connection.BeginTransaction()
End Sub
Public Function Run(pData As VersionFileRequest) As VersionFileResponse
Dim oFilePath As String = Nothing
Dim oExistingObjectId = TestFileChecksumExists(pData.File.FileChecksum)
If oExistingObjectId > 0 Then
Return New VersionFileResponse(oExistingObjectId)
End If
Try
Dim oObjectId = NewObjectId(pData.KindType, pData.BusinessEntity, pData.User.UserName)
If oObjectId = 0 Then
LogAndThrow("Could not create new ObjectId!")
End If
' Find ObjectStore by Title
Logger.Debug("Checking for DataStore [{0}].", pData.StoreName)
Dim oStore = GlobalState.ObjectStores.
Where(Function(store) store.Title.Equals(pData.StoreName, StringComparison.OrdinalIgnoreCase)).
SingleOrDefault()
If oStore Is Nothing Then
LogAndThrow($"DataStore [{pData.StoreName}] does not exist. Exiting.")
End If
' Get Store base path
Dim oBasePath As String = oStore.Path
Logger.Debug("Store BasePath is [{0}]", oBasePath)
' Get directory by DateImported or, if not supplied, by current date
Dim oSubDirectory As String
If IsNothing(pData.File.FileImportedAt) Then
oSubDirectory = GetDateSubDirectory(Now)
Else
oSubDirectory = GetDateSubDirectory(pData.File.FileImportedAt)
End If
Logger.Debug("Subdirectory is [{0}]", oSubDirectory)
' Check and create final path, if necessary
Dim oFinalPath = IO.Path.Combine(oBasePath, oSubDirectory)
If Not IO.Directory.Exists(oFinalPath) Then
Try
Logger.Debug("Path does not exist, creating: [{0}]", oFinalPath)
IO.Directory.CreateDirectory(oFinalPath)
Logger.Debug("Created folder [{0}]", oFinalPath)
Catch ex As Exception
LogAndThrow(ex, $"Store Directory [{oFinalPath}] could not be created!")
End Try
End If
Logger.Debug("Final Directory is [{0}]", oFinalPath)
' Get filename
Dim oKeepFileName As Boolean = False
If oStore.IsArchive Then
Logger.Debug("Object Store is an archive: [{0}]", oStore.IsArchive)
oKeepFileName = True
End If
Dim oFileName As String = GetFileObjectFileName(oObjectId, pData.File.FileName, oKeepFileName)
Logger.Debug("Filename is [{0}]", oFileName)
oFilePath = IO.Path.Combine(oFinalPath, oFileName)
Dim oFileObjectInfo As IO.FileInfo = New IO.FileInfo(oFilePath)
Dim oFileObjectSize As Long = pData.File.FileContents.Length
Dim oFileObjectName As String = oFileObjectInfo.Name
Dim oOriginalExtension As String = pData.File.FileInfoRaw.Extension.Substring(1)
Logger.Debug("File Information for [{0}]:", oFileObjectName)
Logger.Debug("Size: [{0}]", oFileObjectSize)
Logger.Debug("Original Extension: [{0}]", oOriginalExtension)
Logger.Debug("Checksum: [{0}]", pData.File.FileChecksum)
Try
Using oStream = New IO.FileStream(oFilePath, IO.FileMode.Create, IO.FileAccess.Write)
Logger.Info("Saving file to path [{0}]", oFilePath)
oStream.Write(pData.File.FileContents, 0, oFileObjectSize)
oStream.Flush(True)
oStream.Close()
End Using
Catch ex As Exception
LogAndThrow(ex, $"Could not write file [{oFilePath}] to disk!")
End Try
'---------------------------------------------------------------------------
Logger.Info("Creating IDB FileObject for ObjectId [{0}].", oObjectId)
' Insert into DB
Dim oSQL As String = $"EXEC PRIDB_NEW_IDBFO
'{oFinalPath}',
'{oFileObjectName}',
'{oOriginalExtension}',
{oFileObjectSize},
'{pData.File.FileChecksum}' ,
'{pData.User.UserName}',
'{oObjectId}',
{oStore.Id}"
Dim oResult As Boolean = DatabaseIDB.ExecuteNonQueryWithConnectionObject(oSQL, Connection, ExternalTransaction, Transaction)
If oResult = False Then
LogAndThrow("IDB FileObject could not be created!")
End If
'---------------------------------------------------------------------------
'TODO: File dates in try catch
Dim oSystemAttributes As New Dictionary(Of String, Object) From {
{"OriginFileName", pData.File.FileName},
{"OriginCreationDatetime", pData.File.FileCreatedAt},
{"OriginChangedDatetime", pData.File.FileChangedAt}
}
For Each oAttribute As KeyValuePair(Of String, Object) In oSystemAttributes
Try
' Dont write empty attributes
If oAttribute.Value Is Nothing Then
Continue For
End If
Dim oSuccess = Helpers.SetAttributeValue(Connection, Transaction, oObjectId, oAttribute.Key, oAttribute.Value, pData.User.Language, pData.User.UserName)
If oSuccess Then
Logger.Debug("System Attribute [{0}] written with value [{1}]", oAttribute.Key, oAttribute.Value)
Else
Logger.Warn("System attribute value could not be written")
End If
Catch ex As Exception
LogAndThrow(ex, $"System attribute [{oAttribute.Key}] could not be written!")
End Try
Next
'---------------------------------------------------------------------------
' Finally, commit the transaction
Transaction?.Commit()
Return New VersionFileResponse(oObjectId)
Catch ex As Exception
Logger.Warn("Error occurred while creating file!")
Logger.Error(ex)
Logger.Info("Cleaning up files.")
If Not IsNothing(oFilePath) AndAlso IO.File.Exists(oFilePath) Then
Try
IO.File.Delete(oFilePath)
Catch exInner As Exception
Logger.Warn("Error while cleaning up files.")
Logger.Error(exInner)
End Try
End If
Logger.Info("Rolling back transaction.")
Transaction?.Rollback()
Return New VersionFileResponse(ex)
End Try
End Function
Private Function TestFileChecksumExists(pChecksum As String) As Long
Try
Dim oChecksumSQL = $"SELECT IDB_OBJ_ID FROM TBIDB_FILE_OBJECT WHERE FILE_HASH = '{pChecksum}'"
Dim oExistingObjectId As Long = DatabaseIDB.GetScalarValue(oChecksumSQL)
If oExistingObjectId > 0 Then
Logger.Info("Returning early with ObjectId [{0}] because Checksum [{1}] already exists.", oExistingObjectId, pChecksum)
Return oExistingObjectId
End If
Return Nothing
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function NewObjectId(pKindType As String, pBusinessEntity As String, pWho As String) As Long
Try
Dim oNewObjectIdSQL = $"DECLARE @NEW_IDB_OBJ_ID BIGINT
EXEC PRIDB_NEW_OBJECT '{pKindType}','{pWho}','{pBusinessEntity}',0, @IDB_OBJ_ID = @NEW_IDB_OBJ_ID OUTPUT;
SELECT @NEW_IDB_OBJ_ID"
Dim oObjectId As Long = DatabaseIDB.GetScalarValueWithConnectionObject(oNewObjectIdSQL, Connection, ExternalTransaction, Transaction)
Logger.Info("New Object with Id [{0}] created!", oObjectId)
If IsNothing(oObjectId) Then
LogAndThrow("Could not create new ObjectId!")
End If
Return oObjectId
Catch ex As Exception
Logger.Error(ex)
Return Nothing
End Try
End Function
Private Function GetFileObjectFileName(IDB_OBJ_ID As Long, pFilename As String, pKeepFilename As Boolean) As String
' TODO: save actual extensions
If pKeepFilename Then
Return pFilename
Else
Return $"{IDB_OBJ_ID}.ddfo"
End If
End Function
Private Function GetDateSubDirectory(pDate As Date) As String
Return IO.Path.Combine(pDate.ToString("yyyy"), pDate.ToString("MM"), pDate.ToString("dd"))
End Function
End Class
End Namespace

View File

@ -1,38 +0,0 @@
Imports System.Runtime.Serialization
Imports DigitalData.Modules.ZooFlow.State
Namespace Methods.IDB.VersionFile
<Serializable>
<DataContract>
Public Class VersionFileRequest
<DataMember>
Public Property File As FileProperties
''' <summary>
''' Name/title of the ObjectStore to save the file to, ex. Work
''' </summary>
<DataMember>
Public Property StoreName As String
''' <summary>
''' The business entity of the file, ex DEFAULT
''' </summary>
<DataMember>
Public Property BusinessEntity As String
''' <summary>
''' The kind of object to be created, ex. DOC
''' </summary>
<DataMember>
Public Property KindType As String
''' <summary>
''' User Importing the file
''' </summary>
''' <returns></returns>
<DataMember>
Public Property User As UserState
End Class
End Namespace