2023-01-06 00:39:21 +01:00
package primary
2022-11-19 23:16:54 +01:00
import (
2022-11-20 15:40:19 +01:00
scn "blackforestbytes.com/simplecloudnotifier"
2022-11-19 23:16:54 +01:00
"blackforestbytes.com/simplecloudnotifier/models"
"gogs.mikescher.com/BlackForestBytes/goext/langext"
2022-12-07 23:32:58 +01:00
"gogs.mikescher.com/BlackForestBytes/goext/sq"
2022-11-19 23:16:54 +01:00
"time"
)
func ( db * Database ) CreateRetryDelivery ( ctx TxContext , client models . Client , msg models . Message ) ( models . Delivery , error ) {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return models . Delivery { } , err
}
now := time . Now ( ) . UTC ( )
2022-11-20 15:40:19 +01:00
next := scn . NextDeliveryTimestamp ( now )
2022-11-19 23:16:54 +01:00
2022-12-07 22:11:44 +01:00
res , err := tx . Exec ( ctx , "INSERT INTO deliveries (scn_message_id, receiver_user_id, receiver_client_id, timestamp_created, timestamp_finalized, status, fcm_message_id, next_delivery) VALUES (:mid, :ruid, :rcid, :tsc, :tsf, :stat, :fcm, :next)" , sq . PP {
"mid" : msg . SCNMessageID ,
"ruid" : client . UserID ,
"rcid" : client . ClientID ,
"tsc" : time2DB ( now ) ,
"tsf" : nil ,
"stat" : models . DeliveryStatusRetry ,
"fcm" : nil ,
"next" : time2DB ( next ) ,
} )
2022-11-19 23:16:54 +01:00
if err != nil {
return models . Delivery { } , err
}
liid , err := res . LastInsertId ( )
if err != nil {
return models . Delivery { } , err
}
return models . Delivery {
2022-11-20 22:18:24 +01:00
DeliveryID : models . DeliveryID ( liid ) ,
2022-11-19 23:16:54 +01:00
SCNMessageID : msg . SCNMessageID ,
ReceiverUserID : client . UserID ,
ReceiverClientID : client . ClientID ,
TimestampCreated : now ,
TimestampFinalized : nil ,
Status : models . DeliveryStatusRetry ,
RetryCount : 0 ,
NextDelivery : langext . Ptr ( next ) ,
FCMMessageID : nil ,
} , nil
}
func ( db * Database ) CreateSuccessDelivery ( ctx TxContext , client models . Client , msg models . Message , fcmDelivID string ) ( models . Delivery , error ) {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return models . Delivery { } , err
}
now := time . Now ( ) . UTC ( )
2022-12-07 22:11:44 +01:00
res , err := tx . Exec ( ctx , "INSERT INTO deliveries (scn_message_id, receiver_user_id, receiver_client_id, timestamp_created, timestamp_finalized, status, fcm_message_id, next_delivery) VALUES (:mid, :ruid, :rcid, :tsc, :tsf, :stat, :fcm, :next)" , sq . PP {
"mid" : msg . SCNMessageID ,
"ruid" : client . UserID ,
"rcid" : client . ClientID ,
"tsc" : time2DB ( now ) ,
"tsf" : time2DB ( now ) ,
"stat" : models . DeliveryStatusSuccess ,
"fcm" : fcmDelivID ,
"next" : nil ,
} )
2022-11-19 23:16:54 +01:00
if err != nil {
return models . Delivery { } , err
}
liid , err := res . LastInsertId ( )
if err != nil {
return models . Delivery { } , err
}
return models . Delivery {
2022-11-20 22:18:24 +01:00
DeliveryID : models . DeliveryID ( liid ) ,
2022-11-19 23:16:54 +01:00
SCNMessageID : msg . SCNMessageID ,
ReceiverUserID : client . UserID ,
ReceiverClientID : client . ClientID ,
TimestampCreated : now ,
TimestampFinalized : langext . Ptr ( now ) ,
Status : models . DeliveryStatusSuccess ,
RetryCount : 0 ,
NextDelivery : nil ,
FCMMessageID : langext . Ptr ( fcmDelivID ) ,
} , nil
}
2022-11-20 15:40:19 +01:00
func ( db * Database ) ListRetrieableDeliveries ( ctx TxContext , pageSize int ) ( [ ] models . Delivery , error ) {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return nil , err
}
2022-12-07 22:11:44 +01:00
rows , err := tx . Query ( ctx , "SELECT * FROM deliveries WHERE status = 'RETRY' AND next_delivery < :next LIMIT :lim" , sq . PP {
"next" : time2DB ( time . Now ( ) ) ,
"lim" : pageSize ,
} )
2022-11-20 15:40:19 +01:00
if err != nil {
return nil , err
}
data , err := models . DecodeDeliveries ( rows )
if err != nil {
return nil , err
}
return data , nil
}
func ( db * Database ) SetDeliverySuccess ( ctx TxContext , delivery models . Delivery , fcmDelivID string ) error {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return err
}
2022-12-07 22:11:44 +01:00
_ , err = tx . Exec ( ctx , "UPDATE deliveries SET status = 'SUCCESS', next_delivery = NULL, retry_count = :rc, timestamp_finalized = :ts, fcm_message_id = :fcm WHERE delivery_id = :did" , sq . PP {
"rc" : delivery . RetryCount + 1 ,
"ts" : time2DB ( time . Now ( ) ) ,
"fcm" : fcmDelivID ,
"did" : delivery . DeliveryID ,
} )
2022-11-20 15:40:19 +01:00
if err != nil {
return err
}
return nil
}
func ( db * Database ) SetDeliveryFailed ( ctx TxContext , delivery models . Delivery ) error {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return err
}
2022-12-07 22:11:44 +01:00
_ , err = tx . Exec ( ctx , "UPDATE deliveries SET status = 'FAILED', next_delivery = NULL, retry_count = :rc, timestamp_finalized = :ts WHERE delivery_id = :did" ,
sq . PP {
"rc" : delivery . RetryCount + 1 ,
"ts" : time2DB ( time . Now ( ) ) ,
"did" : delivery . DeliveryID ,
} )
2022-11-20 15:40:19 +01:00
if err != nil {
return err
}
return nil
}
func ( db * Database ) SetDeliveryRetry ( ctx TxContext , delivery models . Delivery ) error {
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return err
}
2022-12-07 22:11:44 +01:00
_ , err = tx . Exec ( ctx , "UPDATE deliveries SET status = 'RETRY', next_delivery = :next, retry_count = :rc WHERE delivery_id = :did" , sq . PP {
"next" : scn . NextDeliveryTimestamp ( time . Now ( ) ) ,
"rc" : delivery . RetryCount + 1 ,
"did" : delivery . DeliveryID ,
} )
2022-11-20 15:40:19 +01:00
if err != nil {
return err
}
return nil
}
2022-11-20 22:18:24 +01:00
func ( db * Database ) CancelPendingDeliveries ( ctx TxContext , scnMessageID models . SCNMessageID ) error {
2022-11-20 15:40:19 +01:00
tx , err := ctx . GetOrCreateTransaction ( db )
if err != nil {
return err
}
2022-12-07 22:11:44 +01:00
_ , err = tx . Exec ( ctx , "UPDATE deliveries SET status = 'FAILED', next_delivery = NULL, timestamp_finalized = :ts WHERE scn_message_id = :mid AND status = 'RETRY'" , sq . PP {
"ts" : time . Now ( ) ,
"mid" : scnMessageID ,
} )
2022-11-20 15:40:19 +01:00
if err != nil {
return err
}
return nil
}