packages feed

stakhanov 0.0.1.0 → 0.1.0.0

raw patch · 7 files changed

+37/−29 lines, 7 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Database.PostgreSQL.Stakhanov.Types: [lastReadAt] :: Message -> Maybe UTCTime
- Database.PostgreSQL.Stakhanov.Types: Message :: MsgId -> Int32 -> UTCTime -> UTCTime -> !Value -> !Maybe Value -> Message
+ Database.PostgreSQL.Stakhanov.Types: Message :: MsgId -> Int32 -> UTCTime -> Maybe UTCTime -> UTCTime -> Value -> Maybe Value -> Message
- Database.PostgreSQL.Stakhanov.Types: [headers] :: Message -> !Maybe Value
+ Database.PostgreSQL.Stakhanov.Types: [headers] :: Message -> Maybe Value
- Database.PostgreSQL.Stakhanov.Types: [message] :: Message -> !Value
+ Database.PostgreSQL.Stakhanov.Types: [message] :: Message -> Value

Files

CHANGELOG.md view
@@ -3,3 +3,7 @@ ## 0.0.1.0 -- 2026-01-12  * First version.++## 0.1.0.0 -- 2026-02-11++* Updated to work with pgmq v1.10.0. The field last_read_at has been added to message record.
ReadMe.md view
@@ -2,3 +2,4 @@  The Haskell library `stakhanov`, built upon [Hasql](https://hackage.haskell.org/package/hasql)'s ecosystem and [Vector](https://hackage.haskell.org/package/vector), implements most of the functions of the [API](https://pgmq.github.io/pgmq/api/sql/functions/) of [PGMQ](https://pgmq.github.io/pgmq/), "a lightweight message queue, like AWS SQS and RSMQ but on Postgres". +`stakhanov v0.1.0.0` has been tested against [pgmq v1.10.0](https://github.com/pgmq/pgmq/releases/tag/v1.10.0).
src/Database/PostgreSQL/Stakhanov.hs view
@@ -181,7 +181,7 @@  -- | Reads one or more `Messages` from a `Queue` and /deletes them upon read/. ----- > λ: pop MyQueue 2+-- > λ: pop myQueue 2 -- > Right (Just [Message {msgId = 2, readCount = 13, enqueuedAt = 2025-12-09 09:51:50.259464 UTC, visibilityTimeout = 2025-12-15 10:46:41.096843 UTC, message = Object (fromList [("Action",String "hug"),("Quantity",Number 3)]), headers = Nothing},Message {msgId = 3, readCount = 2, enqueuedAt = 2025-12-15 10:44:45.612983 UTC, visibilityTimeout = 2025-12-29 18:04:32.938332 UTC, message = Object (fromList [("Action",String "hug"),("Quantity",Number 5)]), headers = Object (fromList [("Reason",String empathy"")])}]) -- pop@@ -251,7 +251,7 @@ -- | Add `Details` information, collected with `listQueues`, to a `Queue` record. -- -- > λ: Right list <- listQueues conn--- > λ: details MyQueue list+-- > λ: details myQueue list -- > Just (Queue {qName = "test", qPGConn = "a Hasql connection", qDetails = Just (Details {createdAt = 2025-12-18 14:33:41.563365 UTC, isPartitioned = False, isUnlogged = False}), qMetrics = Nothing}) -- details
src/Database/PostgreSQL/Stakhanov/Internal.hs view
@@ -25,12 +25,12 @@ allJSON = V.all isJSON  maybeMessages-  :: Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value)+  :: Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)   -> Maybe Messages maybeMessages v =-    if V.null v-      then Nothing-      else Just $ tupleToMessage <$> v+  if V.null v+    then Nothing+    else Just $ tupleToMessage <$> v  tupleToDetails :: (UTCTime,Bool,Bool) -> Details tupleToDetails (e1,e2,e3) =@@ -65,16 +65,17 @@     , queueVisibleLength = e6 }  tupleToMessage-  :: (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value)+  :: (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)   -> Message-tupleToMessage (e1,e2,e3,e4,e5,e6) =+tupleToMessage (e1,e2,e3,e4,e5,e6,e7) =   Message     { msgId             = e1     , readCount         = e2     , enqueuedAt        = e3-    , visibilityTimeout = e4-    , message           = e5-    , headers           = e6 }+    , lastReadAt        = e4+    , visibilityTimeout = e5+    , message           = e6+    , headers           = e7 }  maybeHeaders :: Maybe Value -> S.Snippet maybeHeaders (Just v) = "," <> S.encoderAndParam (E.nonNullable E.json) v <> "::jsonb"
src/Database/PostgreSQL/Stakhanov/Statements.hs view
@@ -52,8 +52,8 @@     sql = "select * from pgmq.send($1::text,$2::jsonb)"     encoder =       contrazip2-        (E.param (E.nonNullable E.text))-        (E.param (E.nonNullable E.jsonb))+        (E.param $ E.nonNullable E.text)+        (E.param $ E.nonNullable E.jsonb)     decoder = D.singleRow $ D.column $ D.nonNullable D.int8  sendMessage' :: T.Text -> Value -> Maybe Value -> Maybe Delay -> Statement () Int64@@ -78,7 +78,7 @@       decoder = D.rowVector $ D.column $ D.nonNullable D.int8   in dynamicallyParameterized snippet decoder True -readMessagesWithPoll :: T.Text -> Int32 -> Int32 -> Maybe Int32 -> Maybe Int32 -> Statement () (V.Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value))+readMessagesWithPoll :: T.Text -> Int32 -> Int32 -> Maybe Int32 -> Maybe Int32 -> Statement () (V.Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)) readMessagesWithPoll q vt qty mmp mpi =   let mp = maybe 5 id mmp       pi = maybe 100 id mpi@@ -86,26 +86,26 @@                 mconcat (L.intersperse "," [S.param q, S.param vt, S.param qty, S.param mp, S.param pi]) <> ")"   in dynamicallyParameterized snippet tupleMessageDecoder True -readMessages :: Statement (T.Text,Int32,Int32) (V.Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value))+readMessages :: Statement (T.Text,Int32,Int32) (V.Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)) readMessages =   Statement sql encoder tupleMessageDecoder True   where     sql = "select " <> columnsMessage <> " from pgmq.read($1,$2,$3)"     encoder =       contrazip3-        (E.param (E.nonNullable E.text))-        (E.param (E.nonNullable E.int4))-        (E.param (E.nonNullable E.int4))+        (E.param $ E.nonNullable E.text)+        (E.param $ E.nonNullable E.int4)+        (E.param $ E.nonNullable E.int4) -popMessages :: Statement (T.Text,Int32) (V.Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value))+popMessages :: Statement (T.Text,Int32) (V.Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)) popMessages =   Statement sql encoder tupleMessageDecoder True   where     sql = "select " <> columnsMessage <> " from pgmq.pop($1,$2)"     encoder =       contrazip2-        (E.param (E.nonNullable E.text))-        (E.param (E.nonNullable E.int4))+        (E.param $ E.nonNullable E.text)+        (E.param $ E.nonNullable E.int4)  getMetrics :: Statement T.Text (Int64, Maybe Int32, Maybe Int32, Int64, UTCTime, Int64) getMetrics =@@ -157,25 +157,26 @@       decoder = D.rowVector (D.column (D.nonNullable D.int8))   in dynamicallyParameterized snippet decoder True -setMessagesVT :: T.Text -> V.Vector Int64 -> Int32 -> Statement () (V.Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value))+setMessagesVT :: T.Text -> V.Vector Int64 -> Int32 -> Statement () (V.Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)) setMessagesVT q v s =   let snippet = "select * from pgmq.set_vt(" <> S.param q <> ","                 <> bigintArrayEncoder v <> "," <> S.param s <> ")"   in dynamicallyParameterized snippet tupleMessageDecoder True -tupleMessageDecoder :: D.Result (V.Vector (Int64, Int32, UTCTime, UTCTime, Value, Maybe Value))+tupleMessageDecoder :: D.Result (V.Vector (Int64, Int32, UTCTime, Maybe UTCTime, UTCTime, Value, Maybe Value)) tupleMessageDecoder =   D.rowVector $-    (,,,,,) <$>+    (,,,,,,) <$>       D.column (D.nonNullable D.int8) <*>       D.column (D.nonNullable D.int4) <*>       D.column (D.nonNullable D.timestamptz) <*>+      D.column (D.nullable D.timestamptz) <*>       D.column (D.nonNullable D.timestamptz) <*>       D.column (D.nonNullable D.jsonb) <*>       D.column (D.nullable D.jsonb)  columnsMessage :: ByteString-columnsMessage = "msg_id,read_ct,enqueued_at,vt,message,headers"+columnsMessage = "msg_id,read_ct,enqueued_at,last_read_at,vt,message,headers"  columnsMetrics :: ByteString columnsMetrics = "queue_length,newest_msg_age_sec,oldest_msg_age_sec,total_messages,scrape_time,queue_visible_length"
src/Database/PostgreSQL/Stakhanov/Types.hs view
@@ -45,13 +45,14 @@     { msgId             :: MsgId     , readCount         :: Int32     , enqueuedAt        :: UTCTime+    , lastReadAt        :: Maybe UTCTime     , visibilityTimeout :: UTCTime-    , message           :: !Value-    , headers           :: !(Maybe Value)+    , message           :: Value+    , headers           :: Maybe Value     } deriving (Show)  instance Eq Message where-  Message i _ _ _ _ _ == Message i' _ _ _ _ _ = i == i'+  Message i _ _ _ _ _ _ == Message i' _ _ _ _ _ _ = i == i'  data Metrics =   Metrics
stakhanov.cabal view
@@ -1,6 +1,6 @@ cabal-version:      3.0 name:               stakhanov-version:            0.0.1.0+version:            0.1.0.0 synopsis:           A Haskell PGMQ client description:   A fast Haskell PGMQ client for busy workers