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); } } } }
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))); } } } }
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(); }
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(); }
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(); } }
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); } } }
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); }