// Public methods.
 /// <summary>
 /// Opens the modal dialog to select database objects from the specified database server and table.
 /// </summary>
 /// <typeparam name="T">The database object type.</typeparam>
 /// <param name="owner">The window owner.</param>
 /// <param name="server">The database server.</param>
 /// <param name="table">The database table.</param>
 /// <param name="result">The result to display when the dialog opens.</param>
 /// <returns>The dialog result.</returns>
 public DialogResult ShowDialog(IWin32Window owner, DbServerSql server, ITable table, DbDataObject result)
 {
     // Reset the result.
     this.SelectedResult = null;
     this.AllResults = result;
     // Initialize the control.
     this.control.Select(server, table, result);
     // Show the dialog.
     return base.ShowDialog(owner);
 }
 /// <summary>
 /// Creates a new event instance.
 /// </summary>
 /// <param name="selectedResult">The selected result.</param>
 /// <param name="allResults">All results.</param>
 public DatabaseObjectSelectedEventArgs(DbObject selectedResult, DbDataObject allResults)
 {
     this.SelectedResult = selectedResult;
     this.AllResults = allResults;
 }
 /// <summary>
 /// A method called when the execution of the database query succeeded and the data is object.
 /// </summary>
 /// <param name="server">The database server.</param>
 /// <param name="query">The database query.</param>
 /// <param name="result">The result data.</param>
 /// <param name="recordsAffected">The number of records affected.</param>
 protected virtual void OnQuerySucceeded(DbServerSql server, DbQuerySql query, DbDataObject result, int recordsAffected)
 {
 }
 /// <summary>
 /// An event handler called when the database query completed successfully and the resulting data is object
 /// data.
 /// </summary>
 /// <param name="server">The database server.</param>
 /// <param name="query">The database query.</param>
 /// <param name="result">The database result.</param>
 /// <param name="recordsAffected">The number of records affected.</param>
 private void DatabaseQuerySuccess(DbServerSql server, DbQuerySql query, DbDataObject result, int recordsAffected)
 {
     // Execute the code on the UI thread.
     this.Invoke(() =>
     {
         this.OnQuerySucceeded(server, query, result, recordsAffected);
     });
 }
 /// <summary>
 /// An event handler called when the user selects a new table.
 /// </summary>
 /// <param name="sender">The sender object.</param>
 /// <param name="e">The event arguments.</param>
 private void OnSelectTable(object sender, EventArgs e)
 {
     try
     {
         // Open a new database select window that selects all database tables for the given server.
         if (this.formDatabaseSelect.ShowDialog(this, this.server, this.server.TableTables, this.resultTables) == DialogResult.OK)
         {
             // Get the results.
             this.resultTables = this.formDatabaseSelect.AllResults;
             this.resultTable = this.formDatabaseSelect.SelectedResult as DbObjectTable;
             this.resultColumns = null;
             // Set the name.
             this.textBoxNameDatabase.Text = this.resultTable.Name;
             // Raise a configuration changed event.
             if (this.ConfigurationChanged != null) this.ConfigurationChanged(this, EventArgs.Empty);
             // Set the changes to false.
             this.changes = true;
             // Create a new query to obtain the schema of the selected table.
             DbQuerySql query = DbQuerySql.CreateSelectAllOn(this.server.TableSchema, this.server.TableTables, "Name", this.resultTable.Name, this.server.Database, this.delegateQueryTableSchema);
             query.MessageStart = "Updating the database schema for the table \'{0}\'.".FormatWith(this.resultTable.Name);
             query.MessageFinishSuccess = "Updating the database schema for the table \'{0}\' completed successfully.".FormatWith(this.resultTable.Name);
             query.MessageFinishFail = "Updating the database schema for the table \'{0}\' failed".FormatWith(this.resultTable.Name);
             // Get the table schema.
             this.DatabaseQuery(this.server, query);
         }
     }
     catch (Exception exception)
     {
         // If an error occurs, show an error message.
         MessageBox.Show(this,
             "Changing the table database name failed. {0}".FormatWith(exception.Message),
             "Error",
             MessageBoxButtons.OK,
             MessageBoxIcon.Error);
     }
 }
 /// <summary>
 /// A method called when the execution of the database query succeeded and the data is object.
 /// </summary>
 /// <param name="server">The database server.</param>
 /// <param name="query">The database query.</param>
 /// <param name="result">The result data.</param>
 /// <param name="recordsAffected">The number of records affected.</param>
 protected override void OnQuerySucceeded(DbServerSql server, DbQuerySql query, DbDataObject result, int recordsAffected)
 {
     // Add the databases to the list.
     for (int row = 0; row < result.RowCount; row++)
     {
         // Get the database object.
         DbObjectDatabase database = result[row] as DbObjectDatabase;
         // Add a new list view item.
         ListViewItem item = new ListViewItem(new string[] {
             database.Name,
             database.DatabaseId.ToString(),
             database.CreateDate.ToString()
         });
         item.Tag = database;
         item.ImageIndex = database.Equals(this.server.Database) ? 1 : 0;
         this.listViewDatabases.Items.Add(item);
     }
     // Enable the refresh button.
     this.buttonDatabaseRefresh.Enabled = true;
 }
 /// <summary>
 /// An event handler called when the user selects a new database.
 /// </summary>
 /// <param name="sender">The sender object.</param>
 /// <param name="e">The event arguments.</param>
 private void OnSelectDatabase(object sender, EventArgs e)
 {
     try
     {
         // Open a new database select window that selects all database tables for the given server.
         if (this.formDatabaseSelect.ShowDialog(this, this.server, this.server.TableDatabase, this.resultDatabases) == DialogResult.OK)
         {
             // Get the result.
             this.resultDatabases = this.formDatabaseSelect.AllResults;
             this.resultDatabase = this.formDatabaseSelect.SelectedResult as DbObjectDatabase;
             this.resultColumns = null;
             // Set the name.
             this.textBoxDatabase.Text = "{0} (custom)".FormatWith(this.resultDatabase.Name);
             // Uncheck and enable the uses default database check box.
             this.checkBoxDefaultDatabase.Checked = false;
             this.checkBoxDefaultDatabase.Enabled = true;
             // Raise a configuration changed event.
             if (this.ConfigurationChanged != null) this.ConfigurationChanged(this, EventArgs.Empty);
             // Set the changes to true.
             this.changes = true;
         }
     }
     catch (Exception exception)
     {
         // If an error occurs, show an error message.
         MessageBox.Show(this,
             "Changing the table database failed. {0}".FormatWith(exception.Message),
             "Error",
             MessageBoxButtons.OK,
             MessageBoxIcon.Error);
     }
 }
        /// <summary>
        /// An event handler called when the user selects a new field.
        /// </summary>
        /// <param name="sender">The sender object.</param>
        /// <param name="e">The event arguments.</param>
        private void OnSelectField(object sender, EventArgs e)
        {
            // If there are pending changes, ask the user to save before continuing.
            if (this.changes)
            {
                if (DialogResult.Yes == MessageBox.Show(this,
                    "There are pending changes for this table and you cannot modify the table until all changes have been saved. Do you want to save the changes now?",
                    "Pending Table Changes",
                    MessageBoxButtons.YesNo,
                    MessageBoxIcon.Question))
                {
                    // Save the changes.
                    this.SaveConfiguration();
                }
                else return;
            }
            // Check the table has a database name.
            if ((this.table.DatabaseName == null) || (this.table.DatabaseName == string.Empty))
            {
                MessageBox.Show(
                    this,
                    "Cannot change the field for the current table, because the table does not have a database name yet.",
                    "Cannot Change Table Field",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                return;
            }
            // Check the table has a database (either the default database or a custom one.
            if ((!this.table.DefaultDatabase) && ((this.table.Database == null) || (this.table.Database == string.Empty)))
            {
                MessageBox.Show(
                    this,
                    "Cannot change the field for the current table, because the table does not have a database yet.",
                    "Cannot Change Table Field",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                return;
            }

            try
            {
                // Create a new query to obtain the columns of the selected table.
                DbQuerySql queryColumn = DbQuerySql.CreateSelectAllOn(this.server.TableColumns, this.server.TableTables, "Name", this.table.DatabaseName, this.server.Database);
                queryColumn.MessageStart = "Updating the fields list for the table \'{0}\'.".FormatWith(this.table.DatabaseName);
                queryColumn.MessageFinishSuccess = "Updating the fields list for the table \'{0}\' completed successfully.".FormatWith(this.table.DatabaseName);
                queryColumn.MessageFinishFail = "Updating the fields list for the table \'{0}\' failed".FormatWith(this.table.DatabaseName);

                // Open a new database select window that selects all database columns for the given server and table.
                if (this.formDatabaseSelect.ShowDialog(this, this.server, queryColumn, this.resultColumns) == DialogResult.OK)
                {
                    // Get the result.
                    this.resultColumn = this.formDatabaseSelect.SelectedResult as DbObjectColumn;
                    this.resultColumns = this.formDatabaseSelect.AllResults;

                    // Create a new query to obtain the type of the selected column.
                    DbQuerySql queryType = DbQuerySql.CreateSelectAllOn(this.server.TableTypes, this.server.TableColumns, new string[] {"ObjectId", "ColumnId"}, new object[] {this.resultColumn.ObjectId, this.resultColumn.ColumnId}, this.server.Database, this.delegateQueryColumnType);
                    queryType.MessageStart = "Updating the type for the table field \'{0}\'.".FormatWith(this.resultColumn.Name);
                    queryType.MessageFinishSuccess = "Updating the type for the table field \'{0}\' completed successfully.".FormatWith(this.resultColumn.Name);
                    queryType.MessageFinishFail = "Updating the type for the table field \'{0}\' failed".FormatWith(this.resultColumn.Name);
                    // Get the column type.
                    this.DatabaseQuery(this.server, queryType);
                }
            }
            catch (Exception exception)
            {
                // If an error occurs, show an error message.
                MessageBox.Show(this,
                    "Changing the table field failed. {0}".FormatWith(exception.Message),
                    "Error",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// An event handler called when a query for the column type completed successfully.
        /// </summary>
        /// <param name="result">The database result.</param>
        /// <param name="recordsAffected">The number of affected records.</param>
        private void OnQuerySuccessColumnType(DbDataObject result, int recordsAffected)
        {
            DbObjectType resultType;
            // Check the query result has at least one record.
            if (result.RowCount == 0)
            {
                MessageBox.Show(this,
                    "A query for the type of the table field \'{0}\' did not return any database type.".FormatWith(this.resultColumn.Name),
                    "Column Type Not Found",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                // Set the result to null.
                resultType = null;
            }
            // Check the query result has at most one record.
            else if (result.RowCount > 1)
            {
                MessageBox.Show(this,
                    "A query for the type of the table field \'{0}\' returned multiple database types.".FormatWith(this.resultColumn.Name),
                    "Multiple Column Types Found",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                // Set the result to null.
                resultType = null;
            }
            else
            {
                // Else, choose the result.
                resultType = result[0] as DbObjectType;
            }

            // Get the selected field list view item.
            ListViewItem item = this.listViewFields.SelectedItems[0];
            // Get the database field.
            DbField field = item.Tag as DbField;

            // Confirm the modification of the field.
            if (this.formCompareFields.ShowDialog(
                this,
                field,
                this.resultColumn.Name,
                resultType != null ? resultType.Name : "(unknown)",
                this.resultColumn.MaximumLength,
                this.resultColumn.Precision,
                this.resultColumn.Scale,
                this.resultColumn.IsNullable) == DialogResult.Yes)
            {
                // Update the field.
                item.SubItems[1].Text = resultColumn.Name;
                item.ImageKey = "Field";
                // Raise a configuration changed event.
                if (this.ConfigurationChanged != null) this.ConfigurationChanged(this, EventArgs.Empty);
            }
        }
        /// <summary>
        /// An event handler called when the query for the table schema completed succesfully.
        /// </summary>
        /// <param name="result">The database result.</param>
        /// <param name="recordsAffected">The number of records affected.</param>
        private void OnQuerySuccessTableSchema(DbDataObject result, int recordsAffected)
        {
            // Check the query result has at least one record.
            if (result.RowCount == 0)
            {
                MessageBox.Show(this,
                    "A query for the schema of table \'{0}\' did not return any database schema.".FormatWith(this.textBoxNameDatabase.Text),
                    "Table Schema Not Found",
                    MessageBoxButtons.OK,
                    MessageBoxIcon.Warning);
                return;
            }
            // Get the results.
            this.resultSchemas = result;
            this.resultSchema = null;
            // If the query result has at most one record, let the user select one schema.
            if (result.RowCount > 1)
            {
                try
                {
                    // Create a new query to obtain the schema of the selected table.
                    DbQuerySql query = DbQuerySql.CreateSelectAllOn(this.server.TableSchema, this.server.TableTables, "Name", this.resultTable.Name, this.server.Database, this.delegateQueryTableSchema);

                    query.MessageStart = "Updating the database schema for the table \'{0}\'.".FormatWith(this.resultTable.Name);
                    query.MessageFinishSuccess = "Updating the database schema for the table \'{0}\' completed successfully.".FormatWith(this.resultTable.Name);
                    query.MessageFinishFail = "Updating the database schema for the table \'{0}\' failed".FormatWith(this.resultTable.Name);

                    // Repeat until the user selects a schema.
                    do
                    {
                        // Open a new database select window that selects all database tables for the given server.
                        if (this.formDatabaseSelect.ShowDialog(this, this.server, query, this.resultSchemas) == DialogResult.OK)
                        {
                            // Get the results.
                            this.resultSchemas = this.formDatabaseSelect.AllResults;
                            this.resultSchema = this.formDatabaseSelect.SelectedResult as DbObjectSchema;
                        }
                        if (this.resultSchema == null)
                        {
                            MessageBox.Show(this,
                                "A query for the schema of table \'{0}\' returned multiple database schemas. You must select a schema before continuing.".FormatWith(this.textBoxNameDatabase.Text),
                                "Multiple Table Schemas Found",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Warning);
                        }
                    }
                    while (this.resultSchema == null);
                }
                catch (Exception exception)
                {
                    // If an error occurs, show an error message.
                    MessageBox.Show(this,
                        "Changing the table schema failed. {0}".FormatWith(exception.Message),
                        "Error",
                        MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    return;
                }
            }
            else
            {
                // Otherwise, select the returned schema.
                this.resultSchema = this.resultSchemas[0] as DbObjectSchema;
            }
            // Set the schema name.
            this.textBoxSchema.Text = this.resultSchema.Name;
            // Raise a configuration changed event.
            if (this.ConfigurationChanged != null) this.ConfigurationChanged(this, EventArgs.Empty);
            // Set the changes to true.
            this.changes = true;
        }
 /// <summary>
 /// A method called when a query completed successfully.
 /// </summary>
 /// <param name="server">The database server.</param>
 /// <param name="query">The database query.</param>
 /// <param name="result">The database result.</param>
 /// <param name="recordsAffected">The number of records affected.</param>
 protected override void OnQuerySucceeded(DbServerSql server, DbQuerySql query, DbDataObject result, int recordsAffected)
 {
     // Enable the control.
     this.tabControl.Enabled = true;
     // Raise the database operation finished event.
     if (this.DatabaseOperationFinished != null) this.DatabaseOperationFinished(this, EventArgs.Empty);
     // If the query state is not null.
     if (query.State != null)
     {
         // If the query state is a delegate.
         if (query.State is QuerySuccessAction)
         {
             // Get the call the delegate.
             QuerySuccessAction handler = query.State as QuerySuccessAction;
             handler(result, recordsAffected);
         }
     }
 }
        // Public methods.
        /// <summary>
        /// Selects a table at the given database server for display.
        /// </summary>
        /// <param name="server">The database server.</param>
        /// <param name="table">The table.</param>
        public void Select(DbServerSql server, ITable table)
        {
            // Set the parameters.
            this.server = server;
            this.table = table;

            // Reset the results.
            this.resultTables = null;
            this.resultDatabases = null;
            this.resultSchemas = null;
            this.resultColumns = null;
            this.resultTable = null;
            this.resultDatabase = null;
            this.resultSchema = null;

            // Initialize the control.
            this.labelTitle.Text = table.LocalName;
            this.textBoxId.Text = table.Id.ToString();
            this.textBoxNameLocal.Text = table.LocalName;
            this.textBoxNameDatabase.Text = table.DatabaseName;
            this.textBoxSchema.Text = table.Schema;
            this.textBoxDatabase.Text = table.DefaultDatabase ? "(default)" : table.Database;
            this.checkBoxDefaultDatabase.Checked = table.DefaultDatabase;
            this.checkBoxReadOnly.Checked = table.IsReadOnly;
            this.pictureBox.Image = table.IsConfigured ? Resources.TableSuccess_32 : Resources.TableWarning_32;
            // The table fields.
            this.listViewFields.Items.Clear();
            foreach (DbField field in table.Fields)
            {
                // If the property type is nullable, replace it with the boxed type.
                ListViewItem item = new ListViewItem(new string[] {
                            field.Property.Name,
                            field.HasName ? field.GetDatabaseName() : string.Empty,
                            field.LocalType,
                            field.DatabaseType,
                            field.IsNullable ? "Yes" : "No"
                        });
                item.ImageKey = field.HasName ? "Field" : "FieldWarning";
                item.Tag = field;
                this.listViewFields.Items.Add(item);
            }
            // The table relationships.
            this.listViewRelationships.Items.Clear();
            foreach (IRelationship relationship in table.Relationships)
            {
                ListViewItem item = new ListViewItem(new string[] {
                    relationship.RightTable.LocalName,
                    relationship.LeftField,
                    relationship.RightField });
                item.ImageKey = "Relationship";
                item.Tag = relationship;
                this.listViewRelationships.Items.Add(item);
            }

            // Set the enabled state.
            this.buttonSelectTable.Enabled = !table.IsReadOnly;
            this.buttonSelectDatabase.Enabled = !table.IsReadOnly;
            this.buttonSelectField.Enabled = false;
            this.checkBoxDefaultDatabase.Enabled = !table.IsReadOnly && !table.DefaultDatabase;

            // Set the focus.
            this.tabControl.SelectedTab = this.tabPageGeneral;
            this.textBoxNameLocal.Select();
            this.textBoxNameLocal.SelectionStart = 0;
            this.textBoxNameLocal.SelectionLength = 0;
        }
 /// <summary>
 /// An event handler called when the refresh operation completed successfully and the resulting data is object
 /// data.
 /// </summary>
 /// <param name="server">The database server.</param>
 /// <param name="query">The database query.</param>
 /// <param name="result">The database result.</param>
 /// <param name="recordsAffected">The number of records affected.</param>
 protected override void OnQuerySucceeded(DbServerSql server, DbQuerySql query, DbDataObject result, int recordsAffected)
 {
     // Set the current result.
     this.result = result;
     try
     {
         // Add the table rows.
         for (int row = 0; row < this.result.RowCount; row++)
         {
             // Add the new row, and get the row index.
             int index = this.dataGrid.Rows.Add(this.query.Table.GetValues(this.result[row]));
             // Set the row tag with the table object.
             this.dataGrid.Rows[index].Tag = result[row];
         }
     }
     catch (Exception exception)
     {
         // If an exception occurs, call the refresh fail method.
         this.OnQueryFailed(server, query, exception);
         return;
     }
     // Set the current command to null.
     this.command = null;
     // Enable the buttons.
     this.buttonRefresh.Enabled = true;
     this.buttonCancel.Enabled = false;
     this.buttonClose.Enabled = true;
     // Update the status box.
     this.labelStatus.Text = "{0} object{1} fetched.".FormatWith(result.RowCount, result.RowCount.PluralSuffix());
     // Raise the database operation finished event.
     if (this.DatabaseOperationFinished != null) this.DatabaseOperationFinished(this, EventArgs.Empty);
 }
        /// <summary>
        /// Selects records from the specified database server given a custom query.
        /// </summary>
        /// <param name="server">The database server.</param>
        /// <param name="query">The database table.</param>
        /// <param name="result">The database results, if any.</param>
        public void Select(DbServerSql server, DbQuerySql query, DbDataObject result)
        {
            // Check the database table is configured.
            if (!query.Table.IsConfigured) throw new DbException("Cannot select the list of database objects for table \'{0}\', because the table is not configured.".FormatWith(query.Table.LocalName));
            // Check the results, if different from null, are for the current table and if not, ignore them.
            if (result != null)
            {
                if (result.Table != query.Table) result = null;
            }

            // Set the current server.
            this.server = server;
            // Set the current query.
            this.query = query;
            // Set the current results.
            this.result = result;

            // Clear the data grid.
            this.dataGrid.Rows.Clear();
            this.dataGrid.Columns.Clear();
            // Initialize the data grid columns.
            foreach (DbField field in this.query.Table.Fields)
            {
                this.dataGrid.Columns.Add(field.Property.Name, field.DisplayName);
            }
            // If a current result exists, intialize the data grid rows.
            if (this.result != null)
            {
                for (int row = 0; row < this.result.RowCount; row++)
                {
                    // Add the new row, and get the row index.
                    int index = this.dataGrid.Rows.Add(this.query.Table.GetValues(this.result[row]));
                    // Set the row tag with the table object.
                    this.dataGrid.Rows[index].Tag = result[row];
                }
            }

            // Intialize the buttons.
            this.buttonRefresh.Enabled = true;
            this.buttonCancel.Enabled = false;
            this.buttonSelect.Enabled = false;
            this.buttonClose.Enabled = true;
        }
        // Public methods.
        /// <summary>
        /// Selects all records for the specified databse server and table.
        /// </summary>
        /// <param name="server">The database server.</param>
        /// <param name="table">The database table.</param>
        /// <param name="result">The database results, if any.</param>
        public void Select(DbServerSql server, ITable table, DbDataObject result)
        {
            // Create a select all query for all field in the current table.
            DbQuerySql query = DbQuerySql.CreateSelectAll(table, server.Database);

            query.MessageStart = "Refreshing the data for table \'{0}\' on the database server \'{1}\'...".FormatWith(table.LocalName, server.Name);
            query.MessageFinishSuccess = "Refreshing the data for table \'{0}\' on the database server \'{1}\' completed successfully.".FormatWith(table.LocalName, server.Name);
            query.MessageFinishFail = "Refreshing the data for table \'{0}\' on the database server \'{1}\' failed.".FormatWith(table.LocalName, server.Name);

            // Use the generic select methods.
            this.Select(server, query, result);
        }