-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Firestore: add Watch Support #6191
Merged
+2,497
−5
Merged
Changes from 70 commits
Commits
Show all changes
164 commits
Select commit
Hold shift + click to select a range
4c51dac
groundwork for firestore
crwilcox 972b62f
Use chemelnucfin sample (pythonification of nodejs) as base
crwilcox a66ce73
syntactic and style fixes
crwilcox b06c55b
Merge branch 'master' of github.com:GoogleCloudPlatform/google-cloud-…
crwilcox 1390eb8
hold work
crwilcox 45f48d6
use helper for_document
crwilcox 4758b6b
Staging changes to firestore for watch. still incomplete but returnin…
crwilcox ff7aad7
returning watch result now
crwilcox c597669
broken currently, but nearing handling of multiple documents in colle…
crwilcox 048b5fa
small fixes. seems mostly working
crwilcox a2fdd18
fix variable name, remove things from doc map on remove
crwilcox 421b841
merge crwilcox firestore-watch branch into a recent branch from master
mcdonc 6a0294e
improve doc strings and comment out yet to be done methods
crwilcox fd889d5
remove fstrings for 2.7 compat
mcdonc 83755b8
be more specific on snapshot type
crwilcox eb8a48c
Merge remote-tracking branch 'crwilcox/firestore-watch' into firestor…
mcdonc a327dfe
unit tests for watch module
mcdonc a26699d
these must be staticmethods; improve performance in _affects_target
mcdonc cf85c92
make system test for watch pass
mcdonc 9b0a4c2
containment check instead of iteration
mcdonc 5bd6374
fix filter update test
mcdonc 481ae83
tests for various helper methods
mcdonc a5c78a2
Improve rpc_done and add early query support
crwilcox 4ce2939
Merge branch 'firestore-watch' of github.com:mcdonc/google-cloud-pyth…
crwilcox 4301130
add more tests
mcdonc e00884b
Merge remote-tracking branch 'crwilcox/firestore-watch' into firestor…
mcdonc 623e635
add tests for close
mcdonc 27de7be
not reraising in except broke tests
mcdonc c665d73
compute_snapshot_ordering test still fails but fails later than it us…
mcdonc 86628fd
remove incorrect comment
mcdonc 23eaad5
parent is a fq path
crwilcox 065e988
Merge branch 'firestore-watch' of github.com:mcdonc/google-cloud-pyth…
crwilcox 9db3d18
Merge remote-tracking branch 'crwilcox/firestore-watch' into firestor…
mcdonc 0d9de3c
fix and add test for _reset_docs
mcdonc 199aaf1
Merge branch 'firestore-watch' of github.com:mcdonc/google-cloud-pyth…
crwilcox 2a0723a
undo mistaken push
mcdonc f2b7c13
Merge remote-tracking branch 'crwilcox/firestore-watch' into firestor…
mcdonc 889f350
appease the linter
mcdonc 698e512
idiom
mcdonc 3a70102
enable collection watches
crwilcox ed329dd
Merge branch 'firestore-watch' of github.com:mcdonc/google-cloud-pyth…
crwilcox 2301a0e
undo spurious changes
mcdonc cca772e
add unfinished test
mcdonc 48fac6d
modify the way we compute document references to support query and co…
crwilcox 66b6071
add system tests for each variety of watch
crwilcox 67a609f
fix most unit tests, 3 still fail
mcdonc d598f32
merge and apply
crwilcox c6ae725
expected time of test was not the same as read time, so false failure
crwilcox 87ccc87
tests passing
crwilcox 725f4a4
make the datetime.datetime returned non-naive and assume it's in UTC
mcdonc ee12608
depends directly on pytz now
mcdonc 6aac664
100pct statement coverage for watch and test_watch
mcdonc 97368c9
just cutnpaste this i guess
mcdonc 53d6745
coverage for collection and bidi modules
mcdonc 1e73ab7
coverage for document and query methods added
mcdonc 6ade323
100 percent branch coverage
mcdonc 2ee71fe
appease linter
mcdonc 92e98d7
should return object on snapshot watching. This is needed to unsubscribe
crwilcox cf52f51
Merge branch 'master' into firestore-watch
crwilcox 213169e
Remove use of deprecated assert
crwilcox abd5c97
Fix bug in deletion of document from map (using wrong key)
crwilcox 3ed821e
startings of ordering
crwilcox 2f3cbc7
update tests
crwilcox 9290511
complete implementation of order
crwilcox f5734e9
remove commented code areas in order
crwilcox 78a62a6
refactor order
crwilcox 925495c
refactor order compare_objects
crwilcox 4316fd1
add system test for ordering (currently failing for non-ordering
crwilcox 220ba99
add system test for query and verify order
crwilcox 30972d9
Improve test for order
crwilcox d549145
Add comparator to kw creation of dummyquery, fix old test, move compa…
crwilcox 1abc70d
flake8 fixes
crwilcox ab862d7
coverage + tests
crwilcox be3584f
Properly decode document snapshot data and fix tests
crwilcox abdfe40
coverage
crwilcox 2af7db7
noxfile from master
crwilcox a11f8eb
Merge branch 'master' into firestore-watch
crwilcox 4c52c55
Delete Untitled-1
crwilcox dd9a15f
Merge branch 'master' into firestore-watch
crwilcox 17cd042
modify to use bidi in api-core. one test has started to fail
crwilcox f1d079d
get tests passing (intermittently) on 2.7,3.5,3.6
mcdonc e0cbda4
fix failing test_order tests when left and right were dictionaries of…
mcdonc fb8142c
groundwork for firestore
crwilcox a5dbe62
Use chemelnucfin sample (pythonification of nodejs) as base
crwilcox 8a5bd5f
syntactic and style fixes
crwilcox e296b22
hold work
crwilcox 9499c89
use helper for_document
crwilcox e9855fd
Staging changes to firestore for watch. still incomplete but returnin…
crwilcox 82a4a06
returning watch result now
crwilcox a83ebde
broken currently, but nearing handling of multiple documents in colle…
crwilcox 1d1be53
small fixes. seems mostly working
crwilcox 80c6bea
fix variable name, remove things from doc map on remove
crwilcox 799fac9
improve doc strings and comment out yet to be done methods
crwilcox 77eea6a
remove fstrings for 2.7 compat
mcdonc 0db6a9d
be more specific on snapshot type
crwilcox 374775b
unit tests for watch module
mcdonc 36e431b
these must be staticmethods; improve performance in _affects_target
mcdonc 4f08ac3
make system test for watch pass
mcdonc d0bffa9
containment check instead of iteration
mcdonc 3de5310
fix filter update test
mcdonc 40e8b0b
tests for various helper methods
mcdonc 1853297
Improve rpc_done and add early query support
crwilcox 1e77943
add more tests
mcdonc 2724132
add tests for close
mcdonc d7258c8
not reraising in except broke tests
mcdonc 1396b74
compute_snapshot_ordering test still fails but fails later than it us…
mcdonc 1465bc2
remove incorrect comment
mcdonc 39b97db
parent is a fq path
crwilcox 39e429f
fix and add test for _reset_docs
mcdonc 397c6d6
undo mistaken push
mcdonc 95a485a
appease the linter
mcdonc 3424284
idiom
mcdonc 429f86e
enable collection watches
crwilcox 00de5d3
undo spurious changes
mcdonc 4b96582
add unfinished test
mcdonc bcecb25
modify the way we compute document references to support query and co…
crwilcox 05db07c
add system tests for each variety of watch
crwilcox dfaacc7
fix most unit tests, 3 still fail
mcdonc b59b12b
merge and apply
crwilcox 2a19765
expected time of test was not the same as read time, so false failure
crwilcox 299fd94
tests passing
crwilcox 9081664
make the datetime.datetime returned non-naive and assume it's in UTC
mcdonc 9489ec1
depends directly on pytz now
mcdonc be51be8
100pct statement coverage for watch and test_watch
mcdonc 854d051
just cutnpaste this i guess
mcdonc 1059f2c
coverage for collection and bidi modules
mcdonc 346e5d6
coverage for document and query methods added
mcdonc 6cb3e85
100 percent branch coverage
mcdonc 7c73721
appease linter
mcdonc 7019fd5
should return object on snapshot watching. This is needed to unsubscribe
crwilcox 6f36b6f
Fix bug in deletion of document from map (using wrong key)
crwilcox 23d467d
startings of ordering
crwilcox c8e293a
update tests
crwilcox 6cd0ac6
complete implementation of order
crwilcox 41ef649
remove commented code areas in order
crwilcox 6be3422
refactor order
crwilcox b1c42e9
refactor order compare_objects
crwilcox 59f725b
add system test for ordering (currently failing for non-ordering
crwilcox 6888e8a
add system test for query and verify order
crwilcox f77616c
Improve test for order
crwilcox cc445f1
Add comparator to kw creation of dummyquery, fix old test, move compa…
crwilcox 85c199b
flake8 fixes
crwilcox f75a49c
coverage + tests
crwilcox 0125c87
Properly decode document snapshot data and fix tests
crwilcox cdc6594
coverage
crwilcox 36e8772
noxfile from master
crwilcox 738d938
Delete Untitled-1
crwilcox 9c2ff84
modify to use bidi in api-core. one test has started to fail
crwilcox 3f8e0c8
get tests passing (intermittently) on 2.7,3.5,3.6
mcdonc 4a892a7
fix failing test_order tests when left and right were dictionaries of…
mcdonc cb74bf7
fix transports layer use in watch
crwilcox d42f8c5
try adding wait before doc setting. System tests failing on CI but no…
crwilcox 138a6f1
merge from crwilcox/firestore-watch and fix conflicts
mcdonc 3add82d
linting
mcdonc b484098
make a bit more idiomatic
mcdonc e14421b
more idiomatic, and remove special casing of -0.0 and 0.0 in compare_…
mcdonc e089dac
lint fixes
crwilcox 6e588f3
Merge branch 'firestore-watch' of github.com:mcdonc/google-cloud-pyth…
crwilcox 136a881
Start using self.close where previously using self._consumer.stop
crwilcox 195814b
lint
crwilcox 34b4da3
clean up comments
crwilcox 5622f3c
alias unsubscribe to close
crwilcox 67c9a47
move rpc to internal attr
crwilcox 8900be2
Merge branch 'master' into firestore-watch
crwilcox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,233 @@ | ||
# Copyright 2017 Google LLC All rights reserved. | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from enum import Enum | ||
from google.cloud.firestore_v1beta1._helpers import decode_value | ||
import math | ||
|
||
|
||
class TypeOrder(Enum): | ||
# NOTE: This order is defined by the backend and cannot be changed. | ||
NULL = 0 | ||
BOOLEAN = 1 | ||
NUMBER = 2 | ||
TIMESTAMP = 3 | ||
STRING = 4 | ||
BLOB = 5 | ||
REF = 6 | ||
GEO_POINT = 7 | ||
ARRAY = 8 | ||
OBJECT = 9 | ||
|
||
@staticmethod | ||
def from_value(value): | ||
v = value.WhichOneof('value_type') | ||
|
||
lut = { | ||
'null_value': TypeOrder.NULL, | ||
'boolean_value': TypeOrder.BOOLEAN, | ||
'integer_value': TypeOrder.NUMBER, | ||
'double_value': TypeOrder.NUMBER, | ||
'timestamp_value': TypeOrder.TIMESTAMP, | ||
'string_value': TypeOrder.STRING, | ||
'bytes_value': TypeOrder.BLOB, | ||
'reference_value': TypeOrder.REF, | ||
'geo_point_value': TypeOrder.GEO_POINT, | ||
'array_value': TypeOrder.ARRAY, | ||
'map_value': TypeOrder.OBJECT, | ||
} | ||
|
||
if v not in lut: | ||
raise ValueError( | ||
"Could not detect value type for " + v) | ||
return lut[v] | ||
|
||
|
||
class Order(object): | ||
''' | ||
Order implements the ordering semantics of the backend. | ||
''' | ||
|
||
@classmethod | ||
def compare(cls, left, right): | ||
''' | ||
Main comparison function for all Firestore types. | ||
@return -1 is left < right, 0 if left == right, otherwise 1 | ||
''' | ||
# First compare the types. | ||
leftType = TypeOrder.from_value(left).value | ||
rightType = TypeOrder.from_value(right).value | ||
|
||
if leftType != rightType: | ||
if leftType < rightType: | ||
return -1 | ||
return 1 | ||
|
||
# TODO: may be able to use helpers.decode_value and do direct compares | ||
# after converting to python types | ||
value_type = left.WhichOneof('value_type') | ||
|
||
if value_type == 'null_value': | ||
return 0 # nulls are all equal | ||
elif value_type == 'boolean_value': | ||
return cls._compare_to(left.boolean_value, right.boolean_value) | ||
elif value_type == 'integer_value': | ||
return cls.compare_numbers(left, right) | ||
elif value_type == 'double_value': | ||
return cls.compare_numbers(left, right) | ||
elif value_type == 'timestamp_value': | ||
return cls.compare_timestamps(left, right) | ||
elif value_type == 'string_value': | ||
return cls._compare_to(left.string_value, right.string_value) | ||
elif value_type == 'bytes_value': | ||
return cls.compare_blobs(left, right) | ||
elif value_type == 'reference_value': | ||
return cls.compare_resource_paths(left, right) | ||
elif value_type == 'geo_point_value': | ||
return cls.compare_geo_points(left, right) | ||
elif value_type == 'array_value': | ||
return cls.compare_arrays(left, right) | ||
elif value_type == 'map_value': | ||
return cls.compare_objects(left, right) | ||
else: | ||
raise ValueError('Unknown ``value_type``', str(value_type)) | ||
|
||
@staticmethod | ||
def compare_blobs(left, right): | ||
left_bytes = left.bytes_value | ||
right_bytes = right.bytes_value | ||
|
||
# TODO: Should verify bytes comparisons in python work as expected | ||
return Order._compare_to(left_bytes, right_bytes) | ||
|
||
@staticmethod | ||
def compare_timestamps(left, right): | ||
left = left.timestamp_value | ||
right = right.timestamp_value | ||
|
||
seconds = Order._compare_to(left.seconds or 0, right.seconds or 0) | ||
if seconds != 0: | ||
return seconds | ||
|
||
return Order._compare_to(left.nanos or 0, right.nanos or 0) | ||
|
||
@staticmethod | ||
def compare_geo_points(left, right): | ||
left_value = decode_value(left, None) | ||
right_value = decode_value(right, None) | ||
cmp = 0 | ||
if left_value.latitude < right_value.latitude: | ||
cmp = -1 | ||
elif left_value.latitude == right_value.latitude: | ||
cmp = 0 | ||
else: | ||
cmp = 1 | ||
|
||
if cmp != 0: | ||
return cmp | ||
else: | ||
if left_value.longitude < right_value.longitude: | ||
cmp = -1 | ||
elif left_value.longitude == right_value.longitude: | ||
cmp = 0 | ||
else: | ||
cmp = 1 | ||
return cmp | ||
|
||
@staticmethod | ||
def compare_resource_paths(left, right): | ||
left = left.reference_value | ||
right = right.reference_value | ||
|
||
left_segments = left.split('/') | ||
right_segments = right.split('/') | ||
shorter = min(len(left_segments), len(right_segments)) | ||
# compare segments | ||
for i in range(shorter): | ||
if (left_segments[i] < right_segments[i]): | ||
return -1 | ||
if (left_segments[i] > right_segments[i]): | ||
return 1 | ||
|
||
left_length = len(left) | ||
right_length = len(right) | ||
if left_length < right_length: | ||
return -1 | ||
if left_length > right_length: | ||
return 1 | ||
|
||
return 0 | ||
|
||
@staticmethod | ||
def compare_arrays(left, right): | ||
l_values = left.array_value.values | ||
r_values = right.array_value.values | ||
|
||
length = min(len(l_values), len(r_values)) | ||
for i in range(length): | ||
cmp = Order.compare(l_values[i], r_values[i]) | ||
if cmp != 0: | ||
return cmp | ||
|
||
return Order._compare_to(len(l_values), len(r_values)) | ||
|
||
@staticmethod | ||
def compare_objects(left, right): | ||
left_fields = left.map_value.fields | ||
right_fields = right.map_value.fields | ||
|
||
for left_key, right_key in zip( | ||
sorted(left_fields), sorted(right_fields) | ||
): | ||
keyCompare = Order._compare_to(left_key, right_key) | ||
if keyCompare != 0: | ||
return keyCompare | ||
|
||
value_compare = Order.compare( | ||
left_fields[left_key], right_fields[right_key]) | ||
if value_compare != 0: | ||
return value_compare | ||
|
||
return Order._compare_to(len(left_fields), len(right_fields)) | ||
|
||
@staticmethod | ||
def compare_numbers(left, right): | ||
left_value = decode_value(left, None) | ||
right_value = decode_value(right, None) | ||
return Order.compare_doubles(left_value, right_value) | ||
|
||
@staticmethod | ||
def compare_doubles(left, right): | ||
if math.isnan(left): | ||
if math.isnan(right): | ||
return 0 | ||
return -1 | ||
if math.isnan(right): | ||
return 1 | ||
|
||
if left == -0.0: | ||
left = 0 | ||
if right == -0.0: | ||
right = 0 | ||
|
||
return Order._compare_to(left, right) | ||
|
||
@staticmethod | ||
def _compare_to(left, right): | ||
if left < right: | ||
return -1 | ||
elif left == right: | ||
return 0 | ||
# left > right | ||
return 1 |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This comment was marked as spam.
Sorry, something went wrong.