using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Collections.Specialized; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Tango.PPC.Shared.SQL { /// /// Represents remote database query result composed of rows and columns. /// /// /// /// /// The following example demonstrates how to set the connected machine's demo state and query for the connected machine's jobs. /// /// /// /// public class RemoteSqlDataSet { /// /// Gets or sets the dataset columns. /// public RemoteSqlColumnCollection Columns { get; set; } private ObservableCollection _rows; /// /// Gets or sets the dataset rows. /// public ObservableCollection Rows { get { return _rows; } set { _rows = value; OnRowsChanged(); } } /// /// Initializes a new instance of the class. /// public RemoteSqlDataSet() { Columns = new RemoteSqlColumnCollection(); Rows = new ObservableCollection(); } private void OnRowsChanged() { if (Rows != null) { Rows.CollectionChanged -= Rows_CollectionChanged; Rows.CollectionChanged += Rows_CollectionChanged; InitRows(); } } private void Rows_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { InitRows(); } private void InitRows() { if (Rows != null) { foreach (var row in Rows.ToList()) { row.Init( (key) => { return row.Values[Columns.GetIndexOf(key)]; }, (index) => { return row.Values[index]; }); } } } /// /// Creates a new using the specified . /// /// The reader. /// public static Task Load(SqlDataReader reader) { return Task.Factory.StartNew(() => { bool columnsRead = false; RemoteSqlDataSet dataSet = new RemoteSqlDataSet(); try { while (reader.Read()) { RemoteSqlRow row = new RemoteSqlRow(); for (int i = 0; i < reader.FieldCount; i++) { if (!columnsRead) { dataSet.Columns.Add(new RemoteSqlColumn() { Name = reader.GetName(i) }); } row.Values.Add(reader.GetValue(i)); } columnsRead = true; dataSet.Rows.Add(row); } } finally { reader.Close(); } return dataSet; }); } /// /// Returns a that represents this instance. /// /// /// A that represents this instance. /// public override string ToString() { return String.Join(", ", Columns.Select(x => x.Name)) + "\n" + String.Join(Environment.NewLine, Rows.Select(x => x.ToString())); } /// /// Formats this dataset as a string with columns and rows. /// /// public String ToTableString() { Dictionary columnsMaxLength = new Dictionary(); for (int i = 0; i < Columns.Count; i++) { columnsMaxLength.Add(i, Columns[i].Name.Length); } foreach (var row in Rows) { for (int i = 0; i < row.Values.Count; i++) { int valueLength = row.Values[i].ToStringSafe().Length; if (valueLength > columnsMaxLength[i]) { columnsMaxLength[i] = valueLength; } } } String str = String.Empty; for (int i = 0; i < Columns.Count; i++) { str += $"{Columns[i].Name.PadRight(columnsMaxLength[i])}{(i < Columns.Count - 1 ? " | " : "")}"; } int width = str.Length; str += Environment.NewLine + String.Empty.PadRight(width, '-'); foreach (var row in Rows) { str += Environment.NewLine; for (int i = 0; i < row.Values.Count; i++) { str += $"{row.Values[i].ToStringSafe().PadRight(columnsMaxLength[i])}{(i < Columns.Count - 1 ? " | " : "")}"; } } return str; } } }