コード例 #1
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoChangeValueTypeProperty_To_Nullable(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            var savedProp = savedSchema.FindPersistenceObject<ValueTypeProperty>(prop.ExportGuid);

            if (!PreMigration(PropertyMigrationEventType.ChangeToNullable, savedProp, prop))
                return;

            var tblName = objClass.GetTableRef(db);
            var colName = Construct.ColumnName(prop, prefix);

            db.AlterColumn(tblName, colName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), prop.IsNullable(), null);

            PostMigration(PropertyMigrationEventType.ChangeToNullable, savedProp, prop);
        }
コード例 #2
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewValueTypePropertyList(ObjectClass objClass, ValueTypeProperty prop)
        {
            if (!PreMigration(PropertyMigrationEventType.Add, null, prop))
                return;

            Log.InfoFormat("New ValueType Property List: {0}", prop.Name);
            CheckValueTypePropertyHasWarnings(prop);

            var tblName = db.GetTableName(prop.Module.SchemaName, prop.GetCollectionEntryTable());
            string fkName = Construct.ForeignKeyColumnName(prop);
            string valPropName = prop.Name;
            string valPropIndexName = prop.Name + "Index";
            string assocName = prop.GetAssociationName();
            bool hasPersistentOrder = prop.HasPersistentOrder;

            db.CreateTable(tblName, true);
            db.CreateColumn(tblName, fkName, System.Data.DbType.Int32, 0, 0, false);

            db.CreateColumn(tblName, valPropName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), false, SchemaManager.GetDefaultConstraint(prop));

            if (hasPersistentOrder)
            {
                db.CreateColumn(tblName, valPropIndexName, System.Data.DbType.Int32, 0, 0, false);
            }
            db.CreateFKConstraint(tblName, objClass.GetTableRef(db), fkName, assocName, true);
            db.CreateIndex(tblName, Construct.IndexName(tblName.Name, fkName), false, false, fkName);

            PostMigration(PropertyMigrationEventType.Add, null, prop);
        }
コード例 #3
0
        private void CheckExtraColumns(ObjectClass objClass)
        {
            if (objClass.GetTableMapping() == TableMapping.TPH && objClass.BaseObjectClass != null) return; // Check only base TPH classes

            Log.Debug("Extra Columns: ");
            List<string> columns = new List<string>();
            List<ObjectClass> classes = new List<ObjectClass>(new[] { objClass });

            if (objClass.GetTableMapping() == TableMapping.TPH)
                objClass.CollectChildClasses(classes, true);

            foreach (var cls in classes)
            {
                GetExistingColumnNames(cls, cls.Properties, String.Empty, columns);
                GetRelationColumnNames(cls, columns);
            }

            foreach (string propName in db.GetTableColumnNames(objClass.GetTableRef(db)))
            {
                if (propName == "ID" || propName == TableMapper.DiscriminatorColumnName)
                    continue;
                if (!columns.Contains(propName))
                {
                    Log.WarnFormat("Column '[{0}].[{1}].[{2}]' found in database but no Property was defined",
                        objClass.Module.IfNotNull(o => o.SchemaName),
                        objClass.TableName,
                        propName);
                }
            }
        }
コード例 #4
0
        private void CheckTableSecurityRules(ObjectClass objClass)
        {
            if (objClass.NeedsRightsTable())
            {
                var tblName = objClass.GetTableRef(db);
                var tblRightsName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass));
                var rightsViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass));
                var refreshRightsOnProcedureName = db.GetProcedureName(objClass.Module.SchemaName, Construct.SecurityRulesRefreshRightsOnProcedureName(objClass));

                if (!db.CheckTableExists(tblRightsName))
                {
                    Log.WarnFormat("Security Rules Table '{0}' is missing", tblRightsName);
                    if (repair)
                    {
                        Case.DoNewObjectClassACL(objClass);
                    }
                }
                else
                {
                    if (!db.CheckViewExists(rightsViewUnmaterializedName))
                    {
                        Log.WarnFormat("Security Rules unmaterialized View '{0}' is missing", rightsViewUnmaterializedName);
                        if (repair)
                        {
                            Case.DoCreateRightsViewUnmaterialized(objClass);
                        }
                    }
                    if (!db.CheckProcedureExists(refreshRightsOnProcedureName))
                    {
                        Log.WarnFormat("Security Rules Refresh Procedure '{0}' is missing", refreshRightsOnProcedureName);
                        if (repair)
                        {
                            db.CreateRefreshRightsOnProcedure(refreshRightsOnProcedureName, rightsViewUnmaterializedName, tblName, tblRightsName);
                        }
                    }
                }
            }
        }
コード例 #5
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoRenameObjectClassTable(ObjectClass objClass)
        {
            var savedObjClass = savedSchema.FindPersistenceObject<ObjectClass>(objClass.ExportGuid);

            if (!PreMigration(ClassMigrationEventType.RenameTable, savedObjClass, objClass))
                return;

            var tbl = objClass.GetTableRef(db);
            var saveTbl = savedObjClass.GetTableRef(db);
            Log.InfoFormat("Renaming table from '{0}' to '{1}'", saveTbl, tbl);

            var mapping = objClass.GetTableMapping();
            if (mapping == TableMapping.TPT || (mapping == TableMapping.TPH && objClass.BaseObjectClass == null))
            {
                db.RenameTable(saveTbl, tbl);
            }
            else if (mapping == TableMapping.TPH && objClass.BaseObjectClass != null)
            {
                foreach (var prop in objClass.Properties.OfType<ValueTypeProperty>().Where(p => !p.IsList))
                {
                    DoRenameValueTypePropertyName(objClass, prop, string.Empty);
                }

                // FK names will be changed in DoChangeRelationName case
            }

            if (mapping == TableMapping.TPH)
            {
                db.RenameDiscriminatorValue(tbl, Construct.DiscriminatorValue(savedObjClass), Construct.DiscriminatorValue(objClass));
            }

            PostMigration(ClassMigrationEventType.RenameTable, savedObjClass, objClass);
        }
コード例 #6
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoChangeDefaultValue(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            var savedProp = savedSchema.FindPersistenceObject<Property>(prop.ExportGuid);

            if (!PreMigration(PropertyMigrationEventType.ChangeDefaultValueDefinition, savedProp, prop))
                return;

            var tblName = objClass.GetTableRef(db);
            var colName = Construct.ColumnName(prop, prefix);

            // Use current nullable definition.
            // Another case is responsible to change that.
            var currentIsNullable = db.GetIsColumnNullable(tblName, colName);

            db.AlterColumn(tblName, colName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), currentIsNullable, SchemaManager.GetDefaultConstraint(prop));

            PostMigration(PropertyMigrationEventType.ChangeDefaultValueDefinition, savedProp, prop);
        }
コード例 #7
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoDeleteValueTypeProperty(ObjectClass objClass, ValueTypeProperty savedProp, string prefix)
        {
            if (!PreMigration(PropertyMigrationEventType.Delete, savedProp, null))
                return;

            var tblName = objClass.GetTableRef(db);
            var colName = Construct.ColumnName(savedProp, prefix);
            var checkConstraintName = Construct.CheckConstraintName(tblName.Name, colName);
            Log.InfoFormat("Drop Column: {0}.{1}", tblName, colName);
            if (db.CheckCheckConstraintExists(tblName, checkConstraintName))
                db.DropCheckConstraint(tblName, checkConstraintName);

            if (db.CheckColumnExists(tblName, colName))
                db.DropColumn(tblName, colName);

            PostMigration(PropertyMigrationEventType.Delete, savedProp, null);
        }
コード例 #8
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoRemoveObjectClassInheritance(ObjectClass objClass)
        {
            var savedObjClass = savedSchema.FindPersistenceObject<ObjectClass>(objClass.ExportGuid);

            if (!PreMigration(ClassMigrationEventType.ChangeBase, savedObjClass, objClass))
                return;

            string assocName = Construct.InheritanceAssociationName(savedObjClass.BaseObjectClass, savedObjClass);
            var tblName = objClass.GetTableRef(db);

            Log.InfoFormat("Remove ObjectClass Inheritance: {0} -> {1}: {2}", savedObjClass.Name, savedObjClass.BaseObjectClass.Name, assocName);

            if (db.CheckFKConstraintExists(tblName, assocName))
                db.DropFKConstraint(tblName, assocName);

            PostMigration(ClassMigrationEventType.ChangeBase, savedObjClass, objClass);
        }
コード例 #9
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoDeleteObjectClass(ObjectClass savedObjClass)
        {
            if (!PreMigration(ClassMigrationEventType.Delete, savedObjClass, null))
                return;

            if (savedObjClass.NeedsRightsTable())
            {
                DoDeleteObjectClassSecurityRules(savedObjClass);
            }

            foreach (var lstPop in savedObjClass.Properties.OfType<ValueTypeProperty>().Where(p => p.IsList))
            {
                DoDeleteValueTypePropertyList(savedObjClass, lstPop, string.Empty);
            }
            foreach (var lstPop in savedObjClass.Properties.OfType<CompoundObjectProperty>().Where(p => p.IsList))
            {
                DoDeleteCompoundObjectPropertyList(savedObjClass, lstPop, string.Empty);
            }

            var mapping = savedObjClass.GetTableMapping();
            if (mapping == TableMapping.TPT)
            {
                var tbl = savedObjClass.GetTableRef(db);
                Log.InfoFormat("Drop Table: {0}", tbl);
                if (db.CheckTableExists(tbl))
                    db.DropTable(tbl);
            }
            else if (mapping == TableMapping.TPH)
            {
                // TODO: Do delete all columns
            }
            else
            {
                throw new NotSupportedException(string.Format("Mapping {0} is not supported", mapping));
            }

            PostMigration(ClassMigrationEventType.Delete, savedObjClass, null);
        }
コード例 #10
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoDeleteObjectClassSecurityRules(ObjectClass objClass)
        {
            var tblName = objClass.GetTableRef(db);
            var tblRightsName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass));
            var rightsViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass));
            var refreshRightsOnProcedureName = Construct.SecurityRulesRefreshRightsOnProcedureName(objClass);
            var updateRightsTriggerName = new TriggerRef(tblName, Construct.SecurityRulesUpdateRightsTriggerName(objClass));

            Log.InfoFormat("Delete ObjectClass Security Rules: {0}", objClass.Name);

            if (db.CheckTriggerExists(updateRightsTriggerName))
                db.DropTrigger(updateRightsTriggerName);

            if (db.CheckProcedureExists(db.GetProcedureName(objClass.Module.SchemaName, refreshRightsOnProcedureName)))
                db.DropProcedure(db.GetProcedureName(objClass.Module.SchemaName, refreshRightsOnProcedureName));

            if (db.CheckViewExists(rightsViewUnmaterializedName))
                db.DropView(rightsViewUnmaterializedName);

            if (db.CheckTableExists(tblRightsName))
                db.DropTable(tblRightsName);
        }
コード例 #11
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoDeleteCompoundObjectProperty(ObjectClass objClass, CompoundObjectProperty savedCProp, string prefix)
        {
            if (!PreMigration(PropertyMigrationEventType.Delete, savedCProp, null))
                return;

            Log.InfoFormat("deleting CompoundObject Property: '{0}'", savedCProp.Name);

            var tblName = objClass.GetTableRef(db);
            string baseColName = Construct.ColumnName(savedCProp, prefix);

            foreach (var valProp in savedCProp.CompoundObjectDefinition.Properties.OfType<ValueTypeProperty>())
            {
                var colName = Construct.ColumnName(valProp, baseColName);
                Log.InfoFormat("  deleting ValueType Property: '{0}' ('{1}')", valProp.Name, colName);
                db.DropColumn(tblName, colName);
            }

            // TODO: Add nested CompoundObjectProperty

            PostMigration(PropertyMigrationEventType.Delete, savedCProp, null);
        }
コード例 #12
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoCreateRightsViewUnmaterialized(ObjectClass objClass)
        {
            var tblName = objClass.GetTableRef(db);
            var tblRightsName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass));
            var rightsViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass));

            if (objClass.AccessControlList.Count == 0)
            {
                Log.ErrorFormat("Unable to create RightsViewUnmaterialized: ObjectClass '{0}' has an empty AccessControlList", objClass.Name);
                db.CreateEmptyRightsViewUnmaterialized(rightsViewUnmaterializedName);
                return;
            }

            List<ACL> viewAcls = new List<ACL>();
            foreach (var ac in objClass.AccessControlList.OfType<RoleMembership>())
            {
                if (ac.Relations.Count == 0)
                {
                    Log.ErrorFormat("Unable to create RightsViewUnmaterialized: RoleMembership '{0}' has no relations", ac.Description);
                    db.CreateEmptyRightsViewUnmaterialized(rightsViewUnmaterializedName);
                    return;
                }

                var viewAcl = new ACL();
                viewAcls.Add(viewAcl);
                viewAcl.Right = (Zetbox.API.AccessRights)ac.Rights;
                try
                {
                    viewAcl.Relations.AddRange(SchemaManager.CreateJoinList(db, objClass, ac.Relations));
                }
                catch (SchemaManager.JoinListException ex)
                {
                    Log.ErrorFormat(ex.Message);
                    db.CreateEmptyRightsViewUnmaterialized(rightsViewUnmaterializedName);
                    return;
                }
            }

            db.CreateRightsViewUnmaterialized(rightsViewUnmaterializedName, tblName, tblRightsName, viewAcls);
        }
コード例 #13
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoCreateOrReplaceUpdateRightsTrigger(ObjectClass objClass)
        {
            var tblName = objClass.GetTableRef(db);
            var updateRightsTriggerName = new TriggerRef(tblName, Construct.SecurityRulesUpdateRightsTriggerName(objClass));

            if (db.CheckTriggerExists(updateRightsTriggerName))
                db.DropTrigger(updateRightsTriggerName);

            var tblList = new List<RightsTrigger>();
            tblList.Add(new RightsTrigger()
            {
                TblName = objClass.GetTableRef(db),
                TblNameRights = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass)),
                ViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass))
            });

            // Get all ObjectClasses that depends on current object class
            var list = schema.GetQuery<ObjectClass>()
                .Where(o => o.AccessControlList.OfType<RoleMembership>()
                    .Where(rm => rm.Relations
                        .Where(r => r.A.Type == objClass || r.B.Type == objClass).Count() > 0).Count() > 0)
                .Distinct().ToList().Where(o => o.NeedsRightsTable() && o != objClass);

            var identity = (ObjectClass)NamedObjects.Base.Classes.Zetbox.App.Base.Identity.Find(objClass.Context);

            foreach (var dep in list)
            {
                Log.DebugFormat("  Additional update Table: {0}", dep.TableName);
                foreach (var ac in dep.AccessControlList.OfType<RoleMembership>())
                {
                    var rel = ac.Relations.FirstOrDefault(r => r.A.Type == objClass || r.B.Type == objClass);
                    if (rel != null)
                    {
                        var rt = new RightsTrigger()
                        {
                            TblName = dep.GetTableRef(db),
                            TblNameRights = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesTableName(dep)),
                            ViewUnmaterializedName = db.GetTableName(dep.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(dep)),
                        };
                        try
                        {
                            rt.ObjectRelations.AddRange(SchemaManager.CreateJoinList(db, dep, ac.Relations.TakeWhileInclusive(r => r != rel)));
                            rt.IdentityRelations.AddRange(SchemaManager.CreateJoinList(db, identity, ac.Relations.Reverse().TakeWhile(r => r != rel)));
                        }
                        catch (Zetbox.Server.SchemaManagement.SchemaManager.JoinListException ex)
                        {
                            Log.Warn("Unable to create UpdateRightsTrigger on " + objClass, ex);
                            return;
                        }
                        tblList.Add(rt);
                    }
                }
            }

            // do not check fk_ChangedBy since it always changes, even when only recalculations were done.
            // ACLs MUST never use ChangedBy information
            var fkCols = objClass.GetRelationEndsWithLocalStorage()
                .Where(r => !(r.Type.ImplementsIChangedBy() && r.Navigator != null && r.Navigator.Name == "ChangedBy"))
                .Select(r => Construct.ForeignKeyColumnName(r.GetParent().GetOtherEnd(r)))
                .ToList();
            db.CreateUpdateRightsTrigger(updateRightsTriggerName, tblName, tblList, fkCols);
        }
コード例 #14
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewValueTypePropertyNotNullable(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            if (!PreMigration(PropertyMigrationEventType.Add, null, prop))
                return;

            var tblName = objClass.GetTableRef(db);
            var colName = Construct.ColumnName(prop, prefix);
            var dbType = prop.GetDbType();
            var size = prop.GetSize();
            var scale = prop.GetScale();
            var def = SchemaManager.GetDefaultConstraint(prop);
            var isSimplyCheckable = objClass.GetTableMapping() == TableMapping.TPT || objClass.BaseObjectClass == null;
            bool updateDone = false;

            // classes that do have this property
            var classes = objClass.AndChildren(c => c.SubClasses).Select(cls => Construct.DiscriminatorValue(cls)).ToList();

            Log.InfoFormat("New not nullable ValueType Property: [{0}.{1}] (col:{2})", prop.ObjectClass.Name, prop.Name, colName);

            CheckValueTypePropertyHasWarnings(prop);

            if (db.CheckTableContainsData(tblName, isSimplyCheckable ? null : classes))
            {
                db.CreateColumn(tblName, colName, dbType, size, scale, true, isSimplyCheckable ? def : null);
                updateDone = WriteDefaultValue(tblName, colName, def, isSimplyCheckable ? null : classes);
            }
            else
            {
                db.CreateColumn(tblName, colName, dbType, size, scale, !isSimplyCheckable, isSimplyCheckable ? def : null);
                updateDone = true;
            }

            if (updateDone && isSimplyCheckable)
            {
                db.AlterColumn(tblName, colName, dbType, size, scale, false, def);
            }
            else if (updateDone && !isSimplyCheckable)
            {
                CreateTPHNotNullCheckConstraint(tblName, colName, objClass);
            }
            else if (!updateDone && isSimplyCheckable)
            {
                Log.ErrorFormat("unable to set ValueType Property '{0}' to NOT NULL when table '{1}' contains data: No supported default constraint found", colName, tblName);
            }
            else if (!updateDone && !isSimplyCheckable)
            {
                Log.ErrorFormat("unable to create CHECK constraint on ValueType Property '{0}' when table '{1}' contains data: No supported default constraint found", colName, tblName);
            }

            PostMigration(PropertyMigrationEventType.Add, null, prop);
        }
コード例 #15
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoMoveValueTypeProperty(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            var savedProp = savedSchema.FindPersistenceObject<ValueTypeProperty>(prop.ExportGuid);

            if (!PreMigration(PropertyMigrationEventType.Move, savedProp, prop))
                return;

            // Reflected changed hierarchie
            var currentOriginObjClass = schema.FindPersistenceObject<ObjectClass>(savedProp.ObjectClass.ExportGuid);
            var movedUp = IsParentOf(objClass, currentOriginObjClass);
            var movedDown = IsParentOf(currentOriginObjClass, objClass);

            var tblName = objClass.GetTableRef(db);
            var srcTblName = ((ObjectClass)savedProp.ObjectClass).GetTableRef(db);
            var colName = Construct.ColumnName(prop, prefix);
            var srcColName = Construct.ColumnName(savedProp, prefix); // TODO: What if prefix has changed
            var dbType = prop.GetDbType();
            var size = prop.GetSize();
            var scale = prop.GetScale();
            var def = SchemaManager.GetDefaultConstraint(prop);

            if (movedUp)
            {
                Log.InfoFormat("Moving property '{0}' from '{1}' up to '{2}'", prop.Name, savedProp.ObjectClass.Name, objClass.Name);
                db.CreateColumn(tblName, colName, dbType, size, scale, true, def);

                db.CopyColumnData(srcTblName, srcColName, tblName, colName);

                if (!prop.IsNullable())
                {
                    if (db.CheckColumnContainsNulls(tblName, colName))
                    {
                        Log.ErrorFormat("column '{0}.{1}' contains NULL values, cannot set NOT NULLABLE", tblName, colName);
                    }
                    else
                    {
                        db.AlterColumn(tblName, colName, dbType, size, scale, prop.IsNullable(), def);
                    }
                }

                if (db.CheckColumnExists(srcTblName, srcColName))
                    db.DropColumn(srcTblName, srcColName);
            }
            else if (movedDown)
            {
                Log.InfoFormat("Moving property '{0}' from '{1}' down to '{2}' (dataloss possible)", prop.Name, savedProp.ObjectClass.Name, objClass.Name);
                db.CreateColumn(tblName, colName, dbType, size, scale, true, def);

                db.CopyColumnData(srcTblName, srcColName, tblName, colName);

                if (!prop.IsNullable())
                {
                    db.AlterColumn(tblName, colName, dbType, size, scale, prop.IsNullable(), def);
                }

                if (db.CheckColumnExists(srcTblName, srcColName))
                    db.DropColumn(srcTblName, srcColName);
            }
            else
            {
                Log.ErrorFormat("Moving property '{2}' from '{0}' to '{1}' is not supported. ObjectClasses are not in the same hierarchy. Will only create destination column.", savedProp.ObjectClass.Name, prop.ObjectClass.Name, prop.Name);
                db.CreateColumn(tblName, colName, dbType, size, scale, true, def);
            }

            PostMigration(PropertyMigrationEventType.Move, savedProp, prop);
        }
コード例 #16
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewValueTypePropertyNullable(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            if (!PreMigration(PropertyMigrationEventType.Add, null, prop))
                return;

            string colName = Construct.ColumnName(prop, prefix);
            Log.InfoFormat("New nullable ValueType Property: '{0}' ('{1}')", prop.Name, colName);
            CheckValueTypePropertyHasWarnings(prop);

            CreateValueTypePropertyNullable(objClass.GetTableRef(db), prop, colName, true);

            PostMigration(PropertyMigrationEventType.Add, null, prop);
        }
コード例 #17
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewCompoundObjectProperty(ObjectClass objClass, CompoundObjectProperty cprop, string prefix)
        {
            if (!PreMigration(PropertyMigrationEventType.Add, null, cprop))
                return;

            var tblName = objClass.GetTableRef(db);
            CreateCompoundObjectProperty(tblName, cprop, prefix, true);

            PostMigration(PropertyMigrationEventType.Add, null, cprop);
        }
コード例 #18
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoRenameObjectClassACL(ObjectClass objClass)
        {
            ObjectClass savedObjClass = savedSchema.FindPersistenceObject<ObjectClass>(objClass.ExportGuid);

            var tblName = objClass.GetTableRef(db);
            var savedTblName = savedObjClass.GetTableRef(db);
            var tblRightsName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass));
            var savedTblRightsName = db.GetTableName(savedObjClass.Module.SchemaName, Construct.SecurityRulesTableName(savedObjClass));

            var rightsViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass));
            var savedRightsViewUnmaterializedName = db.GetTableName(savedObjClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(savedObjClass));

            var refreshRightsOnProcedureName = db.GetProcedureName(objClass.Module.SchemaName, Construct.SecurityRulesRefreshRightsOnProcedureName(objClass));
            var savedRefreshRightsOnProcedureName = db.GetProcedureName(savedObjClass.Module.SchemaName, Construct.SecurityRulesRefreshRightsOnProcedureName(savedObjClass));

            var savedUpdateRightsTriggerName = new TriggerRef(savedTblName, Construct.SecurityRulesUpdateRightsTriggerName(savedObjClass));

            Log.InfoFormat("Renaming ObjectClass Security Rules: {0}", objClass.Name);

            if (db.CheckTriggerExists(savedUpdateRightsTriggerName))
                db.DropTrigger(savedUpdateRightsTriggerName);
            if (db.CheckProcedureExists(savedRefreshRightsOnProcedureName))
                db.DropProcedure(savedRefreshRightsOnProcedureName);
            if (db.CheckViewExists(savedRightsViewUnmaterializedName))
                db.DropView(savedRightsViewUnmaterializedName);

            db.RenameTable(savedTblRightsName, tblRightsName);
            db.RenameIndex(tblRightsName, Construct.SecurityRulesIndexName(savedObjClass), Construct.SecurityRulesIndexName(objClass));
            db.RenameFKConstraint(tblRightsName, Construct.SecurityRulesFKName(savedObjClass), objClass.GetTableRef(db), "ID", Construct.SecurityRulesFKName(objClass), true);

            DoCreateOrReplaceUpdateRightsTrigger(objClass);
            DoCreateRightsViewUnmaterialized(objClass);
            db.CreateRefreshRightsOnProcedure(refreshRightsOnProcedureName, rightsViewUnmaterializedName, tblName, tblRightsName);
        }
コード例 #19
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewCompoundObjectPropertyList(ObjectClass objClass, CompoundObjectProperty cprop)
        {
            if (!PreMigration(PropertyMigrationEventType.Add, null, cprop))
                return;

            Log.InfoFormat("New CompoundObject Property List: {0}", cprop.Name);
            var tblName = db.GetTableName(cprop.Module.SchemaName, cprop.GetCollectionEntryTable());
            string fkName = Construct.ForeignKeyColumnName(cprop);

            // TODO: Support nested CompoundObject
            string valPropIndexName = cprop.Name + "Index";
            string assocName = cprop.GetAssociationName();
            bool hasPersistentOrder = cprop.HasPersistentOrder;

            db.CreateTable(tblName, true);
            db.CreateColumn(tblName, fkName, System.Data.DbType.Int32, 0, 0, false);

            foreach (ValueTypeProperty p in cprop.CompoundObjectDefinition.Properties)
            {
                CheckValueTypePropertyHasWarnings(p);
                db.CreateColumn(tblName, Construct.ColumnName(p, cprop.Name), p.GetDbType(), p.GetSize(), p.GetScale(), true, null);
            }

            if (hasPersistentOrder)
            {
                db.CreateColumn(tblName, valPropIndexName, System.Data.DbType.Int32, 0, 0, false);
            }
            db.CreateFKConstraint(tblName, objClass.GetTableRef(db), fkName, assocName, true);
            db.CreateIndex(tblName, Construct.IndexName(tblName.Name, fkName), false, false, fkName);

            PostMigration(PropertyMigrationEventType.Add, null, cprop);
        }
コード例 #20
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoRenameValueTypePropertyName(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            var savedProp = savedSchema.FindPersistenceObject<ValueTypeProperty>(prop.ExportGuid);

            if (!PreMigration(PropertyMigrationEventType.Rename, savedProp, prop))
                return;

            var tblName = objClass.GetTableRef(db);
            var srcName = Construct.ColumnName(savedProp, prefix);
            var dstName = Construct.ColumnName(prop, prefix);
            if (srcName == dstName) return;

            Log.InfoFormat("Renaming property on '{0}' from '{1}' up to '{2}'", tblName, srcName, dstName);

            // TODO: What if prefix has changed
            db.RenameColumn(tblName, srcName, dstName);

            PostMigration(PropertyMigrationEventType.Rename, savedProp, prop);
        }
コード例 #21
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewObjectClass(ObjectClass objClass)
        {
            if (!PreMigration(ClassMigrationEventType.Add, null, objClass))
                return;

            TableMapping mapping = objClass.GetTableMapping();
            if (mapping == TableMapping.TPT || (mapping == TableMapping.TPH && objClass.BaseObjectClass == null))
            {
                var tblName = objClass.GetTableRef(db);
                Log.InfoFormat("New Table: {0}", tblName);
                if (!db.CheckTableExists(tblName))
                {
                    db.CreateTable(tblName, objClass.BaseObjectClass == null);
                    if (mapping == TableMapping.TPH)
                    {
                        db.CreateColumn(tblName, TableMapper.DiscriminatorColumnName, System.Data.DbType.String, TableMapper.DiscriminatorColumnSize, 0, false);
                    }
                }
                else
                {
                    Log.ErrorFormat("Table {0} already exists", tblName);
                }
            }
            else
            {
                Log.DebugFormat("Skipping table for TPH child {0}", objClass.Name);
            }

            PostMigration(ClassMigrationEventType.Add, null, objClass);
        }
コード例 #22
0
        private void CheckColumns(ObjectClass objClass, ICollection<Property> properties, string prefix)
        {
            Log.Debug("  Columns: ");
            var tblName = objClass.GetTableRef(db);
            var mapping = objClass.GetTableMapping();

            if (mapping == TableMapping.TPH && objClass.BaseObjectClass == null)
            {
                CheckColumn(tblName, TableMapper.DiscriminatorColumnName, System.Data.DbType.String, TableMapper.DiscriminatorColumnSize, 0, false, null);
            }

            foreach (ValueTypeProperty prop in properties.OfType<ValueTypeProperty>()
                .Where(p => !p.IsList)
                .OrderBy(p => p.Module.Namespace).ThenBy(p => p.Name))
            {
                var colName = Construct.ColumnName(prop, prefix);
                Log.DebugFormat("    {0}", colName);

                var realIsNullable = prop.IsNullable();
                if (realIsNullable == false)
                    realIsNullable = mapping == TableMapping.TPH && objClass.BaseObjectClass != null;
                CheckColumn(tblName, colName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), realIsNullable, SchemaManager.GetDefaultConstraint(prop));
            }

            foreach (CompoundObjectProperty sprop in properties.OfType<CompoundObjectProperty>().Where(p => !p.IsList))
            {
                CheckColumns(objClass, sprop.CompoundObjectDefinition.Properties, Construct.ColumnName(sprop, prefix));
            }
        }
コード例 #23
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewObjectClassACL(ObjectClass objClass)
        {
            Log.InfoFormat("New ObjectClass Security Rules: {0}", objClass.Name);
            var tblRightsName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesTableName(objClass));

            db.CreateTable(tblRightsName, false, false);
            db.CreateColumn(tblRightsName, "Identity", System.Data.DbType.Int32, 0, 0, false);
            db.CreateColumn(tblRightsName, "Right", System.Data.DbType.Int32, 0, 0, false);

            db.CreateIndex(tblRightsName, Construct.SecurityRulesIndexName(objClass), true, true, "ID", "Identity");
            db.CreateFKConstraint(tblRightsName, objClass.GetTableRef(db), "ID", Construct.SecurityRulesFKName(objClass), true);

            var tblName = objClass.GetTableRef(db);
            var rightsViewUnmaterializedName = db.GetTableName(objClass.Module.SchemaName, Construct.SecurityRulesRightsViewUnmaterializedName(objClass));
            var refreshRightsOnProcedureName = db.GetProcedureName(objClass.Module.SchemaName, Construct.SecurityRulesRefreshRightsOnProcedureName(objClass));

            DoCreateOrReplaceUpdateRightsTrigger(objClass);
            DoCreateRightsViewUnmaterialized(objClass);
            db.CreateRefreshRightsOnProcedure(refreshRightsOnProcedureName, rightsViewUnmaterializedName, tblName, tblRightsName);
            db.ExecRefreshRightsOnProcedure(refreshRightsOnProcedureName);
        }
コード例 #24
0
        private void CheckIndexConstraints(ObjectClass objClass)
        {
            foreach (var uc in objClass.Constraints.OfType<IndexConstraint>())
            {
                var isFulltextConstraint = uc is FullTextIndexConstraint;
                if (isFulltextConstraint) continue;

                var tblName = objClass.GetTableRef(db);
                var columns = Construct.GetUCColNames(uc);
                var idxName = Construct.IndexName(tblName.Name, columns);
                if (!db.CheckIndexExists(tblName, idxName))
                {
                    Log.WarnFormat("Index Constraint '{0}' is missing", idxName);
                    if (repair)
                    {
                        Case.DoNewIndexConstraint(uc);
                    }
                }
            }
        }
コード例 #25
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoNewObjectClassInheritance(ObjectClass objClass)
        {
            var savedObjClass = savedSchema.FindPersistenceObject<ObjectClass>(objClass.ExportGuid);

            if (!PreMigration(ClassMigrationEventType.ChangeBase, savedObjClass, objClass))
                return;

            var newBaseClass = objClass.BaseObjectClass;
            var assocName = Construct.InheritanceAssociationName(newBaseClass, objClass);
            var tblName = objClass.GetTableRef(db);

            Log.InfoFormat("New ObjectClass Inheritance: {0} -> {1}: {2}", objClass.Name, newBaseClass.Name, assocName);

            var movedUp = IsParentOf(newBaseClass, savedObjClass);
            if (!movedUp && db.CheckTableContainsData(tblName))
            {
                Log.ErrorFormat("Table '{0}' contains data. Unable to add inheritance when the new basetable does not contain instances of the child class.", tblName);
                return;
            }

            db.CreateFKConstraint(tblName, newBaseClass.GetTableRef(db), "ID", assocName, false);

            PostMigration(ClassMigrationEventType.ChangeBase, savedObjClass, objClass);
        }
コード例 #26
0
        private void CheckValueTypeCollections(ObjectClass objClass)
        {
            Log.Debug("ValueType Collections: ");

            foreach (ValueTypeProperty prop in objClass.Properties.OfType<ValueTypeProperty>()
                .Where(p => p.IsList)
                .OrderBy(p => p.Module.Namespace).ThenBy(p => p.Name))
            {
                var tblName = db.GetTableName(prop.Module.SchemaName, prop.GetCollectionEntryTable());
                var fkName = Construct.ForeignKeyColumnName(prop);
                var valPropName = prop.Name;
                var valPropIndexName = prop.Name + "Index";
                var assocName = prop.GetAssociationName();
                var refTblName = objClass.GetTableRef(db);
                bool hasPersistentOrder = prop.HasPersistentOrder;
                if (db.CheckTableExists(tblName))
                {
                    Log.DebugFormat("{0}", prop.Name);
                    CheckColumn(tblName, fkName, System.Data.DbType.Int32, 0, 0, false, null);
                    CheckColumn(tblName, valPropName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), false, SchemaManager.GetDefaultConstraint(prop));

                    if (hasPersistentOrder)
                    {
                        CheckColumn(tblName, valPropIndexName, System.Data.DbType.Int32, 0, 0, true, null);
                    }
                    if (!hasPersistentOrder && db.CheckColumnExists(tblName, valPropIndexName))
                    {
                        Log.WarnFormat("Index Column '{0}' exists but property is not indexed", valPropIndexName);
                    }
                    if (!db.CheckFKConstraintExists(tblName, assocName))
                    {
                        Log.WarnFormat("FK Constraint is missing", prop.Name);
                        if (repair)
                        {
                            db.CreateFKConstraint(tblName, refTblName, fkName, assocName, true);
                        }
                    }
                }
                else
                {
                    Log.WarnFormat("Table '{0}' for Property '{1}' is missing", tblName, prop.Name);
                    if (repair)
                    {
                        Case.DoNewValueTypePropertyList(objClass, prop);
                    }
                }
            }
        }
コード例 #27
0
ファイル: Cases.cs プロジェクト: daszat/zetbox
        public void DoChangeValueTypeProperty_To_NotNullable(ObjectClass objClass, ValueTypeProperty prop, string prefix)
        {
            var savedProp = savedSchema.FindPersistenceObject<ValueTypeProperty>(prop.ExportGuid);

            if (!PreMigration(PropertyMigrationEventType.ChangeToNotNullable, savedProp, prop))
                return;

            var tblName = objClass.GetTableRef(db);
            var colName = Construct.ColumnName(prop, prefix);
            var def = SchemaManager.GetDefaultConstraint(prop);

            if (def == null && db.CheckColumnContainsNulls(tblName, colName))
            {
                Log.ErrorFormat("column '{0}.{1}' contains NULL values and has no default contraint, cannot set NOT NULLABLE", tblName, colName);
            }
            else
            {
                if (def != null)
                {
                    var isSimplyCheckable = objClass.GetTableMapping() == TableMapping.TPT || objClass.BaseObjectClass == null;
                    var classes = objClass.AndChildren(c => c.SubClasses).Select(cls => Construct.DiscriminatorValue(cls)).ToList();

                    WriteDefaultValue(tblName, colName, def, isSimplyCheckable ? null : classes);
                }
                db.AlterColumn(tblName, colName, prop.GetDbType(), prop.GetSize(), prop.GetScale(), prop.IsNullable(), null /* don't change contraints */);
            }

            PostMigration(PropertyMigrationEventType.ChangeToNotNullable, savedProp, prop);
        }