@brimdata/zealot
Version:
The Javascript Client for Zed Lakes
149 lines (148 loc) • 4.44 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "Record", {
enumerable: true,
get: ()=>Record
});
const _flatColumns = require("../utils/flat-columns");
const _trueType = require("../utils/true-type");
const _field = require("./field");
const _null = require("./null");
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
class Record {
get null() {
return this.fields === null;
}
get flatColumns() {
return (0, _flatColumns.flatColumns)(this.trueType);
}
get columns() {
if (this.fields === null) return [];
return this.fields.map((f)=>f.name);
}
get trueType() {
return (0, _trueType.trueType)(this.type);
}
toString() {
if (this.fields === null) return "null";
let s = "{";
let sep = "";
this.fields.forEach((f)=>{
// XXX need to check if name has funny chars
s += sep + f.name + ":" + f.value.toString();
sep = ",";
});
s += "}";
return s;
}
serialize(stream) {
if (this.fields === null) return null;
return this.fields.map((f)=>stream.encodeValue(f.value));
}
at(index) {
return this.fieldAt(index)?.value ?? null;
}
fieldAt(index) {
if (this.fields === null) return null;
if (typeof index === "number") return this.fields[index];
if (Array.isArray(index)) {
if (index.length === 1) return this.fieldAt(index[0]);
const [head, ...tail] = index;
const value = this.fieldAt(head)?.value;
if (!value) return null;
if (!(value instanceof Record)) {
throw new Error("Not a record");
}
return value.fieldAt(tail);
} else {
throw new Error("Argument must be number | number[]");
}
}
has(name, ...types) {
try {
let type = this.get(name).type;
return types.length === 0 ? true : types.some((t)=>type === t);
} catch (e) {
return false;
}
}
get(name) {
return (this.getField(name)?.value) ?? null;
}
getField(name) {
if (typeof name === "string") return this._getField(name);
if (Array.isArray(name) && name.length === 0) throw new Error("No fields specified");
if (name.length === 1) return this._getField(name[0]);
const [next, ...rest] = name;
const field = this.getField(next);
if (!field) throw new Error("No field named " + next);
const value = field.baseValue;
if (value == null || value instanceof _null.Null) {
return null;
} else if (value instanceof Record) {
return value.getField(rest);
} else {
throw new Error(`${next} is not a record`);
}
}
try(name) {
try {
return this.get(name);
} catch {
return null;
}
}
tryField(name) {
try {
return this.getField(name);
} catch {
return null;
}
}
_getField(name, parent) {
if (!this.trueType.has(name)) {
throw new UnknownColumnError(name, this.columns);
}
if (this.fields === null) {
return new _field.Field(name, new _null.Null(), parent || this);
} else {
return this.fields.find((f)=>f.name == name);
}
}
isUnset() {
return this.fields === null;
}
toJS(opts = {}) {
if (this.fields === null) return null;
return this.fields.reduce((obj, field)=>{
obj[field.name] = field.value.toJS(opts);
return obj;
}, {});
}
constructor(type, fields){
_defineProperty(this, "type", void 0);
_defineProperty(this, "fields", void 0);
this.type = type;
this.fields = fields;
}
}
class UnknownColumnError extends Error {
constructor(unknown, names){
const available = names.map((n)=>`"${n}"`).join(", ");
super(`"${unknown}" not present in [${available}]`);
}
}