SourceCode/PROMS/DataLoader/Transitions.cs
Rich f5544b7053 Add separate counts for Errors, Warnings and Information
Cleanup memory after transition processing
Adjusted width of Error Count
Added memory usage to output
Added Stored Procedure GetJustFormat
Reduce Memory Use
Removed extra using statement
2012-05-21 13:30:21 +00:00

425 lines
16 KiB
C#

// ========================================================================
// Copyright 2006 - Volian Enterprises, Inc. All rights reserved.
// Volian Enterprises - Proprietary Information - DO NOT COPY OR DISTRIBUTE
// ------------------------------------------------------------------------
// $Workfile: $ $Revision: $
// $Author: $ $Date: $
//
// $History: $
// ========================================================================
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Xml;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using VEPROMS.CSLA.Library;
namespace DataLoader
{
public partial class Loader
{
Dictionary<int, List<string>> _ContentMigrationErrors = new Dictionary<int,List<string>>();
List<string> _TransitionMigrationErrors = null;
//private void AddContentMigrationError(Content fromCon,string errorMsg)
//{
// if (!_ContentMigrationErrors.ContainsKey(fromCon.ContentID))
// _ContentMigrationErrors.Add(fromCon.ContentID,new List<string>());
// _ContentMigrationErrors[fromCon.ContentID].Add(errorMsg);
//}
private string AddTrans(OleDbConnection cn, Content fromCon, DataRow dr, DataRow dr2, string pth)
{
List<string> migrationErrors = new List<string>();
string thekey = dr["TONUMBER"].ToString() + "|" + dr["TOSEQUENCE"].ToString();
if (thekey.EndsWith("0S"))
thekey = thekey.Substring(0, thekey.Length - 1);
string dti = dr["DTI"].ToString().PadRight(18, ' ');
string userid = dti.Substring(13, 5).Trim();
int itype = 0;
ConfigInfo ci = null;
//string otranskey = null;
// The transition type was stored as a character & also, when read in thru
// ado.net may have been converted into unicode. So in order to get the
// correct type, first, use the TextConvert to eliminate the conversion done
// by ado.net. Then convert to a number. The 'anding of 0x80' flags that it
// is a formatted transition (i.e. this was done for byron/braidwood to
// show the transition with a page number or not). The 'anding of 0x7f' gets
// the actual number when subtracted from 0x30 (the value of the 0 character).
try
{
char typech = TextConvert.ConvertSeq(dr["TYPE"].ToString())[0];
int tmpitype = Convert.ToInt32(typech);
if ((tmpitype & 0x80) > 0)
{
ci = new ConfigInfo(null);
ci.AddItem("Transition", "Formatted", "True");
}
itype = (tmpitype&0x7F) - 0x30;
}
catch (Exception ex)
{
frmMain.AddError(ex,"Error converting transition type '{0}'",dr["TYPE"].ToString());
log.Error("Error converting transition type");
log.ErrorFormat("type from database = {0}", dr["TYPE"].ToString());
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
itype = -1;
}
DateTime dts = GetDTS(MakeDate(dti.Substring(0, 8).Trim()), dti.Substring(8, 5).Trim());
// if it's in the dictionary of structure elements already migrated, just use this
// structure id, or if it's in the dictionary of structure elements that have
// not been migrated but a record was created from this code, use it. Otherwise
// create a new structure record and use its id, its data will be updated later.
// a structure record.
Item toItem = null;
Item toItem2 = null;
if (itype == 6) // Outside Transition
{
ItemInfo tmp = _OutTran.GetItem(thekey);
if (tmp != null)
toItem = tmp.Get();
else
{
//toItem = Item.New(null, TransDummyCont, DateTime.Now, "Migration");
fromCon.Save();
migrationErrors.Add("Transition Error: Missing Data - " + _OutTran.GetDescription(thekey) + ". Converted to text");
if (!_ContentMigrationErrors.ContainsKey(fromCon.ContentID))
_ContentMigrationErrors.Add(fromCon.ContentID, migrationErrors);
return _OutTran.GetTransitionText(thekey);
}
toItem2 = toItem;
// the 32-bit program will no longer have a special type for outside transitions - make it a
// type of 0 (procedure with optional step).
itype = 0;
}
else
{
if (itype > 6) itype--; // Corrected to match transformat table (16-bit skips type 6 because it's an outside transition)
if (dicTrans_ItemDone.ContainsKey(thekey))
{
toItem = dicTrans_ItemDone[thekey];
if (toItem.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey);
}
else
{
if (dicTrans_ItemIds.ContainsKey(thekey))
{
toItem = dicTrans_ItemIds[thekey];
if (toItem.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey);
}
else
{
// note that parent is null right now - it will be filled in later.
//toItem = Item.MakeItem(null, fromCon, DateTime.Now, "Migration");
toItem = Item.New(null, TransDummyCont, DateTime.Now, "Migration");
dicTrans_ItemIds.Add(thekey, toItem);
_TransitionMigrationErrors.Add(thekey);
}
}
// if there is data in dr2, it means that it is a range transition. Get its item
// data too.
toItem2 = toItem;
if (dr2 != null)
{
string thekey2 = dr2["TONUMBER"].ToString() + "|" + dr2["TOSEQUENCE"].ToString();
// Range transitions that are type 2 are called 'and' transitions. These should extend to the
// last sibling. In data, these are represented with the SQL database field in the transitions
// table 'IsRange' == 2, and the toid == rangeid. In the content record, the link is
// TransitionRange:[type] [tranid] [toid] [rangeid] -> and the toid == rangeid
if (itype == 2)
{
if (dr["TOSEQUENCE"].ToString().Length > 3 &&
dr["TOSEQUENCE"].ToString().Substring(0, 2) == dr2["TOSEQUENCE"].ToString().Substring(0, 2))
thekey2 = thekey;
else
thekey2 = dr2["TONUMBER"].ToString() + "|" + dr2["TOSEQUENCE"].ToString().Substring(0, 3);
}
if (dicTrans_ItemDone.ContainsKey(thekey2))
{
toItem2 = dicTrans_ItemDone[thekey2];
if (toItem2.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey2);
}
else
{
if (dicTrans_ItemIds.ContainsKey(thekey2))
{
toItem2 = dicTrans_ItemIds[thekey2];
if (toItem2.ContentID == TransDummyCont.ContentID)
_TransitionMigrationErrors.Add(thekey2);
}
else
{
toItem2 = Item.MakeItem(null, TransDummyCont, DateTime.Now, "Migration");
dicTrans_ItemIds.Add(thekey2, toItem2);
_TransitionMigrationErrors.Add(thekey2);
}
}
}
}
if (userid == null || userid == "") userid = "Migration";
string results = null;
try
{
int isRange = 0;
if (toItem.ItemID != toItem2.ItemID)
isRange = 1;
else if (itype == 2)
isRange = 2;
using (Transition tr = Transition.New(fromCon, toItem, toItem2, isRange, itype, ci != null ? ci.ToString() : null, dts, userid))
{
//if (otranskey != null)
// tr.MyZTransition.Oldto = otranskey; // info to finish outside transition processing later
//else
tr.MyZTransition.Oldto = dr["OLDTO"].ToString();
if (!tr.IsSavable) ErrorRpt.ErrorReport(tr);
tr.Save();
if (migrationErrors.Count > 0)
_ContentMigrationErrors.Add(fromCon.ContentID, migrationErrors);
if (toItem.ItemID == toItem2.ItemID && itype != 2)
results = string.Format(@"\v <START]\v0 (Resolved Transition Text)\v #Link:Transition:{0} {1} {2}[END>\v0 ", tr.TranType, tr.TransitionID, tr.ToID);
else
results = string.Format(@"\v <START]\v0 (Resolved Transition Text)\v #Link:TransitionRange:{0} {1} {2} {3}[END>\v0 ", tr.TranType, tr.TransitionID, tr.ToID, tr.RangeID);
}
}
catch (Exception ex)
{
frmMain.AddError(ex, "Error addition transition record");
log.Error("Error addition transition record");
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
}
return results;
}
private string MigrateTrans(OleDbConnection cn, string textm, string seqcvt, Content content, string pth)
{
// TODO: BYRON DATA WILL GENERATE A TRANSITION ERROR WHEN IT IS USED IN PROMS 2010
StringBuilder trtxt = new StringBuilder();
int instance = 0;
int beg = 0;
DataTable dt = null;
DataSet ds = null;
OleDbDataAdapter da = null;
char[] chrtrn = { '\x252C', '\x2566' };
int tok = textm.IndexOfAny(chrtrn);
if (tok > -1)
{
string cmd = "SELECT * FROM [tran] WHERE [FROMNUMBER]='" + ProcNumber.Replace("'", "''") + "' AND [FROMSEQUEN] ='" + seqcvt + "' ORDER BY [FROMINSTAN]";
da = new OleDbDataAdapter(cmd, cn);
// get transition records for this step.
ds = new DataSet();
try
{
da.Fill(ds);
dt = ds.Tables[0];
dt.CaseSensitive = true;
}
catch (Exception ex)
{
frmMain.AddError(ex, "Error getting transitions '{0}' '{1}'", ProcNumber, seqcvt);
log.Error("Error getting transitions");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
log.ErrorFormat("{0}\r\n\r\n{1}", ex.Message, ex.InnerException);
ds.Dispose();
da.Dispose();
return textm;
}
}
while (tok > -1)
{
// found a transition token, add the token and transition id into the string and
// add an transition record for it. Later there may be text added.
trtxt.Append(textm.Substring(beg, tok - beg));
// we have too many tokens and not enough usage records - report an error...
if (instance >= dt.Rows.Count)
{
log.ErrorFormat("Error - ran out of transition records for step, check data ");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
}
else
{
DataRow dr = dt.Rows[instance];
// if type is 2 or 3, this is a range transition, need to get the next
// record too
bool trange = false;
if (dr["Type"].ToString() == "2" || dr["Type"].ToString() == "3")
trange = true;
string rectxt = null;
if (trange)
{
instance++;
DataRow dr2 = dt.Rows[instance];
rectxt = AddTrans(cn, content, dr, dr2, pth);
}
else
rectxt = AddTrans(cn, content, dr, null, pth);
//trtxt.Append(textm[tok]);
trtxt.Append(rectxt);
}
instance++;
beg = tok + 1;
if (beg > textm.Length)
{
tok = -1;
da.Dispose();
}
else
tok = textm.IndexOfAny(chrtrn, beg);
}
if (beg < textm.Length)
trtxt.Append(textm.Substring(beg, textm.Length - beg));
if (dt.Rows.Count > instance + 1)
{
log.ErrorFormat("Error - extra transition records for step, check data ");
log.ErrorFormat("from number = {0} oldstepsequence = {1}", ProcNumber, seqcvt);
}
ds.Dispose();
da.Dispose();
return trtxt.ToString();
}
private void ShowMissingTransitions(DocVersion docver)
{
if (dicTrans_ItemIds.Keys.Count > 0)
{
// see if any end in |A0, if so, point these to the procedure associated with it.
CleanupTransToNonExistentSectionA0(docver);
foreach (string s in dicTrans_ItemIds.Keys)
{
//log.WarnFormat("{0} - {1}", s, dicTrans_ItemIds[s]);
frmMain.AddError("Missing Transition Destination {0} - {1}", s, dicTrans_ItemIds[s].ItemID);
//AddItemAnnotation(dicTrans_ItemIds[s]);
}
}
foreach (string s in dicTrans_MigrationErrors.Keys)
{
foreach (Item itm in dicTrans_MigrationErrors[s])
{
ItemAnnotation ia = itm.ItemAnnotations.Add(MigrationErrorType);
ia.SearchText = "Transition Error: Destination Missing - " + s;
ia.UserID = "Migration";
itm.Save();
}
}
if (TransDummyCont.ContentItemCount > 0)
log.Warn("Bad transitions to 'dummy' content");
foreach (ContentItem itm in TransDummyCont.ContentItems)
{
log.WarnFormat("ItemID = {0}", itm.ItemID);
//AddItemAnnotation(itm.MyItem);
}
log.Info("End of Missing Transitions");
}
private void CleanupTransToNonExistentSectionA0(DocVersion docver)
{
List<string> RemoveFromDicTrans = new List<string>();
// see if any end in |A0, if so, point these to the procedure associated with it.
foreach (string s in dicTrans_ItemIds.Keys)
{
if (s.EndsWith("|A0"))
{
// make a list to store those that need changed because can't change data in
// a foreach:
RemoveFromDicTrans.Add(s);
Item item = dicTrans_ItemIds[s]; // to or range id.
//ItemInfo ii = ItemInfo.Get(item.ItemID);
//get the proc id that will become the new to or range id.
string procnum = s.Substring(0, s.IndexOf("|"));
DocVersionInfo dvi = DocVersionInfo.Get(docver.VersionID);
IList iprcs = dvi.GetChildren();
ItemInfo prc = null;
foreach (ItemInfo ii in iprcs)
{
if (ii.DisplayNumber == procnum)
{
prc = ii;
break;
}
}
// For each transition that points to the A0, make it point to the proc.
// First, find all of them by getting transitions with the A0 (dummy
// transition record). Then update the to or range id in the transition
// record & then update the content/from part.
List<int> transToChg = new List<int>();
List<int> transRgChg = new List<int>();
TransitionInfoList til = TransitionInfoList.GetByToID(item.ItemID);
foreach (TransitionInfo ti in til) UpdateTranDataForA0(prc, ti.TransitionID, false);
til = TransitionInfoList.GetByRangeID(item.ItemID);
foreach (TransitionInfo tir in til) UpdateTranDataForA0(prc, tir.TransitionID, true);
}
}
foreach (string str in RemoveFromDicTrans)
{
dicTrans_ItemIds.Remove(str);
dicTrans_MigrationErrors.Remove(str);
}
}
private static void UpdateTranDataForA0(ItemInfo procItem, int transid, bool isRange)
{
int type;
int oldto;
int oldrg;
int oldfrom;
using (Transition t = Transition.Get(transid))
{
type = t.TranType;
oldto = t.ToID;
oldrg = t.RangeID;
oldfrom = t.FromID;
if (!isRange)
{
t.MyItemToID = procItem.Get();
t.MyItemRangeID = procItem.Get();
}
else
t.MyItemRangeID = procItem.Get();
t.Save();
}
using (Content c = Content.Get(oldfrom))
{
string lookFor = (isRange || oldto != oldrg) ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, oldto, oldrg) :
string.Format(@"#Link:Transition:{0} {1} {2}", type, transid, oldto);
string replaceWith = isRange ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, oldto, procItem.ItemID) :
oldto != oldrg ? string.Format(@"#Link:TransitionRange:{0} {1} {2} {3}", type, transid, procItem.ItemID, oldrg) :
string.Format(@"#Link:Transition:{0} {1} {2}", type, transid, procItem.ItemID);
c.Text = c.Text.Replace(lookFor, replaceWith);
c.Save();
}
}
private void AddItemAnnotation(Item itm)
{
foreach (ItemTransition_ToID tmp in itm.ItemTransitions_ToID)
{
foreach (ContentItem ci in tmp.MyContent.ContentItems)
{
ItemAnnotation ia = ci.MyItem.ItemAnnotations.Add(MigrationErrorType);
ia.SearchText = "Transition Error: Missing end point";
ia.UserID = "Migration";
ci.MyItem.Save();
}
}
}
}
}