/// <exception cref="InstanceNotFoundException">Not found commit for commitId</exception>
        private AjaxTransferDbScheme GetCommit(int appId, int commitId = -1)
        {
            var context         = COREobject.i.Context;
            var result          = new AjaxTransferDbScheme();
            var requestedCommit = FetchDbSchemeCommit(appId, commitId, context);
            int?lockedForUserId = context.Applications.Find(appId).SchemeLockedForUserId;

            result.SchemeLockedForUserId = lockedForUserId; //set the lockedForUserId for ajax model
            if (lockedForUserId != null)
            {
                result.SchemeLockedForUserName = context.Users.SingleOrDefault(u => u.Id == result.SchemeLockedForUserId).DisplayName;
            }
            if (commitId == -1 && requestedCommit != null)
            {
                DbSchemeCommit       sharedCommit = FetchDbSchemeCommit(Application.SystemApp().Id, commitId, context);
                AjaxTransferDbScheme sharedScheme = new AjaxTransferDbScheme();

                SetAttributesRequestCommitTables(sharedCommit, sharedScheme);
                SetAttributesRequestCommitRelations(sharedCommit, sharedScheme);
                SetAttributesRequestCommitViews(sharedCommit, sharedScheme);
                sharedScheme.CurrentSchemeCommitId = context.Applications.Find(appId).DatabaseDesignerSchemeCommits.OrderByDescending(s => s.Timestamp).FirstOrDefault().Id;
                result.Shared = sharedScheme;
                if (requestedCommit == null)
                {
                    return(result);
                }
            }

            //Latest commit was requested, but there are no commits yet. Returning an empty commit.
            if (requestedCommit == null)
            {
                return(new AjaxTransferDbScheme()
                {
                    CurrentSchemeCommitId = null
                });
            }
            result.CurrentSchemeCommitId = context.Applications.Find(appId).DatabaseDesignerSchemeCommits.OrderByDescending(s => s.Timestamp).FirstOrDefault().Id;

            SetAttributesRequestCommitTables(requestedCommit, result);
            SetAttributesRequestCommitRelations(requestedCommit, result);
            SetAttributesRequestCommitViews(requestedCommit, result);

            return(result);
        }
 private static void SetAttributesRequestCommitTables(DbSchemeCommit requestedCommit, AjaxTransferDbScheme result)
 {
     foreach (var table in requestedCommit.Tables)
     {
         var ajaxTable = new AjaxTransferDbTable
         {
             Id        = table.Id,
             Name      = table.Name,
             PositionX = table.PositionX,
             PositionY = table.PositionY
         };
         foreach (var column in table.Columns)
         {
             ajaxTable.Columns.Add(new AjaxTransferDbColumn
             {
                 AllowNull         = column.AllowNull,
                 ColumnLength      = column.ColumnLength,
                 ColumnLengthIsMax = column.ColumnLengthIsMax,
                 DefaultValue      = column.DefaultValue,
                 Id          = column.Id,
                 Name        = column.Name,
                 DisplayName = column.DisplayName,
                 PrimaryKey  = column.PrimaryKey,
                 Type        = column.Type,
                 Unique      = column.Unique,
             });
         }
         foreach (var index in table.Indices)
         {
             ajaxTable.Indices.Add(new AjaxTransferDbIndex
             {
                 ColumnNames = index.ColumnNames.Split(',').ToList(),
                 Id          = index.Id,
                 Name        = index.Name,
                 Unique      = index.Unique,
             });
         }
         result.Tables.Add(ajaxTable);
     }
 }
 private static void SetAttributesRequestCommitRelations(DbSchemeCommit requestedCommit, AjaxTransferDbScheme result)
 {
     foreach (var relation in requestedCommit.Relations)
     {
         result.Relations.Add(new AjaxTransferDbRelation
         {
             SourceColumn = relation.SourceColumnId,
             SourceTable  = relation.SourceTableId,
             TargetColumn = relation.TargetColumnId,
             TargetTable  = relation.TargetTableId,
             Type         = relation.Type
         });
     }
 }
 private static void SetAttributesRequestCommitViews(DbSchemeCommit requestedCommit, AjaxTransferDbScheme result)
 {
     foreach (var view in requestedCommit.Views)
     {
         result.Views.Add(new AjaxTransferDbView
         {
             Id        = view.Id,
             Name      = view.Name,
             PositionX = view.PositionX,
             PositionY = view.PositionY,
             Query     = view.Query,
         });
     }
 }
        public int SaveScheme(int appId, AjaxTransferDbScheme postData)
        {
            bool dbSchemeLocked = false;

            try
            {
                DbSchemeCommit commit       = new DbSchemeCommit();
                var            context      = COREobject.i.Context;
                var            requestedApp = context.Applications.Find(appId);
                requestedApp.SchemeLockedForUserId = null;
                if (requestedApp.DbSchemeLocked)
                {
                    throw new InvalidOperationException("This application's database scheme is locked because another process is currently working with it.");
                }
                requestedApp.DbSchemeLocked = dbSchemeLocked = true;
                requestedApp.EntitronChangedSinceLastBuild = true;
                requestedApp.TapestryChangedSinceLastBuild = true;
                context.SaveChanges();
                commit.Timestamp     = DateTime.UtcNow;
                commit.CommitMessage = postData.CommitMessage;
                requestedApp.DatabaseDesignerSchemeCommits.Add(commit);
                Dictionary <int, int>      tableIdMapping  = new Dictionary <int, int>();
                Dictionary <int, int>      columnIdMapping = new Dictionary <int, int>();
                Dictionary <int, DbColumn> columnMapping   = new Dictionary <int, DbColumn>();

                foreach (var ajaxTable in postData.Tables)
                {
                    int     ajaxTableId = ajaxTable.Id;
                    DbTable newTable    = new DbTable {
                        Name = ajaxTable.Name, PositionX = ajaxTable.PositionX, PositionY = ajaxTable.PositionY
                    };
                    foreach (var column in ajaxTable.Columns)
                    {
                        int      ajaxColumnId = column.Id;
                        DbColumn newColumn    = new DbColumn
                        {
                            Name              = column.Name,
                            DisplayName       = column.DisplayName,
                            Type              = column.Type,
                            PrimaryKey        = column.PrimaryKey,
                            AllowNull         = column.AllowNull,
                            DefaultValue      = column.DefaultValue,
                            ColumnLength      = column.ColumnLength,
                            ColumnLengthIsMax = column.ColumnLengthIsMax,
                            Unique            = column.Unique
                        };
                        newTable.Columns.Add(newColumn);
                        context.SaveChanges();
                        columnMapping.Add(ajaxColumnId, newColumn);
                    }
                    foreach (var index in ajaxTable.Indices)
                    {
                        string columnNamesString = "";
                        if (index.ColumnNames.Count > 0)
                        {
                            for (int i = 0; i < index.ColumnNames.Count - 1; i++)
                            {
                                columnNamesString += index.ColumnNames[i] + ",";
                            }
                            columnNamesString += index.ColumnNames.Last();
                        }
                        DbIndex newIndex = new DbIndex
                        {
                            Name        = index.Name,
                            Unique      = index.Unique,
                            ColumnNames = columnNamesString
                        };
                        newTable.Indices.Add(newIndex);
                    }
                    commit.Tables.Add(newTable);
                    context.SaveChanges();
                    tableIdMapping.Add(ajaxTableId, newTable.Id);
                    foreach (var column in ajaxTable.Columns)
                    {
                        DbColumn col =
                            newTable.Columns.SingleOrDefault(x => x.Name.ToLower() == columnMapping[column.Id].Name.ToLower());

                        columnIdMapping.Add(column.Id, col.Id);
                    }
                }
                foreach (var ajaxRelation in postData.Relations)
                {
                    int     sourceTable   = tableIdMapping[ajaxRelation.SourceTable];
                    int     targetTable   = tableIdMapping[ajaxRelation.TargetTable];
                    int     sourceColumn  = columnIdMapping[ajaxRelation.SourceColumn];
                    int     targetColumn  = columnIdMapping[ajaxRelation.TargetColumn];
                    DbTable targetTableDb = commit.Tables.SingleOrDefault(x => x.Id == targetTable);
                    DbTable sourceTableDb = commit.Tables.SingleOrDefault(x => x.Id == sourceTable);
                    string  name          = targetTableDb.Name + targetTableDb.Columns.SingleOrDefault(x => x.Id == targetColumn).Name + "_" + sourceTableDb.Name + sourceTableDb.Columns.SingleOrDefault(x => x.Id == sourceColumn).Name;
                    commit.Relations.Add(new DbRelation
                    {
                        SourceTableId  = sourceTable,
                        TargetTableId  = targetTable,
                        SourceColumnId = sourceColumn,
                        TargetColumnId = targetColumn,
                        Type           = ajaxRelation.Type,
                        Name           = name
                    });
                }
                foreach (var ajaxView in postData.Views)
                {
                    commit.Views.Add(new DbView
                    {
                        Name      = ajaxView.Name,
                        Query     = ajaxView.Query,
                        PositionX = ajaxView.PositionX,
                        PositionY = ajaxView.PositionY
                    });
                }
                requestedApp.DbSchemeLocked = dbSchemeLocked = false;
                commit.IsComplete           = true;
                context.SaveChanges();
                return(commit.Id);
            }
            catch (Exception ex)
            {
                if (dbSchemeLocked)
                {
                    var context      = COREobject.i.Context;
                    var requestedApp = context.Applications.Find(appId);
                    requestedApp.DbSchemeLocked = false;
                    context.SaveChanges();
                }
                var errorMessage = "DatabaseDesigner: an error occurred when saving the database scheme (POST api/database/apps/{appId}/commits). " +
                                   $"Exception message: {ex.Message}";
                Log.Error(errorMessage);
                throw GetHttpInternalServerErrorResponseException(errorMessage);
            }
        }