44from enum import Enum
55from typing import List , AsyncIterator , Union , Any , Tuple
66
7+ from nitric .api .const import MAX_SUB_COLLECTION_DEPTH
78from nitric .proto .nitric .document .v1 import (
89 DocumentServiceStub ,
910 Collection as CollectionMessage ,
1516from nitric .utils import new_default_channel , _dict_from_struct , _struct_from_dict
1617
1718
19+ class CollectionDepthException (Exception ):
20+ """Exception when the max depth of document sub-collections is exceeded."""
21+
22+ pass
23+
24+
1825@dataclass (frozen = True , order = True )
1926class DocumentRef :
2027 """A reference to a document in a collection."""
@@ -31,9 +38,13 @@ def collection(self, name: str) -> CollectionRef:
3138 e.g. Documents().collection('a').doc('b').collection('c').doc('d') is valid,
3239 Documents().collection('a').doc('b').collection('c').doc('d').collection('e') is invalid (1 level too deep).
3340 """
34- if self .parent .is_sub_collection ():
35- # Collection nesting is currently unsupported, but may be included in a future enhancement.
36- raise Exception ("Currently, sub-collections may only be nested 1 deep" )
41+ current_depth = self .parent .sub_collection_depth ()
42+ if current_depth >= MAX_SUB_COLLECTION_DEPTH :
43+ # Collection nesting is only supported to a maximum depth.
44+ raise CollectionDepthException (
45+ f"sub-collections supported to a depth of { MAX_SUB_COLLECTION_DEPTH } , "
46+ f"attempted to create new collection with depth { current_depth + 1 } "
47+ )
3748 return CollectionRef (_documents = self ._documents , name = name , parent = self )
3849
3950 async def get (self ) -> Document :
@@ -121,6 +132,12 @@ def query(
121132 expressions = [expressions ] if isinstance (expressions , Expression ) else expressions ,
122133 )
123134
135+ def sub_collection_depth (self ) -> int :
136+ if not self .is_sub_collection ():
137+ return 0
138+ else :
139+ return self .parent .parent .sub_collection_depth () + 1
140+
124141 def is_sub_collection (self ):
125142 """Return True if this collection is a sub-collection of a document in another collection."""
126143 return self .parent is not None
@@ -302,7 +319,7 @@ def where(
302319 self ,
303320 * expressions : Union [
304321 Expression , List [Expression ], Union [str , Operator , int , bool , Tuple [str , Union [str , Operator ], Any ]]
305- ]
322+ ],
306323 ) -> QueryBuilder :
307324 """
308325 Add a filter expression to the query.
0 commit comments