Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
"@apache-arrow/esnext-esm": "^12.0.1",
"@cloudquery/plugin-pb-javascript": "^0.0.7",
"boolean": "^3.2.0",
"luxon": "^3.4.0",
"winston": "^3.10.0",
"yargs": "^17.7.2"
}
Expand Down
62 changes: 62 additions & 0 deletions src/scalar/float64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { DataType, Float64 as ArrowFloat64 } from '@apache-arrow/esnext-esm';

import { Scalar } from './scalar.js';
import { isInvalid, NULL_VALUE } from './util.js';

export class Float64 implements Scalar<number> {
private _valid = false;
private _value: number = 0;

public constructor(v: unknown) {
this.value = v;
return this;
}

public get dataType(): DataType {
return new ArrowFloat64();
}

public get valid(): boolean {
return this._valid;
}

public get value(): number {
return this._value;
}

public set value(value: unknown) {
if (isInvalid(value)) {
this._valid = false;
return;
}

if (value instanceof Float64) {
this._valid = value.valid;
this._value = value.value;
return;
}

if (typeof value === 'number') {
this._value = value;
this._valid = true;
return;
}

const floatValue = Number.parseFloat(String(value));
if (!Number.isNaN(floatValue)) {
this._value = floatValue;
this._valid = true;
return;
}

throw new Error(`Unable to set '${value}' as Float64`);
}

public toString() {
if (this._valid) {
return String(this._value);
}

return NULL_VALUE;
}
}
71 changes: 71 additions & 0 deletions src/scalar/int64.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { DataType, Int64 as ArrowInt64 } from '@apache-arrow/esnext-esm';

import { Scalar } from './scalar.js';
import { isInvalid, NULL_VALUE } from './util.js';

export class Int64 implements Scalar<bigint> {
private _valid = false;
private _value: bigint = BigInt(0);

public constructor(v: unknown) {
this.value = v;
return this;
}

public get dataType(): DataType {
return new ArrowInt64();
}

public get valid(): boolean {
return this._valid;
}

public get value(): bigint {
return this._value;
}

public set value(value: unknown) {
if (isInvalid(value)) {
this._valid = false;
return;
}

if (value instanceof Int64) {
this._valid = value.valid;
this._value = value.value;
return;
}

if (typeof value === 'bigint') {
this._value = value;
this._valid = true;
return;
}

if (typeof value === 'number') {
if (!Number.isSafeInteger(value)) {
throw new TypeError(`Value '${value}' cannot be safely converted to Int64`);
}
this._value = BigInt(value);
this._valid = true;
return;
}

const bigintValue = BigInt(value);
if (bigintValue !== undefined) {
this._value = bigintValue;
this._valid = true;
return;
}

throw new Error(`Unable to set '${value}' as Int64`);
}

public toString() {
if (this._valid) {
return String(this._value);
}

return NULL_VALUE;
}
}
84 changes: 84 additions & 0 deletions src/scalar/timestamp.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { DataType, Timestamp as ArrowTimestamp } from '@apache-arrow/esnext-esm';
import { DateTime } from 'luxon';

import { Scalar } from './scalar.js';
import { isInvalid, NULL_VALUE } from './util.js';

export class Timestamp implements Scalar<DateTime> {
private _valid = false;
private _value: DateTime = DateTime.fromMillis(0);

public constructor(v: unknown) {
this.value = v;
return this;
}

public get dataType(): DataType {
return new ArrowTimestamp();
}

public get valid(): boolean {
return this._valid;
}

public get value(): DateTime {
return this._value;
}

public set value(value: unknown) {
if (isInvalid(value)) {
this._valid = false;
return;
}

if (value instanceof Timestamp) {
this._valid = value.valid;
this._value = value.value;
return;
}

let dateValue: DateTime | null = null;

if (typeof value === 'string') {
dateValue = DateTime.fromFormat(value, 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS ZZZZ', { setZone: true });

if (!dateValue.isValid) {
dateValue = DateTime.fromFormat(value, 'yyyy-MM-dd HH:mm:ss.SSSSSSSSS', { zone: 'utc' });
}

if (!dateValue.isValid) {
dateValue = DateTime.fromFormat(value, "yyyy-MM-dd HH:mm:ss.SSSSSSSSS'Z'", { zone: 'utc' });
}

if (!dateValue.isValid) {
dateValue = DateTime.fromISO(value, { setZone: true });
}
}

if (dateValue && dateValue.isValid) {
this._value = dateValue;
this._valid = true;
return;
}

throw new Error(`Unable to set '${value}' as Timestamp`);
}

public toString() {
if (this._valid) {
return this._value.toISO();
}

return NULL_VALUE;
}

public equals(scalar: Timestamp): boolean {
if (!scalar) {
return false;
}
if (scalar instanceof Timestamp) {
return this._value.equals(scalar.value) && this._valid === scalar.valid;
}
return false;
}
}