public void CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { MainWindow vm = ((MainWindow)DataContext); if (e.Action == NotifyCollectionChangedAction.Add) // Decide if this node has to add a new child node { DcTable tab = e.NewItems != null && e.NewItems.Count > 0 && e.NewItems[0] is DcTable ? (DcTable)e.NewItems[0] : null; if (tab == null) { return; } if (vm.TableList.Contains(tab)) { return; } vm.TableList.Add(tab); } else if (e.Action == NotifyCollectionChangedAction.Remove) { DcTable tab = e.OldItems != null && e.OldItems.Count > 0 && e.OldItems[0] is DcTable ? (DcTable)e.OldItems[0] : null; if (tab == null) { return; } if (!vm.TableList.Contains(tab)) { return; } vm.TableList.Remove(tab); } }
public virtual void DeleteTable(DcTable table) { Debug.Assert(!table.IsPrimitive, "Wrong use: primitive tables can be deleted only along with the schema."); //DeleteTablePropagate(table); List <DcColumn> toRemove; // Remove input columns (for which this table is a type) toRemove = table.InputColumns.ToList(); foreach (DcColumn col in toRemove) { this.DeleteColumn(col); NotifyRemove(col); } // Remove output columns toRemove = table.Columns.ToList(); foreach (DcColumn col in toRemove) { this.DeleteColumn(col); NotifyRemove(col); } // Finally, remove the table itself _tables.Remove(table); NotifyRemove(table); }
public PathMappingBox(DcColumn column) { this.okCommand = new DelegateCommand(this.OkCommand_Executed, this.OkCommand_CanExecute); InitializeComponent(); if (column.Input.Columns.Contains(column)) { IsNew = false; } else { IsNew = true; } Column = column; DcTable sourceTable = column.Input; DcTable targetTable = column.Output; // Name NewColumnName = Column.Name; // Compute possible target tables TargetTables = new ObservableCollection <DcTable>(MappingModel.GetPossibleGreaterSets(sourceTable)); // TODO: Suggest the best target type if (targetTable == null) { // Compare the quality of gest mappings from the the source set to possible target sets DcTable bestTargetTable = TargetTables.Count > 0 ? TargetTables[0] : null; double bestSimilarity = 0.0; /* * foreach (ComTable set in targetTables) * { * ComColumn dim2 = set.CreateDefaultLesserDimension(dim.Name, dim.Input); * * List<Mapping> mappings = m.MapDim(new DimPath(dim), new DimPath(dim2)); * if (mappings[0].Similarity > bestSimilarity) { bestTargetTable = set; bestSimilarity = mappings[0].Similarity; } * m.Mappings.Clear(); * } */ targetTable = bestTargetTable; } targetTables.SelectedItem = targetTable; // In edit mode (for existing column), we do not allow for changing the type if (!IsNew) { targetTables.IsEnabled = false; } MappingModel = new MappingModel(sourceTable, targetTable); if (!IsNew) { MappingModel.Mapping = Column.Definition.Mapping; } RefreshAll(); }
public void CreateSampleSchema(DcSchema schema) { DcSpace space = schema.Space; DcColumn d1, d2, d3, d4; DcTable departments = space.CreateTable(DcSchemaKind.Dc, "Departments", schema.Root); d1 = space.CreateColumn("name", departments, schema.GetPrimitiveType("String"), true); d2 = space.CreateColumn("location", departments, schema.GetPrimitiveType("String"), false); DcTableWriter writer; writer = departments.GetData().GetTableWriter(); writer.Open(); writer.Append(new DcColumn[] { d1, d2 }, new object[] { "SALES", "Dresden" }); writer.Append(new DcColumn[] { d1, d2 }, new object[] { "HR", "Walldorf" }); writer.Close(); DcTable employees = space.CreateTable(DcSchemaKind.Dc, "Employees", schema.Root); d1 = space.CreateColumn("name", employees, schema.GetPrimitiveType("String"), true); d2 = space.CreateColumn("age", employees, schema.GetPrimitiveType("Double"), false); d3 = space.CreateColumn("salary", employees, schema.GetPrimitiveType("Double"), false); d4 = space.CreateColumn("dept", employees, departments, false); DcTable managers = space.CreateTable(DcSchemaKind.Dc, "Managers", employees); d1 = space.CreateColumn("title", managers, schema.GetPrimitiveType("String"), false); d2 = space.CreateColumn("is project manager", managers, schema.GetPrimitiveType("Boolean"), false); }
private void OkCommand_Executed(object state) { DcSchema schema = Column.Input.Schema; // Column name Column.Name = newColumnName.Text; // Column type DcTable targetTable = null; if (AggregationFunction == "COUNT") { targetTable = schema.GetPrimitive("Integer");; } else { targetTable = MeasurePath.Output; // The same as the measure path } Column.Output = targetTable; // Column definition Column.Definition.DefinitionType = DcColumnDefinitionType.AGGREGATION; Column.Definition.FactTable = FactTable; Column.Definition.GroupPaths.Clear(); Column.Definition.GroupPaths.Add(GroupingPath); Column.Definition.MeasurePaths.Clear(); Column.Definition.MeasurePaths.Add(MeasurePath); Column.Definition.Updater = AggregationFunction; this.DialogResult = true; }
public void TableProductTest() // Define a new table and populate it { CreateSampleData(schema); DcTable t1 = schema.GetSubTable("Table 1"); DcTable t2 = schema.GetSubTable("Table 2"); // // Define a new product-set // DcTable t3 = space.CreateTable(DcSchemaKind.Dc, "Table 3", schema.Root); DcColumn c31 = space.CreateColumn(t1.Name, t3, t1, true); // {*20, 10, *30} DcColumn c32 = space.CreateColumn(t2.Name, t3, t2, true); // {40, 40, *50, *50} t3.GetData().Populate(); Assert.AreEqual(12, t3.GetData().Length); // // Add simple where expression // t3.GetData().WhereFormula = "([Table 1].[Column 11] > 10) && this.[Table 2].[Column 23] == 50.0"; t3.GetData().Populate(); Assert.AreEqual(4, t3.GetData().Length); Assert.AreEqual(0, c31.GetData().GetValue(0)); Assert.AreEqual(2, c32.GetData().GetValue(0)); Assert.AreEqual(0, c31.GetData().GetValue(1)); Assert.AreEqual(3, c32.GetData().GetValue(1)); }
public Mapping GetBestMapping(DcSchema sourceSchema, DcTable targetSet) { Mapping bestMapping = GetBestMapping(targetSet, sourceSchema); bestMapping.Invert(); return(bestMapping); }
public GreaterTableEntry(DcTable table) { Table = table; ColumnName = table.Name; IsSelected = false; }
public void LinkTest() { CreateSampleData(schema); DcTable t1 = schema.GetSubTable("Table 1"); DcColumn c11 = t1.GetColumn("Column 11"); // 20, 10, 30 DcTable t2 = schema.GetSubTable("Table 2"); DcColumn c22 = t2.GetColumn("Column 22"); // 20, 30, 30, 30 // // Define a derived column with a definition // DcColumn link = space.CreateColumn("Column Link", t2, t1, false); link.GetData().Formula = "(( [Integer] [Column 11] = this.[Column 22], [Double] [Column 14] = 20.0 ))"; // Tuple structure corresponds to output table // Evaluate column link.GetData().Evaluate(); Assert.AreEqual(0, link.GetData().GetValue(0)); Assert.AreEqual(2, link.GetData().GetValue(1)); Assert.AreEqual(2, link.GetData().GetValue(2)); Assert.AreEqual(2, link.GetData().GetValue(3)); }
public FreeColumnBox(DcSchema schema, DcTable table) { this.okCommand = new DelegateCommand(this.OkCommand_Executed, this.OkCommand_CanExecute); // // Options and regime of the dialog // if (table.SuperColumn != null) { IsNew = false; } else { IsNew = true; } Schema = schema; Table = table; TableName = Table.Name; Entries = new ObservableCollection <GreaterTableEntry>(); CreateEntries(); InitializeComponent(); RefreshAll(); }
public void TableDataTest() // ComTableData. Manually read/write data to/from tables { CreateSampleData(schema); DcTable t1 = schema.GetSubTable("Table 1"); DcColumn c11 = t1.GetColumn("Column 11"); DcColumn c12 = t1.GetColumn("Column 12"); DcColumn c13 = t1.GetColumn("Column 13"); DcTableWriter w1 = t1.GetData().GetTableWriter(); // // Data manipulations // Assert.AreEqual(3, t1.GetData().Length); Offset input = w1.Find(new DcColumn[] { c11 }, new object[] { 10 }); Assert.AreEqual(1, input); input = w1.Find(new DcColumn[] { c12 }, new object[] { "Record 1" }); Assert.AreEqual(1, input); input = w1.Find(new DcColumn[] { c12 }, new object[] { "Record Does Not Exist" }); Assert.AreEqual(-1, input); }
public void ArithmeticTest() // ComColumnDefinition. Defining new columns and evaluate them { CreateSampleData(schema); DcTable t1 = schema.GetSubTable("Table 1"); DcColumn c11 = t1.GetColumn("Column 11"); DcColumn c12 = t1.GetColumn("Column 12"); DcColumn c13 = t1.GetColumn("Column 13"); DcColumn c14 = t1.GetColumn("Column 14"); // // Define a derived column with a definition // DcColumn c15 = space.CreateColumn("Column 15", t1, schema.GetPrimitiveType("Double"), false); c15.GetData().Formula = "([Column 11]+10.0) * this.[Column 13]"; // Evaluate column c15.GetData().Evaluate(); Assert.AreEqual(600.0, c15.GetData().GetValue(0)); Assert.AreEqual(200.0, c15.GetData().GetValue(1)); Assert.AreEqual(1200.0, c15.GetData().GetValue(2)); }
/// <summary> /// The method loads structure of the specified table and stores it as a set in this schema. /// /// The method loops through all columns and for each of them creates or finds existing three elements in the schema: /// a complex path from this set to the primtiive domain, a simple FK dimension from this set to the target FK set, and /// a complex path from the target FK set to the primitive domain. The complex path corresponding to the column will /// contain only two segments and this path definition has to be corrected later. /// </summary> /// <param name="tableName"></param> /* * private void ImportPaths(string tableName) * { * // Find set corresonding to this table * ComTable tableSet = Root.FindSubset(tableName); * * Debug.Assert(!tableSet.IsPrimitive, "Wrong use: cannot load paths into a primitive set."); * * DataTable pks = connection.conn.GetOleDbSchemaTable(OleDbSchemaGuid.Primary_Keys, new object[] { null, null, tableName }); * DataTable fks = null; * try * { * fks = connection.conn.GetOleDbSchemaTable(OleDbSchemaGuid.Foreign_Keys, new object[] { null, null, null, null, null, tableName }); * } * catch (Exception e) // For csv, foreign keys are not supported exception is raised * { * fks = new DataTable(); * } * * DataTable columns = connection.conn.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, new object[] { null, null, tableName, null }); * foreach (DataRow col in columns.Rows) // Process all columns of the table (correspond to primitive paths of the set) * { * string columnName = col["COLUMN_NAME"].ToString(); * string columnType = ((OleDbType)col["DATA_TYPE"]).ToString(); * * DimAttribute path = tableSet.GetGreaterPathByColumnName(columnName); // It might have been already created (when processing other tables) * if (path == null) * { * path = new DimAttribute(columnName); * path.RelationalColumnName = columnName; * path.Input = tableSet; // Assign domain set give the table name * path.Output = Top.GetPrimitiveSubset(columnType); * tableSet.AddGreaterPath(path); // We do not know if it is FK or simple dimensin. It will be determined later. * } * * // Find PKs this attribute belongs to (among all PKs of this table) * foreach (DataRow pk in pks.Rows) * { * string pkColumnName = (string)pk["COLUMN_NAME"]; * if (!columnName.Equals(pkColumnName, StringComparison.InvariantCultureIgnoreCase)) continue; * string pkName = (string)pk["PK_NAME"]; * * // Found PK this column belongs to * path.RelationalPkName = pkName; * path.Input.RelationalPkName = pkName; // OPTIMIZE: try to do it only once rather than for each attribute and try to identify and exclude multiple PKs (error) * path.IsIdentity = true; * break; // Assume that a column can belong to only one PK * } * * // Find FKs this attribute belongs to (among all FKs of this table) * foreach (DataRow fk in fks.Rows) * { * if (!columnName.Equals((string)fk["FK_COLUMN_NAME"], StringComparison.InvariantCultureIgnoreCase)) continue; * * // Target PK name fk["PK_NAME"] is not stored and is not used because we assume that there is only one PK * * // * // Step 1. Add FK-segment (as a dimension) * // * * string fkName = (string)fk["FK_NAME"]; * path.RelationalFkName = fkName; * Debug.Assert(tableSet.GetGreaterDim(fkName) == null, "A dimension already exists."); * * Dim fkSegment = new Dim(fkName); // It is the first segment in the path representing this FK * fkSegment.RelationalFkName = fkName; * fkSegment.IsIdentity = path.IsIdentity; * fkSegment.RelationalPkName = path.RelationalPkName; // We assume if one column belongs t PK then the whole FK (this column belongs to) belongs to the same PK * * fkSegment.Input = tableSet; * * string fkTargetTableName = (string)fk["PK_TABLE_NAME"]; // Name of the target set of the simple dimension (first segment of this complex path) * Set fkTargetSet = Root.FindSubset(fkTargetTableName); * fkSegment.Output = fkTargetSet; * fkSegment.Add(); // Add this FK-dimension to the set (it is always new) * * if (path.Path.Count == 0) * { * path.Path.Add(fkSegment); * } * else * { * path.Path[0] = fkSegment; // Or we can insert it before all other segments * Debug.Assert(true, "Wrong use: A primary key dimension must be inserted only as the very first segment - not the second."); * } * * // * // Step 2. Add rest of the path (as a path) * // * * string fkTargetColumnName = (string)fk["PK_COLUMN_NAME"]; // Next path name belonging to the target set * DimPath fkTargetPath = fkTargetSet.GetGreaterPathByColumnName(fkTargetColumnName); // This column might have been created * if (fkTargetPath == null) * { * fkTargetPath = new DimPath(fkTargetColumnName); * fkTargetPath.RelationalColumnName = fkTargetColumnName; * fkTargetPath.IsIdentity = path.IsIdentity; * fkTargetPath.Input = fkTargetSet; * fkTargetPath.Output = path.Output; * fkTargetSet.AddGreaterPath(fkTargetPath); // We do not know if it is really a FK or simple dimension so this needs to be fixed later * } * * if (path.Path.Count == 0) * { * Debug.Assert(true, "Wrong use: A target path must be inserted only as the second segment - not any other."); * } * else if (path.Path.Count == 1) * { * path.Path.Add(fkTargetPath); * } * else * { * path.Path[1] = fkTargetPath; * Debug.Assert(true, "Wrong use: A target path must be inserted only as the second segment - not any other."); * } * * break; // We assume that a column can belong to only one FK and do not continue with the rest of the FK-loop * } * * if (path.Path.Count == 0) // Not FK - just normal column * { * Dim dim = new Dim(path.Name); * dim.RelationalColumnName = path.RelationalColumnName; * dim.RelationalPkName = path.RelationalPkName; * dim.Input = path.Input; * dim.Output = path.Output; * dim.IsIdentity = path.IsIdentity; * dim.Add(); * * path.Path.Add(dim); // The path will consist of a single segment * } * * } * * } */ #endregion #region Data methods /// <summary> /// Load data corresponding to the specified set from the underlying database. /// </summary> /// <returns></returns> public DataTable LoadTable(DcTable table) // Load data for only this table (without greater tables connected via FKs) { TableRel tab = (TableRel)table; string select = ""; List <ColumnAtt> attributes = tab.GreaterPaths; foreach (ColumnAtt att in attributes) { select += "[" + att.RelationalColumnName + "]" + ", "; } select = select.Substring(0, select.Length - 2); string from = "[" + tab.RelationalTableName + "]"; string where = ""; // tab.WhereExpression string orderby = ""; // tab.OrderbyExpression // Send query to the remote database for execution string query = "SELECT " + select + " FROM " + from + " "; query += String.IsNullOrEmpty(where) ? "" : "WHERE " + where + " "; query += String.IsNullOrEmpty(orderby) ? "" : "ORDER BY " + orderby + " "; connection.Open(); DataTable dataTable = connection.ExecuteSelect(query); connection.Close(); return(dataTable); }
public void RemoveFirst(DcTable tab) // Remove first segments till this table (the new path will start from the specified table if trimmed) { if (Input == tab) { return; // Already here } // Find a path to the specified table int index = this.IndexOfGreater(tab); if (index < 0) { return; } Segments.RemoveRange(0, index + 1); if (Segments.Count > 0) { Input = Segments[0].Input; } else { Input = Output; } }
private void CreateEntries(Mapping mapping) { Entries.Clear(); if (mapping == null) { return; } DcTable sourceTable = mapping.SourceSet; DcTable targetTable = mapping.TargetSet; foreach (DcColumn sourceColumn in sourceTable.Columns) { if (sourceColumn.IsSuper) { continue; } if (!sourceColumn.IsPrimitive) { continue; } if (sourceColumn == Column) { continue; // Do not include the generating/projection column } ColumnMappingEntry entry = new ColumnMappingEntry(sourceColumn); PathMatch match = mapping.GetMatchForSource(new DimPath(sourceColumn)); if (match != null) { entry.Target = match.TargetPath.FirstSegment; entry.TargetType = entry.Target.Output; entry.IsKey = entry.Target.IsKey; entry.IsMatched = true; } else { entry.Target = null; entry.TargetType = null; if (IsImport) { entry.IsKey = false; } else { entry.IsKey = true; } entry.IsMatched = false; } Entries.Add(entry); } }
// // Poset relation // // TODO: Maybe rewrite as one method IsLess with parameter as bit mask {Super, Key, Nonkey} // And then define shortcut methods via this general methods. In fact, IsLess *is* already defined via enumeator // Return true if this set is included in the specified set, that is, the specified set is a direct or indirect super-set of this set public bool IsSubTable(DcTable parent) // IsSub { for (DcTable tab = this; tab != null; tab = tab.SuperTable) { if (tab == parent) return true; } return false; }
public virtual void FromJson(JObject json, DcSpace ws) { // List of schemas foreach (JObject schema in json["schemas"]) { DcSchema sch = (DcSchema)Utils.CreateObjectFromJson(schema); if (sch != null) { sch.FromJson(schema, this); _schemas.Add(sch); } } // List of tables foreach (JObject table in json["tables"]) { DcTable tab = (DcTable)Utils.CreateObjectFromJson(table); if (tab != null) { tab.FromJson(table, this); _tables.Add(tab); } } // Load all columns from all schema (now all tables are present) foreach (JObject schema in json["schemas"]) { foreach (JObject column in schema["columns"]) // List of columns { DcColumn col = (DcColumn)Utils.CreateObjectFromJson(column); if (col != null) { col.FromJson(column, this); _columns.Add(col); } } } // Second pass on all columns with the purpose to load their definitions (now all columns are present) foreach (JObject schema in json["schemas"]) { foreach (JObject column in schema["columns"]) // List of columns { DcColumn col = (DcColumn)Utils.CreateObjectFromJson(column); if (col != null) { col.FromJson(column, this); // Find the same existing column (possibly without a definition) DcColumn existing = col.Input.GetColumn(col.Name); // Copy the definition existing.FromJson(column, this); } } } }
public ColumnTree(DcTable set, ColumnTree parent = null) { Column = new Column(set); Children = new List <ColumnTree>(); if (parent != null) { parent.AddChild(this); } }
public ColumnCsv(string name, DcTable input, DcTable output, bool isIdentity, bool isSuper) : base(name, input, output, isIdentity, isSuper) { SampleValues = new List <string>(); ColumnIndex = -1; _data = new ColumnDataEmpty(); _data.Translate(); }
public void Invert() // Invert source and target { var tempTab = _sourceTab; _sourceTab = _targetTab; _targetTab = tempTab; Matches.ForEach(m => m.Invert()); }
public List <Mapping> MapPrimitiveSet(DcSchema sourceSchema, DcTable targetSet) { List <Mapping> maps = MapPrimitiveSet(targetSet, sourceSchema); maps.ForEach(m => Mappings.Remove(m)); maps.ForEach(m => m.Invert()); Mappings.AddRange(maps); return(maps); }
public Mapping(DcTable sourceTab, DcTable targetTab) { // Debug.Assert((sourceTab.IsPrimitive && targetTab.IsPrimitive) || (!sourceTab.IsPrimitive && !targetTab.IsPrimitive), "Wrong use: cannot create a mapping between a primitive table and a non-primitive table."); Debug.Assert(sourceTab != null && targetTab != null, "Wrong use: parametes cannot be null."); Matches = new List <PathMatch>(); SourceTab = sourceTab; TargetTab = targetTab; }
public virtual DcColumn CreateColumn(DcSchemaKind schemaType, string name, DcTable input, DcTable output, bool isKey) { Debug.Assert(!String.IsNullOrEmpty(name), "Wrong use: column name cannot be null or empty."); // TODO: Check constraints: 1. only one super-column can exist 2. no loops can appear DcSchemaKind inSchemaType = input.Schema.GetSchemaKind(); DcSchemaKind outSchemaType = output.Schema.GetSchemaKind(); DcColumn column; // // We create a column according to its table type // if (schemaType == DcSchemaKind.Dc) // Column belongs to a normal table { column = new Column(name, input, output, isKey, false); } else if (schemaType == DcSchemaKind.Csv) // Column belongs to a CSV table { column = new ColumnCsv(name, input, output, isKey, false); } else { throw new NotImplementedException("This schema type is not implemented."); } /* OLD - here we create a column according to import-export status * if (inSchemaType == DcSchemaKind.Dc || outSchemaType == DcSchemaKind.Dc) // Intra-mashup or import/export columns * { * column = new Column(name, input, output, isKey, false); * } * else if (inSchemaType == DcSchemaKind.Csv && outSchemaType == DcSchemaKind.Csv) // Intra-csv columns * { * column = new ColumnCsv(name, input, output, isKey, false); * } * else if (inSchemaType == DcSchemaKind.Oledb && outSchemaType == DcSchemaKind.Oledb) // Intra-oledb columns * { * throw new NotImplementedException("This schema type is not implemented."); * } * else if (inSchemaType == DcSchemaKind.Rel && outSchemaType == DcSchemaKind.Rel) // Intra-rel columns * { * column = new ColumnRel(name, input, output, isKey, false); * } * else * { * throw new NotImplementedException("This schema type is not implemented."); * } */ _columns.Add(column); NotifyAdd(column); return(column); }
public ColumnComplexEnumerator(DcTable tab) : base(tab) { _inputs = new List <DcTable>(new DcTable[] { tab }); // One source table _outputs = new List <DcTable>(new DcTable[] { tab.Schema.Root }); // All destination tables from this schema isInverse = false; childNumber = Enumerable.Repeat(-1, 1024).ToArray(); isValidTab = Enumerable.Repeat(false, 1024).ToArray(); }
public void ProjectionTest() // Defining new tables via function projection and populate them { CreateSampleData(schema); DcTable t2 = schema.GetSubTable("Table 2"); DcColumn c21 = t2.GetColumn("Column 21"); DcColumn c22 = t2.GetColumn("Column 22"); DcColumn c23 = t2.GetColumn("Column 23"); // // Project "Table 2" along "Column 21" and get 2 unique records in a new set "Value A" (3 references) and "Value B" (1 reference) // DcTable t3 = space.CreateTable(DcSchemaKind.Dc, "Table 3", schema.Root); DcColumn c31 = space.CreateColumn(c21.Name, t3, c21.Output, true); // Create a generating column DcColumn c24 = space.CreateColumn("Project", t2, t3, false); c24.GetData().Formula = "(( [String] [Column 21] = [Column 21] ))"; c24.GetData().IsAppendData = true; t3.GetData().Populate(); Assert.AreEqual(2, t3.GetData().Length); Assert.AreEqual(0, c24.GetData().GetValue(0)); Assert.AreEqual(0, c24.GetData().GetValue(1)); Assert.AreEqual(0, c24.GetData().GetValue(2)); Assert.AreEqual(1, c24.GetData().GetValue(3)); // // Defining a combination of "Column 21" and "Column 22" and project with 3 unique records in a new set // DcTable t4 = space.CreateTable(DcSchemaKind.Dc, "Table 4", schema.Root); DcColumn c41 = space.CreateColumn(c21.Name, t4, c21.Output, true); DcColumn c42 = space.CreateColumn(c22.Name, t4, c22.Output, true); DcColumn c25 = space.CreateColumn("Project", t2, t4, false); c25.GetData().Formula = "(( [String] [Column 21] = [Column 21], [Integer] [Column 22] = [Column 22] ))"; c25.GetData().IsAppendData = true; t4.GetData().Populate(); Assert.AreEqual(3, t4.GetData().Length); Assert.AreEqual(0, c25.GetData().GetValue(0)); Assert.AreEqual(1, c25.GetData().GetValue(1)); Assert.AreEqual(1, c25.GetData().GetValue(2)); Assert.AreEqual(2, c25.GetData().GetValue(3)); }
/// <summary> /// Expand one attribute by building its path segments as dimension objects. /// Use the provided list of attributes for expansion recursively. This list essentially represents a schema. /// Also, adjust path names in special cases like empty name or simple structure. /// </summary> public void ExpandAttribute(List <ColumnAtt> attributes, List <DcColumn> columns) // Add and resolve attributes by creating dimension structure from FKs { ColumnAtt att = this; if (att.Segments.Count > 0) { return; // Already expanded (because of recursion) } bool isKey = !string.IsNullOrEmpty(att.RelationalPkName) || att.IsKey; if (string.IsNullOrEmpty(att.RelationalFkName)) // No FK - primitive column - end of recursion { // Find or create a primitive dim segment DcColumn seg = columns.FirstOrDefault(c => c.Input == att.Input && StringSimilarity.SameColumnName(((ColumnRel)c).RelationalFkName, att.RelationalFkName)); if (seg == null) { seg = new ColumnRel(att.RelationalColumnName, att.Input, att.Output, isKey, false); // Maybe copy constructor? ((ColumnRel)seg).RelationalFkName = att.RelationalFkName; columns.Add(seg); } att.InsertLast(seg); // add it to this attribute as a single segment } else { // There is FK - non-primitive column // Find target set and target attribute (name resolution) ColumnAtt tailAtt = attributes.FirstOrDefault(a => StringSimilarity.SameTableName(a.Input.Name, att.RelationalTargetTableName) && StringSimilarity.SameColumnName(a.Name, att.RelationalTargetColumnName)); DcTable gTab = tailAtt.Input; // Find or create a dim segment DcColumn seg = columns.FirstOrDefault(c => c.Input == att.Input && StringSimilarity.SameColumnName(((ColumnRel)c).RelationalFkName, att.RelationalFkName)); if (seg == null) { seg = new ColumnRel(att.RelationalFkName, att.Input, gTab, isKey, false); ((ColumnRel)seg).RelationalFkName = att.RelationalFkName; columns.Add(seg); } att.InsertLast(seg); // add it to this attribute as first segment // // Recursion. Expand tail attribute and add all segments from the tail attribute (continuation) // tailAtt.ExpandAttribute(attributes, columns); att.InsertLast(tailAtt); // Adjust name. How many attributes belong to the same FK as this attribute (FK composition) List <ColumnAtt> fkAtts = attributes.Where(a => a.Input == att.Input && StringSimilarity.SameColumnName(att.RelationalFkName, a.RelationalFkName)).ToList(); if (fkAtts.Count == 1) { seg.Name = att.RelationalColumnName; // Adjust name. For 1-column FK, name of the FK-dim is the column name (not the FK name) } } }
public int IndexOfLesser(DcTable tab) // Return index of the column with this lesser table { for (int i = 0; i < Segments.Count; i++) { if (Segments[i].Input == tab) { return(i); } } return(-1); }
public virtual List <DcColumn> GetInputColumns(DcTable table) { if (table == null) { return(new List <DcColumn>(_columns)); } else { return(_columns.Where(x => x.Output == table).ToList()); } }
public bool IsInMashups(DcTable tab) // Determine if the specified set belongs to some mashup { if (tab == null || MashupTop == null) { return(false); } if (tab.Schema == MashupTop) { return(true); } return(false); }
public void AggregationTest() // Defining new aggregated columns and evaluate them { CreateSampleData(schema); DcTable t1 = schema.GetSubTable("Table 1"); DcTable t2 = schema.GetSubTable("Table 2"); DcColumn c23 = t2.GetColumn("Column 23"); DcColumn c24 = t2.GetColumn("Table 1"); // // Define aggregated column // /* We do not use non-syntactic (object) formulas * DcColumn c15 = schema.CreateColumn("Agg of Column 23", t1, schema.GetPrimitive("Double"), false); * c15.Definition.DefinitionType = DcColumnDefinitionType.AGGREGATION; * * c15.Definition.FactTable = t2; // Fact table * c15.Definition.GroupPaths = new List<DimPath>(new DimPath[] { new DimPath(c24) }); // One group path * c15.Definition.MeasurePaths = new List<DimPath>(new DimPath[] { new DimPath(c23) }); // One measure path * c15.Definition.Updater = "SUM"; // Aggregation function * * c15.Add(); * * // * // Evaluate expression * // * c15.Data.SetValue(0.0); * c15.Definition.Evaluate(); // {40, 140, 0} * * Assert.AreEqual(40.0, c15.Data.GetValue(0)); * Assert.AreEqual(140.0, c15.Data.GetValue(1)); * Assert.AreEqual(0.0, c15.Data.GetValue(2)); // In fact, it has to be NaN or null (no values have been aggregated) */ // // Aggregation via a syntactic formula // DcColumn c16 = space.CreateColumn("Agg2 of Column 23", t1, schema.GetPrimitiveType("Double"), false); c16.GetData().Formula = "AGGREGATE(facts=[Table 2], groups=[Table 1], measure=[Column 23]*2.0 + 1, aggregator=SUM)"; c16.GetData().SetValue(0.0); c16.GetData().Translate(); c16.GetData().Evaluate(); // {40, 140, 0} Assert.AreEqual(81.0, c16.GetData().GetValue(0)); Assert.AreEqual(283.0, c16.GetData().GetValue(1)); Assert.AreEqual(0.0, c16.GetData().GetValue(2)); }