Skip to content

Commit

Permalink
fix: address review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
alvarowolfx committed Apr 17, 2024
1 parent 62e55d7 commit 40197b8
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 29 deletions.
44 changes: 24 additions & 20 deletions src/bigquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,7 +865,7 @@ export class BigQuery extends Service {
* The lower bound is inclusive and the upper bound is exclusive.
*
* @method BigQuery.range
* @param {string|BigQueryRangeOptions} value The range literal or start/end with dates/datetimes/timestamp ranges.
* @param {string|BigQueryRangeOptions} value The range API string or start/end with dates/datetimes/timestamp ranges.
* @param {string} elementType The range element type - DATE|DATETIME|TIMESTAMP
*
* @example
Expand All @@ -886,7 +886,7 @@ export class BigQuery extends Service {
* The lower and upper bound for the range are optional.
* The lower bound is inclusive and the upper bound is exclusive.
*
* @param {string|BigQueryRangeOptions} value The range literal or start/end with dates/datetimes/timestamp ranges.
* @param {string|BigQueryRangeOptions} value The range API string or start/end with dates/datetimes/timestamp ranges.
* @param {string} elementType The range element type - DATE|DATETIME|TIMESTAMP
*
* @example
Expand Down Expand Up @@ -2481,28 +2481,16 @@ export class BigQueryRange {
elementType?: string;
start?: BigQueryTimestamp | BigQueryDate | BigQueryDatetime;
end?: BigQueryTimestamp | BigQueryDate | BigQueryDatetime;

constructor(value: string | BigQueryRangeOptions, elementType?: string) {
if (typeof value === 'string') {
if (!elementType) {
throw new Error(
'invalid RANGE. Element type required when using RANGE literal string.'
);
}
let cleanedValue = value;
if (cleanedValue.startsWith('[') || cleanedValue.startsWith('(')) {
cleanedValue = cleanedValue.substring(1);
}
if (cleanedValue.endsWith(')') || cleanedValue.endsWith(']')) {
cleanedValue = cleanedValue.substring(0, cleanedValue.length - 1);
}
const parts = cleanedValue.split(',');
if (parts.length !== 2) {
throw new Error(
'invalid RANGE. See RANGE literal format docs for more information.'
'invalid RANGE. Element type required when using RANGE API string.'
);
}

const [start, end] = parts.map((s: string) => s.trim());
const [start, end] = BigQueryRange.fromStringValue_(value);
this.start = this.convertElement_(start, elementType);
this.end = this.convertElement_(end, elementType);
this.elementType = elementType;
Expand All @@ -2527,18 +2515,29 @@ export class BigQueryRange {
}
}

public get literalValue() {
/*
* Get Range string representation used by the BigQuery API.
*/
public get apiValue() {
return `[${this.start ? this.start.value : 'UNBOUNDED'}, ${this.end ? this.end.value : 'UNBOUNDED'})`;
}

/*
* Get Range literal representation accordingly to
* https://cloud.google.com/bigquery/docs/reference/standard-sql/lexical#range_literals
*/
public get literalValue() {
return `RANGE<${this.elementType}> ${this.apiValue}`;
}

public get value() {
return {
start: this.start ? this.start.value : 'UNBOUNDED',
end: this.end ? this.end.value : 'UNBOUNDED',
};
}

static fromSchemaValue_(value: string, elementType: string): BigQueryRange {
private static fromStringValue_(value: string): [start: string, end: string] {
let cleanedValue = value;
if (cleanedValue.startsWith('[') || cleanedValue.startsWith('(')) {
cleanedValue = cleanedValue.substring(1);
Expand All @@ -2554,6 +2553,11 @@ export class BigQueryRange {
}

const [start, end] = parts.map((s: string) => s.trim());
return [start, end];
}

static fromSchemaValue_(value: string, elementType: string): BigQueryRange {
const [start, end] = BigQueryRange.fromStringValue_(value);
const convertRangeSchemaValue = (value: string) => {
if (value === 'UNBOUNDED' || value === 'NULL') {
return null;
Expand All @@ -2571,7 +2575,7 @@ export class BigQueryRange {
);
}

convertElement_(
private convertElement_(
value?: string | BigQueryDate | BigQueryDatetime | BigQueryTimestamp,
elementType?: string
) {
Expand Down
54 changes: 45 additions & 9 deletions test/bigquery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -987,27 +987,39 @@ describe('BigQuery', () => {

it('should accept a string literal', () => {
const dateRange = bq.range(INPUT_DATE_RANGE, 'DATE');
assert.strictEqual(dateRange.literalValue, '[2020-01-01, 2020-12-31)');
assert.strictEqual(dateRange.apiValue, '[2020-01-01, 2020-12-31)');
assert.strictEqual(
dateRange.literalValue,
'RANGE<DATE> [2020-01-01, 2020-12-31)'
);
assert.deepStrictEqual(dateRange.value, {
start: '2020-01-01',
end: '2020-12-31',
});

const datetimeRange = bq.range(INPUT_DATETIME_RANGE, 'DATETIME');
assert.strictEqual(
datetimeRange.literalValue,
datetimeRange.apiValue,
'[2020-01-01 12:00:00, 2020-12-31 12:00:00)'
);
assert.strictEqual(
datetimeRange.literalValue,
'RANGE<DATETIME> [2020-01-01 12:00:00, 2020-12-31 12:00:00)'
);
assert.deepStrictEqual(datetimeRange.value, {
start: '2020-01-01 12:00:00',
end: '2020-12-31 12:00:00',
});

const timestampRange = bq.range(INPUT_TIMESTAMP_RANGE, 'TIMESTAMP');
assert.strictEqual(
timestampRange.literalValue,
timestampRange.apiValue,
'[2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.strictEqual(
timestampRange.literalValue,
'RANGE<TIMESTAMP> [2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.deepStrictEqual(timestampRange.value, {
start: '2020-10-01T04:00:00.000Z',
end: '2020-12-31T04:00:00.000Z',
Expand All @@ -1019,7 +1031,11 @@ describe('BigQuery', () => {
start: bq.date('2020-01-01'),
end: bq.date('2020-12-31'),
});
assert.strictEqual(dateRange.literalValue, INPUT_DATE_RANGE);
assert.strictEqual(dateRange.apiValue, INPUT_DATE_RANGE);
assert.strictEqual(
dateRange.literalValue,
`RANGE<DATE> ${INPUT_DATE_RANGE}`
);
assert.strictEqual(dateRange.elementType, 'DATE');
assert.deepStrictEqual(dateRange.value, {
start: '2020-01-01',
Expand All @@ -1030,7 +1046,11 @@ describe('BigQuery', () => {
start: bq.datetime('2020-01-01 12:00:00'),
end: bq.datetime('2020-12-31 12:00:00'),
});
assert.strictEqual(datetimeRange.literalValue, INPUT_DATETIME_RANGE);
assert.strictEqual(datetimeRange.apiValue, INPUT_DATETIME_RANGE);
assert.strictEqual(
datetimeRange.literalValue,
`RANGE<DATETIME> ${INPUT_DATETIME_RANGE}`
);
assert.strictEqual(datetimeRange.elementType, 'DATETIME');
assert.deepStrictEqual(datetimeRange.value, {
start: '2020-01-01 12:00:00',
Expand All @@ -1042,9 +1062,13 @@ describe('BigQuery', () => {
end: bq.timestamp('2020-12-31 12:00:00+08'),
});
assert.strictEqual(
timestampRange.literalValue,
timestampRange.apiValue,
'[2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.strictEqual(
timestampRange.literalValue,
'RANGE<TIMESTAMP> [2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.strictEqual(timestampRange.elementType, 'TIMESTAMP');
assert.deepStrictEqual(timestampRange.value, {
start: '2020-10-01T04:00:00.000Z',
Expand All @@ -1060,7 +1084,11 @@ describe('BigQuery', () => {
},
'DATE'
);
assert.strictEqual(dateRange.literalValue, INPUT_DATE_RANGE);
assert.strictEqual(dateRange.apiValue, INPUT_DATE_RANGE);
assert.strictEqual(
dateRange.literalValue,
`RANGE<DATE> ${INPUT_DATE_RANGE}`
);
assert.strictEqual(dateRange.elementType, 'DATE');

const datetimeRange = bq.range(
Expand All @@ -1070,7 +1098,11 @@ describe('BigQuery', () => {
},
'DATETIME'
);
assert.strictEqual(datetimeRange.literalValue, INPUT_DATETIME_RANGE);
assert.strictEqual(datetimeRange.apiValue, INPUT_DATETIME_RANGE);
assert.strictEqual(
datetimeRange.literalValue,
`RANGE<DATETIME> ${INPUT_DATETIME_RANGE}`
);
assert.strictEqual(datetimeRange.elementType, 'DATETIME');

const timestampRange = bq.range(
Expand All @@ -1081,9 +1113,13 @@ describe('BigQuery', () => {
'TIMESTAMP'
);
assert.strictEqual(
timestampRange.literalValue,
timestampRange.apiValue,
'[2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.strictEqual(
timestampRange.literalValue,
'RANGE<TIMESTAMP> [2020-10-01T04:00:00.000Z, 2020-12-31T04:00:00.000Z)'
);
assert.strictEqual(timestampRange.elementType, 'TIMESTAMP');
});
});
Expand Down

0 comments on commit 40197b8

Please sign in to comment.