@@ -43,6 +43,7 @@ func RegisterRelationshipCmd(rootCmd *cobra.Command) *cobra.Command {
4343 readCmd .Flags ().String ("revision" , "" , "optional revision at which to check" )
4444 _ = readCmd .Flags ().MarkHidden ("revision" )
4545 readCmd .Flags ().String ("subject-filter" , "" , "optional subject filter" )
46+ readCmd .Flags ().Uint32 ("page-limit" , 100 , "limit of relations returned per page" )
4647 registerConsistencyFlags (readCmd .Flags ())
4748
4849 relationshipCmd .AddCommand (bulkDeleteCmd )
@@ -209,62 +210,93 @@ func buildReadRequest(cmd *cobra.Command, args []string) (*v1.ReadRelationshipsR
209210 }
210211 }
211212
213+ limit := cobrautil .MustGetUint32 (cmd , "page-limit" )
212214 return & v1.ReadRelationshipsRequest {
213215 RelationshipFilter : readFilter ,
216+ OptionalLimit : limit ,
214217 }, nil
215218}
216219
217220func readRelationships (cmd * cobra.Command , args []string ) error {
218- request , err := buildReadRequest (cmd , args )
219- if err != nil {
220- return err
221- }
222-
223- request .Consistency , err = consistencyFromCmd (cmd )
221+ spicedbClient , err := client .NewClient (cmd )
224222 if err != nil {
225223 return err
226224 }
227225
228- spicedbClient , err := client . NewClient (cmd )
226+ request , err := buildReadRequest (cmd , args )
229227 if err != nil {
230228 return err
231229 }
230+ limit := request .OptionalLimit
232231
233- log .Trace ().Interface ("request" , request ).Msg ("reading relationships" )
234- resp , err := spicedbClient .ReadRelationships (cmd .Context (), request )
232+ request .Consistency , err = consistencyFromCmd (cmd )
235233 if err != nil {
236234 return err
237235 }
238236
237+ lastCursor := request .OptionalCursor
239238 for {
240- if err := cmd .Context ().Err (); err != nil {
241- return err
239+ request .OptionalCursor = lastCursor
240+ var cursorToken string
241+ if lastCursor != nil {
242+ cursorToken = lastCursor .Token
242243 }
243-
244- msg , err := resp .Recv ()
245- if errors .Is (err , io .EOF ) {
246- return nil
247- }
248-
244+ log .Trace ().Interface ("request" , request ).Str ("cursor" , cursorToken ).Msg ("reading relationships page" )
245+ readRelClient , err := spicedbClient .ReadRelationships (cmd .Context (), request )
249246 if err != nil {
250247 return err
251248 }
252249
253- if cobrautil . MustGetBool ( cmd , "json" ) {
254- prettyProto , err := PrettyProto ( msg )
255- if err != nil {
250+ var relCount uint32
251+ for {
252+ if err := cmd . Context (). Err (); err != nil {
256253 return err
257254 }
258255
259- console .Println (string (prettyProto ))
260- } else {
261- relString , err := relationshipToString (msg .Relationship )
256+ msg , err := readRelClient .Recv ()
257+ if errors .Is (err , io .EOF ) {
258+ break
259+ }
260+
262261 if err != nil {
263262 return err
264263 }
265- console .Println (relString )
264+
265+ lastCursor = msg .AfterResultCursor
266+ relCount ++
267+ if err := printRelationship (cmd , msg ); err != nil {
268+ return err
269+ }
270+ }
271+
272+ if relCount < limit || limit == 0 {
273+ return nil
274+ }
275+
276+ if relCount > limit {
277+ log .Warn ().Uint32 ("limit-specified" , limit ).Uint32 ("relationships-received" , relCount ).Msg ("page limit ignored, pagination may not be supported by the server, consider updating SpiceDB" )
278+ return nil
279+ }
280+ }
281+ }
282+
283+ func printRelationship (cmd * cobra.Command , msg * v1.ReadRelationshipsResponse ) error {
284+ if cobrautil .MustGetBool (cmd , "json" ) {
285+ prettyProto , err := PrettyProto (msg )
286+ if err != nil {
287+ return err
266288 }
289+
290+ console .Println (string (prettyProto ))
291+ } else {
292+ relString , err := relationshipToString (msg .Relationship )
293+ if err != nil {
294+ return err
295+ }
296+ console .Println (relString )
267297 }
298+
299+ return nil
268300}
269301
270302func argsToRelationship (args []string ) (* v1.Relationship , error ) {
0 commit comments