// loaders.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { ArrowLikeField } from "./arrow-like-field.js"; export class ArrowLikeSchema { fields; metadata; constructor(fields, metadata = new Map()) { // checkNames(fields); // For kepler fields, create arrow compatible `Fields` that have kepler fields as `metadata` this.fields = fields.map((field) => new ArrowLikeField(field.name, field.type, field.nullable, field.metadata)); this.metadata = metadata instanceof Map ? metadata : new Map(Object.entries(metadata)); } // TODO - arrow only seems to compare fields, not metadata compareTo(other) { if (this.metadata !== other.metadata) { return false; } if (this.fields.length !== other.fields.length) { return false; } for (let i = 0; i < this.fields.length; ++i) { if (!this.fields[i].compareTo(other.fields[i])) { return false; } } return true; } select(...columnNames) { // Ensure column names reference valid fields const nameMap = Object.create(null); for (const name of columnNames) { nameMap[name] = true; } const selectedFields = this.fields.filter((field) => nameMap[field.name]); return new ArrowLikeSchema(selectedFields, this.metadata); } selectAt(...columnIndices) { // Ensure column indices reference valid fields const selectedFields = columnIndices.map((index) => this.fields[index]).filter(Boolean); return new ArrowLikeSchema(selectedFields, this.metadata); } assign(schemaOrFields) { let fields; let metadata = this.metadata; if (schemaOrFields instanceof ArrowLikeSchema) { const otherArrowLikeSchema = schemaOrFields; fields = otherArrowLikeSchema.fields; metadata = mergeMaps(mergeMaps(new Map(), this.metadata), otherArrowLikeSchema.metadata); } else { fields = schemaOrFields; } // Create a merged list of fields, overwrite fields in place, new fields at end const fieldMap = Object.create(null); for (const field of this.fields) { fieldMap[field.name] = field; } for (const field of fields) { fieldMap[field.name] = field; } const mergedFields = Object.values(fieldMap); return new ArrowLikeSchema(mergedFields, metadata); } } // Warn if any duplicated field names // function checkNames(fields: Field[]): void { // const usedNames: Record = {}; // for (const field of fields) { // if (usedNames[field.name]) { // // eslint-disable-next-line // console.warn('ArrowLikeSchema: duplicated field name', field.name, field); // } // usedNames[field.name] = true; // } // } function mergeMaps(m1, m2) { // @ts-ignore return new Map([...(m1 || new Map()), ...(m2 || new Map())]); }