-
Notifications
You must be signed in to change notification settings - Fork 210
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(params): adds optional param types #599
Conversation
Codecov Report
@@ Coverage Diff @@
## master #599 +/- ##
=======================================
Coverage 94.74% 94.74%
=======================================
Files 7 7
Lines 6218 6218
Branches 358 358
=======================================
Hits 5891 5891
Misses 326 326
Partials 1 1
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking pretty slick 😄
Biggest thing that initially jumped out at me is I think we could potentially use IStandardSqlDataType
rather than any
perhaps? and I'd dig into whether there's a way to get a string representation of this type so that we don't duplicate the list of types.
Might be worth asking @alexander-fenster if this is possible.
src/bigquery.ts
Outdated
type: 'ARRAY', | ||
arrayType: BigQuery.getType_(value[0]), | ||
}; | ||
if (value.length === 0 || value[0] === null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
could someone provide undefined
, or null
is a special case I'm guessing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I know, undefined shouldn't be an option, just null
I don't know much about this library (it's not a GAPIC), but I generally agree that we should avoid using |
src/bigquery.ts
Outdated
@@ -42,6 +42,7 @@ import { | |||
} from './table'; | |||
import {GoogleErrorBody} from '@google-cloud/common/build/src/util'; | |||
import bigquery from './types'; | |||
import {type} from 'os'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this supposed to come in?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope
src/bigquery.ts
Outdated
@@ -94,6 +95,8 @@ export type Query = JobRequest<bigquery.IJobConfigurationQuery> & { | |||
// tslint:disable-next-line no-any | |||
params?: any[] | {[param: string]: any}; | |||
dryRun?: boolean; | |||
// tslint:disable-next-line: no-any | |||
types?: any[] | {[type: string]: any}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this truly any
? It looks like there's an array of types below that define what this can look like.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I can change this.
src/bigquery.ts
Outdated
}; | ||
}), | ||
}; | ||
} else if (is.boolean(providedType)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it valid/expected for a user to provide a boolean as a type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's a BigQuery type that can be detected so they should be able to provide it as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this code path, it looks like the "providedType" would be true
or false
, which would end up returning {type: false}
, as opposed to {type: 'BOOL'}
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, I see. Fixed.
Sorry for the delay @steffnay. I believe we'll want a new I wrote up a working example of how you can verify that a sibling method is being called with the correct arguments, and that the value it returns is being used properly. This template should be repeatable for the different code paths, but let me know if you get stuck or have more questions about how to apply this elsewhere. This is a test that would go under createQueryJob -> SQL parameters -> positional. it('should convert value and type to query parameter', done => {
const fakeQueryParameter = {fake: 'query parameter'};
bq.createJob = (reqOpts: JobOptions) => {
const queryParameters = reqOpts.configuration!.query!.queryParameters;
assert.deepStrictEqual(queryParameters, [fakeQueryParameter]);
done();
};
sandbox
.stub(BigQuery, 'valueToQueryParameter_')
.callsFake((value, type) => {
assert.strictEqual(value, POSITIONAL_PARAMS[0]);
assert.strictEqual(type, POSITIONAL_TYPES[0]);
return fakeQueryParameter;
});
bq.createQueryJob({
query: QUERY_STRING,
params: POSITIONAL_PARAMS,
types: POSITIONAL_TYPES,
});
}); I hope this is helpful! |
src/bigquery.ts
Outdated
}; | ||
}), | ||
}; | ||
} else if (is.boolean(providedType)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this code path, it looks like the "providedType" would be true
or false
, which would end up returning {type: false}
, as opposed to {type: 'BOOL'}
.
test/bigquery.ts
Outdated
types: INVALID_TYPES, | ||
}); | ||
}, /Invalid type provided./); | ||
done(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This done() and the ones that follow in this block can be removed. It's only needed when we want to hold the test from exiting prematurely while we wait for a callback to be executed. In this case, the assert.throws()
will run sync and then exit the test block with a failure or a success.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm really curious about this because these tests that check for errors keep timing out if I don't call done(). Is there something else I should be doing to fix that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you just need to remove the done
argument from the test function's argument list:
- it('should ...', done => {
+ it('should ...', () => {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, got it.
.callsFake(value_ => { | ||
assert.strictEqual(value_, value); | ||
setImmediate(done); | ||
return { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to follow this through to verify this object we return is used as we expect.
src/bigquery.ts
Outdated
@@ -807,12 +873,18 @@ export class BigQuery extends common.Service { | |||
* @returns {object} A properly-formed `queryParameter` object. | |||
*/ | |||
// tslint:disable-next-line no-any | |||
static valueToQueryParameter_(value: any) { | |||
static valueToQueryParameter_(value: any, providedType: any = undefined) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is providedType
really any
? I'm surprised we can't further constrain this to {}
. Side note - for undefined
, you don't need to set a default value. You can say providedType?: {}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
providedType can be a string, object, or array, so I don't understand how to make providedType?: {} work this way. I don't know how I need to refactor providedType[0] on line 899 to work with this change.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you could do something along the lines of:
providedType: string|{[key: string]: string}|string[]
☝️ |
is used to allow for multiple types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@bcoe The array type can also be populated with string, array, or object. Similarly, the object can have values that are arrays. How do I specify that without using any?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@steffnay you'd potentially probably want to start breaking it out into interfaces, but you'd do something along the lines of:
{[key: string]: string|string[]}
☝️ but as it gets complex like this, you'd probably want to start describing an interface. The advantage of putting in this work is that folks using the API have more safety, and it's easier to figure out what to pass to the API.
Adds ability to optionally provide query parameter types when performing queries.
Fixes #400
🦕