예제 #1
0
        /// <summary>
        /// Creates the <see cref="EditConnectionInfo"/> or restores the saved one.
        /// </summary>
        /// <param name="mySqlTable">The <see cref="MySqlDataTable"/> used for the Edit Data session.</param>
        /// <param name="currentWorksheet">The current worksheet.</param>
        /// <returns>A new or restored <see cref="EditConnectionInfo"/> object.</returns>
        private EditConnectionInfo GetEditConnectionInfo(MySqlDataTable mySqlTable, ExcelInterop.Worksheet currentWorksheet)
        {
            if (mySqlTable == null || currentWorksheet == null)
            {
                return(null);
            }

            var atCell       = currentWorksheet.Range["A1", Type.Missing];
            var editingRange = mySqlTable.ImportDataIntoExcelRange(atCell);
            EditConnectionInfo connectionInfo = null;

            var workbookEditConnectionInfos = WorkbookConnectionInfos.GetWorkbookEditConnectionInfos(Globals.ThisAddIn.ActiveWorkbook);

            if (workbookEditConnectionInfos.Count > 0)
            {
                connectionInfo = workbookEditConnectionInfos.GetActiveEditConnectionInfo(mySqlTable.TableName);
            }

            // The EditConnectionInfo is new and has to be created from scratch.
            if (connectionInfo == null)
            {
                var activeWorkbook = Globals.ThisAddIn.ActiveWorkbook;
                connectionInfo = new EditConnectionInfo(activeWorkbook.GetOrCreateId(), activeWorkbook.FullName, WbConnection.Id, WbConnection.Schema, mySqlTable.TableName);
            }

            if (connectionInfo.EditDialog != null)
            {
                return(connectionInfo);
            }

            // The EditConnectionInfo is being either restored from the settings file or created for the newborn object.
            connectionInfo.EditDialog = new EditDataDialog(this, new NativeWindowWrapper(Globals.ThisAddIn.Application.Hwnd), WbConnection, editingRange, mySqlTable, currentWorksheet);
            currentWorksheet.StoreProtectionKey(connectionInfo.EditDialog.WorksheetProtectionKey);
            return(connectionInfo);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ImportConnectionInfo" /> class.
        /// </summary>
        /// <param name="mySqlTable">MySqlDataTable object related to the <see cref="ImportConnectionInfo" />.</param>
        /// <param name="atCell">The top left Excel cell of the new <see cref="ExcelInterop.ListObject"/>.</param>
        /// <param name="addSummaryRow">Flag indicating whether to include a row with summary fields at the end of the data rows.</param>
        public ImportConnectionInfo(MySqlDataTable mySqlTable, ExcelInterop.Range atCell, bool addSummaryRow)
            : this()
        {
            if (mySqlTable == null)
            {
                throw new ArgumentNullException(nameof(mySqlTable));
            }

            _connection             = mySqlTable.WbConnection;
            MySqlTable              = mySqlTable;
            SchemaName              = mySqlTable.SchemaName;
            TableName               = mySqlTable.TableName;
            ConnectionId            = mySqlTable.WbConnection.Id;
            ImportColumnNames       = mySqlTable.ImportColumnNames;
            OperationType           = mySqlTable.OperationType;
            ProcedureResultSetIndex = mySqlTable.ProcedureResultSetIndex;
            SelectQuery             = mySqlTable.SelectQuery;
            var activeWorkbook = Globals.ThisAddIn.ActiveWorkbook;

            WorkbookGuid     = activeWorkbook.GetOrCreateId();
            WorkbookName     = activeWorkbook.Name;
            WorkbookFilePath = activeWorkbook.FullName;
            ExcelInterop.Worksheet worksheet = activeWorkbook.ActiveSheet;
            WorksheetName = worksheet.Name;
            InitializeConnectionObjects(atCell, addSummaryRow);
        }
예제 #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="EditDataDialog"/> class.
        /// </summary>
        /// <param name="parentTaskPane">The <see cref="ExcelAddInPane"/> from which the <see cref="EditDataDialog"/> is called.</param>
        /// <param name="parentWindow">The parent window assigned to the <see cref="EditDataDialog"/> to be opened as a dialog.</param>
        /// <param name="wbConnection">The connection to a MySQL server instance selected by users.</param>
        /// <param name="originalEditDataRange">The Excel cells range containing the MySQL table's data being edited.</param>
        /// <param name="importTable">The table containing the data imported from the MySQL table that will be edited.</param>
        /// <param name="editingWorksheet">The Excel worksheet tied to the current editing session.</param>
        public EditDataDialog(ExcelAddInPane parentTaskPane, IWin32Window parentWindow, MySqlWorkbenchConnection wbConnection, ExcelInterop.Range originalEditDataRange, MySqlDataTable importTable, ExcelInterop.Worksheet editingWorksheet)
        {
            _mouseDownPoint = Point.Empty;
            _neverBeenShown = true;
            _updatingUSeOptimisticUpdateSetting = false;

            InitializeComponent();

            var existingProtectionKey = editingWorksheet.GetProtectionKey();

            WorksheetProtectionKey            = string.IsNullOrEmpty(existingProtectionKey) ? Guid.NewGuid().ToString() : existingProtectionKey;
            _parentTaskPane                   = parentTaskPane;
            _parentWindow                     = parentWindow;
            _wbConnection                     = wbConnection;
            _editDataRange                    = originalEditDataRange;
            _mySqlTable                       = importTable;
            EditingWorksheet                  = editingWorksheet;
            EditingWorksheet.SelectionChange += EditingWorksheet_SelectionChange;
            ResetToolTip();
            Opacity = 0.60;
            AddNewRowToEditingRange(false);
            _useOptimisticUpdateForThisSession           = Settings.Default.EditUseOptimisticUpdate;
            ForThisSessionToolStripMenuItem.Checked      = _useOptimisticUpdateForThisSession;
            ForAllSessionsToolStripMenuItem.Checked      = _useOptimisticUpdateForThisSession;
            UseOptimisticUpdateToolStripMenuItem.Checked = _useOptimisticUpdateForThisSession;
            Settings.Default.PropertyChanged            += SettingsPropertyValueChanged;
        }
예제 #4
0
        /// <summary>
        /// Executes the given procedure and returns its result sets in tables within a <see cref="DataSet"/> object.
        /// </summary>
        /// <remarks>Only works against Procedures, but not with Tables or Views.</remarks>
        /// <returns><see cref="DataSet"/> where each table within it represents each of the result sets returned by the stored procedure.</returns>
        public DataSet Execute()
        {
            if (Parameters == null)
            {
                InitializeParameters();
            }

            if (Parameters == null)
            {
                return(null);
            }

            var sql         = $"`{Connection.Schema}`.`{Name}`";
            var resultSetDs = Connection.ExecuteRoutine(sql, Parameters.Select(tuple => tuple.Item2).ToArray());

            if (resultSetDs == null || resultSetDs.Tables.Count == 0)
            {
                return(null);
            }

            // Create result set data set and MySqlDataTable tables for each table in the result sets
            var returnDataSet = new DataSet(Name + "ResultSet");
            var procedureSql  = GetSql();
            var resultIndex   = 1;

            foreach (DataTable table in resultSetDs.Tables)
            {
                table.TableName = $"Result{resultIndex}";
                var mySqlDataTable = new MySqlDataTable(Connection, table, procedureSql, resultIndex - 1);
                returnDataSet.Tables.Add(mySqlDataTable);
                resultIndex++;
            }

            if (ReadOnlyParameters == null || ReadOnlyParameters.Count <= 0)
            {
                return(returnDataSet);
            }

            // Create a table containing output parameters and return values
            var outParamsTable = new DataTable(OUT_AND_RETURN_VALUES_TABLE_NAME);

            foreach (var readOnlyTuple in ReadOnlyParameters)
            {
                var dataType  = readOnlyTuple.Item1;
                var parameter = readOnlyTuple.Item2;
                outParamsTable.Columns.Add(new MySqlDataColumn(parameter.ParameterName, dataType, true));
            }

            // Add output/return parameter values to OutAndReturnValues table
            var valuesRow = outParamsTable.NewRow();

            valuesRow.ItemArray = ReadOnlyParameters.Select(tuple => tuple.Item2.Value).ToArray();
            outParamsTable.Rows.Add(valuesRow);
            var outParamsMySqlTable = new MySqlDataTable(Connection, outParamsTable, procedureSql, resultIndex - 1);

            returnDataSet.Tables.Add(outParamsMySqlTable);
            return(returnDataSet);
        }
예제 #5
0
        /// <summary>
        /// Checks if the <see cref="ExcelInterop.Range"/> where the data of this <see cref="DbObject"/> is imported would collide with another Excel object.
        /// </summary>
        /// <param name="mySqlTable">A <see cref="MySqlDataTable"/> filled with data for this <see cref="DbObject"/>.</param>
        /// <returns><c>true</c> if the <see cref="ExcelInterop.Range"/> where the data of this <see cref="DbObject"/> is imported would collide with another Excel object, <c>false</c> otherwise.</returns>
        private bool DetectDataForImportPossibleCollisions(MySqlDataTable mySqlTable)
        {
            if (mySqlTable == null)
            {
                return(false);
            }

            var atCell = Globals.ThisAddIn.Application.ActiveCell;
            var ranges = mySqlTable.GetExcelRangesToOccupy(atCell, ImportParameters.AddSummaryRow, ImportParameters.CreatePivotTable);

            return(ranges != null && ranges.Aggregate(false, (current, range) => current || range.IntersectsWithAnyExcelObject()));
        }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of the DataRow. Constructs a row from the builder.
 /// </summary>
 /// <remarks>Only for internal usage.</remarks>
 /// <param name="builder">A <see cref="DataRowBuilder"/> to construct the row.</param>
 protected internal MySqlDataRow(DataRowBuilder builder) : base(builder)
 {
     _excelRange             = null;
     _mySqlTable             = null;
     _refreshingData         = false;
     _setVariablesSql        = null;
     _sqlQuery               = null;
     ChangedColumnNames      = new List <string>(Table.Columns.Count);
     IsBeingDeleted          = false;
     IsHeadersRow            = false;
     ExcelModifiedRangesList = new List <ExcelInterop.Range>(Table.Columns.Count);
     Statement               = new MySqlStatement(this);
 }
예제 #7
0
        /// <summary>
        /// Creates the import my SQL table.
        /// </summary>
        /// <param name="wbConnection">The wb connection.</param>
        /// <param name="operationType">The <see cref="MySqlDataTable.DataOperationType"/> intended for the new <see cref="MySqlDataTable"/>.</param>
        /// <param name="tableOrViewName">The name of the MySQL table or view to import data from..</param>
        /// <param name="importColumnNames">Flag indicating if column names will be imported as the first row of imported data.</param>
        /// <param name="selectQuery">A SELECT query against a database object to fill the [MySqlDataTable] return object with.</param>
        /// <param name="procedureResultSetIndex">The index of the result set of a stored procedure this table contains data for.</param>
        /// <returns>MySql Table created from the selectQuery.</returns>
        public static MySqlDataTable CreateImportMySqlTable(this MySqlWorkbenchConnection wbConnection, MySqlDataTable.DataOperationType operationType, string tableOrViewName, bool importColumnNames, string selectQuery, int procedureResultSetIndex = 0)
        {
            DataTable dt = GetDataFromSelectQuery(wbConnection, selectQuery);

            if (dt == null)
            {
                MySqlSourceTrace.WriteToLog(string.Format(Resources.SelectQueryReturnedNothing, selectQuery));
                return(null);
            }

            var importMySqlDataTable = new MySqlDataTable(wbConnection, tableOrViewName, dt, operationType, selectQuery)
            {
                ImportColumnNames       = importColumnNames,
                ProcedureResultSetIndex = procedureResultSetIndex
            };

            return(importMySqlDataTable);
        }
예제 #8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MySqlScriptDialog"/> class.
        /// </summary>
        private MySqlScriptDialog()
        {
            _createdTable                      = false;
            _errorDialogSummary                = null;
            _isUserInput                       = true;
            _lockedTable                       = false;
            _mySqlMaxAllowedPacket             = 0;
            _mySqlTable                        = null;
            _originalStatementRowsList         = null;
            _refreshRowsDataAfterPush          = false;
            _showOriginalOperationsInformation = false;
            _useOptimisticUpdate               = false;
            _userChangedOriginalQuery          = false;
            _wbConnection                      = null;
            ActualStatementRowsList            = null;
            ErroredOutDataRow                  = null;
            OriginalSqlScript                  = null;
            ScriptResult                       = MySqlStatement.StatementResultType.NotApplied;

            InitializeComponent();
            OriginalQueryButton.Enabled = false;
            ResetTextZoom();
        }
예제 #9
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MySqlScriptDialog"/> class.
        /// </summary>
        /// <param name="mySqlTable">The <see cref="MySqlDataTable"/> object containing data changes to be committed to the database.</param>
        /// <param name="refreshRowsDataAfterPush">Flag indicating whether rows data is refreshed after their push operation is executed.</param>
        public MySqlScriptDialog(MySqlDataTable mySqlTable, bool refreshRowsDataAfterPush)
            : this()
        {
            if (mySqlTable != null)
            {
                switch (mySqlTable.OperationType)
                {
                case MySqlDataTable.DataOperationType.Export:
                    _errorDialogSummary = string.Format(Resources.ExportDataGenericErrorText, mySqlTable.TableName);
                    break;

                case MySqlDataTable.DataOperationType.Append:
                    _errorDialogSummary = string.Format(Resources.AppendDataDetailsDoneErrorText, mySqlTable.TableName);
                    break;

                case MySqlDataTable.DataOperationType.Edit:
                    _errorDialogSummary = string.Format(Resources.EditedDataForTable, mySqlTable.TableName) + Resources.EditedDataCommittedError;
                    break;

                default:
                    _errorDialogSummary = Resources.ScriptErrorThrownSummary;
                    break;
                }

                _mySqlTable = mySqlTable;
                _refreshRowsDataAfterPush          = refreshRowsDataAfterPush;
                _showOriginalOperationsInformation = true;
                _useOptimisticUpdate = _mySqlTable.UseOptimisticUpdate;
                _wbConnection        = _mySqlTable.WbConnection;
                CreateOriginalStatementsList();
                SetOriginalOperationsInfoAvailability();
            }

            SqlScript           = OriginalSqlScript;
            ApplyButton.Enabled = SqlScript.Trim().Length > 0;
        }
예제 #10
0
        /// <summary>
        /// Imports the result sets of this stored procedure to a <see cref="ExcelInterop.Worksheet"/>.
        /// </summary>
        /// <param name="importType">The <see cref="ProcedureResultSetsImportType"/> defining what result sets are imported and how they are laid out in the Excel worksheet. </param>
        /// <param name="selectedResultSetIndex">The index of the result set selected for import in case the <see cref="importType"/> is <see cref="ProcedureResultSetsImportType.SelectedResultSet"/>.</param>
        /// <param name="resultSetsDataSet">The <see cref="DataSet"/> containing all result sets returned by the stored procedure's execution.</param>
        /// <returns><c>true</c> if the import is successful, <c>false</c> otherwise.</returns>
        public bool ImportData(ProcedureResultSetsImportType importType, int selectedResultSetIndex, DataSet resultSetsDataSet = null)
        {
            if (resultSetsDataSet == null)
            {
                resultSetsDataSet = Execute();
            }

            var success = true;

            try
            {
                var activeWorkbook = Globals.ThisAddIn.ActiveWorkbook;

                // Check if the data being imported does not overlap with the data of an existing Excel table.
                if (DetectDataForImportPossibleCollisions(importType, selectedResultSetIndex, resultSetsDataSet))
                {
                    var infoProperties = InfoDialogProperties.GetYesNoDialogProperties(
                        InfoDialog.InfoType.Warning,
                        Resources.ImportOverExcelObjectErrorTitle,
                        Resources.ImportOverExcelObjectErrorDetail,
                        Resources.ImportOverExcelObjectErrorSubDetail);
                    if (InfoDialog.ShowDialog(infoProperties).DialogResult == DialogResult.No)
                    {
                        return(false);
                    }

                    var newWorkSheet = activeWorkbook.CreateWorksheet(Name, true);
                    if (newWorkSheet == null)
                    {
                        return(false);
                    }
                }

                var tableIdx         = 0;
                var createPivotTable = ImportParameters.CreatePivotTable;
                var addSummaryRow    = ImportParameters.AddSummaryRow;
                var nextTopLeftCell  = Globals.ThisAddIn.Application.ActiveCell;
                foreach (var mySqlTable in resultSetsDataSet.Tables.Cast <MySqlDataTable>().Where(mySqlTable => importType != ProcedureResultSetsImportType.SelectedResultSet || selectedResultSetIndex == tableIdx++))
                {
                    var importingMySqlTable   = mySqlTable;
                    var excludedColumnIndexes = mySqlTable.Columns.Cast <MySqlDataColumn>().Where(mySqlColumn => mySqlColumn.ExcludeColumn).Select(mySqlColumn => mySqlColumn.Ordinal).ToList();
                    if (excludedColumnIndexes.Count > 0)
                    {
                        importingMySqlTable = new MySqlDataTable(Connection, mySqlTable, mySqlTable.SelectQuery, mySqlTable.ProcedureResultSetIndex);
                        excludedColumnIndexes.Reverse();
                        foreach (var excludedColumnIndex in excludedColumnIndexes)
                        {
                            importingMySqlTable.Columns.RemoveAt(excludedColumnIndex);
                        }
                    }

                    Globals.ThisAddIn.Application.Goto(nextTopLeftCell, false);
                    importingMySqlTable.ImportColumnNames = ImportParameters.IncludeColumnNames;
                    importingMySqlTable.TableName         = Name + "." + mySqlTable.TableName;
                    var excelObj = Settings.Default.ImportCreateExcelTable
            ? importingMySqlTable.ImportDataIntoExcelTable(createPivotTable, ExcelUtilities.PivotTablePosition.Right, addSummaryRow)
            : importingMySqlTable.ImportDataIntoExcelRange(createPivotTable, ExcelUtilities.PivotTablePosition.Right, addSummaryRow);
                    if (excelObj == null)
                    {
                        continue;
                    }

                    var fillingRange = excelObj is ExcelInterop.ListObject listObject
            ? listObject.Range
            : excelObj as ExcelInterop.Range;
                    nextTopLeftCell = fillingRange.GetNextResultSetTopLeftCell(importType, createPivotTable);
                }
            }
            catch (Exception ex)
            {
                success = false;
                Logger.LogException(ex, true, string.Format(Resources.UnableToRetrieveData, "procedure", Name));
            }

            return(success);
        }
예제 #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TableWarningsChangedArgs"/> class.
 /// </summary>
 /// <param name="table">The <see cref="MySqlDataTable"/> object that contains changes in its warning texts.</param>
 /// <param name="autoPkWarning">Flag indicating if the warning is related to the auto-generated primary key or to the table.</param>
 public TableWarningsChangedArgs(MySqlDataTable table, bool autoPkWarning)
 {
     CurrentWarning = autoPkWarning ? table.CurrentAutoPkWarningText : table.CurrentTableWarningText;
     WarningsType   = autoPkWarning ? TableWarningsType.AutoPrimaryKeyWarnings : TableWarningsType.TableNameWarnings;
 }