using System; using System.Collections.Generic; using System.Text; using System.Data; using System.Collections; namespace FastReport.Data { internal static class DataHelper { public static DataSourceBase GetDataSource(Dictionary dictionary, string complexName) { if (String.IsNullOrEmpty(complexName)) return null; string[] names = complexName.Split('.'); DataSourceBase data = dictionary.FindByAlias(names[0]) as DataSourceBase; if (data == null) return null; Column column = data; // take into account nested tables. Table may even be nested into Column. for (int i = 1; i < names.Length; i++) { Column childColumn = column.Columns.FindByAlias(names[i]); if (childColumn == null) break; if (childColumn is DataSourceBase) data = childColumn as DataSourceBase; column = childColumn; } return data; } public static Column GetColumn(Dictionary dictionary, string complexName) { if (String.IsNullOrEmpty(complexName)) return null; string[] names = complexName.Split('.'); // the first part of complex name is always datasource name. DataSourceBase data = dictionary.FindByAlias(names[0]) as DataSourceBase; return GetColumn(dictionary, data, names, false); } public static Column GetColumn(Dictionary dictionary, DataSourceBase data, string[] names, bool initRelation) { // Process the following cases: // - Table.Column // - Table.NestedTable.Column (specific to BO) // - Table.RelatedTable.Column // - Table.Column where Column has '.' inside (specific to MSSQL) // - Table.ComplexColumn.Column (specific to BO) if (data == null || names.Length < 2) return null; // search for relation int i = 1; for (; i < names.Length; i++) { bool found = false; foreach (Relation r in dictionary.Relations) { if (r.ChildDataSource == data && (r.ParentDataSource != null && r.ParentDataSource.Alias == names[i] || r.Alias == names[i])) { data = r.ParentDataSource; if (initRelation) data.FindParentRow(r); found = true; break; } } // nothing found, break and try column name. if (!found) break; } // the rest is column name. ColumnCollection columns = data.Columns; // try full name first string columnName = String.Empty; for (int j = i; j < names.Length; j++) columnName += (columnName.Length == 0 ? "" : ".") + names[j]; Column column = columns.FindByAlias(columnName); if (column != null) return column; // try nested columns for (int j = i; j < names.Length; j++) { column = columns.FindByAlias(names[j]); if (column == null) return null; columns = column.Columns; } return column; } public static bool IsValidColumn(Dictionary dictionary, string complexName) { return GetColumn(dictionary, complexName) != null; } // Checks if the specified column name is simple column. // The column is simple if it belongs to the datasource, and that datasource // is simple as well. This check is needed when we prepare a script for compile. // Simple columns are handled directly by the Report component, so they should be // skipped when generating the expression handler code. public static bool IsSimpleColumn(Dictionary dictionary, string complexName) { Column column = GetColumn(dictionary, complexName); return column != null && column.Parent is DataSourceBase && (column.Parent as DataSourceBase).FullName + "." + column.Alias == complexName; } public static bool IsValidParameter(Dictionary dictionary, string complexName) { string[] names = complexName.Split('.'); Parameter par = dictionary.Parameters.FindByName(names[0]); if (par == null) { if (names.Length == 1) par = dictionary.SystemVariables.FindByName(names[0]); return par != null; } for (int i = 1; i < names.Length; i++) { par = par.Parameters.FindByName(names[i]); if (par == null) return false; } return true; } public static bool IsValidTotal(Dictionary dictionary, string name) { Total sum = dictionary.Totals.FindByName(name); return sum != null; } public static Parameter GetParameter(Dictionary dictionary, string complexName) { string[] names = complexName.Split('.'); Parameter par = dictionary.Parameters.FindByName(names[0]); if (par == null) { par = dictionary.SystemVariables.FindByName(names[0]); return par; } for (int i = 1; i < names.Length; i++) { par = par.Parameters.FindByName(names[i]); if (par == null) return null; } return par; } public static Parameter CreateParameter(Dictionary dictionary, string complexName) { string[] names = complexName.Split('.'); ParameterCollection parameters = dictionary.Parameters; Parameter par = null; for (int i = 0; i < names.Length; i++) { par = parameters.FindByName(names[i]); if (par == null) { par = new Parameter(names[i]); parameters.Add(par); } parameters = par.Parameters; } return par; } public static object GetTotal(Dictionary dictionary, string name) { Total sum = dictionary.Totals.FindByName(name); if (sum != null) return sum.Value; return null; } public static Type GetColumnType(Dictionary dictionary, string complexName) { Column column = GetColumn(dictionary, complexName); return column.DataType; } public static Relation FindRelation(Dictionary dictionary, DataSourceBase parent, DataSourceBase child) { foreach (Relation relation in dictionary.Relations) { if (relation.ParentDataSource == parent && relation.ChildDataSource == child) return relation; } return null; } } }