Improve ROFst Update Performance

Add RoFstLookup Dicitonary Entries for Multiple Return Values
AddByROFstIDImageIDs - Add a list of figures based upon a List of ImageIDs
Fix regular expression to find RO Text to replace
GetDROUsagesByROIDs - get a list of ROUSages for a list of ROIDs
GetJustRODB - Get Just RODB object without children
GetJustROFst - Get Just ROFst or ROFstInfo object without children
Reduce duplicate gets of RODB and ROFst
Improve ROFst Update Performance
GetByRODbIDNoData - Get RoImageInfo objects without graphic data for ROFst Update comparison
GetROUSagesByROIDs - Get a list of ROUSages by ROIDs.  This reduces the number of ROIDs to be checked when updating ROFst.
Use GetJustRoFst and GetJustRoDB to improve the performance to see if the "Update ROFst" button should be active.
This commit is contained in:
Rich
2011-07-18 14:57:47 +00:00
parent 248c1679bc
commit be814b9743
9 changed files with 652 additions and 85 deletions

View File

@@ -39,6 +39,83 @@ namespace VEPROMS.CSLA.Library
return _ROFSTLookup;
}
}
public static ROFst GetJustROFst(int rOFstID)
{
if (!CanGetObject())
throw new System.Security.SecurityException("User not authorized to view a ROFst");
try
{
ROFst tmp = GetCachedByPrimaryKey(rOFstID);
if (tmp == null)
{
tmp = DataPortal.Fetch<ROFst>(new PKCriteriaJustROFst(rOFstID));
AddToCache(tmp);
}
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up ROFst
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ROFst.Get", ex);
}
}
[Serializable()]
protected class PKCriteriaJustROFst
{
private int _ROFstID;
public int ROFstID
{ get { return _ROFstID; } }
public PKCriteriaJustROFst(int rOFstID)
{
_ROFstID = rOFstID;
}
}
private void DataPortal_Fetch(PKCriteriaJustROFst criteria)
{
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROFst.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 = "getJustROFst";
cm.Parameters.AddWithValue("@ROFstID", criteria.ROFstID);
using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
{
if (!dr.Read())
{
_ErrorMessage = "No Record Found";
return;
}
ReadData(dr);
// load child objects
//dr.NextResult();
//_ROFstAssociations = ROFstAssociations.Get(dr);
// load child objects
//dr.NextResult();
//_ROFstFigures = ROFstFigures.Get(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("ROFst.DataPortal_Fetch", ex);
_ErrorMessage = ex.Message;
throw new DbCslaException("ROFst.DataPortal_Fetch", ex);
}
}
}
public delegate List<string> ROFstInfoROTableUpdateEvent(object sender, ROFstInfoROTableUpdateEventArgs args);
public partial class ROFstInfo
@@ -135,27 +212,34 @@ namespace VEPROMS.CSLA.Library
byte[] ab = r.ReadBytes((int)fsIn.Length);
fsIn.Close();
using (RODb rd = RODb.Get(rdi.RODbID))
using (RODb rodb = RODb.Get(rdi.RODbID))
{
rofst = ROFst.MakeROFst(rd, ab, null, di.LastWriteTime, rdi.UserID);
// Hook this into the current docversion by replacing the rofstid field in the doc version
// association object:
docver.DocVersionAssociations.Add(rofst);
docver.Save();
// Now load any images in... type 8 - integrated graphics ro type
for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++)
using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbID(rdi.RODbID))
{
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null)
Dictionary<string, int> myROImagesList = BuildROImagesList(myROImages);
List<int> myROImageIDs = new List<int>();
rofst = ROFst.MakeROFst(rodb, ab, null, di.LastWriteTime, rdi.UserID);
// Hook this into the current docversion by replacing the rofstid field in the doc version
// association object:
docver.DocVersionAssociations.Add(rofst);
docver.Save();
// Now load any images in... type 8 - integrated graphics ro type
for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++)
{
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null)
{
rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children);
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
{
rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children, rodb, rofst, myROImagesList, myROImageIDs);// TODO: Need to add MyImages
}
}
}
if(myROImageIDs.Count > 0)
using(FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID,buildImageIDString(myROImageIDs)));
return rofst;
}
return rofst;
}
}
#endregion
@@ -172,7 +256,6 @@ namespace VEPROMS.CSLA.Library
public static ROFst UpdateRoFst(RODbInfo rdi, DocVersionAssociation dva, DocVersion docver, ROFstInfo origROFst)
{
DirectoryInfo di = new DirectoryInfo(rdi.FolderPath);
// check if this rofst has been loaded, i.e. dts on file versus dts in db...
// if so, just make association to existing with docversion.
ROFst rofst = ROFst.GetByRODbID_DTS(rdi.RODbID, di.LastWriteTime);
@@ -190,26 +273,31 @@ namespace VEPROMS.CSLA.Library
BinaryReader r = new BinaryReader(fsIn);
byte[] ab = r.ReadBytes((int)fsIn.Length);
fsIn.Close();
using (RODb rd = RODb.Get(rdi.RODbID))
using (RODb rodb = RODb.GetJustRoDb(rdi.RODbID))
{
rofst = ROFst.MakeROFst(rd, ab, null, di.LastWriteTime, rdi.UserID);
rofst = ROFst.MakeROFst(rodb, ab, null, di.LastWriteTime, rdi.UserID);
// Hook this into the current docversion by replacing the rofstid field in the doc version
// association object:
dva.MyROFst = rofst;
docver.Save();
// Now load any images in... type 8 - integrated graphics ro type
for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++)
using (ROImageInfoList myROImages = ROImageInfoList.GetByRODbIDNoData(rdi.RODbID))
{
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null)
Dictionary<string, int> myROImagesList = BuildROImagesList(myROImages);
List<int> myROImageIDs = new List<int>();
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
{
using (ROFstInfo rfi = ROFstInfo.Get(rofst.ROFstID))
for (int i = 0; i < rofst.ROFSTLookup.myHdr.myDbs.Length; i++)
{
rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children);
// walk through the rofst 'database' searching for all nodes that are integrated graphics, type 8:
if (rofst.ROFSTLookup.myHdr.myDbs[i].children != null)
{
rfi.MigrateRoFstGraphics(rdi, rofst.ROFSTLookup.myHdr.myDbs[i].children, rodb, rofst, myROImagesList, myROImageIDs);
}
}
}
if (myROImageIDs.Count > 0)
using(FigureInfoList fil = FigureInfoList.AddByROFstIDImageIDs(rofst.ROFstID,buildImageIDString(myROImageIDs)));
}
// Now update the usages: compare old to new rofsts and update usages accordingly, i.e. modified
// values, deleted ros, etc.
@@ -217,60 +305,127 @@ namespace VEPROMS.CSLA.Library
return rofst;
}
}
private static void UpdateROValuesText(ROFstInfo origROFstInfo, ROFst newROFst)
private static Dictionary<string,int> BuildROImagesList(ROImageInfoList myROImages)
{
Dictionary<string,int> myRoImagesList = new Dictionary<string,int>();
foreach (ROImageInfo myROImage in myROImages)
myRoImagesList.Add(ROImageKey(myROImage.FileName, myROImage.DTS),myROImage.ImageID);
return myRoImagesList;
}
private static string ROImageKey(string fileName, DateTime dts)
{
return string.Format("{0}:{1}", fileName, dts);
}
private static string buildImageIDString(List<int> myROImageIDs)
{
StringBuilder sb = new StringBuilder();
string sep = "";
foreach (int imageID in myROImageIDs)
{
sb.Append(sep + imageID.ToString());
sep = ",";
}
return sb.ToString();
}
private static void UpdateROValuesText(ROFstInfo origROFstInfo, ROFst newROFst)
{
ROFSTLookup origLU = new ROFSTLookup(origROFstInfo);
ROFSTLookup newLU = new ROFSTLookup(newROFst);
List <string> delList = new List<string>();
List<string> delList = new List<string>();
List<string> chgList = newLU.GetValueDifferences(origLU, ref delList);
string RoidList = GetRoidList(newROFst.RODbID, chgList);
List<string> activeRoids = BuildActiveROIDsForRoUsages(RoidList);
foreach (string chg in chgList)
{
ROFSTLookup.rochild roch = newLU.GetRoChild(chg);
string desc = string.Format("Change in RO Values: Old value = {0}, New value = {1}", origLU.GetRoValue(chg), roch.value);
// roid's are stored in database as 16 characters long in the rousages table. They may be stored
// as 12 characters in the ro.fst.
string padroid = chg.Length <= 12 ? chg + "0000" : chg;
using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed"))
if (activeRoids.Contains(chg))
{
foreach (RoUsageInfo roUsg in affected)
ROFSTLookup.rochild roch = newLU.GetRoChild(chg);
string desc = string.Format("Change in RO Values: Old value = {0}, New value = {1}", origLU.GetRoValue(chg), roch.value);
// roid's are stored in database as 16 characters long in the rousages table. They may be stored
// as 12 characters in the ro.fst.
string padroid = chg.Length <= 12 ? chg + "0000" : chg;
using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed"))
{
using (Content content = Content.Get(roUsg.MyContent.ContentID))
foreach (RoUsageInfo roUsg in affected)
{
content.FixContentText(roUsg, roch, origROFstInfo);
if (content.IsDirty)
content.Save();
using (Content content = Content.Get(roUsg.MyContent.ContentID))
{
content.FixContentText(roUsg, roch, origROFstInfo);
if (content.IsDirty)
content.Save();
}
}
}
}
using (DROUsageInfoList affected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed"))
}
activeRoids = BuildActiveROIDsForDRoUsages(RoidList);
foreach (string chg in chgList)
{
if (activeRoids.Contains(chg))
{
foreach (DROUsageInfo droUsg in affected)
ROFSTLookup.rochild roch = newLU.GetRoChild(chg);
string desc = string.Format("Change in RO Values: Old value = {0}, New value = {1}", origLU.GetRoValue(chg), roch.value);
// roid's are stored in database as 16 characters long in the rousages table. They may be stored
// as 12 characters in the ro.fst.
string padroid = chg.Length <= 12 ? chg + "0000" : chg;
using (DROUsageInfoList affected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroid, desc, "Changed"))
{
//using (Document document = Document.Get(droUsg.DocID))
//{
foreach (DROUsageInfo droUsg in affected)
{
Pdf.DeleteAll(droUsg.DocID);
// Delete PDFs
//if (document.DocPdf != null)
//{
// document.DocPdf = null;
// document.Save();
//}
//}
}
}
}
}
foreach (string del in delList)
{
Console.WriteLine("Deleted ROID = {0}", del);
string desc = string.Format("Deleted RO: Value = {0}", origLU.GetRoValue(del));
string padroiddel = del.Length <= 12 ? del + "0000" : del;
using (RoUsageInfoList affected = RoUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroiddel, desc, "Deleted")) ;
using (DROUsageInfoList Daffected = DROUsageInfoList.GetAffected(origROFstInfo.MyRODb.RODbID, padroiddel, desc, "Deleted")) ;
}
}
private static List<string> BuildActiveROIDsForRoUsages(string RoidList)
{
List<string> activeRoids = new List<string>();
using (RoUsageInfoList activeList = RoUsageInfoList.GetROUSagesByROIDs(RoidList))
{
foreach (RoUsageInfo roui in activeList)
{
string roid = roui.ROID.ToUpper();
if (roid.EndsWith("0000")) roid = roid.Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static List<string> BuildActiveROIDsForDRoUsages(string RoidList)
{
List<string> activeRoids = new List<string>();
using (DROUsageInfoList activeList = DROUsageInfoList.GetDROUsagesByROIDs(RoidList))
{
foreach (DROUsageInfo roui in activeList)
{
string roid = roui.ROID;
if (roid.EndsWith("0000")) roid = roid.Substring(0, 12);
if (!activeRoids.Contains(roid))
activeRoids.Add(roid);
}
}
return activeRoids;
}
private static string GetRoidList(int dbid, List<string> chgList)
{
StringBuilder sb = new StringBuilder(string.Format("{0}", dbid));
string sep=":";
foreach (string roid in chgList)
{
sb.Append(sep + roid);
sep = ",";
}
return sb.ToString();
}
private static string NewROName(string roName)
{
string retval = roName;
@@ -295,15 +450,15 @@ namespace VEPROMS.CSLA.Library
retval = string.Format("{0}_{1}", roName, iSuffix + 1);
return retval;
}
private void MigrateRoFstGraphics(RODbInfo rdi, ROFSTLookup.rochild[] rochild)
private void MigrateRoFstGraphics(RODbInfo rdi, ROFSTLookup.rochild[] rochild, RODb rodb, ROFst rofst, Dictionary<string,int> myROImagesList, List<int> myROImageIDs)
{
for (int i = 0; i < rochild.Length; i++)
{
if (rochild[i].type == 8) this.AddGraphic(rdi, rochild[i].value);
if (rochild[i].children != null) this.MigrateRoFstGraphics(rdi, rochild[i].children);
if (rochild[i].type == 8) this.AddGraphic(rdi, rochild[i].value, rodb, rofst, myROImagesList, myROImageIDs);
if (rochild[i].children != null) this.MigrateRoFstGraphics(rdi, rochild[i].children, rodb, rofst, myROImagesList, myROImageIDs);
}
}
private void AddGraphic(RODbInfo rdi, string p)
private void AddGraphic(RODbInfo rdi, string p, RODb rodb, ROFst rofst, Dictionary<string, int> myROImagesList, List<int> myROImageIDs)
{
if (p == null) return;
string imgname = p.Substring(0, p.IndexOf('\n'));
@@ -312,7 +467,7 @@ namespace VEPROMS.CSLA.Library
if (thedot == -1 || (thedot != (imgname.Length - 4)))
{
RODbConfig roDbCfg = new RODbConfig(rdi.Config);
fname += string.Format(".{0}", roDbCfg.GetDefaultGraphicExtension());
fname += string.Format(".{0}", roDbCfg.GetDefaultGraphicExtension());
}
string imgfile = rdi.FolderPath + @"\" + fname;
@@ -322,30 +477,34 @@ namespace VEPROMS.CSLA.Library
{
FileInfo fi = new FileInfo(imgfile);
// if the roimage record exists, don't create a new one...
using (roImg = ROImage.GetByRODbID_FileName_DTS(rdi.RODbID, imgname,fi.LastWriteTime))
string key = ROImageKey(imgname, fi.LastWriteTime);
if (myROImagesList.ContainsKey(key))
{
if (roImg == null)
{
FileStream fsIn = new FileStream(imgfile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader r = new BinaryReader(fsIn);
byte[] ab = r.ReadBytes((int)fsIn.Length);
r.Close();
fsIn.Close();
using (RODb rodb = RODb.Get(rdi.RODbID))
{
roImg = ROImage.MakeROImage(rodb, imgname, ab, null, fi.LastWriteTime, "Migration");
}
}
int imageID = myROImagesList[key];
if(myROImageIDs.Contains(imageID))
myROImageIDs.Add(imageID);
}
else
{
FileStream fsIn = new FileStream(imgfile, FileMode.Open, FileAccess.Read, FileShare.Read);
BinaryReader r = new BinaryReader(fsIn);
byte[] ab = r.ReadBytes((int)fsIn.Length);
r.Close();
fsIn.Close();
roImg = ROImage.MakeROImage(rodb, imgname, ab, null, fi.LastWriteTime, "Migration");
Figure figure = Figure.GetByROFstID_ImageID(this.ROFstID, roImg.ImageID);
if (figure != null) return;
using (ROFst rofst = ROFst.Get(this.ROFstID))
{
figure = Figure.MakeFigure(rofst, roImg, null);
}
figure = Figure.MakeFigure(rofst, roImg, null);
}
}
else
Console.WriteLine(string.Format("{0}", imgfile), "Cannot Find Image File");
}
private ROImageInfo GetMyImage(Dictionary<string, ROImageInfo> myImages, string imgname, DateTime dts)
{
string key = string.Format("{0}:{1}", imgname, dts);
if(myImages.ContainsKey(key))
return myImages[key];
return null;
}
#endregion
#endregion
@@ -365,6 +524,77 @@ namespace VEPROMS.CSLA.Library
if (ROTableUpdate != null) return ROTableUpdate(sender, args);
return null;
}
public static ROFstInfo GetJustROFst(int rOFstID)
{
//if (!CanGetObject())
// throw new System.Security.SecurityException("User not authorized to view a ROFst");
try
{
ROFstInfo tmp = GetCachedByPrimaryKey(rOFstID);
if (tmp == null)
{
tmp = DataPortal.Fetch<ROFstInfo>(new PKCriteriaJustROFst(rOFstID));
AddToCache(tmp);
}
if (tmp.ErrorMessage == "No Record Found")
{
tmp.Dispose(); // Clean-up ROFstInfo
tmp = null;
}
return tmp;
}
catch (Exception ex)
{
throw new DbCslaException("Error on ROFstInfo.Get", ex);
}
}
[Serializable()]
protected class PKCriteriaJustROFst
{
private int _ROFstID;
public int ROFstID
{ get { return _ROFstID; } }
public PKCriteriaJustROFst(int rOFstID)
{
_ROFstID = rOFstID;
}
}
private void DataPortal_Fetch(PKCriteriaJustROFst criteria)
{
if (_MyLog.IsDebugEnabled) _MyLog.DebugFormat("[{0}] ROFstInfo.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 = "getJustROFst";
cm.Parameters.AddWithValue("@ROFstID", criteria.ROFstID);
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("ROFstInfo.DataPortal_Fetch", ex);
_ErrorMessage = ex.Message;
throw new DbCslaException("ROFstInfo.DataPortal_Fetch", ex);
}
}
}
public class ROFstInfoROTableUpdateEventArgs
{