Imports System.Data.SqlClient Imports DigitalData.Modules.Base.IDB Imports DigitalData.Modules.Database Imports DigitalData.Modules.Database.MSSQLServer.TransactionMode Imports DigitalData.Modules.Logging Namespace Methods.IDB.NewFile Public Class NewFileMethod 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 NewFile.NewFileRequest) As NewFile.NewFileResponse Dim oFilePath As String = Nothing Dim oExistingObjectId = Helpers.TestFileChecksumExists(pData.File.FileChecksum) If oExistingObjectId > 0 Then Return New NewFile.NewFileResponse(oExistingObjectId) End If Try Dim oObjectId = Helpers.NewObjectIdWithTransaction(pData.KindType, pData.BusinessEntity, pData.User.UserName, Connection, Transaction) 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 = pData.StoreName). SingleOrDefault() If oStore Is Nothing Then LogAndThrow($"DataStore [{pData.StoreName}] does not exist. Exiting.") End If ' Get Store base and final path Logger.Debug("Store BasePath is [{0}]", oStore.Path) Dim oFinalPath = Helpers.GetFileObjectPath(oStore, pData.File.FileImportedAt) ' 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 oFileObjectName As String = oFileObjectInfo.Name Logger.Debug("File Information for [{0}]:", oFileObjectName) Dim oFileObjectSize As Long = pData.File.FileContents.Length Logger.Debug("Size: [{0}]", oFileObjectSize) Dim oOriginalExtension As String = pData.File.FileInfoRaw.Extension.Substring(1) 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 '--------------------------------------------------------------------------- Dim oSystemAttributes As New Dictionary(Of String, Object) From { {Attributes.ATTRIBUTE_ORIGIN_FILENAME, pData.File.FileName}, {Attributes.ATTRIBUTE_ORIGIN_CREATED, pData.File.FileCreatedAt}, {Attributes.ATTRIBUTE_ORIGIN_CHANGED, 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 NewFile.NewFileResponse(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 NewFile.NewFileResponse(ex) 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 End Class End Namespace