/// <summary> /// Creates a page in a specified view /// </summary> /// <old-param name="pageposition">Position of the page</old-param> /// <old-param name="viewid">Id of the view</old-param> /// <old-param name="pagename">Name of the page</old-param> public void InsertPage(Page page) { try { #region Input Validation if (page == null) { throw new ArgumentNullException("page"); } #endregion Input validation Query query = db.CreateQuery("insert into metaPages([Name], [Position], [ViewId], [CheckCodeBefore], [CheckCodeAfter], [BackgroundId]) values (@Name, @Position, @ViewId, @CheckCodeBefore, @CheckCodeAfter, @BackgroundId)"); query.Parameters.Add(new QueryParameter("@Name", DbType.String, page.Name)); query.Parameters.Add(new QueryParameter("@Position", DbType.Int32, page.Position)); query.Parameters.Add(new QueryParameter("@ViewId", DbType.Int32, page.GetView().Id)); query.Parameters.Add(new QueryParameter("@CheckCodeBefore", DbType.String, page.CheckCodeBefore)); query.Parameters.Add(new QueryParameter("@CheckCodeAfter", DbType.String, page.CheckCodeAfter)); query.Parameters.Add(new QueryParameter("@BackgroundId", DbType.Int32, page.BackgroundId)); db.ExecuteNonQuery(query); page.Id = GetMaxPageId(page.GetView().Id); } catch (Exception ex) { throw new GeneralException("Could not create page in the database", ex); } finally { } }
/// <summary> /// Deletes a page from the Xml metadata project file /// </summary> /// <param name="page">Id of the page</param> public void DeletePage(Page page) { try { #region Input Validation if (page.Id < 1) { throw new ArgumentOutOfRangeException("PageId"); } #endregion XmlDocument doc = GetXmlDocument(); XmlNode pagesNode = GetPagesNode(page.GetView().ViewElement); XmlNode pageNode = pagesNode.SelectSingleNode("//Page[@PageId= '" + page.Id + "']"); pageNode.ParentNode.RemoveChild(pageNode); Save(); } catch (Exception ex) { throw new GeneralException("Could not delete page in the database", ex); } finally { } }
/// <summary> /// Creates a page in a specified view /// </summary> /// <old-param name="pageposition">Position of the page</old-param> /// <old-param name="viewid">Id of the view</old-param> /// <old-param name="pagename">Name of the page</old-param> public void InsertPage(Page page) { try { #region Input Validation if (page == null) { throw new ArgumentNullException("page"); } #endregion Input validation XmlDocument doc = GetXmlDocument(); XmlNode pagesNode = GetPagesNode(page.GetView().ViewElement); CreatePage(page.GetView(), page.Name, page.Position); XmlNode pageNode = pagesNode.SelectSingleNode("//Page[@PageId= '" + page.Id + "']"); page.Id = GetMaxPageId(page.GetView().Id) + 1; pageNode.Attributes["PageId"].Value = page.Id.ToString(); Save(); //Query query = db.CreateQuery("insert into metaPages([Name], [Position], [ViewId], [CheckCodeBefore], [CheckCodeAfter]) values (@Name, @Position, @ViewId, @CheckCodeBefore, @CheckCodeAfter)"); //query.Parameters.Add(new QueryParameter("@Name", DbType.String, page.Name)); //query.Parameters.Add(new QueryParameter("@Position", DbType.Int32, page.Position)); //query.Parameters.Add(new QueryParameter("@ViewId", DbType.Int32, page.GetView().Id)); //query.Parameters.Add(new QueryParameter("@CheckCodeBefore", DbType.String, page.CheckCodeBefore)); //query.Parameters.Add(new QueryParameter("@CheckCodeAfter", DbType.String, page.CheckCodeAfter)); //db.ExecuteNonQuery(query); //page.Id = GetMaxPageId(page.GetView().Id); } catch (Exception ex) { throw new GeneralException("Could not create page in the database", ex); } finally { } }
/// <summary> /// Deletes fields on a page from the Xml metadata project file /// </summary> /// <param name="page"></param> public void DeleteFields(Page page) { try { XmlDocument doc = GetXmlDocument(); XmlNode fieldsNode = GetFieldsNode(page.GetView().ViewElement); XmlNodeList nodeList = fieldsNode.SelectNodes("Field[@PageId = '" + page.Id + "']"); foreach (XmlNode node in nodeList) { node.ParentNode.RemoveChild(node); } Save(); } catch (Exception ex) { throw new GeneralException("Could not delete fields in the database", ex); } finally { } }
/// <summary> /// Constructor /// </summary> /// <param name="page">The page the field belongs to</param> public RenderableField(Page page) : base(page.GetView()) { this.page = page; }
/// <summary> /// Converts a field /// </summary> /// <param name="fieldRow">A field record from the legacy database</param> /// <param name="page">A page object</param> /// <param name="tableName">Name of the view table in EI 3.x</param> private void CopyField(DataRow fieldRow, Page page, string tableName) { RenderableField field = null; try { bool FieldHasBeforeCheckCode = false; bool FieldHasAfterCheckCode = false; bool FieldHasClickCheckCode = false; string ckBefore = String.Empty; string ckAfter = String.Empty; MetaFieldType fieldType = Epi.Epi2000.MetadataDbProvider.InferFieldType(fieldRow); field = (RenderableField)page.CreateField(fieldType); if (field is GridField) { // Grids not supported in initial 7.0.7 release Logger.Log(DateTime.Now + ": " + string.Format(SharedStrings.IMPORT_WARNING_GRID_NOT_SUPPORTED, field.Name)); return; } // Field Name string fieldName = fieldRow[ColumnNames.NAME].ToString(); // KKM4 - Commented out to test the requirement of Reserved words. //if (Epi.Data.Services.AppData.Instance.IsReservedWord(fieldName)) //{ // throw new ReservedWordException(fieldName); //} //else //{ // field.Name = fieldName; //} field.Name = fieldName; // ControlFont if (!string.IsNullOrEmpty(fieldRow["Ffont"].ToString())) { if (!string.IsNullOrEmpty(fieldRow["Ffontsize"].ToString())) { if (float.Parse(fieldRow["Ffontsize"].ToString()) > 0) { field.ControlFont = new System.Drawing.Font(fieldRow["Ffont"].ToString(), float.Parse(fieldRow["Ffontsize"].ToString())); } } } // ControlHeightPercentage if (fieldRow["Fsize"] != DBNull.Value) { field.ControlHeightPercentage = (double)fieldRow["Fsize"]; } // ControlLeftPositionPercentage if (fieldRow["Flocx"] != DBNull.Value) { field.ControlLeftPositionPercentage = ((double)fieldRow["Flocx"]) / 100; } // ControlTopPositionPercentage if (fieldRow["Flocy"] != DBNull.Value) { field.ControlTopPositionPercentage = ((double)fieldRow["Flocy"]) / 100; } // ControlWidthPercentage if (fieldRow["Dsize"] != DBNull.Value) { field.ControlWidthPercentage = (double)fieldRow["Dsize"]; } // HasTabStop field.HasTabStop = true; // Prompt if (fieldRow["Prompt"] != DBNull.Value) { field.PromptText = fieldRow["Prompt"].ToString(); } // TabIndex if (fieldRow["Taborder"] != DBNull.Value) { field.TabIndex = int.Parse(fieldRow["Taborder"].ToString()); } // Check Code if (fieldRow[ColumnNames.CHECK_CODE] != DBNull.Value) { string checkCode = fieldRow[ColumnNames.CHECK_CODE].ToString(); Epi.Epi2000.MetadataDbProvider.SplitCheckCode(checkCode, ref ckBefore, ref ckAfter); if (field is IFieldWithCheckCodeAfter) { if (!string.IsNullOrEmpty(ckAfter)) { FieldHasAfterCheckCode = true; } } if (field is IFieldWithCheckCodeBefore) { if (!string.IsNullOrEmpty(ckBefore)) { FieldHasBeforeCheckCode = true; } } if (field is CommandButtonField) { if (!string.IsNullOrEmpty(ckAfter)) { FieldHasClickCheckCode = true; } } } if (FieldHasBeforeCheckCode || FieldHasAfterCheckCode || FieldHasClickCheckCode) { CheckCode.Append("\nField "); if (field.Name.Trim().IndexOf(' ') > -1) { CheckCode.Append("["); CheckCode.Append(field.Name.Trim()); CheckCode.Append("]"); } else { CheckCode.Append(field.Name.Trim()); } if (FieldHasBeforeCheckCode) { CheckCode.Append("\n\tBefore\n\t\t"); CheckCode.Append(ckBefore.Replace("\n", "\n\t\t")); CheckCode.Append("\n\tEnd-Before\n"); } if (FieldHasAfterCheckCode) { CheckCode.Append("\n\tAfter\n\t\t"); CheckCode.Append(ckAfter.Replace("\n", "\n\t\t")); CheckCode.Append("\n\tEnd-After\n"); } if (FieldHasClickCheckCode) { CheckCode.Append("\n\tClick\n\t\t"); CheckCode.Append(ckAfter.Replace("\n","\n\t\t")); CheckCode.Append("\n\tEnd-Click\n"); } CheckCode.Append("End-Field\n"); } if (field is FieldWithSeparatePrompt) { // PromptLeftPositionPercentage if (fieldRow["Plocx"] != DBNull.Value) { ((FieldWithSeparatePrompt)field).PromptLeftPositionPercentage = double.Parse(fieldRow["Plocx"].ToString()) / 100; } // PromptTopPositionPercentage if (fieldRow["Plocy"] != DBNull.Value) { ((FieldWithSeparatePrompt)field).PromptTopPositionPercentage = double.Parse(fieldRow["Plocy"].ToString()) / 100; } // PromptFont if (fieldRow["Pfont"] != DBNull.Value) { ((FieldWithSeparatePrompt)field).PromptFont = new System.Drawing.Font(fieldRow["Pfont"].ToString(), float.Parse(fieldRow["Pfontsize"].ToString())); } } if (field is IInputField) { string lists = fieldRow["Lists"].ToString().Trim(); int parenPos = lists.IndexOf('('); if (parenPos < 0) { parenPos = lists.Length; } lists = lists.Substring(0, parenPos).ToUpper().Trim(); if (!string.IsNullOrEmpty(lists)) { ((IInputField)field).IsRequired = lists.Contains("M"); ((IInputField)field).IsReadOnly = lists.Contains("N"); ((IInputField)field).ShouldRepeatLast = lists.Contains("R"); } } if (field is ImageField) { ((ImageField)field).ShouldRetainImageSize = false; } if (field is LabelField) { if (fieldRow["Plocx"] != DBNull.Value) { field.ControlLeftPositionPercentage = double.Parse(fieldRow["Plocx"].ToString()) / 100; } if (fieldRow["Plocy"] != DBNull.Value) { field.ControlTopPositionPercentage = double.Parse(fieldRow["Plocy"].ToString()) / 100; } if ((fieldRow["Pfont"] != DBNull.Value) && (fieldRow["Pfontsize"] != DBNull.Value)) { field.ControlFont = new System.Drawing.Font(fieldRow["Pfont"].ToString(), float.Parse(fieldRow["Pfontsize"].ToString())); } } if (field is TableBasedDropDownField) { ((TableBasedDropDownField)field).SourceTableName = GetCodeTableName(fieldRow["Lists"].ToString(), tableName); ((TableBasedDropDownField)field).TextColumnName = GetCodeTableTextField(fieldRow["Lists"].ToString()); } if (field is DDLFieldOfCodes) { ((DDLFieldOfCodes)field).CodeColumnName = GetCodeTableValueField(fieldRow["Lists"].ToString()); if (!(field is DDLFieldOfCommentLegal) && !(field is DDLFieldOfLegalValues)) { ((DDLFieldOfCodes)field).AssociatedFieldInformation = GetCodeTableAssociatedFields(fieldRow["Lists"].ToString(), field.GetView()); } } if (field is MirrorField) { ((MirrorField)field).SourceFieldId = 1; } if (field is RelatedViewField) { // Relate Condition if (fieldRow["FormatString"] != DBNull.Value) { ((RelatedViewField)field).Condition = (fieldRow["FormatString"].ToString()); } ((RelatedViewField)field).RelatedViewID = 1; // this will be re-set later during CopyViewRelations() } if (field is NumberField) { if (fieldRow["FormatString"] != DBNull.Value) { Match m = Regex.Match(fieldRow["FormatString"].ToString(), "[;]"); if (m.Success) { string[] pattern = (fieldRow["FormatString"].ToString()).Split(';'); ((NumberField)field).Pattern = pattern[1]; } else { ((NumberField)field).Pattern = (fieldRow["FormatString"].ToString()); } } } else if (field is PhoneNumberField) { if (fieldRow["FormatString"] != DBNull.Value) { Match m = Regex.Match(fieldRow["FormatString"].ToString(), "[;]"); if (m.Success) { string[] pattern = (fieldRow["FormatString"].ToString()).Split(';'); ((PhoneNumberField)field).Pattern = pattern[1]; } else { ((PhoneNumberField)field).Pattern = (fieldRow["FormatString"].ToString()); } } } else if (field is TextField) { if (fieldRow["FormatString"] != DBNull.Value) { int maxLength = 0; if (Int32.TryParse(fieldRow["FormatString"].ToString(), out maxLength) && maxLength > 0) { ((TextField)field).MaxLength = maxLength; } } } else if (field is GroupField) { if (fieldRow["Plocx"] != DBNull.Value) { field.ControlLeftPositionPercentage = double.Parse(fieldRow["Plocx"].ToString()) / 100; } if (fieldRow["Plocy"] != DBNull.Value) { field.ControlTopPositionPercentage = double.Parse(fieldRow["Plocy"].ToString()) / 100; } if (fieldRow["Flocx"] != DBNull.Value) { field.ControlWidthPercentage = double.Parse(fieldRow["Flocx"].ToString()); } if (fieldRow["Flocy"] != DBNull.Value) { field.ControlHeightPercentage = double.Parse(fieldRow["Flocy"].ToString()); } string[] items = fieldRow["Lists"].ToString().Split(';'); ((GroupField)field).ChildFieldNames = string.Join(",", items); } else if (field is OptionField) { string[] items = fieldRow["Lists"].ToString().Split(';'); // TODO: We have to strip the commas out because that's how the values are delimited in Epi 7 now. Later, change how this is delimited (and thus we need to remove this code at that point). if (fieldRow["Lists"].ToString().Contains(",")) { for (int i = 0; i < items.Length; i++) { items[i] = items[i].Replace(",", string.Empty); } } ((OptionField)field).Options = new System.Collections.Generic.List<string>(); ((OptionField)field).Options.AddRange(items); } if (field is CheckBoxField) { AdjustCheckboxWidth(field); } field.SaveToDb(); if (field is GridField) { DataTable columns = sourceProject.Metadata.GetGridColumns(fieldRow["Ffont"].ToString()); foreach (DataRow column in columns.Rows) { MetaFieldType columnType = Epi.Epi2000.MetadataDbProvider.InferFieldType(column); GridColumnBase gridColumn = ((GridField)field).CreateGridColumn(columnType); gridColumn.Name = column[ColumnNames.NAME].ToString(); gridColumn.Text = column["Prompt"].ToString(); gridColumn.Width = int.Parse(column["Dsize"].ToString()); gridColumn.SaveToDb(); } } // Raise Import status event string fieldDisplayName = page.DisplayName + "::" + field.Name; RaiseEventProgressBarStep(); MessageEventArgs args = new MessageEventArgs(fieldDisplayName + StringLiterals.ELLIPSIS, false); RaiseEventImportStatus(fieldDisplayName + StringLiterals.ELLIPSIS, args); } catch (Exception e) { Logger.Log(DateTime.Now + ": " + string.Format(SharedStrings.IMPORT_ERROR_BAD_METADATA_IN_FIELD, field.Name, page.GetView().Name)); string message = string.Format(SharedStrings.IMPORT_BAD_FIELD_DATA, field.Name, page.Name, page.GetView().Name); throw new GeneralException(message, e); } finally { } }
/// <summary> /// Updates option field data in the destination view's data table to match /// Epi Info 7 format for option fields. /// </summary> /// <param name="page">A page in the destination view</param> private void UpdateOptionFields(Page page) { // Epi Info 7 stores data for option fields as integers, with 0 being the 1st option, 2 for the second option, etc. Epi Info 3 just // stores the literal text value that the user selected. We must convert from Epi 3 format to Epi 7 format otherwise we'll wind up with // errors on import. TODO: Check for SQL server compliance; likely SQL server will behave differently than Access-to-Access imports. try { string viewNameWithPrefix = "view" + page.GetView().Name; string tableName = page.GetView().TableName; DataTable fieldsTable = sourceProject.Metadata.GetFieldsOnPageAsDataTable(viewNameWithPrefix, page.Position); // iterate over all fields in the page foreach (DataRow fieldRow in fieldsTable.Rows) { // find the field type MetaFieldType fieldType = Epi.Epi2000.MetadataDbProvider.InferFieldType(fieldRow); // If it's an option field... if (fieldType == MetaFieldType.Option) { string fieldName = fieldRow["Name"].ToString(); Epi.Data.Services.CollectedDataProvider collectedDataProvider = destinationProject.CollectedData; Epi.Data.IDbDriver db = collectedDataProvider.GetDatabase(); // If the Epi 3 view is corrupted in such a way that the data // column for this field doesn't exist, we have to break here else we run into errors if (db.ColumnExists(page.GetView().TableName, fieldName) == false) { break; } // We start a queue. The queue will store each option in the option field. Queue<string> options = new Queue<string>(); // Enqueue items to the queue in the order they came out of the list column string[] items = fieldRow["Lists"].ToString().Split(';'); for (int i = 0; i < items.Length; i++) { options.Enqueue(items[i]); } // Create a temporary column that will store our translated data string tempFieldName = "Epi7_import_" + fieldName; TableColumn column = new TableColumn(tempFieldName, GenericDbColumnType.Int16, true); db.AddColumn(tableName, column); // For each option in our options queue... for(int i = 0; options.Count > 0; i++) { // ... run an UPDATE query that upates our temporary import column with an int16 value based on the Epi 3 string literal value Query updateQuery = db.CreateQuery("UPDATE " + tableName + " SET " + tempFieldName + " = " + (i).ToString() + " WHERE " + fieldName + " = @Options"); // TODO: If Epi 7 option fields are ever changed from 0-based to 1-based, this MUST be updated, too! updateQuery.Parameters.Add(new QueryParameter("@Options", DbType.String, options.Dequeue())); db.ExecuteNonQuery(updateQuery); } // Delete the original Epi 3 column with its string literal values db.DeleteColumn(tableName, fieldName); // Very important - we must compact to avoid 'Too many fields defined' error db.CompactDatabase(); // We now need to re-create the data column for our field, which we just deleted column = new TableColumn(fieldName, GenericDbColumnType.Int16, true); db.AddColumn(tableName, column); // Then we copy the data from the temp import field into the column we just added above // (Note: We can't do an ALTER TABLE... RENAME COLUMN because Access does not support this) Query copyQuery = db.CreateQuery("UPDATE " + tableName + " SET " + fieldName + " = " + tempFieldName); db.ExecuteNonQuery(copyQuery); // Finally, we delete the temporary import column. db.DeleteColumn(tableName, tempFieldName); } } } catch { } }
/// <summary> /// Converts the fields in a page /// </summary> /// <param name="page">A page object</param> private void CopyFields(Page page) { try { string viewNameWithPrefix = "view" + page.GetView().Name; DataTable fieldsTable = sourceProject.Metadata.GetFieldsOnPageAsDataTable(viewNameWithPrefix, page.Position); bool hasOptionFields = false; foreach (DataRow fieldRow in fieldsTable.Rows) { string fieldName = fieldRow["Name"].ToString(); if (Char.IsNumber(fieldName[0])) { Logger.Log(DateTime.Now + ": " + string.Format(SharedStrings.IMPORT_WARNING_FIELD_LEADING_DIGIT, fieldName)); continue; } MetaFieldType fieldType = Epi.Epi2000.MetadataDbProvider.InferFieldType(fieldRow); Epi.Data.Services.CollectedDataProvider collectedDataProvider = destinationProject.CollectedData; Epi.Data.IDbDriver db = collectedDataProvider.GetDatabase(); if (fieldType != MetaFieldType.CommandButton && fieldType != MetaFieldType.Grid && fieldType != MetaFieldType.Group && fieldType != MetaFieldType.LabelTitle && fieldType != MetaFieldType.Mirror && fieldType != MetaFieldType.Relate && db.ColumnExists(page.TableName, fieldName) == false) { if (db.TableExists(page.TableName)) { Logger.Log(DateTime.Now + ": " + string.Format( SharedStrings.IMPORT_LOG_NO_DATA_COLUMN, fieldName, page.TableName)); } } if (fieldType != MetaFieldType.Codes) { CopyField(fieldRow, page, viewNameWithPrefix); } if (fieldType == MetaFieldType.Option) { hasOptionFields = true; } } DataRow[] codeRows = fieldsTable.Select(ColumnNames.TYPE + " = 'COMBO'"); foreach (DataRow codeRow in codeRows) { MetaFieldType fieldType = Epi.Epi2000.MetadataDbProvider.InferFieldType(codeRow); if (fieldType == MetaFieldType.Codes) { CopyField(codeRow, page, viewNameWithPrefix); } } if (hasOptionFields == true) { UpdateOptionFields(page); } } catch (Exception ex) { throw ex; } finally { } }