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.
|
bcoe
left a comment
There was a problem hiding this comment.
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.
| type: 'ARRAY', | ||
| arrayType: BigQuery.getType_(value[0]), | ||
| }; | ||
| if (value.length === 0 || value[0] === null) { |
There was a problem hiding this comment.
could someone provide undefined, or null is a special case I'm guessing.
There was a problem hiding this comment.
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 |
| } 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.
Was this supposed to come in?
| 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.
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.
You're right, I can change this.
| }; | ||
| }), | ||
| }; | ||
| } else if (is.boolean(providedType)) { |
There was a problem hiding this comment.
Is it valid/expected for a user to provide a boolean as a type?
There was a problem hiding this comment.
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.
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'}.
|
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! |
| }; | ||
| }), | ||
| }; | ||
| } else if (is.boolean(providedType)) { |
There was a problem hiding this comment.
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'}.
| types: INVALID_TYPES, | ||
| }); | ||
| }, /Invalid type provided./); | ||
| done(); |
There was a problem hiding this comment.
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.
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.
I think you just need to remove the done argument from the test function's argument list:
- it('should ...', done => {
+ it('should ...', () => {| .callsFake(value_ => { | ||
| assert.strictEqual(value_, value); | ||
| setImmediate(done); | ||
| return { |
There was a problem hiding this comment.
We need to follow this through to verify this object we return is used as we expect.
| */ | ||
| // tslint:disable-next-line no-any | ||
| static valueToQueryParameter_(value: any) { | ||
| static valueToQueryParameter_(value: any, providedType: any = undefined) { |
There was a problem hiding this comment.
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.
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.
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.
@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.
@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
🦕