예제 #1
0
파일: Field.cs 프로젝트: rjankovic/deskmin
 public FKField(int fieldId, string column, int typeId, string typeName, int panelId, IFK fk,
     PropertyCollection attr = null, PropertyCollection rules = null)
     : base(fieldId, column, typeId, typeName, panelId, attr, rules)
 {
     this.fk = fk;
 }
예제 #2
0
        /// <summary>
        /// checks if edited fields exist in webDB and their types are adequate, checks constraints on FKs and mapping tables,
        /// also checks if controls` dataTables` columns exist and everything that has to be inserted in DB is a required field,
        /// whether attributes don`t colide and every panel has something to display.
        /// As it goes through the Panel, it fires an ArchitectureError event.
        /// </summary>
        /// <param name="proposalPanel"></param>
        /// <param name="recursive">run itself on panel children</param>
        /// <returns>true if no errors found, true othervise</returns>
        public bool checkPanelProposal(IPanel proposalPanel, bool recursive = true)
        // non-recursive checking after the initial check - after panel modification
        {
            string messageBeginning = "In panel " + (proposalPanel.viewAttr.ContainsKey(CC.PANEL_NAME) ?
                                                     (proposalPanel.viewAttr[CC.PANEL_NAME] + " (" + proposalPanel.tableName + ") ") :
                                                     ("of type " + proposalPanel.typeName + " for " + proposalPanel.tableName)) + ": ";

            DataColumnCollection cols = stats.columnTypes(proposalPanel.tableName);

            if (cols.Count == 0)
            {
                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "table not found or has 0 columns",
                                                           proposalPanel.tableName));
                return(false);
            }

            List <IFK> FKs = stats.foreignKeys(proposalPanel.tableName);

            bool good = true;

            if (proposalPanel.typeName == PanelTypes.Editable.ToString() ||
                proposalPanel.typeName == PanelTypes.NavTable.ToString())
            // this is indeed the only panelType containing fields
            {
                bool isNavTable = proposalPanel.typeName == PanelTypes.NavTable.ToString();
                foreach (IField field in proposalPanel.fields)
                {
                    if (field.typeName == FieldTypes.Holder.ToString())
                    {
                        continue;
                    }
                    if (!cols.Contains(field.column))
                    {
                        Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the column " + field.column +
                                                                   "managed by the field does not exist in table", proposalPanel, field));
                        good = false;
                    }
                    else
                    {
                        if (!(field is IFKField) && !(field is IM2NMapping) && !isNavTable)     // NavTable won`t be edited in the panel
                        {
                            PropertyCollection r = field.rules;
                            if (cols[field.column].AllowDBNull == false && !r.ContainsKey(CC.RULES_REQUIRED))
                            {
                                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the column " + field.column
                                                                           + " cannot be set to null, but the coresponding field is not required", proposalPanel, field));
                                good = false;
                            }

                            if ((r.ContainsKey(CC.RULUES_DECIMAL) || r.ContainsKey(CC.RULES_ORDINAL)) &&
                                !(typeof(long).IsAssignableFrom(cols[field.column].DataType)))
                            {
                                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the column " + field.column
                                                                           + " is of type " + cols[field.column].DataType.ToString()
                                                                           + ", thus cannot be edited as a decimalnumber", proposalPanel, field));
                                good = false;
                            }

                            if ((r.ContainsKey(CC.RULES_DATE) || r.ContainsKey(CC.RULES_DATETIME)) &&
                                !(cols[field.column].DataType == typeof(DateTime)))
                            {
                                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the column " + field.column
                                                                           + " is not a date / datetime, thus cannot be edited as a date", proposalPanel, field));
                                good = false;
                            }
                        }
                        else if (field is IM2NMappingField)
                        {
                            // just cannot occur in a NavTable, but just in case...
                            if (isNavTable)
                            {
                                throw new Exception("Cannot display a M2NMapping in NavTable");
                            }
                            IM2NMapping thisMapping = ((IM2NMappingField)field).mapping;
                            if (!mappings.Contains(thisMapping))
                            {
                                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the schema " +
                                                                           "does not define an usual M2NMapping batween tables " + thisMapping.myTable +
                                                                           " and " + thisMapping.refTable + " using " + thisMapping.mapTable +
                                                                           " as a map table", proposalPanel, field));
                                good = false;
                            }
                        }
                        else if (field is IFKField)
                        {
                            IFK fieldFK = ((IFKField)field).fk;
                            if (!FKs.Contains(fieldFK))
                            {
                                Error(this, new ArchitectureErrorEventArgs(messageBeginning + "the column " + field.column
                                                                           + " is not a foreign key representable by the FK field", proposalPanel, field));
                                good = false;
                            }
                        }
                    }
                }
            }

            // controls...

            PanelTypes PTEnum = (PanelTypes)Enum.Parse(typeof(PanelTypes), proposalPanel.typeName);

            if (PTEnum == PanelTypes.NavTable || PTEnum == PanelTypes.NavTree || PTEnum == PanelTypes.MenuDrop)
            {
                if (proposalPanel.controlAttr.ContainsKey(CC.NAV_THROUGH_PANELS))
                {
                    if (proposalPanel.tableName != null)
                    {
                        Error(this, new ArchitectureErrorEventArgs(messageBeginning + "Panel that navigates through panels "
                                                                   + "cannot have tableName set", proposalPanel.tableName));
                        good = false;
                    }
                }
                else if (proposalPanel.controlAttr.ContainsKey(CC.NAV_THROUGH_RECORDS))
                {
                    if (!proposalPanel.controlAttr.ContainsKey(CC.NAV_PANEL_ID))
                    {
                        Error(this, new ArchitectureErrorEventArgs(messageBeginning + "Navigation panel "
                                                                   + "that does not navigate through panels must have target panel id set",
                                                                   proposalPanel, proposalPanel.controls[0]));
                        good = false;
                    }
                }
            }

            // TODO & TODO & TODO (CONTROLS & OTHER PROPERTIES)
            // OR allow the admin-user take valid steps only (?)

            if (recursive)
            {
                foreach (IPanel child in proposalPanel.children)
                {
                    good = good && checkPanelProposal(child, true);
                }
            }
            return(good);
        }
예제 #3
0
파일: Field.cs 프로젝트: rjankovic/deskmin
 public FKField(int fieldId, string column, int typeId, string typeName, int panelId, IFK fk,
                PropertyCollection attr = null, PropertyCollection rules = null)
     : base(fieldId, column, typeId, typeName, panelId, attr, rules)
 {
     this.fk = fk;
 }
예제 #4
0
        /// <summary>
        /// Ignores mappings, displays first 4 columns in a classic NavTable
        /// or the first display column in a NavTree if a self-referential FK is present.
        /// navtable includes edit and delete action buttons, second control - insert button
        /// </summary>
        /// <param name="tableName">string</param>
        /// <returns>IPanel</returns>
        private IPanel proposeSummaryPanel(string tableName)
        {
            DataColumnCollection cols = stats.columnTypes(tableName);
            List <IFK>           FKs  = stats.foreignKeys(tableName);
            // a table with more than one self-referential FK is improbable
            List <IFK>    selfRefs  = new List <IFK>(from FK in FKs where FK.myTable == FK.refTable select FK as IFK);
            List <string> PKCols    = stats.primaryKeyCols(tableName);
            IFK           selfRefFK = null;
            // strict hierarchy structure validation - not nice => no Tree

            string hierarchyExplanation = "(For a tree-like navigation within view, the table must have exactly one FK pointing "
                                          + " to it`s PK column. (It can of course have other FKs refering to other tables.))";

            if (selfRefs.Count > 1)
            {
                Warning(this, new ArchitectWarningEventArgs(
                            "Unexpected hierarchy table structure for " + tableName + " - multiple self-referential columns. "
                            + hierarchyExplanation, tableName));
            }
            else
            if (selfRefs.Count == 1 && PKCols.Count == 1)
            {
                selfRefFK = selfRefs.First();

                if (PKCols.Count > 1)
                {
                    Warning(this, new ArchitectWarningEventArgs(
                                "Hierarchical table " + tableName + " does have a signle-column PK. "
                                + hierarchyExplanation, tableName));
                    selfRefFK = null;       // remove the selfRefFK => as if there was no hierarchy
                }
                if (selfRefFK.refColumn != PKCols[0])
                {
                    selfRefFK = null;
                    Warning(this, new ArchitectWarningEventArgs("The self-referential FK in table "
                                                                + tableName + " must refer to the PK column. "
                                                                + hierarchyExplanation, tableName));
                }
            }
            List <string> displayColOrder = DisplayColOrder(tableName);

            PropertyCollection controlProps = new PropertyCollection();
            PropertyCollection displayProps = new PropertyCollection();

            displayProps.Add(CC.PANEL_DISPLAY_COLUMN_ORDER, String.Join(",", displayColOrder));
            displayProps.Add(CC.PANEL_NAME, tableName);
            controlProps.Add(UserAction.View.ToString() + CC.CONTROL_ACCESS_LEVEL_REQUIRED_SUFFIX, 1);
            IControl   control;
            DataTable  controlTab = new DataTable();
            PanelTypes panelType;

            List <IField> fields = new List <IField>();

            if (selfRefFK == null)
            {
                //displayProps.Add(CC.NAVTAB_COLUMNS_DISLAYED, CC.NAVTAB_COLUMNS_DISLAYED_DEFAULT);
                // table takes first four display-suitable fields; the above is not neccessary, in Navtable Columns are fields
                foreach (string column in displayColOrder.Take(CC.NAVTAB_COLUMNS_DISLAYED_DEFAULT))
                {
                    //controlTab.Columns.Add(column);
                    if (FKs.Any(x => x.myColumn == column))
                    {
                        IFK myFK = FKs.Find(x => x.myColumn == column);
                        fields.Add(new FKField(0, column, fieldTypeIdMap[FieldTypes.Varchar], FieldTypes.Varchar.ToString(),
                                               0, myFK));
                    }
                    else
                    {
                        fields.Add(new Field(0, column, fieldTypeIdMap[FieldTypes.Varchar], FieldTypes.Varchar.ToString(), 0));
                    }
                    fields.OrderBy(x => displayColOrder.IndexOf(x.column));
                    // to maintain the order from displayColOrder without further properties
                }
                control   = new Control(controlTab, PKCols, UserAction.Update);
                panelType = PanelTypes.NavTable;
            }
            else
            {
                controlProps.Add(CC.CONTROL_HIERARCHY_SELF_FK_COL, selfRefFK.myColumn);
                controlTab.Columns.Add(PKCols[0]);
                controlTab.Columns.Add(selfRefFK.myColumn);
                controlTab.Columns.Add(displayColOrder[0]);
                control   = new TreeControl(controlTab, PKCols[0], selfRefFK.myColumn, displayColOrder[0], UserAction.Update);
                panelType = PanelTypes.NavTree;
            }

            List <IControl> controls = new List <IControl>();

            controls.Add(control);

            return(new Panel(tableName, 0, panelTypeIdMp[panelType], panelType.ToString(),
                             new List <IPanel>(), fields, controls, PKCols, null, displayProps, controlProps));
        }
예제 #5
0
        private void RewriteFieldProperties(IField field)
        {
            //set control properties
            Dictionary <string, object> insertVals = new Dictionary <string, object>();

            insertVals["id_field"] = field.fieldId;
            insertVals["concerns"] = CC.ATTR_CONTROLS;

            IFK         fk      = null;
            IM2NMapping mapping = null;

            if (field is FKField)
            {
                fk = (field as FKField).fk;
            }
            if (field is M2NMappingField)
            {
                fk = mapping = (field as M2NMappingField).mapping;
            }

            if (fk != null)
            {
                insertVals["name"] = CC.FIELD_REF_TABLE;
                insertVals["val"]  = fk.refTable;
                query("REPLACE INTO fields_meta", insertVals);

                insertVals["name"] = CC.FIELD_REF_COLUMN;
                insertVals["val"]  = fk.refColumn;
                query("REPLACE INTO fields_meta", insertVals);

                insertVals["name"] = CC.FIELD_DISPLAY_COLUMN;
                insertVals["val"]  = fk.displayColumn;
                query("REPLACE INTO fields_meta", insertVals);
            }

            if (mapping != null)
            {
                insertVals["name"] = CC.FIELD_REF_TABLE;
                insertVals["val"]  = mapping.mapTable;
                query("REPLACE INTO fields_meta", insertVals);

                insertVals["name"] = CC.FIELD_MAP_MY_COLUMN;
                insertVals["val"]  = mapping.myColumn;
                query("REPLACE INTO fields_meta", insertVals);

                insertVals["name"] = CC.FIELD_MAP_REF_COLUMN;
                insertVals["val"]  = mapping.refColumn;
                query("REPLACE INTO fields_meta", insertVals);
            }

            // validation rules & view properties - just copy
            insertVals             = new Dictionary <string, object>();
            insertVals["id_field"] = field.fieldId;
            insertVals["concerns"] = "view";
            foreach (string attrKey in field.attr.Keys)
            {
                insertVals["name"] = attrKey;
                insertVals["val"]  = field.attr[attrKey].ToString();
                query("REPLACE INTO fields_meta", insertVals);
            }

            insertVals["concerns"] = "validation";
            foreach (string ruleKey in field.rules.Keys)
            {
                insertVals["name"] = ruleKey;
                insertVals["val"]  = field.rules[ruleKey].ToString();
                query("REPLACE INTO fields_meta", insertVals);
            }
        }