private void CreateAttacher(ITableInfo t, QueryBuilder qb, LoadMetadata lmd, LoadProgress loadProgressIfAny)
        {
            var pt = new ProcessTask(Activator.RepositoryLocator.CatalogueRepository, lmd, LoadStage.Mounting);

            pt.ProcessTaskType = ProcessTaskType.Attacher;
            pt.Name            = "Read from " + t;
            pt.Path            = typeof(RemoteTableAttacher).FullName;
            pt.SaveToDatabase();

            pt.CreateArgumentsForClassIfNotExists <RemoteTableAttacher>();


            pt.SetArgumentValue("RemoteServer", t.Server);
            pt.SetArgumentValue("RemoteDatabaseName", t.GetDatabaseRuntimeName(LoadStage.PostLoad));
            pt.SetArgumentValue("RemoteTableName", t.GetRuntimeName());
            pt.SetArgumentValue("DatabaseType", DatabaseType.MicrosoftSQLServer);
            pt.SetArgumentValue("RemoteSelectSQL", qb.SQL);

            pt.SetArgumentValue("RAWTableName", t.GetRuntimeName(LoadBubble.Raw));

            if (loadProgressIfAny != null)
            {
                pt.SetArgumentValue("Progress", loadProgressIfAny);
//              pt.SetArgumentValue("ProgressUpdateStrategy", DataLoadProgressUpdateStrategy.UseMaxRequestedDay);
                pt.SetArgumentValue("LoadNotRequiredIfNoRowsRead", true);
            }

            /*
             *
             *  public DataLoadProgressUpdateInfo { get; set; }
             */
        }
        /// <summary>
        /// Returns the reason why <paramref name="table"/> is not refactorable e.g. if it's name is not properly qualified
        /// with database.  Returns null if it is refactorable
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public string GetReasonNotRefactorable(ITableInfo table)
        {
            if (string.IsNullOrWhiteSpace(table.Name))
            {
                return("Table has no Name property, this should be the fully qualified database table name");
            }

            if (string.IsNullOrWhiteSpace(table.Database))
            {
                return("Table does not have it's Database property set");
            }

            //ensure database and Name match correctly
            var syntaxHelper = table.GetQuerySyntaxHelper();
            var db           = table.GetDatabaseRuntimeName(Curation.Data.DataLoad.LoadStage.PostLoad);

            if (!table.Name.StartsWith(syntaxHelper.EnsureWrapped(db)))
            {
                return(string.Format("Table with Name '{0}' has incorrect database propery '{1}'", table.Name, table.Database));
            }

            if (table.Name != table.GetFullyQualifiedName())
            {
                return(string.Format("Table name '{0}' did not match the expected fully qualified name '{1}'", table.Name, table.GetFullyQualifiedName()));
            }

            return(null);
        }
Exemple #3
0
        public void Add(ColumnInfo columnInfo, ITableInfo tableInfo, string databaseName, LoadStage stage, IQuerySyntaxHelper syntaxHelper)
        {
            var col    = columnInfo.GetRuntimeName(stage);
            var table  = tableInfo.GetRuntimeName(stage);
            var dbName = tableInfo.GetDatabaseRuntimeName(stage);

            var snip = new SubstringAutocompleteItem(col);

            snip.MenuText = col;

            var fullySpecified = syntaxHelper.EnsureFullyQualified(dbName, tableInfo.Schema, table, col);

            snip.Text       = fullySpecified;
            snip.Tag        = columnInfo;
            snip.ImageIndex = GetIndexFor(columnInfo, RDMPConcept.ColumnInfo.ToString());

            AddUnlessDuplicate(snip);
        }
Exemple #4
0
        public void Add(ITableInfo tableInfo, LoadStage loadStage)
        {
            //we already have it or it is not setup properly
            if (items.Any(i => i.Tag.Equals(tableInfo)) || string.IsNullOrWhiteSpace(tableInfo.Database) || string.IsNullOrWhiteSpace(tableInfo.Server))
            {
                return;
            }

            var runtimeName = tableInfo.GetRuntimeName(loadStage);
            var dbName      = tableInfo.GetDatabaseRuntimeName(loadStage);

            var syntaxHelper = tableInfo.GetQuerySyntaxHelper();
            var fullSql      = syntaxHelper.EnsureFullyQualified(dbName, null, runtimeName);

            var snip = new SubstringAutocompleteItem(tableInfo.GetRuntimeName());

            snip.MenuText   = runtimeName; //name of table
            snip.Text       = fullSql;     //full SQL
            snip.Tag        = tableInfo;   //record object for future reference
            snip.ImageIndex = GetIndexFor(tableInfo, RDMPConcept.TableInfo.ToString());


            foreach (IHasStageSpecificRuntimeName o in tableInfo.GetColumnsAtStage(loadStage))
            {
                var preDiscarded = o as PreLoadDiscardedColumn;
                var columnInfo   = o as ColumnInfo;

                if (preDiscarded != null)
                {
                    Add(preDiscarded, tableInfo, dbName);
                }
                else
                if (columnInfo != null)
                {
                    Add(columnInfo, tableInfo, dbName, loadStage, syntaxHelper);
                }
                else
                {
                    throw new Exception("Expected IHasStageSpecificRuntimeName returned by TableInfo.GetColumnsAtStage to return only ColumnInfos and PreLoadDiscardedColumns.  It returned a '" + o.GetType().Name + "'");
                }
            }

            AddUnlessDuplicate(snip);
        }
Exemple #5
0
        /// <summary>
        ///
        /// </summary>
        /// <exception cref="SynchronizationFailedException">Could not figure out how to resolve a synchronization problem between the TableInfo and the underlying table structure</exception>
        /// <param name="notifier">Called every time a fixable problem is detected, method must return true or false.  True = apply fix, False = don't - but carry on checking</param>
        public bool Synchronize(ICheckNotifier notifier)
        {
            bool IsSynched = true;

            //server exists and is accessible?
            try
            {
                _toSyncTo.TestConnection();
            }
            catch (Exception e)
            {
                throw new SynchronizationFailedException("Could not connect to " + _toSyncTo, e);
            }

            //database exists?
            var expectedDatabase = _toSyncTo.ExpectDatabase(_tableToSync.GetDatabaseRuntimeName());

            if (!expectedDatabase.Exists())
            {
                throw new SynchronizationFailedException("Server did not contain a database called " + _tableToSync.GetDatabaseRuntimeName());
            }

            //identify new columns
            DiscoveredColumn[] liveColumns;
            DiscoveredTable    expectedTable;

            if (_tableToSync.IsTableValuedFunction)
            {
                expectedTable = expectedDatabase.ExpectTableValuedFunction(_tableToSync.GetRuntimeName(), _tableToSync.Schema);
                if (!expectedTable.Exists())
                {
                    throw new SynchronizationFailedException("Database " + expectedDatabase + " did not contain a TABLE VALUED FUNCTION called " + _tableToSync.GetRuntimeName());
                }
            }
            else
            {
                //table exists?
                expectedTable = expectedDatabase.ExpectTable(_tableToSync.GetRuntimeName(), _tableToSync.Schema, _tableToSync.IsView ? TableType.View:TableType.Table);
                if (!expectedTable.Exists())
                {
                    throw new SynchronizationFailedException(
                              $"Database {expectedDatabase} did not contain a {(_tableToSync.IsView ? "view" : "table") } called {_tableToSync.GetRuntimeName()} (make sure you have marked whether it is a table/view and that it exists in your database)");
                }
            }

            try
            {
                liveColumns = expectedTable.DiscoverColumns();
            }
            catch (SqlException e)
            {
                throw new Exception("Failed to enumerate columns in " +
                                    _toSyncTo +
                                    " (we were attempting to synchronize the TableInfo " + _tableToSync + " (ID=" + _tableToSync.ID + ").  Check the inner exception for specifics", e);
            }

            ColumnInfo[] catalogueColumns = _tableToSync.ColumnInfos.ToArray();


            IDataAccessCredentials credentialsIfExists = _tableToSync.GetCredentialsIfExists(DataAccessContext.InternalDataProcessing);
            string pwd = null;
            string usr = null;

            if (credentialsIfExists != null)
            {
                usr = credentialsIfExists.Username;
                pwd = credentialsIfExists.GetDecryptedPassword();
            }

            ITableInfoImporter importer;

            //for importing new stuff
            if (_tableToSync.IsTableValuedFunction)
            {
                importer = new TableValuedFunctionImporter(_repository, (DiscoveredTableValuedFunction)expectedTable);
            }
            else
            {
                importer = new TableInfoImporter(_repository, _toSyncTo.Name, _toSyncTo.GetCurrentDatabase().GetRuntimeName(), _tableToSync.GetRuntimeName(), _tableToSync.DatabaseType, username: usr, password: pwd, importFromSchema: _tableToSync.Schema, importTableType: _tableToSync.IsView ? TableType.View:TableType.Table);
            }

            DiscoveredColumn[] newColumnsInLive =
                liveColumns.Where(
                    live => !catalogueColumns.Any(columnInfo =>
                                                  columnInfo.GetRuntimeName()
                                                  .Equals(live.GetRuntimeName()))).ToArray();

            //there are new columns in the live database that are not in the Catalogue
            if (newColumnsInLive.Any())
            {
                //see if user wants to add missing columns
                bool addMissingColumns = notifier.OnCheckPerformed(new CheckEventArgs("The following columns are missing from the TableInfo:" + string.Join(",", newColumnsInLive.Select(c => c.GetRuntimeName())), CheckResult.Fail, null, "The ColumnInfos will be created and added to the TableInfo"));

                List <ColumnInfo> added = new List <ColumnInfo>();

                if (addMissingColumns)
                {
                    foreach (DiscoveredColumn missingColumn in newColumnsInLive)
                    {
                        added.Add(importer.CreateNewColumnInfo(_tableToSync, missingColumn));
                    }

                    ForwardEngineerExtractionInformationIfAppropriate(added, notifier);
                }
                else
                {
                    IsSynched = false;
                }
            }

            //See if we need to delete any ColumnInfos
            ColumnInfo[] columnsInCatalogueButSinceDisapeared =
                catalogueColumns
                .Where(columnInfo => !liveColumns.Any(                                  //there are not any
                           c => columnInfo.GetRuntimeName().Equals(c.GetRuntimeName())) //columns with the same name between discovery/columninfo
                       ).ToArray();

            if (columnsInCatalogueButSinceDisapeared.Any())
            {
                foreach (var columnInfo in columnsInCatalogueButSinceDisapeared)
                {
                    bool deleteExtraColumnInfos = notifier.OnCheckPerformed(new CheckEventArgs("The ColumnInfo " + columnInfo.GetRuntimeName() + " no longer appears in the live table.", CheckResult.Fail, null, "Delete ColumnInfo " + columnInfo.GetRuntimeName()));
                    if (deleteExtraColumnInfos)
                    {
                        columnInfo.DeleteInDatabase();
                    }
                    else
                    {
                        IsSynched = false;
                    }
                }
            }

            _tableToSync.ClearAllInjections();

            if (IsSynched)
            {
                IsSynched = SynchronizeTypes(notifier, liveColumns);
            }

            if (IsSynched && !_tableToSync.IsTableValuedFunction)//table valued functions don't have primary keys!
            {
                IsSynched = SynchronizeField(liveColumns, _tableToSync.ColumnInfos, notifier, "IsPrimaryKey");
            }

            if (IsSynched && !_tableToSync.IsTableValuedFunction)//table valued functions don't have autonum
            {
                IsSynched = SynchronizeField(liveColumns, _tableToSync.ColumnInfos, notifier, "IsAutoIncrement");
            }

            if (IsSynched)
            {
                IsSynched = SynchronizeField(liveColumns, _tableToSync.ColumnInfos, notifier, "Collation");
            }

            if (IsSynched && _tableToSync.IsTableValuedFunction)
            {
                IsSynched = SynchronizeParameters((TableValuedFunctionImporter)importer, notifier);
            }

            _tableToSync.ClearAllInjections();

            //get list of primary keys from underlying table
            return(IsSynched);
        }