blob: 59d19214dbdd2ebc27841e9ed5dfcae5bb4bb6d1 [file] [log] [blame]
// 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;
using System.Diagnostics;
using System.Linq;
namespace Apache.Arrow
{
public partial class Schema
{
public IReadOnlyDictionary<string, Field> Fields
{
get => _fieldsDictionary;
}
private readonly Dictionary<string, Field> _fieldsDictionary;
public IReadOnlyDictionary<string, string> Metadata { get; }
public bool HasMetadata =>
Metadata != null && Metadata.Count > 0;
private readonly IList<Field> _fields;
public Schema(
IEnumerable<Field> fields,
IEnumerable<KeyValuePair<string, string>> metadata)
{
if (fields == null)
{
throw new ArgumentNullException(nameof(fields));
}
_fields = fields.ToList();
_fieldsDictionary = fields.ToDictionary(
field => field.Name, field => field,
StringComparer.OrdinalIgnoreCase);
Metadata = metadata?.ToDictionary(kv => kv.Key, kv => kv.Value);
}
internal Schema(List<Field> fields, IReadOnlyDictionary<string, string> metadata, bool copyCollections)
{
Debug.Assert(fields != null);
Debug.Assert(copyCollections == false, "This internal constructor is to not copy the collections.");
_fields = fields;
_fieldsDictionary = fields.ToDictionary(
field => field.Name, field => field,
StringComparer.OrdinalIgnoreCase);
Metadata = metadata;
}
public Field GetFieldByIndex(int i)
{
return _fields[i];
}
public Field GetFieldByName(string name) =>
Fields.TryGetValue(name, out Field field) ? field : null;
public int GetFieldIndex(string name, StringComparer comparer = default)
{
if (comparer == null)
comparer = StringComparer.CurrentCulture;
return _fields.IndexOf(
_fields.Single(x => comparer.Compare(x.Name, name) == 0));
}
public Schema RemoveField(int fieldIndex)
{
if (fieldIndex < 0 || fieldIndex >= _fields.Count)
{
throw new ArgumentException("Invalid fieldIndex", nameof(fieldIndex));
}
IList<Field> fields = Utility.DeleteListElement(_fields, fieldIndex);
return new Schema(fields, Metadata);
}
public Schema InsertField(int fieldIndex, Field newField)
{
newField = newField ?? throw new ArgumentNullException(nameof(newField));
if (fieldIndex < 0 || fieldIndex > _fields.Count)
{
throw new ArgumentException(nameof(fieldIndex), $"Invalid fieldIndex {fieldIndex} passed in to Schema.AddField");
}
IList<Field> fields = Utility.AddListElement(_fields, fieldIndex, newField);
return new Schema(fields, Metadata);
}
public Schema SetField(int fieldIndex, Field newField)
{
if (fieldIndex <0 || fieldIndex >= Fields.Count)
{
throw new ArgumentException($"Invalid fieldIndex {fieldIndex} passed in to Schema.SetColumn");
}
IList<Field> fields = Utility.SetListElement(_fields, fieldIndex, newField);
return new Schema(fields, Metadata);
}
}
}