2023-01-21 04:11:30 +00:00
package iter
2023-01-20 11:08:22 +00:00
2023-01-25 09:29:23 +00:00
// Iterators - composable high-level abstraction to iterate over. It's more high-level than kv.Cursor and provides less controll, less features, but enough to build an app.
//
// for s.HasNext() {
// k, v, err := s.Next()
// if err != nil {
// return err
// }
// }
//
2023-01-20 11:08:22 +00:00
// - K, V are valid only until next .Next() call (TODO: extend it to whole Tx lifetime?)
// - No `Close` method: all streams produced by TemporalTx will be closed inside `tx.Rollback()` (by casting to `kv.Closer`)
// - automatically checks cancelation of `ctx` passed to `db.Begin(ctx)`, can skip this
// check in loops on stream. Dual has very limited API - user has no way to
// terminate it - but user can specify more strict conditions when creating stream (then server knows better when to stop)
2023-01-25 09:29:23 +00:00
// Dual - return 2 items - usually called Key and Value (or `k` and `v`)
// Example:
//
// for s.HasNext() {
// k, v, err := s.Next()
// if err != nil {
// return err
// }
// }
2023-01-20 11:08:22 +00:00
type Dual [ K , V any ] interface {
Next ( ) ( K , V , error )
HasNext ( ) bool
}
2023-01-25 09:29:23 +00:00
// Unary - return 1 item. Example:
//
// for s.HasNext() {
// v, err := s.Next()
// if err != nil {
// return err
// }
// }
2023-01-20 11:08:22 +00:00
type Unary [ V any ] interface {
Next ( ) ( V , error )
//NextBatch() ([]V, error)
HasNext ( ) bool
}
2023-01-25 09:29:23 +00:00
// KV - return 2 items of type []byte - usually called Key and Value (or `k` and `v`). Example:
2023-01-20 11:08:22 +00:00
//
// for s.HasNext() {
// k, v, err := s.Next()
// if err != nil {
// return err
// }
// }
2023-01-25 09:29:23 +00:00
// often used shortcuts
type (
U64 Unary [ uint64 ]
KV Dual [ [ ] byte , [ ] byte ]
)
func ToU64Arr ( s U64 ) ( [ ] uint64 , error ) { return ToArr [ uint64 ] ( s ) }
func ToKVArray ( s KV ) ( [ ] [ ] byte , [ ] [ ] byte , error ) { return ToDualArray [ [ ] byte , [ ] byte ] ( s ) }
func TransformKV ( it KV , transform func ( k , v [ ] byte ) ( [ ] byte , [ ] byte ) ) * TransformDualIter [ [ ] byte , [ ] byte ] {
return TransformDual [ [ ] byte , [ ] byte ] ( it , transform )
}
// internal types
type (
NextPageUnary [ T any ] func ( pageToken string ) ( arr [ ] T , nextPageToken string , err error )
NextPageDual [ K , V any ] func ( pageToken string ) ( keys [ ] K , values [ ] V , nextPageToken string , err error )
)
func PaginateKV ( f NextPageDual [ [ ] byte , [ ] byte ] ) * PaginatedDual [ [ ] byte , [ ] byte ] {
return PaginateDual [ [ ] byte , [ ] byte ] ( f )
}
func PaginateU64 ( f NextPageUnary [ uint64 ] ) * Paginated [ uint64 ] {
return Paginate [ uint64 ] ( f )
}