@@ -141,6 +141,14 @@ type BackendSpannerClient interface {
141141 AddUserSearchBookmark (ctx context.Context , req gcpspanner.UserSavedSearchBookmark ) error
142142 DeleteUserSearchBookmark (ctx context.Context , req gcpspanner.UserSavedSearchBookmark ) error
143143 SyncUserProfileInfo (ctx context.Context , userProfile gcpspanner.UserProfile ) error
144+ CreateSavedSearchSubscription (
145+ ctx context.Context , req gcpspanner.CreateSavedSearchSubscriptionRequest ) (* string , error )
146+ GetSavedSearchSubscription (ctx context.Context , subscriptionID string , userID string ) (
147+ * gcpspanner.SavedSearchSubscription , error )
148+ UpdateSavedSearchSubscription (ctx context.Context , req gcpspanner.UpdateSavedSearchSubscriptionRequest ) error
149+ DeleteSavedSearchSubscription (ctx context.Context , subscriptionID string , userID string ) error
150+ ListSavedSearchSubscriptions (ctx context.Context , req gcpspanner.ListSavedSearchSubscriptionsRequest ) (
151+ []gcpspanner.SavedSearchSubscription , * string , error )
144152 GetNotificationChannel (
145153 ctx context.Context , channelID string , userID string ) (* gcpspanner.NotificationChannel , error )
146154 ListNotificationChannels (ctx context.Context , req gcpspanner.ListNotificationChannelsRequest ) (
@@ -1323,3 +1331,143 @@ func (s *Backend) GetIDFromFeatureKey(
13231331
13241332 return id , nil
13251333}
1334+
1335+ func (s * Backend ) CreateSavedSearchSubscription (ctx context.Context ,
1336+ userID string , req backend.Subscription ) (* backend.SubscriptionResponse , error ) {
1337+ createReq := gcpspanner.CreateSavedSearchSubscriptionRequest {
1338+ UserID : userID ,
1339+ ChannelID : req .ChannelId ,
1340+ SavedSearchID : req .SavedSearchId ,
1341+ Triggers : req .Triggers ,
1342+ Frequency : string (req .Frequency ),
1343+ }
1344+
1345+ id , err := s .client .CreateSavedSearchSubscription (ctx , createReq )
1346+ if err != nil {
1347+ return nil , err
1348+ }
1349+
1350+ // Retrieve the newly created subscription to return to the client.
1351+ sub , err := s .client .GetSavedSearchSubscription (ctx , * id , userID )
1352+ if err != nil {
1353+ return nil , err
1354+ }
1355+
1356+ return toBackendSubscription (sub ), nil
1357+
1358+ }
1359+
1360+ func (s * Backend ) ListSavedSearchSubscriptions (ctx context.Context ,
1361+ userID string , pageSize int , pageToken * string ) (* backend.SubscriptionPage , error ) {
1362+ listReq := gcpspanner.ListSavedSearchSubscriptionsRequest {
1363+ UserID : userID ,
1364+ PageSize : pageSize ,
1365+ PageToken : pageToken ,
1366+ }
1367+ subs , token , err := s .client .ListSavedSearchSubscriptions (ctx , listReq )
1368+ if err != nil {
1369+ return nil , err
1370+ }
1371+ backendSubs := make ([]backend.SubscriptionResponse , 0 , len (subs ))
1372+ for i := range subs {
1373+ backendSubs = append (backendSubs , * toBackendSubscription (& subs [i ]))
1374+ }
1375+
1376+ return & backend.SubscriptionPage {
1377+ Data : & backendSubs ,
1378+ Metadata : & backend.PageMetadata {
1379+ NextPageToken : token ,
1380+ },
1381+ }, nil
1382+ }
1383+
1384+ func (s * Backend ) GetSavedSearchSubscription (ctx context.Context ,
1385+ userID , subscriptionID string ) (* backend.SubscriptionResponse , error ) {
1386+ sub , err := s .client .GetSavedSearchSubscription (ctx , subscriptionID , userID )
1387+ if err != nil {
1388+ if errors .Is (err , gcpspanner .ErrMissingRequiredRole ) {
1389+ return nil , errors .Join (err , backendtypes .ErrUserNotAuthorizedForAction )
1390+ } else if errors .Is (err , gcpspanner .ErrQueryReturnedNoResults ) {
1391+ return nil , errors .Join (err , backendtypes .ErrEntityDoesNotExist )
1392+ }
1393+
1394+ return nil , err
1395+ }
1396+
1397+ return toBackendSubscription (sub ), nil
1398+ }
1399+
1400+ func (s * Backend ) UpdateSavedSearchSubscription (ctx context.Context ,
1401+ userID , subscriptionID string , req backend.UpdateSubscriptionRequest ) (* backend.SubscriptionResponse , error ) {
1402+ updateReq := gcpspanner.UpdateSavedSearchSubscriptionRequest {
1403+ ID : subscriptionID ,
1404+ UserID : userID ,
1405+ Triggers : gcpspanner.OptionallySet [[]string ]{
1406+ IsSet : false ,
1407+ Value : nil ,
1408+ },
1409+ Frequency : gcpspanner.OptionallySet [string ]{
1410+ IsSet : false ,
1411+ Value : "" ,
1412+ },
1413+ }
1414+
1415+ for _ , field := range req .UpdateMask {
1416+ switch field {
1417+ case backend .UpdateSubscriptionRequestMaskTriggers :
1418+ updateReq .Triggers = gcpspanner.OptionallySet [[]string ]{Value : * req .Triggers , IsSet : true }
1419+ case backend .UpdateSubscriptionRequestMaskFrequency :
1420+ updateReq .Frequency = gcpspanner.OptionallySet [string ]{Value : string (* req .Frequency ), IsSet : true }
1421+ }
1422+ }
1423+
1424+ err := s .client .UpdateSavedSearchSubscription (ctx , updateReq )
1425+ if err != nil {
1426+ if errors .Is (err , gcpspanner .ErrMissingRequiredRole ) {
1427+ return nil , errors .Join (err , backendtypes .ErrUserNotAuthorizedForAction )
1428+ } else if errors .Is (err , gcpspanner .ErrQueryReturnedNoResults ) {
1429+ return nil , errors .Join (err , backendtypes .ErrEntityDoesNotExist )
1430+ }
1431+
1432+ return nil , err
1433+ }
1434+
1435+ // Fetch the updated subscription to return.
1436+ sub , err := s .client .GetSavedSearchSubscription (ctx , subscriptionID , userID )
1437+ if err != nil {
1438+ return nil , err
1439+ }
1440+
1441+ return toBackendSubscription (sub ), nil
1442+ }
1443+
1444+ func (s * Backend ) DeleteSavedSearchSubscription (ctx context.Context , userID , subscriptionID string ) error {
1445+ err := s .client .DeleteSavedSearchSubscription (ctx , subscriptionID , userID )
1446+ if err != nil {
1447+ if errors .Is (err , gcpspanner .ErrMissingRequiredRole ) {
1448+ return errors .Join (err , backendtypes .ErrUserNotAuthorizedForAction )
1449+ } else if errors .Is (err , gcpspanner .ErrQueryReturnedNoResults ) {
1450+ return errors .Join (err , backendtypes .ErrEntityDoesNotExist )
1451+ }
1452+
1453+ return err
1454+ }
1455+
1456+ return nil
1457+ }
1458+
1459+ func toBackendSubscription (sub * gcpspanner.SavedSearchSubscription ) * backend.SubscriptionResponse {
1460+ if sub == nil {
1461+ return nil
1462+ }
1463+
1464+ return & backend.SubscriptionResponse {
1465+ Id : sub .ID ,
1466+ ChannelId : sub .ChannelID ,
1467+ SavedSearchId : sub .SavedSearchID ,
1468+ Triggers : sub .Triggers ,
1469+ Frequency : backend .SubscriptionResponseFrequency (sub .Frequency ),
1470+ CreatedAt : sub .CreatedAt ,
1471+ UpdatedAt : sub .UpdatedAt ,
1472+ }
1473+ }
0 commit comments