170 lines
7.2 KiB
VB.net

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.IDBDoctypeId, 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