66 "fmt"
77 "os"
88
9+ "github.com/oom-ai/oomstore/internal/database/dbutil"
10+
911 "github.com/pkg/errors"
1012 "github.com/spf13/cast"
1113
@@ -14,7 +16,7 @@ import (
1416)
1517
1618/*
17- Export feature values of a particular revision.
19+ ChannelExport exports batch feature values of a particular revision.
1820Usage Example:
1921 exportResult, err := store.Export(ctx, opt)
2022 if err != nil {
@@ -93,3 +95,48 @@ func (s *OomStore) Export(ctx context.Context, opt types.ExportOpt) error {
9395 }
9496 return exportResult .CheckStreamError ()
9597}
98+
99+ // ChannelExportStream exports the latest streaming feature values up to the given timestamp.
100+ // Currently, this API can only export features in one feature group.
101+ func (s * OomStore ) ChannelExportStream (ctx context.Context , opt types.ChannelExportStreamOpt ) (* types.ExportResult , error ) {
102+ if err := validateFeatureFullNames (opt .FeatureFullNames ); err != nil {
103+ return nil , errors .WithStack (err )
104+ }
105+ features , err := s .ListFeature (ctx , types.ListFeatureOpt {
106+ FeatureFullNames : & opt .FeatureFullNames ,
107+ })
108+ if err != nil {
109+ return nil , errors .WithStack (err )
110+ }
111+ if len (features .GroupIDs ()) != 1 {
112+ return nil , fmt .Errorf ("expected 1 group, got %d groups" , len (features .GroupIDs ()))
113+ }
114+ group := features [0 ].Group
115+ revisions , err := s .ListRevision (ctx , & group .ID )
116+ if err != nil {
117+ return nil , errors .WithStack (err )
118+ }
119+ revision := revisions .Before (opt .UnixMilli )
120+ if revision == nil {
121+ return nil , fmt .Errorf ("no feature values up to %d, use a later timestamp" , opt .UnixMilli )
122+ }
123+ if revision .SnapshotTable == "" {
124+ if err = s .Snapshot (ctx , group .Name ); err != nil {
125+ return nil , errors .WithStack (err )
126+ }
127+ }
128+
129+ snapshotTable := dbutil .OfflineStreamSnapshotTableName (group .ID , revision .Revision )
130+ cdcTable := dbutil .OfflineStreamCdcTableName (group .ID , revision .Revision )
131+ stream , exportErr := s .offline .Export (ctx , offline.ExportOpt {
132+ SnapshotTable : snapshotTable ,
133+ CdcTable : & cdcTable ,
134+ UnixMilli : & opt .UnixMilli ,
135+ EntityName : group .Entity .Name ,
136+ Features : features ,
137+ Limit : opt .Limit ,
138+ })
139+
140+ header := append ([]string {group .Entity .Name }, features .Names ()... )
141+ return types .NewExportResult (header , stream , exportErr ), nil
142+ }
0 commit comments