Rich 14a0b600fd Added method RofstInfo.GetROImageByFilename to find image files by name.
Added method RoImageInforList GetByRODbIDFilename to find image files by name.
Find ROImages if not attached to the current ROFST.  The Export/Import code was not saving ROImage usages properly
2015-02-18 14:43:00 +00:00

513 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using Csla;
using Csla.Data;
using System.IO;
using System.IO.Compression;
using Volian.Base.Library;
namespace VEPROMS.CSLA.Library
{
public delegate void ROImageInfoCompressionEvent(object sender, ROImageInfoCompressionEventArgs args);
public class ROImageInfoCompressionEventArgs
{
private int _Total;
public int Total
{
get { return _Total; }
set { _Total = value; }
}
private int _Current;
public int Current
{
get { return _Current; }
set { _Current = value; }
}
private string _FileName;
public string FileName
{
get { return _FileName; }
set { _FileName = value; }
}
private ROImageCompressionEventType _Type;
public ROImageCompressionEventType Type
{
get { return _Type; }
set { _Type = value; }
}
public ROImageInfoCompressionEventArgs(ROImageCompressionEventType type)
{
_Type = type;
}
public ROImageInfoCompressionEventArgs(int current, string fileName)
{
_Current = current;
_FileName = fileName;
_Type = ROImageCompressionEventType.Update;
}
public ROImageInfoCompressionEventArgs(int total)
{
_Type = ROImageCompressionEventType.Initialize;
_Total = total;
}
}
public enum ROImageCompressionEventType:int {Initialize, Update, Complete};
public partial class ROImageInfo
{
public static event ROImageInfoCompressionEvent CompressAllExistingImages;
public static void OnCompressAllExistingImages(object sender, ROImageInfoCompressionEventArgs args)
{
if (CompressAllExistingImages != null) CompressAllExistingImages(sender, args);
}
// put in for debug
//public static int CacheCountPrimaryKey
//{ get { return _CacheByPrimaryKey.Count; } }
//public static int CacheCountList
//{ get { return _CacheList.Count; } }
public static ROImageInfo GetByROFstID_FileName(int rOFstID, string fileName)
{
//if (!CanGetObject())
// throw new System.Security.SecurityException("User not authorized to view a ROImage");
try
{
if (fileName.EndsWith("PCX")) fileName = fileName.Replace(".PCX", ".TIF");
ROImageInfo tmp = DataPortal.Fetch<ROImageInfo>(new ROFstID_FileNameCriteria(rOFstID, fileName));
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up ROImage
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ROImage.GetByROFstID_FileName", ex);
}
}
public bool ImagesZipped()
{
FolderInfo topFolder = FolderInfo.Get(1);
FolderConfig fc = topFolder.MyConfig as FolderConfig;
return fc.Images_zipped;
}
public static byte[] Compress(byte[] blob)
{
int size = blob.Length;
using (MemoryStream Source = new MemoryStream(blob))
{
using (MemoryStream Destination = new MemoryStream())
{
using (DeflateStream Zip = new DeflateStream(Destination, CompressionMode.Compress, true))
{
int bytesToRead = 0;
Source.Position = 0;
while (Source.Position < Source.Length)
{
if (Source.Length > int.MaxValue)
bytesToRead = int.MaxValue;
else
bytesToRead = (int)(Source.Length - Source.Position);
byte[] buf = new byte[bytesToRead];
Source.Read(buf, 0, bytesToRead);
Zip.Write(buf, 0, bytesToRead);
}
Zip.Close();
}
return Destination.ToArray();
}
}
}
public static byte[] Decompress(byte[] blob, int bsize)
{
if (blob == null) return null;
using (MemoryStream inputStream = new MemoryStream(blob))
{
using (DeflateStream unzip = new DeflateStream(inputStream, CompressionMode.Decompress))
{
using (BinaryReader reader = new BinaryReader(unzip))
{
byte[] bytes = new byte[bsize];
reader.Read(bytes, 0, bsize);
return bytes;
}
}
}
}
public static void FlagImagesZipped()
{
using (Folder folder = Folder.Get(1))
{
FolderConfig cf = folder.MyConfig as FolderConfig;
cf.Images_zipped = true;
folder.Config = cf.ToString(); ;
folder.Save();
}
}
// zip all images in the database. It was decided that images would be zipped in September of 2012
// for a few reasons: 1) database size will be smaller; 2) transfer from server of images will be faster;
// 3) database migration wouldn't use as much memory.
//
public static void ZipImages()
{
FolderInfo fi = FolderInfo.Get(1);
FolderConfig cf = fi.MyConfig as FolderConfig;
if (cf.Images_zipped) return;
// put the ids in a list and process each separately because if we do it any other way, we run
// into memory issues.
ROImageInfoList rol = ROImageInfoList.Get();
List<int> imageIds = new List<int>();
foreach (ROImageInfo roi in rol) imageIds.Add(roi.ImageID);
rol.Dispose();
OnCompressAllExistingImages(null, new ROImageInfoCompressionEventArgs(imageIds.Count));
int pcount = 1;
foreach (int id in imageIds)
{
using (ROImage ro = ROImage.Get(id))
{
string nm = ro.FileName;
OnCompressAllExistingImages(null, new ROImageInfoCompressionEventArgs(pcount++, nm));
ROImageConfig rc = new ROImageConfig();
rc.Image_Size = ro.Content.Length.ToString();
ro.Content = ROImageInfo.Compress(ro.Content);
ro.Config = rc.ToString();
ro.Save();
}
}
OnCompressAllExistingImages(null, new ROImageInfoCompressionEventArgs( ROImageCompressionEventType.Complete));
using (Folder folder = Folder.Get(1))
{
cf.Images_zipped = true;
folder.Config = cf.ToString();
folder.Save();
}
}
private void DataPortal_Fetch(ROFstID_FileNameCriteria criteria)
{
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROImageInfo.DataPortal_Fetch", GetHashCode());
try
{
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
{
ApplicationContext.LocalContext["cn"] = cn;
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "getROImageByROFstID_FileName";
cm.Parameters.AddWithValue("@ROFstID", criteria.ROFstID);
cm.Parameters.AddWithValue("@FileName", criteria.FileName);
cm.CommandTimeout = Database.DefaultTimeout;
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
if (!dr.Read())
{
_ErrorMessage = "No Record Found";
return;
}
ReadData(dr);
}
}
// removing of item only needed for local data portal
if (ApplicationContext.ExecutionLocation == ApplicationContext.ExecutionLocations.Client)
ApplicationContext.LocalContext.Remove("cn");
}
}
catch (Exception ex)
{
if (_MyLog.IsErrorEnabled) _MyLog.Error("ROImageInfo.DataPortal_Fetch", ex);
_ErrorMessage = ex.Message;
throw new DbCslaException("ROImageInfo.DataPortal_Fetch", ex);
}
}
[Serializable()]
private class ROFstID_FileNameCriteria
{
private int _ROFstID;
public int ROFstID
{ get { return _ROFstID; } }
private string _FileName;
public string FileName
{ get { return _FileName; } }
public ROFstID_FileNameCriteria(int rOFstID, string fileName)
{
_ROFstID = rOFstID;
_FileName = fileName;
}
}
}
public class ROImageFile : IDisposable
{
private static readonly log4net.ILog _MyLog = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
#region Fields
private bool _IsDisposed;
//private static string _TemporaryFolder = null;
#endregion
#region Properties
private ROImageInfo _MyROImage = null;
public ROImageInfo MyROImage
{
get { return _MyROImage; }
set
{
TryDelete();
_MyROImage = value;
CreateFile();
}
}
private FileInfo _MyFile = null;
public FileInfo MyFile
{
get { return _MyFile; }
}
private string _Extension = "TIF";
public string Extension
{
get { return _Extension; }
set { _Extension = value; }
}
#endregion
#region Private Methods
private void TryDelete()
{
if (_MyROImage == null) return;
if (_MyFile == null) return;
if (_MyFile.Exists)
{
try
{
_MyFile.Delete();
}
catch (IOException ex)
{
_MyLog.Error("TryDelete", ex);
}
finally
{
_MyFile = null;
_MyROImage = null;
}
}
}
private bool _Created = false;
private int _Unique = 0;
private string Unique
{
get
{
string retval = "";
if (_Unique != 0) retval = "_" + _Unique.ToString();
_Unique++;
return retval;
}
}
private void CreateFile()
{
while (!_Created)
CreateTemporaryFile();
}
private void CreateTemporaryFile()
{
try
{
if (_MyROImage != null)
{
_MyFile = new FileInfo(string.Format(@"{0}\tmp_{1}{2}", VlnSettings.TemporaryFolder, Unique, MyROImage.FileName));
FileStream fs = _MyFile.Create();
ROImageConfig roicfg = new ROImageConfig(MyROImage);
int size = Convert.ToInt32(roicfg.Image_Size);
byte[] tmpb = ROImageInfo.Decompress(MyROImage.Content, size);
fs.Write(tmpb, 0, tmpb.Length);
fs.Close();
_MyFile.CreationTimeUtc = MyROImage.DTS;
_MyFile.LastWriteTimeUtc = MyROImage.DTS;
_Created = true;
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
public string FullName
{
get { return _MyFile.FullName; }
set
{
if (FullName != value)
_MyFile = new FileInfo(value);
}
}
public void SaveFile()
{
if (_MyROImage == null) return;
ROImage roImage = _MyROImage.Get();
FileStream fs = _MyFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Byte[] buf = new byte[_MyFile.Length];
fs.Read(buf, 0, buf.Length);
fs.Close();
roImage.Content = buf;
roImage.UserID = Volian.Base.Library.VlnSettings.UserID;
roImage.DTS = _MyFile.LastWriteTimeUtc;
roImage.Save();
}
#endregion
#region Constructors
public ROImageFile(ROImageInfo myROImage)
{
MyROImage = myROImage;
}
#endregion
#region Destructor
~ROImageFile()
{
Dispose(false);
}
public void Dispose()
{
Dispose(false);
GC.SuppressFinalize(this);
}
protected void Dispose(bool disposing)
{
if (!_IsDisposed)
{
_IsDisposed = true;
TryDelete();
}
}
#endregion
}
public partial class ROImageInfoList
{
public static ROImageInfoList GetByRODbIDNoData(int rODbID)
{
try
{
ROImageInfoList tmp = DataPortal.Fetch<ROImageInfoList>(new RODbIDNoDataCriteria(rODbID));
//ROImageInfo.AddList(tmp);
tmp.AddEvents();
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ROImageInfoList.GetByRODbID", ex);
}
}
private class RODbIDNoDataCriteria
{
public RODbIDNoDataCriteria(int rODbID)
{
_RODbID = rODbID;
}
private int _RODbID;
public int RODbID
{
get { return _RODbID; }
set { _RODbID = value; }
}
}
private void DataPortal_Fetch(RODbIDNoDataCriteria criteria)
{
this.RaiseListChangedEvents = false;
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROImageInfoList.DataPortal_FetchRODbID", GetHashCode());
try
{
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
{
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "getROImagesByRODbIDNoData";
cm.Parameters.AddWithValue("@RODbID", criteria.RODbID);
cm.CommandTimeout = Database.DefaultTimeout;
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
IsReadOnly = false;
while (dr.Read()) this.Add(new ROImageInfo(dr));
IsReadOnly = true;
}
}
}
}
catch (Exception ex)
{
if (_MyLog.IsErrorEnabled) _MyLog.Error("ROImageInfoList.DataPortal_FetchRODbID", ex);
throw new DbCslaException("ROImageInfoList.DataPortal_Fetch", ex);
}
this.RaiseListChangedEvents = true;
}
public static ROImageInfoList GetByRODbIDFilename(int rODbID,string filename)
{
try
{
ROImageInfoList tmp = DataPortal.Fetch<ROImageInfoList>(new RODbIDFilenameCriteria(rODbID,filename));
//ROImageInfo.AddList(tmp);
tmp.AddEvents();
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ROImageInfoList.GetByRODbIDFilename", ex);
}
}
private class RODbIDFilenameCriteria
{
public RODbIDFilenameCriteria(int rODbID,string filename)
{
_RODbID = rODbID;
_Filename = filename;
}
private int _RODbID;
public int RODbID
{
get { return _RODbID; }
set { _RODbID = value; }
}
private string _Filename;
public string Filename
{
get { return _Filename; }
set { _Filename = value; }
}
}
private void DataPortal_Fetch(RODbIDFilenameCriteria criteria)
{
this.RaiseListChangedEvents = false;
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROImageInfoList.DataPortal_FetchRODbIDFilename", GetHashCode());
try
{
using (SqlConnection cn = Database.VEPROMS_SqlConnection)
{
using (SqlCommand cm = cn.CreateCommand())
{
cm.CommandType = CommandType.StoredProcedure;
cm.CommandText = "getROImagesByRODbID_Filename";
cm.Parameters.AddWithValue("@RODbID", criteria.RODbID);
cm.Parameters.AddWithValue("@FileName", criteria.Filename);
cm.CommandTimeout = Database.DefaultTimeout;
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
IsReadOnly = false;
while (dr.Read()) this.Add(new ROImageInfo(dr));
IsReadOnly = true;
}
}
}
}
catch (Exception ex)
{
if (_MyLog.IsErrorEnabled) _MyLog.Error("ROImageInfoList.DataPortal_FetchRODbIDFilename", ex);
throw new DbCslaException("ROImageInfoList.DataPortal_FetchRODbIDFilename", ex);
}
this.RaiseListChangedEvents = true;
}
}
}