예제 #1
0
        private void Check_1_1_RelationColumns(Relation rel, RelationEnd relEnd, RelationEndRole role)
        {
            if (rel.HasStorage(role))
            {
                var         tblName    = db.GetTableName(relEnd.Type.Module.SchemaName, relEnd.Type.TableName);
                RelationEnd otherEnd   = rel.GetOtherEnd(relEnd);
                var         refTblName = db.GetTableName(otherEnd.Type.Module.SchemaName, otherEnd.Type.TableName);
                string      colName    = Construct.ForeignKeyColumnName(otherEnd);
                string      assocName  = rel.GetRelationAssociationName(role);
                string      idxName    = Construct.IndexName(tblName.Name, colName);

                CheckColumn(tblName, Construct.ForeignKeyColumnName(otherEnd), System.Data.DbType.Int32, 0, 0, otherEnd.IsNullable(), null);
                if (!db.CheckFKConstraintExists(tblName, assocName))
                {
                    Log.WarnFormat("FK Constraint '{0}' is missing", assocName);
                    if (repair)
                    {
                        db.CreateFKConstraint(tblName, refTblName, colName, assocName, false);
                    }
                }
                if (!db.CheckIndexExists(tblName, idxName))
                {
                    Log.WarnFormat("Index '{0}' is missing", idxName);
                    if (repair)
                    {
                        db.CreateIndex(tblName, idxName, true, false, colName);
                    }
                }
            }
        }
예제 #2
0
 private void GetRelationColumnNames(ObjectClass objClass, List <string> columns)
 {
     foreach (var relEnd in schema.GetQuery <RelationEnd>().Where(e => e.Type == objClass))
     {
         if (relEnd.Parent.HasStorage(relEnd.GetRole()))
         {
             columns.Add(Construct.ForeignKeyColumnName(relEnd.Parent.GetOtherEnd(relEnd)));
             if (relEnd.Parent.NeedsPositionStorage(relEnd.GetRole()))
             {
                 columns.Add(Construct.ListPositionColumnName(relEnd.Parent.GetOtherEnd(relEnd)));
             }
         }
     }
 }
예제 #3
0
        private void ApplyNMProperty(
            Relation rel, RelationEnd relEnd, RelationEnd otherEnd,
            ObjectReferenceProperty prop)
        {
            this.WriteLine("        <!-- NMProperty -->");
            this.WriteLine("        <!-- rel={0} -->", rel.GetRelationClassName());
            this.WriteLine("        <!-- relEnd={0} otherEnd={1} -->", relEnd.RoleName, otherEnd.RoleName);

            string nameAttr  = String.Format("name=\"{0}\"", prop.Name);
            string tableName = rel.GetRelationTableName();
            string tableAttr = String.Format("table=\"`{0}`\"", tableName);

            string relationEntryClassAttr = String.Format("class=\"{0}.{1}{2}+{1}Proxy,Zetbox.Objects.NHibernateImpl\"",
                                                          rel.Module.Namespace,
                                                          rel.GetRelationClassName(),
                                                          ImplementationSuffix);

            string fkThisColumnAttr = String.Format("column=\"`{0}`\"", Construct.ForeignKeyColumnName(relEnd));

            //string fkOtherColumnAttr = String.Format("column=\"`{0}`\"", Construct.ForeignKeyColumnName(otherEnd));

            // always map as set, the wrapper has to translate/order the elements
            this.WriteObjects("        <set ", nameAttr, " ", tableAttr, " inverse=\"true\" cascade=\"all-delete-orphan\" batch-size=\"100\" ");
            if (prop.EagerLoading)
            {
                // TODO: re-think and re-test eagerloading
                //this.WriteObjects("lazy=\"false\" fetch=\"join\" ");
            }
            this.WriteLine(">");

            this.WriteObjects("            <key ", fkThisColumnAttr, " />");
            this.WriteLine();
            this.WriteObjects("            <one-to-many ", relationEntryClassAttr, " />");
            this.WriteLine();
            this.WriteObjects("        </set>");
            this.WriteLine();
        }
예제 #4
0
        protected virtual void ApplyObjectReferenceProperty(string prefix, ObjectReferenceProperty prop)
        {
            this.WriteLine("<!-- ObjectReferenceProperty -->");

            var rel      = Zetbox.App.Extensions.RelationExtensions.Lookup(ctx, prop);
            var relEnd   = rel.GetEnd(prop);
            var otherEnd = rel.GetOtherEnd(relEnd);

            string nameAttr  = String.Format("name=\"{0}\"", prop.Name);
            string classAttr = String.Format("class=\"{0}\"",
                                             ObjectClassHbm.GetAssemblyQualifiedProxy(otherEnd.Type, this.Settings));

            //string tableAttr = String.Format("table =\"`{0}`\" ", rel.GetAssociationName());

            switch (rel.GetRelationType())
            {
            case RelationType.one_one:
                if (rel.HasStorage(relEnd.GetRole()))
                {
                    string columnAttr = String.Format("column=\"`{0}`\"", Construct.ForeignKeyColumnName(otherEnd, prefix));
                    this.WriteObjects("        <many-to-one ", nameAttr, " ", columnAttr, " ", classAttr, " unique=\"true\" ");
                    if (prop.EagerLoading)
                    {
                        // TODO: re-think and re-test eagerloading
                        //this.WriteObjects("fetch=\"join\" ");
                    }
                    this.WriteLine("/>");
                }
                else
                {
                    this.WriteObjects("        <one-to-one ", nameAttr, " ", classAttr,
                                      " constrained=\"false\" ", // constrained must be false, because else the reference is not optional(!)
                                                                 // TODO: re-think and re-test eagerloading
                                                                 //prop.EagerLoading ? "fetch=\"join\" " : String.Empty,
                                      "property-ref=\"" + (otherEnd.Navigator != null ? otherEnd.Navigator.Name : "(no nav)") + "\" />");
                }
                break;

            case RelationType.one_n:
                if (otherEnd.Multiplicity.UpperBound() > 1)     // we are 1-side
                {
                    // always map as set, the wrapper has to translate/order the elements
                    this.WriteObjects("        <set ", nameAttr, " batch-size=\"100\" cascade=\"none\" inverse=\"true\" ");
                    if (prop.EagerLoading)
                    {
                        // TODO: re-think and re-test eagerloading
                        //this.WriteObjects("lazy=\"false\" fetch=\"join\" ");
                    }
                    this.WriteLine(">");
                    string columnAttr = String.Format("column=\"`{0}`\"", Construct.ForeignKeyColumnName(relEnd, prefix));
                    this.WriteObjects("            <key ", columnAttr, " />");
                    this.WriteLine();
                    this.WriteObjects("            <one-to-many ", classAttr, " />");
                    this.WriteLine();
                    this.WriteLine("        </set>");
                }
                else     // we are n-side
                {
                    string columnAttr = String.Format("column=\"`{0}`\"", Construct.ForeignKeyColumnName(otherEnd, prefix));
                    this.WriteObjects("        <many-to-one ", nameAttr, " ", columnAttr, " ", classAttr, " ");
                    if (prop.EagerLoading)
                    {
                        // TODO: re-think and re-test eagerloading
                        //this.WriteObjects("fetch=\"join\" ");
                    }
                    this.WriteLine("/>");
                    if (rel.NeedsPositionStorage(relEnd.GetRole()))
                    {
                        string posNameAttr   = String.Format("name=\"{0}\"", Construct.ListPositionPropertyName(relEnd));
                        string posColumnAttr = String.Format("column=\"`{0}`\"", Construct.ListPositionColumnName(otherEnd, prefix));
                        this.WriteObjects("        <property ", posNameAttr, " ", posColumnAttr, " />");
                        this.WriteLine();
                    }
                }
                break;

            case RelationType.n_m:
                ApplyNMProperty(rel, relEnd, otherEnd, prop);
                break;

            default:
                throw new NotImplementedException(String.Format("Unknown RelationType {0} found", rel.GetRelationType()));
            }

            this.WriteLine();
        }
예제 #5
0
        private void UpdateProcedures()
        {
            Log.Info("Updating Procedures");
            Log.Debug("-------------------");

            var refSpecsASide = schema.GetQuery <RelationEnd>()
                                .Where(relEnd =>
                                       relEnd.Multiplicity == Multiplicity.ZeroOrMore &&
                                       relEnd.HasPersistentOrder &&
                                       relEnd.AParent != null &&
                                       (relEnd.AParent.B.Multiplicity == Multiplicity.One ||
                                        relEnd.AParent.B.Multiplicity == Multiplicity.ZeroOrOne))
                                .Select(relEnd => new
            {
                OtherEnd      = relEnd.AParent.B,
                schemaName    = relEnd.Type.Module.SchemaName,
                tblName       = relEnd.Type.TableName,
                refSchemaName = relEnd.AParent.B.Type.Module.SchemaName,
                refTableName  = relEnd.AParent.B.Type.TableName,
            })
                                .ToList();

            var refSpecsBSide = schema.GetQuery <RelationEnd>()
                                .Where(relEnd =>
                                       relEnd.Multiplicity == Multiplicity.ZeroOrMore &&
                                       relEnd.HasPersistentOrder &&
                                       relEnd.BParent != null &&
                                       (relEnd.BParent.A.Multiplicity == Multiplicity.One ||
                                        relEnd.BParent.A.Multiplicity == Multiplicity.ZeroOrOne))
                                .Select(relEnd => new
            {
                OtherEnd      = relEnd.BParent.A,
                schemaName    = relEnd.Type.Module.SchemaName,
                tblName       = relEnd.Type.TableName,
                refSchemaName = relEnd.BParent.A.Type.Module.SchemaName,
                refTableName  = relEnd.BParent.A.Type.TableName,
            })
                                .ToList();

            var refSpecs = refSpecsASide.Concat(refSpecsBSide)
                           .ToLookup(
                refSpec => db.GetTableName(refSpec.schemaName, refSpec.tblName),
                refSpec => new KeyValuePair <TableRef, string>(db.GetTableName(refSpec.refSchemaName, refSpec.refTableName), Construct.ForeignKeyColumnName(refSpec.OtherEnd)));

            db.CreatePositionColumnValidCheckProcedures(refSpecs);

            var getSequenceNumberRef = db.GetProcedureName("dbo", "GetSequenceNumber");

            if (!db.CheckProcedureExists(getSequenceNumberRef))
            {
                db.CreateSequenceNumberProcedure();
            }
            else if (repair)
            {
                db.DropProcedure(getSequenceNumberRef);
                db.CreateSequenceNumberProcedure();
            }

            var getContinuousSequenceNumberRef = db.GetProcedureName("dbo", "GetContinuousSequenceNumber");

            if (!db.CheckProcedureExists(getContinuousSequenceNumberRef))
            {
                db.CreateContinuousSequenceNumberProcedure();
            }
            else if (repair)
            {
                db.DropProcedure(getContinuousSequenceNumberRef);
                db.CreateContinuousSequenceNumberProcedure();
            }
        }
예제 #6
0
        private void Check_1_N_RelationColumns(Relation rel)
        {
            string assocName = rel.GetAssociationName();

            RelationEnd relEnd, otherEnd;

            switch (rel.Storage)
            {
            case StorageType.MergeIntoA:
                relEnd   = rel.A;
                otherEnd = rel.B;
                break;

            case StorageType.MergeIntoB:
                otherEnd = rel.A;
                relEnd   = rel.B;
                break;

            default:
                Log.ErrorFormat("Relation '{0}' has unsupported Storage set: {1}, skipped", assocName, rel.Storage);
                return;
            }

            var  tblName    = db.GetTableName(relEnd.Type.Module.SchemaName, relEnd.Type.TableName);
            var  refTblName = db.GetTableName(otherEnd.Type.Module.SchemaName, otherEnd.Type.TableName);
            bool isIndexed  = rel.NeedsPositionStorage(relEnd.GetRole());

            string colName   = Construct.ForeignKeyColumnName(otherEnd);
            string indexName = Construct.ListPositionColumnName(otherEnd);

            CheckColumn(tblName, colName, System.Data.DbType.Int32, 0, 0, otherEnd.IsNullable(), null);

            if (!db.CheckFKConstraintExists(tblName, assocName))
            {
                Log.WarnFormat("FK Constraint '{0}' is missing", assocName);
                if (repair)
                {
                    db.CreateFKConstraint(tblName, refTblName, colName, assocName, false);
                }
            }

            if (!db.CheckIndexExists(tblName, Construct.IndexName(tblName.Name, colName)))
            {
                Log.WarnFormat("Index '{0}' is missing", Construct.IndexName(tblName.Name, colName));
                if (repair)
                {
                    db.CreateIndex(tblName, Construct.IndexName(tblName.Name, colName), false, false, colName);
                }
            }

            if (isIndexed)
            {
                CheckOrderColumn(tblName, indexName);
            }
            if (!isIndexed && db.CheckColumnExists(tblName, indexName))
            {
                Log.WarnFormat("Index Column exists but property is not indexed");
                if (repair)
                {
                    Case.Do_1_N_RelationChange_FromIndexed_To_NotIndexed(rel);
                }
            }
        }
예제 #7
0
        public static IList <Join> CreateJoinList(ISchemaProvider db, ObjectClass objClass, IEnumerable <Relation> relations, Relation until)
        {
            if (db == null)
            {
                throw new ArgumentNullException("db");
            }
            if (objClass == null)
            {
                throw new ArgumentNullException("objClass");
            }
            if (relations == null)
            {
                throw new ArgumentNullException("relations");
            }

            List <Join> result        = new List <Join>();
            string      lastColumName = "ID";
            Join        lastJoin      = ColumnRef.PrimaryTable;
            ObjectClass lastType      = objClass;

            foreach (var rel in relations)
            {
                RelationEnd lastRelEnd;
                RelationEnd nextRelEnd;

                if (rel.A.Type == lastType)
                {
                    lastRelEnd = rel.A;
                    nextRelEnd = rel.B;
                }
                else if (rel.B.Type == lastType)
                {
                    lastRelEnd = rel.B;
                    nextRelEnd = rel.A;
                }
                else
                {
                    throw new JoinListException(string.Format("Unable to create JoinList: Unable to navigate from '{0}' over '{1}' to next type", lastType.Name, rel.ToString()));
                }

                if (rel.GetRelationType() == RelationType.n_m)
                {
                    var viewRel = new Join();
                    result.Add(viewRel);
                    viewRel.JoinTableName  = db.GetTableName(rel.Module.SchemaName, rel.GetRelationTableName());
                    viewRel.JoinColumnName = new[] { new ColumnRef(Construct.ForeignKeyColumnName(lastRelEnd), ColumnRef.Local) };
                    viewRel.FKColumnName   = new[] { new ColumnRef(lastColumName, lastJoin) };
                    lastJoin = viewRel;

                    viewRel = new Join();
                    result.Add(viewRel);
                    viewRel.JoinTableName  = db.GetTableName(nextRelEnd.Type.Module.SchemaName, nextRelEnd.Type.TableName);
                    viewRel.JoinColumnName = new[] { new ColumnRef("ID", ColumnRef.Local) };
                    viewRel.FKColumnName   = new[] { new ColumnRef(Construct.ForeignKeyColumnName(nextRelEnd), lastJoin) };

                    lastColumName = "ID"; // viewRel.FKColumnName.Single().ColumnName;
                    lastJoin      = viewRel;
                }
                else
                {
                    var viewRel = new Join();
                    result.Add(viewRel);
                    viewRel.JoinTableName = db.GetTableName(nextRelEnd.Type.Module.SchemaName, nextRelEnd.Type.TableName);
                    string localCol = string.Empty;
                    string fkCol    = string.Empty;
                    if (nextRelEnd == rel.A && rel.Storage == StorageType.MergeIntoA)
                    {
                        localCol = Construct.ForeignKeyColumnName(lastRelEnd);
                        fkCol    = "ID";
                    }
                    else if (nextRelEnd == rel.A && rel.Storage == StorageType.MergeIntoB)
                    {
                        localCol = "ID";
                        fkCol    = Construct.ForeignKeyColumnName(nextRelEnd);
                    }
                    else if (nextRelEnd == rel.B && rel.Storage == StorageType.MergeIntoA)
                    {
                        localCol = "ID";
                        fkCol    = Construct.ForeignKeyColumnName(nextRelEnd);
                    }
                    else if (nextRelEnd == rel.B && rel.Storage == StorageType.MergeIntoB)
                    {
                        localCol = Construct.ForeignKeyColumnName(lastRelEnd);
                        fkCol    = "ID";
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format("StorageType {0} is not supported", rel.Storage));
                    }
                    viewRel.JoinColumnName = new[] { new ColumnRef(localCol, ColumnRef.Local) };
                    viewRel.FKColumnName   = new[] { new ColumnRef(fkCol, lastJoin) };
                    lastColumName          = localCol;
                    lastJoin = viewRel;
                }

                lastType = nextRelEnd.Type;
                if (rel == until)
                {
                    return(result);
                }
            }
            return(result);
        }