-
Notifications
You must be signed in to change notification settings - Fork 106
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
fix: allow IN queries on __key__ #1085
fix: allow IN queries on __key__ #1085
Conversation
This change matches the change shown in another PR, but the test cases won’t allow for the new change. There must be some edge cases that haven’t been considered here.
isDsKey currently does not check to see that the key is an entity.Key properly so we need to modify this function so that it does a proper check.
This reverts commit 4f0db50.
This reverts commit d279595.
For an instanceof check to pass, we need to import the entity property the right way
Make code a lot more succinct for the PropertyFilter class before adding the new test in.
There is no need for a private encodeValue function so we just inline this change.
This test supports using __key__ with IN and an array.
This change modifies the proto to be what we want it to be so that the deep strict equal check works.
This commit removes a comment that isn’t necessary anymore and renames a variable to demonstrate its proper use.
The new test doesn’t enter the DSKey check when the entity is used from the beforeEach hook. Use the global entity instead.
The specific query proto used should be moved into the test as it is only used by that specific test.
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.
Looks nice 👍
There are a few "GitHub Actions / lint" that look worth addressing - IMO the typings of this lib could use some love but out of scope for this PR.
src/filter.ts
Outdated
@@ -13,7 +13,7 @@ | |||
// limitations under the License. | |||
|
|||
import {Operator, Filter as IFilter} from './query'; | |||
import {entity} from './entity'; | |||
import {entity, ValueProto} from './entity'; |
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.
Please fix (remove ValueProto
)
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.
Done
src/filter.ts
Outdated
this.op, | ||
this.val | ||
).encodedValue(); | ||
const value = entity.encodeValue(this.val, this.name); |
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 can also value: entity.encodeValue(this.val, this.name)
inline. Not sure what the preferred style is.
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.
Yes. This can be even more compact.
test/entity.ts
Outdated
@@ -1894,8 +1894,62 @@ describe('entity', () => { | |||
assert.deepStrictEqual(entity.queryToQueryProto(query), queryProto); | |||
}); | |||
|
|||
it('should support using key with 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.
nit: I'm not sure if "with IN" is relevant here?
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.
Good point.
I think more specifically, it is addressing the case of using an array as a value as that was what was causing the error in the first place.
Remove an unused import, make value more inline and change name of test case to reflect new functionality.
@vicb There is just one more thing we should confirm. I notice that |
Since the new test simply introduces a new proto and checks it against __key__ with an array, we still have no way to verify if this encoding will actually work. In this system test we verify that using __key__ with an array actually works in a query.
As discussed it should probably be
Probably. |
Modify the type to use `unknown` instead of `any`.
Leverage typescript to let the user know at compile time that Keys and arrays of keys are to be used when __key__ is used.
The restricted value type should be used on filter as well as the property filter.
src/filter.ts
Outdated
@@ -56,42 +57,34 @@ export abstract class EntityFilter { | |||
abstract toProto(): any; | |||
} | |||
|
|||
export type restrictedValueType<T> = T extends '__key__' |
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.
RestrictedValueType
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.
Changed the name of this variable to more specifically describe what this does
src/query.ts
Outdated
value?: restrictedValueType<T> | null | ||
): Query; | ||
filter<T extends string>( | ||
propertyOrFilter: T, |
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.
T | EntityFilter
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.
Signature has been updated
src/query.ts
Outdated
value: restrictedValueType<T> | null | ||
): Query; | ||
filter<T extends string>( | ||
propertyOrFilter: T | EntityFilter, | ||
operatorOrValue?: Operator, |
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 should be restrictedValueType<T> | null | Operator
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.
Signature has been updated
See 8d269d2 for a case where the compiler doesn't seem to complain even though it should. |
I mean see 8d269d2 |
I mean #1089 |
Checking for nulls is now included in the restricted value type so we don’t need to declare it in the signature of the function.
rename a value type variable to allowed filter value type to more accurately describe the type’s purpose.
The old variable name doesn’t follow the naming convention.
prettier and change the typeguard so that it checks to see if the input is an instance of EntityFilter.
@@ -156,5 +144,5 @@ class CompositeFilter extends EntityFilter { | |||
} | |||
|
|||
export function isFilter(filter: any): filter is EntityFilter { | |||
return (filter as EntityFilter).toProto !== undefined; | |||
return filter instanceof EntityFilter; |
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.
why does this have to 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.
I suggested the fix so I'll answer.
filter.toProto !== undefined
only checks if the object has a toProto
properties (not set to undefined
)
It is the case that EntityFilter
s have a toProto
methods but it is not necessarily the case that an object with a toProto
property is an EntityFilter
.
filter instanceof EntityFilter
is the correct check for filter is EntityFilter
I hope that makes sense.
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.
thanks @vicb, both using instanceof
and avoiding type assertions (filter as EntityFilter
) are recommended in the Google TypeScript Style Guide. LGTM 👍
propertyOrFilter: string | EntityFilter, | ||
operatorOrValue?: Operator, | ||
value?: {} | null | ||
filter(filter: EntityFilter): Query; |
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.
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.
My take is that the old signature was buggy and wouldn't catch unsupported calls. So I see this as a bug fix.
Also I think the impl could be improved by switch
ing on arguments.length
. 1, 2, 3 corresponding to the first 3 signatures in order.
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 will do this in a separate issue:
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.
+1 to go with a patch version
bump
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.
LGTM 👍
Let's just make sure to keep an eye and monitor if the internal change from src/filter.ts
encodeValue()
is going to have any impact in the end users of the library. Releasing this as a patch version release is going to help us having the flexibility to rollback if needed, so I'd advise to proceed with a fix:
commit.
Great work @danieljbruce!
propertyOrFilter: string | EntityFilter, | ||
operatorOrValue?: Operator, | ||
value?: {} | null | ||
filter(filter: EntityFilter): Query; |
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.
+1 to go with a patch version
bump
@@ -156,5 +144,5 @@ class CompositeFilter extends EntityFilter { | |||
} | |||
|
|||
export function isFilter(filter: any): filter is EntityFilter { | |||
return (filter as EntityFilter).toProto !== undefined; | |||
return filter instanceof EntityFilter; |
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.
thanks @vicb, both using instanceof
and avoiding type assertions (filter as EntityFilter
) are recommended in the Google TypeScript Style Guide. LGTM 👍
The fix contains:
Fixes #1024