// Licensed to the Apache Software Foundation (ASF) under one or more // contributor license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright ownership. // The ASF licenses this file to You under the Apache License, Version 2.0 // (the "License"); you may not use this file except in compliance with // the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. using System; using System.Collections.Generic; namespace Apache.Arrow { /// /// A logical Table class to represent a dataset as a sequence of Columns /// public class Table { public Schema Schema { get; } public long RowCount { get; } public int ColumnCount { get; private set; } public Column Column(int columnIndex) => _columns[columnIndex]; private readonly IList _columns; public static Table TableFromRecordBatches(Schema schema, IList recordBatches) { int nBatches = recordBatches.Count; int nColumns = schema.Fields.Count; List columns = new List(nColumns); List columnArrays = new List(nBatches); for (int icol = 0; icol < nColumns; icol++) { for (int jj = 0; jj < nBatches; jj++) { columnArrays.Add(recordBatches[jj].Column(icol) as Array); } columns.Add(new Arrow.Column(schema.GetFieldByIndex(icol), columnArrays)); columnArrays.Clear(); } return new Table(schema, columns); } public Table(Schema schema, IList columns) { Schema = schema; _columns = columns; if (columns.Count > 0) { RowCount = columns[0].Length; ColumnCount = columns.Count; } } public Table() { Schema = new Schema.Builder().Build(); _columns = new List(); } public Table RemoveColumn(int columnIndex) { Schema newSchema = Schema.RemoveField(columnIndex); IList newColumns = Utility.DeleteListElement(_columns, columnIndex); return new Table(newSchema, newColumns); } public Table InsertColumn(int columnIndex, Column column) { column = column ?? throw new ArgumentNullException(nameof(column)); if (columnIndex < 0 || columnIndex > _columns.Count) { throw new ArgumentException($"Invalid columnIndex {columnIndex} passed into Table.AddColumn"); } if (column.Length != RowCount) { throw new ArgumentException($"Column's length {column.Length} must match Table's length {RowCount}"); } Schema newSchema = Schema.InsertField(columnIndex, column.Field); IList newColumns = Utility.AddListElement(_columns, columnIndex, column); return new Table(newSchema, newColumns); } public Table SetColumn(int columnIndex, Column column) { column = column ?? throw new ArgumentNullException(nameof(column)); if (columnIndex < 0 || columnIndex >= ColumnCount) { throw new ArgumentException($"Invalid columnIndex {columnIndex} passed in to Table.SetColumn"); } if (column.Length != RowCount) { throw new ArgumentException($"Column's length {column.Length} must match table's length {RowCount}"); } Schema newSchema = Schema.SetField(columnIndex, column.Field); IList newColumns = Utility.SetListElement(_columns, columnIndex, column); return new Table(newSchema, newColumns); } // TODO: Flatten for Tables with Lists/Structs? } }