using System; using System.Collections; using System.IO; using System.Data; using System.Xml; using System.Xml.XPath; using System.Xml.Schema; using System.Text; using System.Windows.Forms; using DBEncapsulation; using ROFields; using VlnStatus; using System.Collections.Specialized; using Org.Mentalis.Files; using System.Data.SqlClient; using System.Text.RegularExpressions; using System.Collections.Generic; namespace RODBInterface { public static class ShowCount // use for debugging only { public static int GetRootGroups = 0; public static int GetChildData = 0; public static int ReadRo = 0; public static int GetFields = 0; public static int Children = 0; public static int RoFields = 0; public static void OutputResults() { Console.WriteLine("GetRootGroups = {0}, GetChildData = {1}, ReadRo = {2}, GetFields = {3}, Children = {4}, RoFields = {5}", GetRootGroups, GetChildData, ReadRo, GetFields, Children, RoFields); } } // /// C2017-003: support for sql server /// The following class handles generation of sql strings to get/put requested parts of /// XML RO Tree. It uses queries that are stored in the sql database that contains the ro data. /// public partial class SqlRODB : RODB { public DBEncapsulation.SQLEncap DBE_SQL; public string SqlConnectionStr = null; private SqlConnection ROAPP_SqlConnectionOnce = null; public SqlConnection ROAPP_SqlConnection { get { if (OnlyConnectOnce && ROAPP_SqlConnectionOnce != null) return ROAPP_SqlConnectionOnce; // Attempt to make a connection SqlConnection cn = new SqlConnection(SqlConnectionStr); try { cn.Open(); if (OnlyConnectOnce && ROAPP_SqlConnectionOnce == null) ROAPP_SqlConnectionOnce = cn; return cn; } catch (SqlException ex) { MessageBox.Show(ex.Message, "Could Not Make Connection To Database"); return null; } } } public SqlRODB(string RODirectoyPath, string sqlConnectionStr, bool useConnStr) { SqlConnectionStr = sqlConnectionStr; if (!useConnStr) BuildConnectionString(RODirectoyPath, sqlConnectionStr); DBE_SQL = new SQLEncap(); DBE = DBE_SQL; try { strDatabaseConnectionCommand = sqlConnectionStr; DBE.Connection(SqlConnectionStr); } catch (Exception e) { MessageBox.Show(e.Message, "Setup of OLEDB/ODBC"); } } #region SQL version info // The following code was taken from PROMS so that the Database server can be available for the 'About' dialog and the error log: private static DateTime _RevDate = DateTime.MinValue; public static DateTime RevDate { get { return _RevDate; } set { _RevDate = value; } } private static string _RevDescription = "Unknown"; public static string RevDescription { get { return _RevDescription; } set { _RevDescription = value; } } private string _DBServer = null; public string DBServer { get { if (_DBServer == null) { string cnstr = null; try { using (SqlConnection cn = ROAPP_SqlConnection) { cnstr = cn.ConnectionString; try { using (SqlCommand cmd = new SqlCommand("vesp_GetSQLCodeRevision", cn)) { cmd.CommandType = CommandType.StoredProcedure; cmd.CommandTimeout = 0; SqlDataReader dr = cmd.ExecuteReader(); while (dr.Read()) { _RevDate = dr.GetDateTime(0); _RevDescription = dr.GetString(1); } } } catch (Exception ex) { _RevDate = DateTime.MinValue; _RevDescription = "Unknown"; } string server = ""; string db = ""; Match m = Regex.Match(cnstr, "Data Source=([^;]+)(;[^;]+)*;*Initial Catalog=([^;]+)(;[^;]+)*"); if (m.Success && m.Groups.Count > 4) { server = m.Groups[1].Value; db = m.Groups[3].Value; } _DBServer = string.Format("{0} - {1} [SQL:{2:yyMM.ddHH}]", server, db, RevDate); } } catch (Exception) { _DBServer = cnstr; } } return _DBServer; } } #endregion #region overrides public override string RODB_HasBeenConverted() { return SqlConnectionStr; } public override string RODB_GetDBNameForAbout() { int indx = DBServer.IndexOf("-"); return string.Format("Database: {0}", DBServer.Substring(indx + 2, DBServer.Length - indx - 2)); } public override string RODB_GetDBServerForAbout() { return string.Format("SQL Server: {0}", DBServer.Substring(0, DBServer.IndexOf(" -"))); } public override string RODB_GetNextGroupTable() { try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; // B2020-003: missing command connection. command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfobyRecidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMASTER"); command.Parameters.AddWithValue("@RecID", "00000001"); command.Parameters.AddWithValue("@RecType", (int)RecordType.Master); string rettable = null; string newstr = null; using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.Read()) { MessageBox.Show("Read returned null", "Getting New Group Table"); return null; } rettable = reader.GetString(0); string nxttable = rettable.Substring(2, 6); int ltbl = System.Convert.ToInt32(nxttable, 10); ltbl++; nxttable = ltbl.ToString("d6"); // this format "d6" should pad left with zeros newstr = "RO" + nxttable; } string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); command.Parameters.Clear(); command.CommandText = "updateInfoByRecidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMASTER"); command.Parameters.AddWithValue("@Info", newstr); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecID", "00000001"); command.Parameters.AddWithValue("@RecType", (int)RecordType.Master); using (SqlDataReader reader = command.ExecuteReader()) { return rettable; } } } catch (Exception e) { MessageBox.Show(e.Message, "Getting New Group Table"); } return null; } public override string RODB_GetNextRecId(string table) { // read record type of master for this table. This is where the highest recid is stored. // Update the recid by 1, write it out and return the new recid. try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfobyRecidRectype"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecID", "00000000"); command.Parameters.AddWithValue("@RecType", (int)RecordType.Master); string retrec = null; string padstr = null; using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.Read()) { MessageBox.Show("Read returned null", "Getting New Record Id"); return null; } retrec = reader.GetString(0); int lrecid = System.Convert.ToInt32(retrec, 16); lrecid++; retrec = lrecid.ToString("x"); // need an 8 char string so pad left with zero padstr = retrec.PadLeft(8, '0'); } string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); command.Parameters.Clear(); command.CommandText = "updateInfoByRecidRectype"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecID", "00000000"); command.Parameters.AddWithValue("@Info", padstr); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecType", (int)RecordType.Master); using (SqlDataReader reader = command.ExecuteReader()) { return padstr; } } } catch (Exception e) { MessageBox.Show(e.Message, "Getting New Record Id"); } return null; } public override bool RODB_GetRootGroups(VlnXmlElement root) { ShowCount.GetRootGroups++; string table; string group; string title; // Get menu fields to display SortedList mySL = new SortedList(); try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectypeAsc"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SubDatabase); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { // Parse info string, it has group name & table name. Store in a sorted // list, sorting by Group Name. string mrecid = reader.GetString(0); group = reader.GetString(1); mySL.Add(mrecid, group); } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectypeAsc"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SubDatabase); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { // Parse info string, it has group name & table name. Store in a sorted // list, sorting by Group Name. string mrecid = reader.GetString(0); group = reader.GetString(1); mySL.Add(mrecid, group); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Root Groups"); return false; } // Now, for each group, i.e. table, make xml elements for the top level groups by // reading in the Xml Element for the group from each table. for (int i = 0; i < mySL.Count; i++) { group = mySL.GetByIndex(i).ToString(); int grnamindx = group.IndexOf("\t"); if (grnamindx == -1) {// no tab, default to RO000001 table = "RO000001"; title = group; } else { StringBuilder tablesb = new StringBuilder(70); tablesb.Append(group); tablesb.Remove(0, grnamindx + 1); table = tablesb.ToString(); title = group.Substring(0, grnamindx); } try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectypeParidAsc"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); command.Parameters.AddWithValue("@ParentID", "00000000"); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { string RecID = reader.GetString(0); string Info = reader.GetString(1); XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); VlnXmlElement elem = (VlnXmlElement)nd; elem.MyROID = RecID; root.AppendChild(elem); elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", "00000000"); elem.SetAttribute("Table", table); elem.SetAttribute("MasterRecID", mySL.GetKey(i).ToString()); } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectypeParidAsc"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); command.Parameters.AddWithValue("@ParentID", "00000000"); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { string RecID = reader.GetString(0); string Info = reader.GetString(1); XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); VlnXmlElement elem = (VlnXmlElement)nd; elem.MyROID = RecID; root.AppendChild(elem); elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", "00000000"); elem.SetAttribute("Table", table); elem.SetAttribute("MasterRecID", mySL.GetKey(i).ToString()); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Root Groups"); return false; } } // get child count for each group. XmlNode node = root.FirstChild; while (node != null) { if (node is VlnXmlElement) { VlnXmlElement child = (VlnXmlElement)node; string tablex = child.GetAttribute("Table"); //get child count for each table listed in innertext. try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRecidByParid"; command.Parameters.AddWithValue("@ROTable", tablex); command.Parameters.AddWithValue("@ParentID", child.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int cnt = reader.GetInt32(0); if (cnt > 0) child.SetAttribute("HasChild", "True"); else child.SetAttribute("HasChild", "False"); child.SetAttribute("ChildLoaded", "False"); } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRecidByParid"; command.Parameters.AddWithValue("@ROTable", tablex); command.Parameters.AddWithValue("@ParentID", child.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int cnt = reader.GetInt32(0); if (cnt > 0) child.SetAttribute("HasChild", "True"); else child.SetAttribute("HasChild", "False"); child.SetAttribute("ChildLoaded", "False"); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Root Groups"); return false; } } node = node.NextSibling; } // for the beginning and end schema element, go to the master & read it from there. Store these to be used // by all of the databases. schemastart = null; try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByParidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SchemaStart); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { schemastart = reader.GetString(0); } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByParidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SchemaStart); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { schemastart = reader.GetString(0); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Root Groups"); return false; } schemaend = null; try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByParidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SchemaEnd); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { schemaend = reader.GetString(0); } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByParidRectype"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", (int)RecordType.SchemaEnd); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { schemaend = reader.GetString(0); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Root Groups"); return false; } return true; } public override bool RODB_DeleteGroup(XmlNode group, string tbname, string toprecid) { VlnXmlElement egroup = null; // delete table entry in ROMaster try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "deleteByRecid"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); if (group != null) { egroup = (VlnXmlElement)group; command.Parameters.AddWithValue("@RecID", egroup.GetAttribute("MasterRecID")); } else command.Parameters.AddWithValue("@RecID", toprecid); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); // if this fails, it will go to the catch. } } } catch (Exception e) { MessageBox.Show(e.Message, "Error When deleting SubGroup ROs."); return false; } // now remove all entries in the table (from roall) try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "deleteByROTable"; if (egroup != null) { command.Parameters.AddWithValue("@ROTable", egroup.GetAttribute("Table")); } else command.Parameters.AddWithValue("@ROTable", tbname); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); // if this fails, it will go to the catch. } } } catch (Exception e) { MessageBox.Show(e.Message, "Error When deleting SubGroup ROs."); return false; } return true; } public override bool RODB_DeleteRO(XmlNode group) { // delete from database and then delete from tree. delete group and all subgroups & ros beneath it. delete // subgroups by calling this. note that if just an ro is passed in, it will only delete it. XmlNode node = group.FirstChild; VlnXmlElement child; VlnXmlElement egroup = (VlnXmlElement)group; if (group.Name == "vlnGroup") { while (node != null) { if (node is VlnXmlElement) { child = (VlnXmlElement)node; // if this is a group, call this again. if (child.Name == "vlnGroup") { bool success = RODB_DeleteRO(node); if (success == false) { MessageBox.Show("error in RODB_DeleteGroup"); return false; } } } node = node.NextSibling; } // delete all db records that have the ParentID = to this group RecID. // (All subgroups should be processed from above recursion. try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "deleteByParid"; command.Parameters.AddWithValue("@ROTable", egroup.GetAttribute("Table")); command.Parameters.AddWithValue("@ParentID", egroup.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); // if this fails, it will go to the catch. } } } catch (Exception e) { MessageBox.Show(e.Message, "Error When deleting SubGroup ROs."); return false; } } // now delete this ro or group, i.e. the one passed in. try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "deleteByRecid"; command.Parameters.AddWithValue("@ROTable", egroup.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", egroup.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { reader.Read(); } } } catch (Exception e) { MessageBox.Show(e.Message, "Error When deleting this RO."); return false; } return true; } public override bool RODB_WriteGroup(XmlNode group, VlnXmlElement master) { bool success = true; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); string xmlstr = GenerateXmlString(group, true); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "updateInfoByRecid"; command.Parameters.AddWithValue("@ROTable", master.GetAttribute("Table")); command.Parameters.AddWithValue("@Info", xmlstr); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecID", master.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error on Write Group"); success = false; } return success; } public override bool RODB_InsertGroup(VlnXmlElement group) { bool success = true; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); string xmlstr = GenerateXmlString(group, true); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "insertAllRectypes"; command.Parameters.AddWithValue("@ROTable", group.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", group.GetAttribute("RecID")); command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); command.Parameters.AddWithValue("@ParentID", group.GetAttribute("ParentID")); command.Parameters.AddWithValue("@AccPageID", ""); // B2020-003: make null empty string. command.Parameters.AddWithValue("@Info", xmlstr); command.Parameters.AddWithValue("@ModDateTime", dt); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error on Insert group"); success = false; } return success; } public override string RODB_AddNewTable(string TblName, string newgrpname) { //for sql server version, a new table is not added. A new value for the ROTable field is used (TblName that is passed in ) bool success = false; // now insert the first record with the new table name string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "insertAllRectypes"; command.Parameters.AddWithValue("@ROTable", TblName); command.Parameters.AddWithValue("@RecID", "00000000"); command.Parameters.AddWithValue("@RecType", 0); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@AccPageID", ""); // B2020-003: make null empty string. command.Parameters.AddWithValue("@Info", "00000001"); command.Parameters.AddWithValue("@ModDateTime", dt); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error Creating New " + TblName); success = false; } // return if error on insert of master record of new table, otherwise add // this table reference to the master. if (success == false) return null; string recid = RODB_GetNextRecId("ROMaster"); string info = CvtUserFldToFld(newgrpname) + "\t" + TblName; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "insertAllRectypes"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@RecID", recid); command.Parameters.AddWithValue("@RecType", 1); command.Parameters.AddWithValue("@ParentID", "00000001"); command.Parameters.AddWithValue("@AccPageID", ""); // B2020-003: make null empty string. command.Parameters.AddWithValue("@Info", info); command.Parameters.AddWithValue("@ModDateTime", dt); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error Writing new table to master."); success = false; } if (success == false) return null; else return recid; } public override bool RODB_CopyFieldDefs(string fromtb, string totb, int type) { // Copy over field definitions from the ROMaster to the input table name. ArrayList retlist = new ArrayList(); string Info; string RecID; string name; uint ftype; ROField rof; bool success; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectype"; command.Parameters.AddWithValue("@ROTable", "ROMaster"); command.Parameters.AddWithValue("@RecType", 2); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { RecID = reader.GetString(0); Info = reader.GetString(1); // it's defined in the local table if the first character is "<" which starts // the schema definition string. name = ParseEleName(Info); if (name != null) { // what type of schema element? rof = new ROField(name, RecID, null, 0); ftype = rof.ParseFieldType(Info); rof.SetFieldType(ftype); retlist.Add((object)rof); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on Copy Field Definitions"); return false; } // using this list, add new records for field definition references to the new // table. for (int i = 0; i < retlist.Count; i++) { rof = (ROField)retlist[i]; if (rof.GetFieldname != null) { string mrecid = rof.GetRecID; string lrecid = RODB_GetNextRecId(totb); StringBuilder strbld = new StringBuilder(); strbld.Append(mrecid); strbld.Append(" "); string strtype = rof.GetFieldType.ToString(); strbld.Append(strtype.PadLeft(3, '0')); strbld.Append(" "); if (strtype == "128") // append an 'a' for combo type strbld.Append(rof.MakeFieldName(rof.GetFieldname) + "a"); else strbld.Append(rof.MakeFieldName(rof.GetFieldname)); // add new field. success = RODB_NewSchemaPiece(lrecid, "00000002", totb, strbld.ToString(), 2); if (success == false) return false; } } return true; } public override bool RODB_GetGroupAndSubgroups(VlnXmlElement node, StringBuilder sb) { // This is similar to GetChildData() but this function reads in all the subgroups for the given node // Note that this function is designed to be call for the root node (i.e. it gets all of group and RO data // for a given database table) VlnStatusBar StatBar = new VlnStatusBar("Reading from the Database"); string tablename = node.GetAttribute("Table"); HybridDictionary dicGroups = new HybridDictionary(); dicGroups.Add(node.GetAttribute("RecID").ToString(), node); StatBar.BarMax = RODB_GetNumberOfGroupRecords(tablename); //get number of groups StatBar.BarStepValue = 5; StatBar.StatMsg = node.InnerText; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getGroupAndSubgroups"; command.Parameters.AddWithValue("@ROTable", tablename); using (SqlDataReader reader = command.ExecuteReader()) { if (!reader.Read()) { StatBar.PerformStep(1); reader.Close(); return false; } while (reader.Read()) { string RecID = reader.GetString(0); int RecType = reader.GetInt32(1); string ParID = reader.GetString(2); string AccPageID = reader.GetString(3); string Info = reader.GetString(4); if (!ParID.Equals(node.GetAttribute("RecID"))) { if (!dicGroups.Contains(ParID)) { if (sb.Length == 0) { sb.AppendLine("The following records were skipped."); sb.AppendLine("The parent for these RO's was missing."); sb.AppendLine(); } string strMBText = "RecID: " + RecID + "\n\n Table: " + tablename + "\n"; sb.AppendLine(strMBText); continue; // skip - no parent for this node } node = (VlnXmlElement)dicGroups[ParID]; node.SetAttribute("HasChild", "True"); node.SetAttribute("ChildLoaded", "True"); } else { node.SetAttribute("ChildLoaded", "True"); } if (RecType == (int)RecordType.Group) { VlnXmlElement elem; StatBar.PerformStep(); try { XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); elem = (VlnXmlElement)nd; } catch (Exception e) { MessageBox.Show(e.Message, "Error reading Xml Group From data"); reader.Close(); return false; } elem.MyROID = RecID; elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); if (!dicGroups.Contains(RecID)) { node.AppendChild(elem); dicGroups.Add(RecID, elem); } // The Parameter Display Data is stored along with the group. This data // was migrated over so that the data was not lost, but there is no // User Interface to get to it. So remove the xml elements from the // group part of tree. All valid group data only has one sublevel of // data defining the group name. XmlNode grp = (XmlNode)elem; XmlNode kid = grp.FirstChild; XmlNode tmpkid; while (kid != null) { tmpkid = kid.NextSibling; if (kid is VlnXmlElement) if (kid.ChildNodes.Count > 1) grp.RemoveChild(kid); kid = tmpkid; } } // Store data in the VlnXmlElement as an RO else if (RecType == (int)RecordType.RRO) { //Create the reader. XmlNode ro; try { XmlTextReader roreader = new XmlTextReader(Info, XmlNodeType.Element, null); ro = ROXml.ReadNode(roreader); } catch (Exception e) { MessageBox.Show(e.Message, "Error reading Xml RRO From data"); reader.Close(); return false; } VlnXmlElement elem = (VlnXmlElement)ro; node.AppendChild(ro); elem.MyROID = RecID; elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); elem.SetAttribute("AccPageID", AccPageID); } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error reading Xml RRO From data"); return false; } dicGroups = null; StatBar.Dispose(); return true; } public override bool RODB_GetChildData(VlnXmlElement node, bool CheckChildCount) { ShowCount.GetChildData++; // get menu fields to display here. string tablename = node.GetAttribute("Table"); try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getChildData"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@ParentID", node.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { ShowCount.Children++; string RecID = reader.GetString(0); MyRecID = RecID; //if (RecID.StartsWith("000300006193")) Console.WriteLine("here"); if (RecID.StartsWith("0003")) Console.WriteLine("here"); if (RecID.EndsWith("6193")) Console.WriteLine("here"); int RecType = reader.GetInt32(1); string AccPageID = reader.GetString(2); string Info = reader.GetString(3); node.SetAttribute("HasChild", "True"); if (RecType == (int)RecordType.Group) { VlnXmlElement elem; try { XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); elem = (VlnXmlElement)nd; } catch (Exception e) { MessageBox.Show(e.Message, "Error Reading Xml Group From Data"); return false; } node.AppendChild(elem); elem.MyROID = RecID; elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); // The Parameter Display Data is stored along with the group. This data // was migrated over so that the data was not lost, but there is no // User Interface to get to it. So remove the xml elements from the // group part of tree. All valid group data only has one sublevel of // data defining the group name. XmlNode grp = (XmlNode)elem; XmlNode kid = grp.FirstChild; XmlNode tmpkid; while (kid != null) { tmpkid = kid.NextSibling; if (kid is VlnXmlElement) if (kid.ChildNodes.Count > 1) grp.RemoveChild(kid); kid = tmpkid; } } // Store data in the VlnXmlElement as an RO else if (RecType == (int)RecordType.RRO) { //Create the reader. XmlNode ro; try { XmlTextReader roreader = new XmlTextReader(Info, XmlNodeType.Element, null); ro = ROXml.ReadNode(roreader); } catch (Exception e) { MessageBox.Show(e.Message, "Error Reading Xml RRO From Data"); return false; } VlnXmlElement elem = (VlnXmlElement)ro; elem.MyROID = RecID; node.AppendChild(ro); elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); elem.SetAttribute("AccPageID", AccPageID); } } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getChildData"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@ParentID", node.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { ShowCount.Children++; string RecID = reader.GetString(0); MyRecID = RecID; //if (RecID.StartsWith("000300006193")) Console.WriteLine("here"); if (RecID.StartsWith("0003")) Console.WriteLine("here"); if (RecID.EndsWith("6193")) Console.WriteLine("here"); int RecType = reader.GetInt32(1); string AccPageID = reader.GetString(2); string Info = reader.GetString(3); node.SetAttribute("HasChild", "True"); if (RecType == (int)RecordType.Group) { VlnXmlElement elem; try { XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); elem = (VlnXmlElement)nd; } catch (Exception e) { MessageBox.Show(e.Message, "Error Reading Xml Group From Data"); return false; } node.AppendChild(elem); elem.MyROID = RecID; elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); // The Parameter Display Data is stored along with the group. This data // was migrated over so that the data was not lost, but there is no // User Interface to get to it. So remove the xml elements from the // group part of tree. All valid group data only has one sublevel of // data defining the group name. XmlNode grp = (XmlNode)elem; XmlNode kid = grp.FirstChild; XmlNode tmpkid; while (kid != null) { tmpkid = kid.NextSibling; if (kid is VlnXmlElement) if (kid.ChildNodes.Count > 1) grp.RemoveChild(kid); kid = tmpkid; } } // Store data in the VlnXmlElement as an RO else if (RecType == (int)RecordType.RRO) { //Create the reader. XmlNode ro; try { XmlTextReader roreader = new XmlTextReader(Info, XmlNodeType.Element, null); ro = ROXml.ReadNode(roreader); } catch (Exception e) { MessageBox.Show(e.Message, "Error Reading Xml RRO From Data"); return false; } VlnXmlElement elem = (VlnXmlElement)ro; elem.MyROID = RecID; node.AppendChild(ro); elem.SetAttribute("RecID", RecID); elem.SetAttribute("ParentID", node.GetAttribute("RecID")); elem.SetAttribute("Table", node.GetAttribute("Table")); elem.SetAttribute("AccPageID", AccPageID); } } } } } } catch (Exception e) { MessageBox.Show(e.Message, "Error Getting Child Data"); return false; } // get child count for each subgroup. if (CheckChildCount) { //Build a Dictionary of Children with Children from the query results HybridDictionary dicChild = new HybridDictionary(); //A different approach - Look for grandchildren and set the haschildren attribute //Build a query to get a list of children with children try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountChildrenOfChildData"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@ParentID", node.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { string tmp = reader.GetString(0); int tmpi = reader.GetInt32(1); dicChild[tmp] = tmpi; } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountChildrenOfChildData"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@ParentID", node.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { string tmp = reader.GetString(0); int tmpi = reader.GetInt32(1); //dicChild[reader.GetString(0)] = reader.GetInt32(1);//This adds the entry and sets the value dicChild[tmp] = tmpi; } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Reading Child Counts"); return false; } XmlNode child = node.FirstChild; while (child != null) //Look at each child node { if (child is VlnXmlElement) { VlnXmlElement echild = (VlnXmlElement)child; if (echild.Name == "vlnGroup") { //If the dictionary contains an entry, the child has children echild.SetAttribute("HasChild", (dicChild.Contains(echild.GetAttribute("RecID"))) ? "True" : "False"); echild.SetAttribute("ChildLoaded", "False"); } } child = child.NextSibling; } dicChild = null; } node.SetAttribute("ChildLoaded", "True"); return true; } public override bool IsDuplicateAccPageID(VlnXmlElement ro, string newacc) { string inacc = null; bool isdup = false; int indx = newacc.IndexOf("'"); if (indx >= 0) inacc = newacc.Insert(indx, "'"); else inacc = newacc; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; if (ro.HasAttribute("RecID")) // new ro's don't have recid defined yet before this test. { command.CommandText = "getCountRecidByAccidNotRecid"; command.Parameters.AddWithValue("RecID", ro.GetAttribute("RecID")); } else command.CommandText = "getCountRecidByAccid"; command.Parameters.AddWithValue("@AccPageID", inacc); command.Parameters.AddWithValue("@ROTable", ro.GetAttribute("Table")); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int cnt = reader.GetInt32(0); if (cnt > 0) isdup = true; else isdup = false; } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on IsDuplicateAccPageID"); return true; } return isdup; } public override VlnXmlElement RODB_ReadRO(string tbl, string recid) { ShowCount.ReadRo++; VlnXmlElement retele = null; if (OnlyConnectOnce) { try { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; if (recid == null) { command.CommandText = "getParidAccidInfoByRectypeParid"; command.Parameters.AddWithValue("@ROTable", tbl); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", 3); } else { command.CommandText = "getParidAccidInfoByRecid"; command.Parameters.AddWithValue("@ROTable", tbl); command.Parameters.AddWithValue("@RecId", recid); } using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { string ParentID = reader.GetString(0); string AccPageID = reader.GetString(1); string Info = reader.GetString(2); // Store data in the VlnXmlElement XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); retele = (VlnXmlElement)nd; retele.SetAttribute("RecID", recid); retele.SetAttribute("ParentID", ParentID); retele.SetAttribute("Table", tbl); if (retele.Name != "vlnGroup") retele.SetAttribute("AccPageID", AccPageID); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on ReadRo"); return null; } } else { try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; if (recid == null) { command.CommandText = "getParidAccidInfoByRectypeParid"; command.Parameters.AddWithValue("@ROTable", tbl); command.Parameters.AddWithValue("@ParentID", "00000000"); command.Parameters.AddWithValue("@RecType", 3); } else { command.CommandText = "getParidAccidInfoByRecid"; command.Parameters.AddWithValue("@ROTable", tbl); command.Parameters.AddWithValue("@RecId", recid); } using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { string ParentID = reader.GetString(0); string AccPageID = reader.GetString(1); string Info = reader.GetString(2); // Store data in the VlnXmlElement XmlTextReader rdr = new XmlTextReader(Info, XmlNodeType.Element, null); XmlNode nd = ROXml.ReadNode(rdr); retele = (VlnXmlElement)nd; retele.SetAttribute("RecID", recid); retele.SetAttribute("ParentID", ParentID); retele.SetAttribute("Table", tbl); if (retele.Name != "vlnGroup") retele.SetAttribute("AccPageID", AccPageID); } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on ReadRo"); return null; } } // if this is a group, see if children. If the RO is not found, return null if (retele != null && retele.Name == "vlnGroup") { if (OnlyConnectOnce) { try { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRecidByParid"; command.Parameters.AddWithValue("@ROTable", tbl); if (recid == null) command.Parameters.AddWithValue("@ParentID", "00000000"); else command.Parameters.AddWithValue("@ParentID", recid); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int cnt = reader.GetInt32(0); if (cnt > 0) retele.SetAttribute("HasChild", "True"); else retele.SetAttribute("HasChild", "False"); } else retele.SetAttribute("HasChild", "False"); retele.SetAttribute("ChildLoaded", "False"); } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on ReadRo"); return null; } } else { try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRecidByParid"; command.Parameters.AddWithValue("@ROTable", tbl); if (recid == null) command.Parameters.AddWithValue("@ParentID", "00000000"); else command.Parameters.AddWithValue("@ParentID", recid); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int cnt = reader.GetInt32(0); if (cnt > 0) retele.SetAttribute("HasChild", "True"); else retele.SetAttribute("HasChild", "False"); } else retele.SetAttribute("HasChild", "False"); retele.SetAttribute("ChildLoaded", "False"); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on ReadRo"); return null; } } } return retele; } public override bool RODB_WriteRO(VlnXmlElement ro, bool movedRO = false) { bool success; if (ro.Name == "vlnGroup") { success = RODB_WriteGroup(ro, ro); return success; } else { string wraccid = null; string accid = ro.GetAttribute("AccPageID"); int quote = accid.IndexOf("'"); if (quote >= 0) wraccid = accid.Insert(quote, "'"); else wraccid = accid; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); string xmlstr = GenerateXmlString(ro, false); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "updateInfoAccidByRecid"; command.Parameters.AddWithValue("@ROTable", ro.GetAttribute("Table")); command.Parameters.AddWithValue("@Info", xmlstr); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@AccPageID", wraccid); // B2020-003: set accpageid to correct value command.Parameters.AddWithValue("@RecID", ro.GetAttribute("RecID")); if (movedRO) { VlnXmlElement parent = (VlnXmlElement)ro.ParentNode; ro.SetAttribute("ParentID", parent.GetAttribute("RecID")); command.Parameters.AddWithValue("@ParentID", ro.GetAttribute("ParentID")); } using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error on Write RO"); success = false; } } return success; } public override bool RODB_InsertRO(VlnXmlElement ro) { bool success = false; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); VlnXmlElement parent = (VlnXmlElement)ro.ParentNode; string lrecid = RODB_GetNextRecId(parent.GetAttribute("Table")); ro.SetAttribute("Table", parent.GetAttribute("Table")); ro.SetAttribute("RecID", lrecid); ro.SetAttribute("ParentID", parent.GetAttribute("RecID")); string haskids = parent.GetAttribute("HasChild"); if (haskids == "False" || haskids == "") { parent.SetAttribute("HasChild", "True"); parent.SetAttribute("ChildLoaded", "True"); } string xmlstr = GenerateXmlString(ro, false); string wraccid = null; if (ro.HasAttribute("AccPageID")) { string accid = ro.GetAttribute("AccPageID"); int quote = accid.IndexOf("'"); if (quote >= 0) wraccid = accid.Insert(quote, "'"); else wraccid = accid; } try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "insertAllRectypes"; if (ro.Name == "vlnGroup") { // add attribute to flag that this does not have xml children, i.e. any // other subgroups or ros under it. ro.SetAttribute("HasChild", "False"); if (ro.HasAttribute("AccPageID")) { command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); command.Parameters.AddWithValue("@AccPageID", wraccid); } else { command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); command.Parameters.AddWithValue("@AccPageID", ""); // B2020-003: set accpageid to correct value } } else { command.Parameters.AddWithValue("@RecType", (int)RecordType.RRO); command.Parameters.AddWithValue("@AccPageID", wraccid); } command.Parameters.AddWithValue("@ROTable", parent.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", ro.GetAttribute("RecID")); command.Parameters.AddWithValue("@ParentID", ro.GetAttribute("ParentID")); command.Parameters.AddWithValue("@Info", xmlstr); command.Parameters.AddWithValue("@ModDateTime", dt); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error on Insert RO"); success = false; } return success; } public override ushort RODB_GetFieldType(VlnXmlElement elem, string TableName, string Fld) { string Info; string RecID; string name; string tmpname; ushort ftype = 0; ROField rof; if (TableName != lastTable) { lastTable = TableName; dicFldTypes = new HybridDictionary(); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectype"; command.Parameters.AddWithValue("@ROTable", TableName); command.Parameters.AddWithValue("@RecType", 2); using (SqlDataReader reader = command.ExecuteReader()) { // NOTE !!!! // This function does not handle Combo type fields (128). while (reader.Read()) { RecID = reader.GetString(0); Info = reader.GetString(1); // it's defined in the local table if the first character is "<" which starts // the schema definition string. if ("<" == Info.Substring(0, 1)) { name = ParseEleName(Info); if (name != null) { tmpname = CvtUserFldToFld(name); rof = new ROField(name, RecID, null, 0); ftype = GetFSTreturnType(System.Convert.ToUInt16(rof.ParseFieldType(Info)), tmpname, elem); dicFldTypes[tmpname] = ftype; } } else { // references master, but what we need is here: the field name and // the the field type. Just parse this from the info field. string parsename; parsename = Info.Substring(13, Info.Length - 13); ftype = GetFSTreturnType(System.Convert.ToUInt16(Info.Substring(9, 3)), parsename, elem); dicFldTypes[parsename] = ftype; } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Field Type"); return 0; } } ftype = ((ushort)dicFldTypes[Fld]); return ftype; } // For the given element's table, get all of the RO fields defined in this table. public override ArrayList RODB_GetFields(VlnXmlElement elem, uint rtype, bool refresh = false) { string table = elem.GetAttribute("Table"); if (!FieldDefinitions.ContainsKey(table)) { FieldDefinitions.Add(table, RODB_GetFieldsFromDB(elem)); } else if (refresh) { FieldDefinitions.Remove(table); FieldDefinitions.Add(table, RODB_GetFieldsFromDB(elem)); } return FieldDefinitions[table]; } private Dictionary _FieldDefinitions = null; public Dictionary FieldDefinitions { get { if (_FieldDefinitions == null) _FieldDefinitions = new Dictionary(); return _FieldDefinitions; } set { _FieldDefinitions = value; } } public ArrayList RODB_GetFieldsFromDB(VlnXmlElement elem) { ArrayList retlist = new ArrayList(); string Info; string RecID; string name; uint ftype; ROField rof; ShowCount.GetFields++; try { if (OnlyConnectOnce) { SqlConnection cn = ROAPP_SqlConnection; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectype"; command.Parameters.AddWithValue("@ROTable", elem.GetAttribute("Table")); command.Parameters.AddWithValue("@RecType", 2); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { ShowCount.RoFields++; RecID = reader.GetString(0); MyRecID = RecID; Info = reader.GetString(1); // it's defined in the local table if the first character is "<" which starts // the schema definition string. if ("<" == Info.Substring(0, 1)) { name = ParseEleName(Info); if (name != null) { // what type of schema element? rof = new ROField(name, RecID, null, 0); ftype = rof.ParseFieldType(Info); rof.SetFieldType(ftype); retlist.Add((object)rof); } } else { // the recid points to a field definition (schema) in the master - use it to get // the schema element from the master and copy it. string parsename; string masterrecid; string strftype; masterrecid = Info.Substring(0, 8); strftype = Info.Substring(9, 3); ftype = System.Convert.ToUInt32(Info.Substring(9, 3)); parsename = CvtFldToUserFld(Info.Substring(13, Info.Length - 13)); // if we have a choice element, remove the last character (it was added to the // field names in order to allow for unique fields names for the choice items. if (ftype == (uint)FieldTypes.Combination) { string tparsename = parsename.Remove((parsename.Length) - 1, 1); // remove the choice string and the space parsename = tparsename; } rof = new ROField(parsename, RecID, masterrecid, ftype); retlist.Add((object)rof); } } } } else { using (SqlConnection cn = ROAPP_SqlConnection) { ShowCount.RoFields++; SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidInfoByRectype"; command.Parameters.AddWithValue("@ROTable", elem.GetAttribute("Table")); command.Parameters.AddWithValue("@RecType", 2); using (SqlDataReader reader = command.ExecuteReader()) { while (reader.Read()) { RecID = reader.GetString(0); MyRecID = RecID; Info = reader.GetString(1); // it's defined in the local table if the first character is "<" which starts // the schema definition string. if ("<" == Info.Substring(0, 1)) { name = ParseEleName(Info); if (name != null) { // what type of schema element? rof = new ROField(name, RecID, null, 0); ftype = rof.ParseFieldType(Info); rof.SetFieldType(ftype); retlist.Add((object)rof); } } else { // the recid points to a field definition (schema) in the master - use it to get // the schema element from the master and copy it. string parsename; string masterrecid; string strftype; masterrecid = Info.Substring(0, 8); strftype = Info.Substring(9, 3); ftype = System.Convert.ToUInt32(Info.Substring(9, 3)); parsename = CvtFldToUserFld(Info.Substring(13, Info.Length - 13)); // if we have a choice element, remove the last character (it was added to the // field names in order to allow for unique fields names for the choice items. if (ftype == (uint)FieldTypes.Combination) { string tparsename = parsename.Remove((parsename.Length) - 1, 1); // remove the choice string and the space parsename = tparsename; } rof = new ROField(parsename, RecID, masterrecid, ftype); retlist.Add((object)rof); } } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Fields"); return null; } return retlist; } public override string RODB_GetSchemaPiece(string Recid, string table) { string Info; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByRecid"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecID", Recid); using (SqlDataReader reader = command.ExecuteReader()) { if (DBE.Read()) Info = reader.GetString(0); else Info = null; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Schema Piece"); return null; } return Info == null ? null : Info.Replace("'", "\'"); } public override bool RODB_NewSchemaPiece(string recid, string parentid, string table, string schpiece, uint rtype) { bool success = true; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "insertAllRectypes"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@RecID", recid); command.Parameters.AddWithValue("@RecType", 2); command.Parameters.AddWithValue("@ParentID", parentid); command.Parameters.AddWithValue("@AccPageID", ""); // B2020-003: set accpageid to correct value command.Parameters.AddWithValue("@Info", schpiece.Replace("\'", "'")); command.Parameters.AddWithValue("@ModDateTime", dt); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error on New Schema Piece"); success = false; } return success; } public override bool RODB_WriteSchemaPiece(string Recid, string table, string schpiece) { bool success = true; string dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "updateInfoByRecid"; command.Parameters.AddWithValue("@ROTable", table); command.Parameters.AddWithValue("@Info", schpiece.Replace("\'", "'")); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecID", Recid); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } catch (Exception e) { MessageBox.Show(e.Message, "Error on Write Schema Piece"); success = false; } return success; } public override bool RODB_ProcessRROFieldChange(VlnXmlElement child, string oldname, string newname, uint editlevel, VlnStatusMessage StatMsgWindow, bool combofield) { bool success = false; string info; string tinfo1, tinfo2, tinfo3, tinfo4; string dt; string onameOpen, nnameOpen, onameClose, nnameClose, onameComma, nnameComma; string onameOpenX, nnameOpenX; onameOpen = "<" + oldname + ">"; nnameOpen = "<" + newname + ">"; onameOpenX = "<" + oldname + ">"; nnameOpenX = "<" + newname + ">"; onameComma = "<" + oldname + ","; // if format in attribute nnameComma = "<" + newname + ","; onameClose = ""; nnameClose = ""; dt = string.Format("{0:yyyyMMddHHmmss}", System.DateTime.Now); // first do the string replace for the group node. This will change any // attributes which may have changed. try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByRecid"; command.Parameters.AddWithValue("@ROTable", child.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", child.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) info = reader.GetString(0); else info = null; } } tinfo1 = info.Replace(onameOpen, nnameOpen); tinfo2 = tinfo1.Replace(onameClose, nnameClose); tinfo3 = tinfo2.Replace(onameComma, nnameComma); tinfo4 = tinfo3.Replace(onameOpenX, nnameOpenX); if (tinfo4 != info) { StatMsgWindow.StatusMessage = child.GetAttribute("MenuTitle"); using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "updateInfoByRecid"; command.Parameters.AddWithValue("@ROTable", child.GetAttribute("Table")); command.Parameters.AddWithValue("@Info", tinfo4); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecID", child.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } if (child.Name == "vlnGroup" && child.ParentNode.Name != "RO_Root") { XmlNodeList nodeList; nodeList = child.SelectNodes(oldname); foreach (XmlNode nod in nodeList) { XmlNode newnode = ROXml.CreateNode(XmlNodeType.Element, newname, ""); newnode.InnerXml = nod.InnerXml; child.ReplaceChild(newnode, nod); } } // if at top, replace strings in attributes for xml node. Only needs done // for top node because remainder are done in xml string replace for entire // node and written to database, but XML tree is deleted from memory and // reread in as needed. if (child.ParentNode.Name == "RO_Root") { string tmp, tmp1; tmp = child.GetAttribute("RetVal"); if (tmp != null) { tmp1 = tmp.Replace(onameOpen, nnameOpen); child.SetAttribute("RetVal", tmp1); } tmp = child.GetAttribute("MenuItem"); if (tmp != null) { string conameOpen = "<" + oldname + ","; string cnnameOpen = "<" + newname + ","; tmp1 = tmp.Replace(onameOpen, nnameOpen); string tmp2 = tmp1.Replace(conameOpen, cnnameOpen); child.SetAttribute("MenuItem", tmp2); } tmp = child.GetAttribute("AccPageID"); if (tmp != null) { tmp1 = tmp.Replace(onameOpen, nnameOpen); child.SetAttribute("AccPageID", tmp1); } tmp = child.GetAttribute("GroupMenuItem"); if (tmp != null) { tmp1 = tmp.Replace(onameOpen, nnameOpen); child.SetAttribute("GroupMenuItem", tmp1); } } } // if this was an RO field definition change, need to go through the XML for // the ROs too. if (editlevel == (int)RecordType.Schema) { XmlNode chldnode = (XmlNode)child.FirstChild; VlnXmlElement echild; while (chldnode != null) { if (chldnode is VlnXmlElement) { echild = (VlnXmlElement)chldnode; if (echild.Name != "vlnGroup") { // If this is a group definition subtree it will only have one // child, which is the text definition for the subgroup. Don't // include these in the tree. int levelCnt = chldnode.ChildNodes.Count; string TheMenuTitle = echild.GetAttribute("MenuTitle"); if ((levelCnt >= 1) && !TheMenuTitle.Equals("")) { // read record, do string replace in info & write record. Also, replace // the xml node with a node with the new name. using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByRecid"; command.Parameters.AddWithValue("@ROTable", echild.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", echild.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) info = reader.GetString(0); else info = null; } } if (combofield == false) { tinfo1 = info.Replace(onameOpen, nnameOpen); tinfo1 = DoReplaceParentChildField(tinfo1, onameOpen, nnameOpen); //C2021-0226 also update Parent/Child fields tinfo2 = tinfo1.Replace(onameClose, nnameClose); tinfo2 = DoReplaceParentChildField(tinfo2, onameClose, nnameClose); //C2021-0226 also update Parent/Child fields XmlNodeList nodeList; nodeList = echild.SelectNodes(oldname); foreach (XmlNode nod in nodeList) { XmlNode newnode = ROXml.CreateNode(XmlNodeType.Element, newname, ""); newnode.InnerXml = nod.InnerXml; echild.ReplaceChild(newnode, nod); } } else // need a,b,c,d yikes { string nma, nmb, nmc, nmd; nma = DoCmbFieldReplace(info, onameOpen, nnameOpen, "a"); nmb = DoCmbFieldReplace(nma, onameOpen, nnameOpen, "b"); nmc = DoCmbFieldReplace(nmb, onameOpen, nnameOpen, "c"); nmd = DoCmbFieldReplace(nmc, onameOpen, nnameOpen, "d"); nma = DoCmbFieldReplace(nmd, onameClose, nnameClose, "a"); nmb = DoCmbFieldReplace(nma, onameClose, nnameClose, "b"); nmc = DoCmbFieldReplace(nmb, onameClose, nnameClose, "c"); tinfo2 = DoCmbFieldReplace(nmc, onameClose, nnameClose, "d"); // replace the combo nodes with the new name, do a-d in case there are more than // one value field stored for this combo type for (char tmplet = 'a'; tmplet < 'e'; tmplet++) { XmlNodeList nodeList; nodeList = echild.SelectNodes(oldname + tmplet.ToString()); foreach (XmlNode nod in nodeList) { XmlNode newnode = ROXml.CreateNode(XmlNodeType.Element, newname + tmplet, ""); newnode.InnerXml = nod.InnerXml; echild.ReplaceChild(newnode, nod); } } } StatMsgWindow.StatusMessage = echild.GetAttribute("MenuTitle"); using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "updateInfoByRecid"; command.Parameters.AddWithValue("@ROTable", echild.GetAttribute("Table")); command.Parameters.AddWithValue("@Info", tinfo2); command.Parameters.AddWithValue("@ModDateTime", dt); command.Parameters.AddWithValue("@RecID", echild.GetAttribute("RecID")); using (SqlDataReader reader = command.ExecuteReader()) { success = true; } } } } } chldnode = chldnode.NextSibling; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Processing RRO Field Change"); success = false; } return success; } public override bool RODB_UpdateFieldRecord(ROField myrof, VlnXmlElement myelem, string strschema, string oldname, string newname, uint editlevel, bool combofield) { bool success = false; // If this is a generic definition that was modified, i.e. from ROMaster, ask // the user whether to update the generic field definition or make it local. if (myrof.GetMasterRecID != null) { // if field is defined in the ROMaster, and we change the field name - // first check if it is using one of the names used to define new // setpoint or graphics databases. If so, make it a local change only! bool changegeneric = true; if (oldname != newname) { // if this is one of the standard names - don't let them save it. bool isused = RODB_CheckForStandardName(oldname); if (isused == true) { MessageBox.Show("The field name is used to define new Setpoints or Graphics Database.\n The update will be for this local (database) group only.", "Field name modification."); changegeneric = false; } } // if standard name, from above check, don't ask user if it is generic // or not. if (changegeneric != false) { System.Windows.Forms.DialogResult result = MessageBox.Show("Update Generic definition?", "Referenced Object Definition", MessageBoxButtons.YesNo, MessageBoxIcon.Question); if (result == DialogResult.No) changegeneric = false; } if (changegeneric == true) { success = RODB_WriteSchemaPiece(myrof.GetMasterRecID, "ROMaster", strschema); if (success != true) return false; // if change in fieldname, need to go through all of the databases (tables) to // adjust for it. if (oldname != newname) { VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Status of RO Field Change"); // get root xml element // loop through each subgroup under root. VlnXmlElement topgroup; topgroup = (VlnXmlElement)ROXml.FirstChild.FirstChild; string sqlstr, recid, tbl; while (topgroup != null) { tbl = topgroup.GetAttribute("Table"); // get the recid of this field definition from the current table. try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getRecidByRectypeInfo"; command.Parameters.AddWithValue("@ROTable", tbl); command.Parameters.AddWithValue("@RecType", 2); command.Parameters.AddWithValue("@Info", myrof.GetMasterRecID + "%"); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { recid = reader.GetString(0); } else recid = null; } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Group Schema"); return false; } if (recid != null) { // update the local field definition record StringBuilder strbld = new StringBuilder(); strbld.Append(myrof.GetMasterRecID); strbld.Append(" "); string strtype = myrof.GetFieldType.ToString(); strbld.Append(strtype.PadLeft(3, '0')); strbld.Append(" "); strbld.Append(myrof.MakeFieldName(myrof.GetFieldname)); success = RODB_WriteSchemaPiece(recid, topgroup.GetAttribute("Table"), strbld.ToString()); topgroup.SetAttribute("TreeNotData", "True"); // Update subelements too. if (success == true) success = RODB_UpdateFieldNames(topgroup, recid, oldname, newname, editlevel, false, StatMsgWindow, combofield); topgroup = (VlnXmlElement)topgroup.NextSibling; } } StatMsgWindow.Dispose(); } } else // change local { // modify the current to have the definition local. success = RODB_WriteSchemaPiece(myrof.GetRecID, myelem.GetAttribute("Table"), strschema); // get top group node in tree. and from there process fields if // there was a change in fieldname text if (success == true && oldname != newname) { VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Status of RO Field Change"); // get top node - the one immediately below the RO_Root. VlnXmlElement parent, startEle; parent = myelem; startEle = myelem; while (parent.Name != "RO_Root") { startEle = parent; parent = (VlnXmlElement)parent.ParentNode; } startEle.SetAttribute("TreeNotData", "True"); success = RODB_UpdateFieldNames(startEle, myrof.GetRecID, oldname, newname, editlevel, false, StatMsgWindow, combofield); StatMsgWindow.Dispose(); } } } else { success = RODB_WriteSchemaPiece(myrof.GetRecID, myelem.GetAttribute("Table"), strschema); // changed the fieldname, change xml text. if (success == true && oldname != newname) { VlnStatusMessage StatMsgWindow = new VlnStatusMessage("Status of RO Field Change"); // get top node - the one immediately below the RO_Root. VlnXmlElement parent, startEle; parent = myelem; startEle = myelem; while (parent.Name != "RO_Root") { startEle = parent; parent = (VlnXmlElement)parent.ParentNode; } startEle.SetAttribute("TreeNotData", "True"); success = RODB_UpdateFieldNames(startEle, myrof.GetRecID, oldname, newname, editlevel, false, StatMsgWindow, combofield); StatMsgWindow.Dispose(); } } return success; } public override XmlSchema RODB_GetGroupSchema(VlnXmlElement elem) { XmlSchema myschema; VlnXmlElement parent; string entireschema; // if at top of tree, use this group schema information (fields in use). but if not, // the parent node defines the schema for the subgroups. if (elem.ParentNode.Name == "RO_Root") parent = elem; else parent = elem; while (parent != null) { if (parent.HasAttribute("GroupFieldsInUse") == true) break; // if we've looped to the top, just set the parent to null. (B2004-015) if (parent.ParentNode is VlnXmlElement) parent = (VlnXmlElement)parent.ParentNode; else parent = null; } if (parent == null) return null; // The group schema never gets saved as an attribute. it's always read in, because // it's not used as often as the ro schema. So for the Group Schema, we're looking // for 'GroupFieldsInUse'. // otherwise, read in schema definitions for those 'FieldsInUse'. entireschema = null; string GroupFieldsInUse = parent.GetAttribute("GroupFieldsInUse"); int strpos = 0; string Info = null; // For each item in use, get its xmlschema text. If unique to this group, the definition // exists local to this table. Otherwise, go back to the master. string recid; recid = GroupFieldsInUse.Substring(0, 8); while (recid != null) { try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByRecid"; command.Parameters.AddWithValue("@ROTable", elem.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", recid); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { Info = reader.GetString(0); } } if (Info != null) { // if the info string has "<", i.e. an opening XML schema bracket, use // this text as the field definition, otherwise, go to the master to get it if ("<" == Info.Substring(0, 1)) entireschema = entireschema + Info; // use this field definition, else get from the master. else { string recidpart = Info.Substring(0, 8); string localfieldname = Info.Substring(13, Info.Length - 13); SqlCommand command1 = new SqlCommand(); command1.Connection = cn; command1.CommandType = CommandType.StoredProcedure; command1.CommandText = "getInfoByRecid"; command1.Parameters.AddWithValue("@ROTable", "RoMaster"); command1.Parameters.AddWithValue("@RecID", recidpart); using (SqlDataReader reader1 = command1.ExecuteReader()) { if (reader1.Read()) { Info = reader1.GetString(0); entireschema = entireschema + Info; } } } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Group Schema"); return null; } strpos = strpos + 9; if (strpos > GroupFieldsInUse.Length) recid = null; else recid = GroupFieldsInUse.Substring(strpos, 8); } entireschema = schemastart + entireschema + schemaend; XmlTextReader schemareader = new XmlTextReader(entireschema, XmlNodeType.Element, null); try { myschema = XmlSchema.Read(schemareader, null); return myschema; } catch (Exception e) { MessageBox.Show(e.Message, "Schema Error"); return null; } } public override XmlSchema RODB_GetSchema(VlnXmlElement elem) { XmlSchema myschema; VlnXmlElement parent; string entireschema; XmlNode nparent; nparent = elem; if (nparent is VlnXmlDocument) { // at top already. use this one. parent = elem; } else { parent = (VlnXmlElement)nparent; while (parent != null) { if (parent.HasAttribute("Schema") == true) break; if (parent.HasAttribute("FieldsInUse") == true) break; parent = (VlnXmlElement)parent.ParentNode; } } // if the schema has already been read in, just use it from the schema attribute, // otherwise, read in schema definitions for those 'FieldsInUse'. if (parent.HasAttribute("Schema")) { entireschema = parent.GetAttribute("Schema"); } else { entireschema = null; string FieldsInUse = parent.GetAttribute("FieldsInUse"); int strpos = 0; string Info = null; // For each item in use, get its xmlschema text. If unique to this group, the definition // exists local to this table. Otherwise, go back to the master. string recid; recid = FieldsInUse.Substring(0, 8); while (recid != null) { try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getInfoByRecid"; command.Parameters.AddWithValue("@ROTable", elem.GetAttribute("Table")); command.Parameters.AddWithValue("@RecID", recid); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { Info = reader.GetString(0); } } if (Info != null) { // if the info string has "<", i.e. an opening XML schema bracket, use // this text as the field definition, otherwise, go to the master to get // it. if ("<" == Info.Substring(0, 1)) { // use this field definition, else get from the master. entireschema = entireschema + Info; } else { string recidpart = Info.Substring(0, 8); string localfieldname = Info.Substring(13, Info.Length - 13); SqlCommand command1 = new SqlCommand(); command1.Connection = cn; command1.CommandType = CommandType.StoredProcedure; command1.CommandText = "getInfoByRecid"; command1.Parameters.AddWithValue("@ROTable", "RoMaster"); command1.Parameters.AddWithValue("@RecID", recidpart); using (SqlDataReader reader1 = command1.ExecuteReader()) { if (reader1.Read()) { // check if field name is same, if not, use local name. string goodname; Info = reader1.GetString(0); int indx1 = Info.IndexOf("\""); int indx2 = Info.IndexOf("\"", indx1 + 1); string masterfieldname = Info.Substring(indx1 + 1, indx2 - indx1 - 1); if (localfieldname != masterfieldname) goodname = Info.Replace(masterfieldname, localfieldname); else goodname = Info; entireschema = entireschema + goodname; } } } strpos = strpos + 9; if (strpos > FieldsInUse.Length) recid = null; else recid = FieldsInUse.Substring(strpos, 8); } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Schema"); return null; } } // C2021-026 read in schema for the "ApplicabilityEnabled" attribute entireschema = schemastart + entireschema + schemaend; } XmlTextReader schemareader = new XmlTextReader(entireschema, XmlNodeType.Element, null); try { myschema = XmlSchema.Read(schemareader, null); parent.SetAttribute("Schema", entireschema); return myschema; } catch (Exception e) { MessageBox.Show(e.Message, "Schema Read Error"); return null; } } public override int RODB_GetNumberOfROValueRecords(string tablename) { int ROCnt = 0; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRectypeByRectype"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@RecType", (int)RecordType.RRO); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { ROCnt = reader.GetInt32(0); } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Number of RO Value Records"); return 0; } return ROCnt; } public override int RODB_GetNumberOfGroupRecords(string tablename) { int GrpCnt = 0; try { using (SqlConnection cn = ROAPP_SqlConnection) { SqlCommand command = new SqlCommand(); command.Connection = cn; command.CommandType = CommandType.StoredProcedure; command.CommandText = "getCountRectypeByRectype"; command.Parameters.AddWithValue("@ROTable", tablename); command.Parameters.AddWithValue("@RecType", (int)RecordType.Group); using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { GrpCnt = reader.GetInt32(0); } } } } catch (Exception ex) { MessageBox.Show(ex.Message, "Error Getting Number of Group Value Records"); return 0; } return GrpCnt; } #endregion public static bool TestConnect(string constring) { bool success = false; using (SqlConnection connection = new SqlConnection(constring)) { try { connection.Open(); if (connection.State == ConnectionState.Open) { // now see if there is an roall table SqlCommand command = new SqlCommand(); command.Connection = connection; command.CommandType = CommandType.Text; command.CommandText = "SELECT count(*) FROM roall"; using (SqlDataReader reader = command.ExecuteReader()) { if (reader.Read()) { int count = reader.GetInt32(0); if (count > 0) success = true; } } } } catch (Exception ex) { } } return success; } public static string GetSqlDbConnectString(string origConString) { string value = origConString; InputBox inpbox = new InputBox(origConString); DialogResult dr = inpbox.ShowDialog(); if (dr == DialogResult.OK) { // test & if successful, save and return: if (TestConnect(inpbox.ResultConnectString)) return inpbox.ResultConnectString; } return null; } public override bool RODB_WriteSqlConnectToAccess(string newConectStr) { return false; } } }