private static void LoadEntitiesYaml(string rootFolder, DiskModelYaml results) { var folder = Path.Combine(rootFolder, FOLDER_ET); if (!Directory.Exists(folder)) { folder = Path.Combine(rootFolder, FOLDER_OLD_ET); if (!Directory.Exists(folder)) { return; } } var fList = Directory.GetFiles(folder, "*.yaml"); //Only use Yaml if there are actual files if (!fList.Any()) { return; } results.Entities.Clear(); foreach (var f in fList) { //Try single object Exception lastException = null; try { results.Entities.Add(GetYamlObject <EntityYaml>(f)); } catch (Exception ex) { lastException = ex; } if (lastException != null) { //If fails try multiple objects per file. If error then really throw try { results.Entities.AddRange(GetYamlObject <EntityYaml[]>(f)); } catch (Exception ex) { //This is a bogus error because the file does NOT contain multiple objects //The first error was correct as the single object YAML was incorrect format if (ex.Message.Contains("Line: 1, Col: 1, Idx: 0")) { throw lastException; } else { throw; } } } } }
private static void SaveViewsYaml(string rootFolder, DiskModelYaml model, List <string> generatedFileList) { var folder = Path.Combine(rootFolder, FOLDER_VW); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } //Save Views foreach (var obj in model.Views) { var f = Path.Combine(folder, $"{obj.Name}.yaml".ToLower()); SaveYamlObject(obj, f, generatedFileList); } }
private static void ConvertViewsOld2Yaml(string rootFolder, DiskModel model, DiskModelYaml model2) { var folder = Path.Combine(rootFolder, FOLDER_VW); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } //Views foreach (var obj in model.Views) { var newView = model2.Views.AddItem(new ViewYaml { CodeFacade = obj.codefacade, GeneratesDoubleDerived = obj.generatesdoublederived != 0, Id = obj.id.ToGuid(), Sql = obj.sql, Name = obj.name, Schema = obj.schema, Summary = obj.summary, }); //Fields foreach (var ff in obj.fieldset) { newView.Fields.AddItem(new ViewFieldYaml { CodeFacade = ff.codefacade, Datatype = ff.datatype.ToEnum <DataTypeConstants>(), Default = ff.@default, Id = ff.id.ToGuid(), IsPrimaryKey = ff.isprimarykey != 0, Length = ff.length, Name = ff.name, Nullable = ff.nullable != 0, Scale = ff.scale, Summary = ff.summary, }); } } }
private static void LoadViewsYaml(string rootFolder, DiskModelYaml results) { var folder = Path.Combine(rootFolder, FOLDER_VW); if (!Directory.Exists(folder)) { folder = Path.Combine(rootFolder, FOLDER_OLD_VW); if (!Directory.Exists(folder)) { return; } } var fList = Directory.GetFiles(folder, "*.yaml"); //Only use Yaml if there are actual files if (!fList.Any()) { return; } results.Views.Clear(); foreach (var f in fList) { results.Views.Add(GetYamlObject <ViewYaml>(f)); } foreach (var f in Directory.GetFiles(folder, "*.sql")) { var fi = new FileInfo(f); var name = fi.Name.Substring(0, fi.Name.Length - fi.Extension.Length).ToLower(); var item = results.Views.FirstOrDefault(x => x.Name.ToLower() == name); if (item != null) { item.Sql = File.ReadAllText(f); } } FixupModel(results); }
public static void Save2(string rootFolder, string modelName, DiskModelYaml model) { FixupModel(model); var modelFolder = GetModelFolder(rootFolder, modelName.Replace(".nhydrate", ".model")); if (modelName.EndsWith(ModelExtension)) { modelFolder = rootFolder; } var generatedFileList = new List <string>(); SaveViewsYaml(modelFolder, model, generatedFileList); //must come before entities SaveEntitiesYaml(modelFolder, model, generatedFileList); //Save the global model properties SaveYamlObject(model.ModelProperties, Path.Combine(modelFolder, "model" + ModelExtension), generatedFileList); //Do not remove diagram file generatedFileList.Add(Path.Combine(modelFolder, "diagram.xml")); generatedFileList.Add(Path.Combine(modelFolder, "nhydrate.generators")); RemoveOrphans(modelFolder, generatedFileList); var folder = Path.Combine(modelFolder, FOLDER_OLD_ET); if (Directory.Exists(folder)) { Directory.Delete(folder, true); } folder = Path.Combine(modelFolder, FOLDER_OLD_VW); if (Directory.Exists(folder)) { Directory.Delete(folder, true); } }
private static void ConvertEntitiesOld2Yaml(string rootFolder, DiskModel model, DiskModelYaml model2) { var folder = Path.Combine(rootFolder, FOLDER_ET); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } foreach (var obj in model.Entities) { var newEntity = model2.Entities.AddItem(new EntityYaml { AllowCreateAudit = obj.allowcreateaudit != 0, AllowModifyAudit = obj.allowmodifyaudit != 0, AllowTimestamp = obj.allowtimestamp != 0, CodeFacade = obj.codefacade, GeneratesDoubleDerived = obj.generatesdoublederived != 0, Id = obj.id.ToGuid(), Immutable = obj.immutable != 0, TypedTable = obj.typedentity.ToEnum <TypedTableConstants>(), IsAssociative = obj.isassociative != 0, IsTenant = obj.isTenant != 0, Name = obj.name, Schema = obj.schema, Summary = obj.summary, }); #region Fields foreach (var ff in obj.fieldset.OrderBy(x => x.sortorder)) { newEntity.Fields.AddItem(new EntityFieldYaml { CodeFacade = ff.codefacade, DataFormatString = ff.dataformatstring, Datatype = ff.datatype.ToEnum <DataTypeConstants>(), Default = ff.@default, DefaultIsFunc = ff.defaultisfunc != 0, Formula = ff.formula, Id = ff.id.ToGuid(), Identity = ff.identity.ToEnum <IdentityTypeConstants>(), IsCalculated = ff.Iscalculated != 0, IsIndexed = ff.isindexed != 0, IsPrimaryKey = ff.isprimarykey != 0, IsReadonly = ff.isreadonly != 0, IsUnique = ff.isunique != 0, Length = ff.length, Name = ff.name, Nullable = ff.nullable != 0, Obsolete = ff.obsolete != 0, Scale = ff.scale, Summary = ff.summary, }); } #endregion #region Indexes foreach (var ii in model.Indexes.Where(x => x.id == obj.id)) { foreach (var ifield in ii.index) { var newIndex = newEntity.Indexes.AddItem(new IndexYaml { Clustered = ifield.clustered != 0, Id = ifield.id.ToGuid(), ImportedName = ifield.importedname, IndexType = (IndexTypeConstants)ifield.indextype, IsUnique = ifield.isunique != 0, Summary = ifield.summary, }); foreach (var i2 in ifield.indexcolumnset.OrderBy(x => x.sortorder)) { newIndex.Fields.AddItem(new IndexFieldYaml { Ascending = i2.ascending != 0, FieldId = i2.fieldid.ToGuid(), FieldName = newEntity.Fields.FirstOrDefault(x => x.Id == i2.fieldid.ToGuid())?.Name, //Id = i2.id.ToGuid(), }); } } } #endregion #region Static data foreach (var sd in model.StaticData.Where(x => x.id == obj.id)) { foreach (var dd in sd.data.OrderBy(x => x.orderkey)) { newEntity.StaticData.AddItem(new StaticDataYaml { ColumnId = dd.columnkey.ToGuid(), Value = dd.value, SortOrder = dd.orderkey, }); } } #endregion } #region Relations (After all entities are loaded) foreach (var obj in model.Entities) { var newEntity = model2.Entities.First(x => x.Id == new Guid(obj.id)); foreach (var rr in model.Relations.Where(x => x.id == obj.id)) { foreach (var relation in rr.relation) { var entity = model.Entities.FirstOrDefault(x => x.id == rr.id); var entity2 = model.Entities.FirstOrDefault(x => x.id == relation.childid); var newRelation = newEntity.Relations.AddItem(new RelationYaml { Id = relation.id.ToGuid(), ForeignEntityName = entity2.name, ForeignEntityId = entity2.id.ToGuid(), }); newRelation.IsEnforced = relation.isenforced != 0; newRelation.DeleteAction = relation.deleteaction.ToEnum <DeleteActionConstants>(); newRelation.RoleName = relation.rolename; newRelation.Summary = relation.summary; foreach (var fsi in relation.relationfieldset) { var newRelationField = new RelationFieldYaml { //Id = fsi.id.ToGuid(), PrimaryFieldId = fsi.sourcefieldid.ToGuid(), PrimaryFieldName = entity.fieldset.FirstOrDefault(x => x.id == fsi.sourcefieldid)?.name, ForeignFieldId = fsi.targetfieldid.ToGuid(), ForeignFieldName = entity2.fieldset.FirstOrDefault(x => x.id == fsi.targetfieldid)?.name, }; newRelation.Fields.AddItem(newRelationField); } } } } #endregion }
private static void FixupModel(DiskModelYaml results) { //Fill in field IDs if need be results.Entities .Where(x => x.Id == Guid.Empty) .ToList() .ForEach(x => x.Id = Guid.NewGuid()); //Validate model. Ensure all Guids match up, etc var allEntities = results.Entities.Select(x => x.Id).ToList(); if (allEntities.Count != allEntities.Distinct().Count()) { throw new ModelException("Entities must have unique ID values."); } foreach (var entity in results.Entities) { //Fill in field IDs if need be entity.Fields .Where(x => x.Id == Guid.Empty) .ToList() .ForEach(x => x.Id = Guid.NewGuid()); //Reset predefined sizes if necessary foreach (var field in entity.Fields) { var size = nHydrate.Generator.Common.Models.ColumnBase.GetPredefinedSize(field.Datatype.Convert <System.Data.SqlDbType>()); field.Length = (size == -1) ? field.Length : size; } if (entity.Fields.Count != entity.Fields.Select(x => x.Id).Count()) { throw new ModelException($"Entity: '{entity.Name}': All fields must have a unique ID."); } #region Indexes if (entity.Indexes.Count(x => x.Clustered) > 1) { throw new ModelException($"Entity: '{entity.Name}': An entity can have only one clustered index."); } foreach (var index in entity.Indexes) { foreach (var field in index.Fields) { var targetField = entity.Fields.FirstOrDefault(x => x.Id == field.FieldId); if (field.FieldId == Guid.Empty) { targetField = entity.Fields.FirstOrDefault(x => x.Name?.ToLower() == field.FieldName?.ToLower()); } if (targetField == null) { throw new ModelException($"Entity: '{entity.Name}': The index must map to an existing field."); } field.FieldId = targetField.Id; field.FieldName = targetField.Name; } } #endregion #region Indexes (Ensure if on fields marked then on index exists) foreach (var field in entity.Fields.Where(x => x.IsIndexed)) { if (!entity.Indexes.Any(x => x.Fields.Any(z => z.FieldId == field.Id))) { entity.Indexes.Add(new IndexYaml { Clustered = false, Id = Guid.NewGuid(), IndexType = field.IsPrimaryKey ? IndexTypeConstants.PrimaryKey : IndexTypeConstants.IsIndexed, IsUnique = false, Fields = new List <IndexFieldYaml>(new[] { new IndexFieldYaml { FieldId = field.Id, FieldName = field.Name, } }), }); } } #endregion #region Relations foreach (var relation in entity.Relations) { var foreignEntity = results.Entities.FirstOrDefault(x => x.Id == relation.ForeignEntityId); if (relation.ForeignEntityId == Guid.Empty) { foreignEntity = results.Entities.FirstOrDefault(x => x.Name?.ToLower() == relation.ForeignEntityName?.ToLower()); } if (foreignEntity == null) { throw new ModelException($"Entity: '{entity.Name}': The relation must map to an existing entity."); } if (!relation.Fields.Any()) { //If there are 0 fields and the foreign table has the same field name as primary table //then add a relation based on that field as this is a short cut for Table1.FieldName->Table2.FieldName //This is the format of most PK-FK anyway. if (entity.Fields.Count(x => x.IsPrimaryKey) == 1) { var pk = entity.Fields.FirstOrDefault(x => x.IsPrimaryKey); var fk = foreignEntity.Fields.FirstOrDefault(x => x.Name == pk.Name); if (fk != null) { relation.Id = Guid.NewGuid(); relation.Fields.Add(new RelationFieldYaml { ForeignFieldId = fk.Id, ForeignFieldName = fk.Name, PrimaryFieldId = pk.Id, PrimaryFieldName = pk.Name, }); } } if (!relation.Fields.Any()) { throw new ModelException($"Entity: '{entity.Name}': The relation must have at least one field."); } } relation.ForeignEntityName = foreignEntity.Name; relation.ForeignEntityId = foreignEntity.Id; foreach (var field in relation.Fields) { var primaryField = entity.Fields.FirstOrDefault(x => x.Id == field.PrimaryFieldId); if (field.PrimaryFieldId == Guid.Empty) { primaryField = entity.Fields.FirstOrDefault(x => x.Name?.ToLower() == field.PrimaryFieldName?.ToLower()); } var foreignField = foreignEntity.Fields.FirstOrDefault(x => x.Id == field.ForeignFieldId); if (field.ForeignFieldId == Guid.Empty) { foreignField = foreignEntity.Fields.FirstOrDefault(x => x.Name?.ToLower() == field.ForeignFieldName?.ToLower()); } if (primaryField == null) { throw new ModelException($"Entity: '{entity.Name}': The relation primary field must map to an existing field."); } if (foreignField == null) { throw new ModelException($"Entity: '{entity.Name}': The relation foreign field must map to an existing field."); } field.PrimaryFieldId = primaryField.Id; field.PrimaryFieldName = primaryField.Name; field.ForeignFieldId = foreignField.Id; field.ForeignFieldName = foreignField.Name; } } #endregion } }
public static DiskModelYaml Load2(string rootFolder, string modelName, out bool wasLoaded) { wasLoaded = false; var modelFile = Path.Combine(rootFolder, modelName); var fi = new FileInfo(modelFile); var showError = (fi.Length > 10); //New file is small so show no error if creating new var modelFolder = GetModelFolder(rootFolder, modelName.Replace(".nhydrate", ".model")); if (modelName.EndsWith(".yaml")) { modelFolder = rootFolder; } //If this is a new visual modeler file then create the folder to hold all files if (modelFolder.EndsWith(".model") && !Directory.Exists(modelFolder)) { Directory.CreateDirectory(modelFolder); System.Threading.Thread.Sleep(500); } //If the model file is empty and folder has 1 file if (fi.Length == 0 && Directory.EnumerateFileSystemEntries(modelFolder).Count() == 1) { //The model file is 0 bytes and there is no folder, so this is a new model wasLoaded = true; } else if (!Directory.Exists(modelFolder)) { if (showError) { throw new Exception("The model folder was not found."); } } else { wasLoaded = true; } //Remove old ZIP file. It is no longer used try { var compressedFile = Path.Combine(rootFolder, modelName + ".zip"); if (File.Exists(compressedFile)) { File.Delete(compressedFile); } } catch { } //Opened the ".nhydrate" XML file if (modelName.EndsWith(OldModelExtension) && File.Exists(modelFile)) { var ff = Directory.GetFiles(Path.Combine(modelFolder)).FirstOrDefault(x => x.EndsWith("model.nhydrate.yaml")); if (ff != null) { modelFile = ff; modelName = (new FileInfo(ff)).Name; } } var results = new DiskModelYaml(); //Determine if model is old XML style and convert var oldModel = Load(rootFolder, modelName, out bool wasOldLoaded); if (wasOldLoaded && oldModel.ModelProperties.Id != Guid.Empty) { ConvertEntitiesOld2Yaml(rootFolder, oldModel, results); ConvertViewsOld2Yaml(rootFolder, oldModel, results); results.ModelProperties = oldModel.ModelProperties; } else { LoadEntitiesYaml(modelFolder, results); LoadViewsYaml(modelFolder, results); //Save the global model properties var globalFile = Path.Combine(modelFolder, modelName); if (File.Exists(globalFile)) { results.ModelProperties = GetYamlObject <ModelProperties>(globalFile) ?? new ModelProperties { Id = Guid.NewGuid() } } ; } return(results); }