#region License Information /* HeuristicLab * Copyright (C) 2002-2013 Heuristic and Evolutionary Algorithms Laboratory (HEAL) * * This file is part of HeuristicLab. * * HeuristicLab is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * HeuristicLab is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with HeuristicLab. If not, see . */ #endregion using System; using System.Collections.Generic; using System.Linq; using System.Data.Common; using System.Windows.Forms; using System.ComponentModel; using HeuristicLab.DataImporter.Data.Model; namespace HeuristicLab.DataImporter.DbExplorer.Interfaces { public abstract class DbExplorerBase : IDbExplorer { private DbConnectionBase connection; protected DbConnectionBase Connection { get { return this.connection; } set { this.connection = value; } } public bool IsConnected { get { if (connection != null) return connection.TestConnection(); return false; } } protected virtual string EscapeSqlString(string s) { return s; } public abstract string MenuItemDescription { get; } public abstract bool IsDateDataType(string type); public abstract bool IsNumericDataType(string type); public abstract bool IsStringDataType(string type); public abstract bool IsFilterableDataType(string type); protected abstract string ConvertDate(DateTime date); protected abstract string ConvertDouble(double value); protected abstract IDbConnectionWizard DbConnectionWizard { get; } private ProgressChangedEventHandler newRowLoaded; public ProgressChangedEventHandler NewRowLoaded { get { return newRowLoaded; } set { newRowLoaded = value; } } private DbTable actTable; private void FireNewRowLoaded(int actRow) { if (newRowLoaded != null && actTable != null && actTable.AffectedRows != 0) newRowLoaded(this, new ProgressChangedEventArgs(actRow * 100 / actTable.AffectedRows , "Loading " + actRow + " / " + actTable.AffectedRows + " rows of table " + actTable.TableName)); } public void ShowDbConnectionWizard() { if (DbConnectionWizard.ShowDialog() == DialogResult.OK) { if (!DbConnectionWizard.Connection.TestConnection()) { this.connection = null; HandleConnectionError(); } else connection = DbConnectionWizard.Connection; } } private void HandleConnectionError() { DialogResult result = MessageBox.Show(DbConnectionWizard.Connection.ErrorMessage, "Connect to database failed", MessageBoxButtons.RetryCancel); if (result == DialogResult.Retry) ShowDbConnectionWizard(); } public abstract IEnumerable AllTables { get; } public virtual void FillMinMaxValuesForTable(DbTable table) { using (DbConnection conn = connection.CreateConnection()) { conn.Open(); List filterColumns = new List(); using (DbCommand cmd = conn.CreateCommand()) { string cmdText = @"select "; foreach (DbColumn col in table.Columns) if (this.IsFilterableDataType(col.SqlDataType) && !this.IsStringDataType(col.SqlDataType)) { cmdText += @"min(" + EscapeSqlString(col.ColumnName) + "), max(" + EscapeSqlString(col.ColumnName) + "), "; filterColumns.Add(col); } cmdText += "count(*) from " + EscapeSqlString(table.OwnerName) + "." + EscapeSqlString(table.TableName); cmd.CommandText = cmdText; using (DbDataReader reader = cmd.ExecuteReader()) { reader.Read(); for (int i = 0; i < reader.FieldCount - 1; i++) { if (i % 2 == 0) filterColumns[i / 2].MinValue = reader.GetValue(i).ToString(); else filterColumns[i / 2].MaxValue = reader.GetValue(i).ToString(); } table.TotalRows = reader.GetInt32(reader.FieldCount - 1); reader.Close(); }//end using reader // cmd.Dispose(); }//end using command conn.Close(); }//end using connection table.UpdateInformationLoaded(); } public void FillAffectedRowsForTable(DbTable table) { string cmdText = @"select count(*) from " + EscapeSqlString(table.OwnerName) + "." + EscapeSqlString(table.TableName) + " where "; bool executeSql = false; foreach (DbColumn col in table.SelectedColumns) { if (col.FilterColumn) { executeSql = true; if (IsNumericDataType(col.SqlDataType)) { string min = this.ConvertDouble(double.Parse(col.MinValue)); string max = this.ConvertDouble(double.Parse(col.MaxValue)); cmdText += EscapeSqlString(col.ColumnName) + ">=" + min + " and " + EscapeSqlString(col.ColumnName) + "<=" + max + " and "; } else if (IsDateDataType(col.SqlDataType)) { string x = this.ConvertDate(DateTime.Parse(col.MinValue)); string y = this.ConvertDate(DateTime.Parse(col.MaxValue)); cmdText += EscapeSqlString(col.ColumnName) + ">=" + x + " and " + EscapeSqlString(col.ColumnName) + "<=" + y + " and "; } else if (IsStringDataType(col.SqlDataType)) cmdText += EscapeSqlString(col.ColumnName) + " like '%" + EscapeSqlString(col.LikeValue) + "%' and "; } } if (!executeSql) { if (table.IsSelected) table.AffectedRows = table.TotalRows; else table.AffectedRows = 0; } else { cmdText = cmdText.Remove(cmdText.Length - 5); using (DbConnection conn = Connection.CreateConnection()) { conn.Open(); using (DbCommand cmd = conn.CreateCommand()) { cmd.CommandText = cmdText; table.AffectedRows = Convert.ToInt32(cmd.ExecuteScalar()); }//end using cmd conn.Close(); }//end using connection } } public ColumnGroup CreateColumnGroup(DbTable table) { //select clause string sqlString = "select "; foreach (DbColumn col in table.SelectedColumns) { sqlString += EscapeSqlString(table.TableName) + "." + EscapeSqlString(col.ColumnName) + ", "; } sqlString = sqlString.Remove(sqlString.Length - 2); sqlString += " from " + EscapeSqlString(table.OwnerName) + "." + EscapeSqlString(table.TableName); //where clause bool addedWhereclause = false; foreach (DbColumn col in table.SelectedColumns) { if (col.FilterColumn) { if (!addedWhereclause) { sqlString += " where "; addedWhereclause = true; } if (IsNumericDataType(col.SqlDataType)) sqlString += EscapeSqlString(col.ColumnName) + ">=" + col.MinValue + " and " + EscapeSqlString(col.ColumnName) + "<=" + col.MaxValue + " and "; else if (IsDateDataType(col.SqlDataType)) { string x = this.ConvertDate(DateTime.Parse(col.MinValue)); string y = this.ConvertDate(DateTime.Parse(col.MaxValue)); sqlString += EscapeSqlString(col.ColumnName) + ">=" + x + " and " + EscapeSqlString(col.ColumnName) + "<=" + y + " and "; } else if (IsStringDataType(col.SqlDataType)) sqlString += EscapeSqlString(col.ColumnName) + " like '%" + EscapeSqlString(col.LikeValue) + "%' and "; } } if (addedWhereclause) sqlString = sqlString.Remove(sqlString.Length - 5); this.actTable = table; ColumnGroup columnGroup = CreateColumnGroup(sqlString); columnGroup.Name = table.TableName; this.actTable = null; return columnGroup; } public ColumnGroup CreateColumnGroup(string sqlString) { ColumnGroup columnGroup = new ColumnGroup(); bool initColumns = true; string dbDataType; int actRow = 0; using (DbConnection conn = connection.CreateConnection()) { conn.Open(); using (DbCommand cmd = conn.CreateCommand()) { cmd.CommandText = sqlString; using (DbDataReader reader = cmd.ExecuteReader()) { while (reader.Read()) { //create & initialize columns if (initColumns) { for (int i = 0; i < reader.FieldCount; i++) { dbDataType = reader.GetDataTypeName(i); if (IsDateDataType(dbDataType)) columnGroup.AddColumn(new DateTimeColumn(reader.GetName(i))); else if (IsNumericDataType(dbDataType)) columnGroup.AddColumn(new DoubleColumn(reader.GetName(i))); else columnGroup.AddColumn(new StringColumn(reader.GetName(i))); } initColumns = false; } //fill columns with values for (int i = 0; i < reader.FieldCount; i++) { if (reader.IsDBNull(i)) { columnGroup.Columns.ElementAt(i).AddValue(null); } else if (columnGroup.Columns.ElementAt(i).DataType == typeof(double?)) { try { columnGroup.Columns.ElementAt(i).AddValue(Convert.ToDouble(reader.GetValue(i))); } catch (DbException) { columnGroup.Columns.ElementAt(i).AddValue(null); } } else if (columnGroup.Columns.ElementAt(i).DataType == typeof(DateTime?)) { try { columnGroup.Columns.ElementAt(i).AddValue(reader.GetDateTime(i)); } catch (DbException) { columnGroup.Columns.ElementAt(i).AddValue(null); } } else { try { columnGroup.Columns.ElementAt(i).AddValue(reader.GetValue(i).ToString()); } catch (DbException) { columnGroup.Columns.ElementAt(i).AddValue(null); } } } actRow++; if (actRow % 1000 == 0) FireNewRowLoaded(actRow); } if (initColumns) { for (int i = 0; i < reader.FieldCount; i++) { if (reader.GetName(i).ToUpper().Contains("ZEIT")) columnGroup.AddColumn(new DateTimeColumn(reader.GetName(i))); else columnGroup.AddColumn(new DoubleColumn(reader.GetName(i))); } } reader.Close(); } //end using reader } //end using command } // using connection return columnGroup; } } }