generated from tpl/purs
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
c9e5ee9205
|
|||
|
9ab6e37bb1
|
|||
|
f23eb4143a
|
|||
|
d10d21b708
|
|||
|
826c1e10b1
|
|||
|
fbb1f3b8a5
|
|||
|
b4a84a3210
|
|||
|
a56add0ffc
|
|||
|
7ed85ae22b
|
|||
|
bead3d81c3
|
|||
|
27a7abb329
|
|||
|
86263a7521
|
|||
|
2db29b8916
|
|||
|
cfb01608cd
|
|||
|
aca76f7de3
|
|||
|
188403681a
|
|||
|
ca7ebb4337
|
|||
|
b3806d5f6e
|
|||
|
adb414662e
|
|||
|
69721fcda4
|
|||
|
a616440abe
|
|||
|
d66c3261b6
|
90
README.md
90
README.md
@@ -259,59 +259,59 @@ the api of [`node-postgres`]:
|
||||
- release clients with [`Pool.release`] or [`Pool.destroy`]
|
||||
- release with [`Pool.end`]
|
||||
|
||||
[`Pool`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#t:Pool
|
||||
[`Config`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#t:Config
|
||||
[`Pool.make`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#v:make
|
||||
[`Pool.end`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#v:end
|
||||
[`Pool.connect`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#v:connect
|
||||
[`Pool.destroy`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#v:destroy
|
||||
[`Pool.release`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Pool#v:release
|
||||
[`Pool`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#t:Pool
|
||||
[`Config`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#t:Config
|
||||
[`Pool.make`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#v:make
|
||||
[`Pool.end`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#v:end
|
||||
[`Pool.connect`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#v:connect
|
||||
[`Pool.destroy`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#v:destroy
|
||||
[`Pool.release`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Pool#v:release
|
||||
|
||||
[`Client`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#t:Client
|
||||
[`Client.end`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:end
|
||||
[`Client.make`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:make
|
||||
[`Client.connected`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:connected
|
||||
[`Client.query`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:query
|
||||
[`Client.queryRaw`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:queryRaw
|
||||
[`Client.exec`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Effect.Aff.Postgres.Client#v:exec
|
||||
[`Client`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#t:Client
|
||||
[`Client.end`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:end
|
||||
[`Client.make`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:make
|
||||
[`Client.connected`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:connected
|
||||
[`Client.query`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:query
|
||||
[`Client.queryRaw`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:queryRaw
|
||||
[`Client.exec`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Effect.Aff.Postgres.Client#v:exec
|
||||
|
||||
[`Range`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Range#t:Range
|
||||
[`Range.gt`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Range#v:gt
|
||||
[`Range.gte`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Range#v:gte
|
||||
[`Range.lt`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Range#v:lt
|
||||
[`Range.lte`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Range#v:lte
|
||||
[`Range`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Range#t:Range
|
||||
[`Range.gt`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Range#v:gt
|
||||
[`Range.gte`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Range#v:gte
|
||||
[`Range.lt`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Range#v:lt
|
||||
[`Range.lte`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Range#v:lte
|
||||
|
||||
[`Raw`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Raw#t:Raw
|
||||
[`Null`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Raw#t:Null
|
||||
[`Raw`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Raw#t:Raw
|
||||
[`Null`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Raw#t:Null
|
||||
|
||||
[`Serialize`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres#t:Serialize
|
||||
[`Deserialize`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres#t:Deserialize
|
||||
[`Rep`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres#t:Rep
|
||||
[`modifyPgTypes`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres#v:modifyPgTypes
|
||||
[`Serialize`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres#t:Serialize
|
||||
[`Deserialize`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres#t:Deserialize
|
||||
[`Rep`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres#t:Rep
|
||||
[`modifyPgTypes`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres#v:modifyPgTypes
|
||||
|
||||
[`Result`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Result#t:Result
|
||||
[`FromRow`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Result#t:FromRow
|
||||
[`FromRows`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Result#t:FromRows
|
||||
[`Result`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Result#t:Result
|
||||
[`FromRow`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Result#t:FromRow
|
||||
[`FromRows`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Result#t:FromRows
|
||||
|
||||
[`Query`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Query#t:Query
|
||||
[`AsQuery`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Query#t:AsQuery
|
||||
[`Query`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Query#t:Query
|
||||
[`AsQuery`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Query#t:AsQuery
|
||||
|
||||
[`Query.Builder`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Query.Builder#t:Builder
|
||||
[`Query.Builder.param`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Query.Builder#v:param
|
||||
[`Query.Builder.build`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Data.Postgres.Query.Builder#v:build
|
||||
[`Query.Builder`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Query.Builder#t:Builder
|
||||
[`Query.Builder.param`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Query.Builder#v:param
|
||||
[`Query.Builder.build`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Data.Postgres.Query.Builder#v:build
|
||||
|
||||
[`MonadCursor`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#t:MonadCursor
|
||||
[`MonadSession`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#t:MonadSession
|
||||
[`CursorT`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#t:CursorT
|
||||
[`SessionT`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#t:SessionT
|
||||
[`PostgresT`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#t:PostgresT
|
||||
[`cursor`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:cursor
|
||||
[`session`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:session
|
||||
[`transaction`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:transaction
|
||||
[`runPostgres`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:runPostgres
|
||||
[`query`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:query
|
||||
[`exec`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:exec
|
||||
[`exec_`]: https://pursuit.purescript.org//////////////////////////////packages/purescript-postgresql/1.5.0/Control.Monad.Postgres#v:exec_
|
||||
[`MonadCursor`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#t:MonadCursor
|
||||
[`MonadSession`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#t:MonadSession
|
||||
[`CursorT`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#t:CursorT
|
||||
[`SessionT`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#t:SessionT
|
||||
[`PostgresT`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#t:PostgresT
|
||||
[`cursor`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:cursor
|
||||
[`session`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:session
|
||||
[`transaction`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:transaction
|
||||
[`runPostgres`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:runPostgres
|
||||
[`query`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:query
|
||||
[`exec`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:exec
|
||||
[`exec_`]: https://pursuit.purescript.org//////////////////////////////////////////packages/purescript-postgresql/1.7.2/Control.Monad.Postgres#v:exec_
|
||||
|
||||
[`node-postgres`]: https://node-postgres.com/
|
||||
[`pg-types`]: https://github.com/brianc/node-pg-types/
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "purs",
|
||||
"name": "purescript-postgresql",
|
||||
"private": true,
|
||||
"module": "index.js",
|
||||
"type": "module",
|
||||
@@ -15,6 +15,8 @@
|
||||
"decimal.js": "^10.4.3",
|
||||
"pg": "^8.11.3",
|
||||
"pg-copy-streams": "^6.0.6",
|
||||
"pg-listen": "^1.7.0",
|
||||
"postgres-interval": "1.2.0",
|
||||
"postgres-range": "^1.1.4"
|
||||
}
|
||||
}
|
||||
|
||||
72
spago.lock
72
spago.lock
@@ -23,10 +23,12 @@ workspace:
|
||||
- newtype: ">=5.0.0 <6.0.0"
|
||||
- node-buffer: ">=9.0.0 <10.0.0"
|
||||
- node-event-emitter: ">=3.0.0 <4.0.0"
|
||||
- node-stream-pipes: ">=2.1.0 <3.0.0"
|
||||
- node-streams: ">=9.0.0 <10.0.0"
|
||||
- nullable: ">=6.0.0 <7.0.0"
|
||||
- parallel: ">=6.0.0 <7.0.0"
|
||||
- partial: ">=4.0.0 <5.0.0"
|
||||
- pipes: ">=8.0.0 <9.0.0"
|
||||
- precise-datetime: ">=7.0.0 <8.0.0"
|
||||
- prelude: ">=6.0.1 <7.0.0"
|
||||
- profunctor: ">=6.0.1 <7.0.0"
|
||||
@@ -44,6 +46,7 @@ workspace:
|
||||
- foreign-object
|
||||
- node-child-process
|
||||
- node-process
|
||||
- precise-datetime
|
||||
- quickcheck
|
||||
- spec
|
||||
- spec-quickcheck
|
||||
@@ -99,7 +102,9 @@ workspace:
|
||||
- node-os
|
||||
- node-path
|
||||
- node-process
|
||||
- node-stream-pipes
|
||||
- node-streams
|
||||
- node-zlib
|
||||
- nonempty
|
||||
- now
|
||||
- nullable
|
||||
@@ -132,6 +137,7 @@ workspace:
|
||||
- unfoldable
|
||||
- unicode
|
||||
- unlift
|
||||
- unordered-collections
|
||||
- unsafe-coerce
|
||||
- variant
|
||||
extra_packages: {}
|
||||
@@ -720,6 +726,44 @@ packages:
|
||||
- posix-types
|
||||
- prelude
|
||||
- unsafe-coerce
|
||||
node-stream-pipes:
|
||||
type: registry
|
||||
version: 2.1.0
|
||||
integrity: sha256-pYBOQY4bGEZzI5UHsUxJAhsKqtmE6CC1sHmFqgj64V8=
|
||||
dependencies:
|
||||
- aff
|
||||
- arrays
|
||||
- console
|
||||
- control
|
||||
- datetime
|
||||
- effect
|
||||
- either
|
||||
- exceptions
|
||||
- foldable-traversable
|
||||
- foreign-object
|
||||
- fork
|
||||
- lists
|
||||
- maybe
|
||||
- mmorph
|
||||
- newtype
|
||||
- node-buffer
|
||||
- node-event-emitter
|
||||
- node-fs
|
||||
- node-path
|
||||
- node-streams
|
||||
- node-zlib
|
||||
- now
|
||||
- ordered-collections
|
||||
- parallel
|
||||
- pipes
|
||||
- prelude
|
||||
- st
|
||||
- strings
|
||||
- tailrec
|
||||
- transformers
|
||||
- tuples
|
||||
- unordered-collections
|
||||
- unsafe-coerce
|
||||
node-streams:
|
||||
type: registry
|
||||
version: 9.0.0
|
||||
@@ -733,6 +777,19 @@ packages:
|
||||
- node-event-emitter
|
||||
- nullable
|
||||
- prelude
|
||||
node-zlib:
|
||||
type: registry
|
||||
version: 0.4.0
|
||||
integrity: sha256-kYSajFQFzWVg71l5/y4w4kXdTr5EJoqyV3D2RqmAjQ4=
|
||||
dependencies:
|
||||
- aff
|
||||
- effect
|
||||
- either
|
||||
- functions
|
||||
- node-buffer
|
||||
- node-streams
|
||||
- prelude
|
||||
- unsafe-coerce
|
||||
nonempty:
|
||||
type: registry
|
||||
version: 7.0.0
|
||||
@@ -1132,6 +1189,21 @@ packages:
|
||||
- st
|
||||
- transformers
|
||||
- tuples
|
||||
unordered-collections:
|
||||
type: registry
|
||||
version: 3.1.0
|
||||
integrity: sha256-H2eQR+ylI+cljz4XzWfEbdF7ee+pnw2IZCeq69AuJ+Q=
|
||||
dependencies:
|
||||
- arrays
|
||||
- enums
|
||||
- functions
|
||||
- integers
|
||||
- lists
|
||||
- prelude
|
||||
- record
|
||||
- tuples
|
||||
- typelevel-prelude
|
||||
- unfoldable
|
||||
unsafe-coerce:
|
||||
type: registry
|
||||
version: 6.0.0
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package:
|
||||
name: postgresql
|
||||
publish:
|
||||
version: '1.5.0'
|
||||
version: '1.7.2'
|
||||
license: 'GPL-3.0-or-later'
|
||||
location:
|
||||
githubOwner: 'cakekindel'
|
||||
@@ -33,10 +33,12 @@ package:
|
||||
- newtype: ">=5.0.0 <6.0.0"
|
||||
- node-buffer: ">=9.0.0 <10.0.0"
|
||||
- node-event-emitter: ">=3.0.0 <4.0.0"
|
||||
- node-stream-pipes: ">=2.1.0 <3.0.0"
|
||||
- node-streams: ">=9.0.0 <10.0.0"
|
||||
- nullable: ">=6.0.0 <7.0.0"
|
||||
- parallel: ">=6.0.0 <7.0.0"
|
||||
- partial: ">=4.0.0 <5.0.0"
|
||||
- pipes: ">=8.0.0 <9.0.0"
|
||||
- precise-datetime: ">=7.0.0 <8.0.0"
|
||||
- prelude: ">=6.0.1 <7.0.0"
|
||||
- profunctor: ">=6.0.1 <7.0.0"
|
||||
@@ -56,6 +58,7 @@ package:
|
||||
- foreign-object
|
||||
- node-child-process
|
||||
- node-process
|
||||
- precise-datetime
|
||||
- quickcheck
|
||||
- spec
|
||||
- spec-quickcheck
|
||||
|
||||
@@ -3,7 +3,7 @@ module Control.Monad.Postgres.Base where
|
||||
import Prelude
|
||||
|
||||
import Control.Alt (class Alt)
|
||||
import Control.Alternative (class Plus)
|
||||
import Control.Alternative (class Alternative, class Plus)
|
||||
import Control.Monad.Error.Class (class MonadError, class MonadThrow, catchError, throwError)
|
||||
import Control.Monad.Fork.Class (class MonadBracket, class MonadFork, class MonadKill, bracket, kill, never, uninterruptible)
|
||||
import Control.Monad.Morph (class MFunctor, class MMonad)
|
||||
@@ -57,6 +57,7 @@ newtype PostgresT m a = PostgresT (ReaderT Pool m a)
|
||||
derive instance Newtype (PostgresT m a) _
|
||||
derive newtype instance (Functor m) => Functor (PostgresT m)
|
||||
derive newtype instance (Apply m) => Apply (PostgresT m)
|
||||
derive newtype instance (Alternative m) => Alternative (PostgresT m)
|
||||
derive newtype instance (Applicative m) => Applicative (PostgresT m)
|
||||
derive newtype instance (Plus m) => Plus (PostgresT m)
|
||||
derive newtype instance (Alt m) => Alt (PostgresT m)
|
||||
@@ -104,7 +105,7 @@ instance (MonadBracket e f m, MonadAff m) => MonadSession (PostgresT m) where
|
||||
-- | - `session` - Session monad (for `PostgresT` this is `SessionT`)
|
||||
-- | - `cursor` - Cursor session monad (for `PostgresT` this is `CursorT`)
|
||||
-- | - `ct` - Open type parameter for cursor type. Don't pin this to a concrete type.
|
||||
class (MonadSession session, MonadCursor cursor ct) <= MonadPostgres m session cursor ct | m -> ct cursor session where
|
||||
class (Monad m, MonadSession session, MonadCursor cursor ct) <= MonadPostgres m session cursor ct | m -> ct cursor session where
|
||||
-- | Run a session in `m`.
|
||||
session :: session ~> m
|
||||
-- | Run a session in `m`, wrapped in a transaction.
|
||||
|
||||
@@ -3,7 +3,7 @@ module Control.Monad.Postgres.Cursor where
|
||||
import Prelude
|
||||
|
||||
import Control.Alt (class Alt)
|
||||
import Control.Alternative (class Plus)
|
||||
import Control.Alternative (class Alternative, class Plus)
|
||||
import Control.Monad.Error.Class (class MonadError, class MonadThrow)
|
||||
import Control.Monad.Fork.Class (class MonadBracket, class MonadFork, class MonadKill, bracket, kill, never, uninterruptible)
|
||||
import Control.Monad.Postgres.Session (class MonadSession, exec, exec_, query, streamIn, streamOut)
|
||||
@@ -39,6 +39,7 @@ derive newtype instance (Apply m) => Apply (CursorT t m)
|
||||
derive newtype instance (Applicative m) => Applicative (CursorT t m)
|
||||
derive newtype instance (Plus m) => Plus (CursorT t m)
|
||||
derive newtype instance (Alt m) => Alt (CursorT t m)
|
||||
derive newtype instance (Alternative m) => Alternative (CursorT t m)
|
||||
derive newtype instance (Bind m) => Bind (CursorT t m)
|
||||
derive newtype instance (Monad m) => Monad (CursorT t m)
|
||||
derive newtype instance (MonadEffect m) => MonadEffect (CursorT t m)
|
||||
|
||||
@@ -2,20 +2,13 @@ module Data.Postgres.Custom where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Except (ExceptT)
|
||||
import Data.Either (hush)
|
||||
import Data.List.NonEmpty (NonEmptyList)
|
||||
import Data.Maybe (Maybe, fromJust)
|
||||
import Data.Postgres.Raw (Raw)
|
||||
import Data.Maybe (fromJust)
|
||||
import Data.String as String
|
||||
import Data.String.Regex (Regex)
|
||||
import Data.String.Regex as Regex
|
||||
import Data.String.Regex.Flags as Regex.Flags
|
||||
import Effect (Effect)
|
||||
import Foreign (ForeignError)
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
import Type.Data.Symbol (reflectSymbol)
|
||||
import Type.Prelude (class IsSymbol, Proxy(..))
|
||||
|
||||
quoted :: String -> String
|
||||
quoted s = "'" <> s <> "'"
|
||||
|
||||
30
src/Data.Postgres.Interval.js
Normal file
30
src/Data.Postgres.Interval.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import PostgresInterval from 'postgres-interval'
|
||||
|
||||
/** @typedef {import('postgres-interval').IPostgresInterval} I */
|
||||
|
||||
/** @type {(o: {years: number, months: number, days: number, hours: number, minutes: number, seconds: number, milliseconds: number}) => I} */
|
||||
export const make = o => Object.assign(PostgresInterval(''), o)
|
||||
|
||||
/** @type {(s: string) => () => I} */
|
||||
export const parse = s => () => PostgresInterval(s)
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getYears = i => i.years || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getMonths = i => i.months || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getDays = i => i.days || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getMinutes = i => i.minutes || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getHours = i => i.hours || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getSeconds = i => i.seconds || 0.0
|
||||
|
||||
/** @type {(a: I) => number} */
|
||||
export const getMilliseconds = i => i.milliseconds || 0.0
|
||||
88
src/Data.Postgres.Interval.purs
Normal file
88
src/Data.Postgres.Interval.purs
Normal file
@@ -0,0 +1,88 @@
|
||||
module Data.Postgres.Interval where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Int as Int
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Newtype (unwrap)
|
||||
import Data.Time.Duration (class Duration, Days(..), Hours(..), Milliseconds(..), Minutes(..), Seconds(..), convertDuration)
|
||||
import Effect (Effect)
|
||||
|
||||
zero :: IntervalRecord
|
||||
zero = {years: 0, months: 0, days: 0, hours: 0, minutes: 0, seconds: 0, milliseconds: 0.0}
|
||||
|
||||
type IntervalRecord =
|
||||
{ years :: Int
|
||||
, months :: Int
|
||||
, days :: Int
|
||||
, hours :: Int
|
||||
, minutes :: Int
|
||||
, seconds :: Int
|
||||
, milliseconds :: Number
|
||||
}
|
||||
|
||||
foreign import data Interval :: Type
|
||||
|
||||
foreign import make :: IntervalRecord -> Interval
|
||||
foreign import parse :: String -> Effect Interval
|
||||
|
||||
foreign import getYears :: Interval -> Int
|
||||
foreign import getMonths :: Interval -> Int
|
||||
foreign import getDays :: Interval -> Int
|
||||
foreign import getHours :: Interval -> Int
|
||||
foreign import getMinutes :: Interval -> Int
|
||||
foreign import getSeconds :: Interval -> Int
|
||||
foreign import getMilliseconds :: Interval -> Number
|
||||
|
||||
toDuration :: forall d. Semigroup d => Duration d => Interval -> Maybe d
|
||||
toDuration a =
|
||||
let
|
||||
includesMonths = getYears a > 0 || getMonths a > 0
|
||||
|
||||
days :: d
|
||||
days = convertDuration $ Days $ Int.toNumber $ getDays a
|
||||
|
||||
hours :: d
|
||||
hours = convertDuration $ Hours $ Int.toNumber $ getHours a
|
||||
|
||||
minutes :: d
|
||||
minutes = convertDuration $ Minutes $ Int.toNumber $ getMinutes a
|
||||
|
||||
seconds :: d
|
||||
seconds = convertDuration $ Seconds $ Int.toNumber $ getSeconds a
|
||||
|
||||
milliseconds :: d
|
||||
milliseconds = convertDuration $ Milliseconds $ getMilliseconds a
|
||||
in
|
||||
if includesMonths then Nothing else Just (days <> hours <> minutes <> seconds <> milliseconds)
|
||||
|
||||
toRecord :: Interval -> IntervalRecord
|
||||
toRecord a =
|
||||
{ years: getYears a
|
||||
, months: getMonths a
|
||||
, days: getDays a
|
||||
, hours: getHours a
|
||||
, minutes: getMinutes a
|
||||
, seconds: getSeconds a
|
||||
, milliseconds: getMilliseconds a
|
||||
}
|
||||
|
||||
fromDuration :: forall d. Duration d => d -> Interval
|
||||
fromDuration a =
|
||||
let
|
||||
millisTotal :: Number
|
||||
millisTotal = (unwrap :: Milliseconds -> Number) $ convertDuration a
|
||||
secondFactor = 1000.0
|
||||
minuteFactor = 60.0 * secondFactor
|
||||
hourFactor = 60.0 * minuteFactor
|
||||
dayFactor = 24.0 * hourFactor
|
||||
days = Int.trunc $ millisTotal / dayFactor
|
||||
daysRem = millisTotal - (Int.toNumber days * dayFactor)
|
||||
hours = Int.trunc $ daysRem / hourFactor
|
||||
hoursRem = daysRem - (Int.toNumber hours * hourFactor)
|
||||
minutes = Int.trunc $ hoursRem / minuteFactor
|
||||
minutesRem = hoursRem - (Int.toNumber minutes * minuteFactor)
|
||||
seconds = Int.trunc $ minutesRem / secondFactor
|
||||
milliseconds = minutesRem - (Int.toNumber seconds * secondFactor)
|
||||
in
|
||||
make {years: 0, months: 0, days, hours, minutes, seconds, milliseconds}
|
||||
@@ -1,5 +1,24 @@
|
||||
import Pg from 'pg'
|
||||
import Range from 'postgres-range'
|
||||
import { Buffer } from 'buffer'
|
||||
import PostgresInterval from 'postgres-interval'
|
||||
|
||||
/** @type {(a: unknown) => boolean} */
|
||||
export const isInstanceOfBuffer = a => a instanceof Buffer
|
||||
|
||||
/** @type {(a: unknown) => boolean} */
|
||||
export const isInstanceOfInterval = a => {
|
||||
return typeof a === 'object'
|
||||
&& a !== null
|
||||
&& ('years' in a
|
||||
|| 'months' in a
|
||||
|| 'days' in a
|
||||
|| 'hours' in a
|
||||
|| 'minutes' in a
|
||||
|| 'seconds' in a
|
||||
|| 'milliseconds' in a
|
||||
)
|
||||
}
|
||||
|
||||
export const modifyPgTypes = () => {
|
||||
// https://github.com/brianc/node-pg-types/blob/master/lib/textParsers.js
|
||||
|
||||
@@ -3,23 +3,28 @@ module Data.Postgres where
|
||||
import Prelude
|
||||
|
||||
import Control.Alt ((<|>))
|
||||
import Control.Monad.Error.Class (liftEither, liftMaybe)
|
||||
import Control.Monad.Error.Class (liftEither, liftMaybe, throwError)
|
||||
import Control.Monad.Except (ExceptT, runExceptT)
|
||||
import Control.Monad.Morph (hoist)
|
||||
import Control.Monad.Trans.Class (lift)
|
||||
import Data.Bifunctor (lmap)
|
||||
import Data.DateTime (DateTime)
|
||||
import Data.DateTime.Instant (Instant)
|
||||
import Data.DateTime.Instant as Instant
|
||||
import Data.List.NonEmpty (NonEmptyList)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Data.Newtype (class Newtype, unwrap, wrap)
|
||||
import Data.Postgres.Interval (Interval)
|
||||
import Data.Postgres.Interval as Interval
|
||||
import Data.Postgres.Range (Range, __rangeFromRecord, __rangeRawFromRaw, __rangeRawFromRecord, __rangeRawToRecord, __rangeToRecord)
|
||||
import Data.Postgres.Raw (Null(..), Raw, jsNull)
|
||||
import Data.Postgres.Raw (unsafeFromForeign, asForeign) as Raw
|
||||
import Data.RFC3339String as DateTime.ISO
|
||||
import Data.Time.Duration (Days, Hours, Milliseconds, Minutes, Seconds)
|
||||
import Data.Traversable (traverse)
|
||||
import Effect (Effect)
|
||||
import Effect.Exception (error)
|
||||
import Foreign (ForeignError(..), unsafeToForeign)
|
||||
import Foreign (ForeignError(..), tagOf, unsafeFromForeign, unsafeToForeign)
|
||||
import Foreign as F
|
||||
import JS.BigInt (BigInt)
|
||||
import JS.BigInt as BigInt
|
||||
@@ -40,6 +45,9 @@ derive newtype instance ReadForeign a => ReadForeign (JSON a)
|
||||
-- | for some types to unmarshal as strings rather than JS values.
|
||||
foreign import modifyPgTypes :: Effect Unit
|
||||
|
||||
foreign import isInstanceOfBuffer :: F.Foreign -> Boolean
|
||||
foreign import isInstanceOfInterval :: F.Foreign -> Boolean
|
||||
|
||||
-- | The serialization & deserialization monad.
|
||||
type RepT = ExceptT (NonEmptyList ForeignError) Effect
|
||||
|
||||
@@ -68,6 +76,9 @@ instance (Serialize a, Deserialize a) => Rep a
|
||||
unsafeSerializeCoerce :: forall m a. Monad m => a -> m Raw
|
||||
unsafeSerializeCoerce = pure <<< Raw.unsafeFromForeign <<< F.unsafeToForeign
|
||||
|
||||
invalidDuration :: NonEmptyList ForeignError
|
||||
invalidDuration = pure $ ForeignError $ "Can't convert interval with year or month components to Milliseconds"
|
||||
|
||||
instance Serialize Raw where
|
||||
serialize = pure
|
||||
|
||||
@@ -107,10 +118,38 @@ instance Serialize String where
|
||||
instance Serialize Number where
|
||||
serialize = unsafeSerializeCoerce
|
||||
|
||||
-- | `timestamp`, `timestamptz`
|
||||
-- | `interval`
|
||||
instance Serialize DateTime where
|
||||
serialize = serialize <<< unwrap <<< DateTime.ISO.fromDateTime
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Interval where
|
||||
serialize = unsafeSerializeCoerce
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Milliseconds where
|
||||
serialize = serialize <<< Interval.fromDuration
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Seconds where
|
||||
serialize = serialize <<< Interval.fromDuration
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Minutes where
|
||||
serialize = serialize <<< Interval.fromDuration
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Hours where
|
||||
serialize = serialize <<< Interval.fromDuration
|
||||
|
||||
-- | `interval`
|
||||
instance Serialize Days where
|
||||
serialize = serialize <<< Interval.fromDuration
|
||||
|
||||
-- | `timestamp`, `timestamptz`
|
||||
instance Serialize Instant where
|
||||
serialize = serialize <<< Instant.toDateTime
|
||||
|
||||
-- | `Just` -> `a`, `Nothing` -> `NULL`
|
||||
instance Serialize a => Serialize (Maybe a) where
|
||||
serialize (Just a) = serialize a
|
||||
@@ -142,7 +181,41 @@ instance ReadForeign a => Deserialize (JSON a) where
|
||||
|
||||
-- | `bytea`
|
||||
instance Deserialize Buffer where
|
||||
deserialize = (F.unsafeReadTagged "Buffer") <<< Raw.asForeign
|
||||
deserialize =
|
||||
let
|
||||
notBuffer a = pure $ TypeMismatch (tagOf a) "Buffer"
|
||||
readBuffer a = when (not $ isInstanceOfBuffer a) (throwError $ notBuffer a) $> unsafeFromForeign a
|
||||
in
|
||||
readBuffer <<< Raw.asForeign
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Interval where
|
||||
deserialize =
|
||||
let
|
||||
notInterval a = pure $ TypeMismatch (tagOf a) "Interval"
|
||||
readInterval a = when (not $ isInstanceOfInterval a) (throwError $ notInterval a) $> unsafeFromForeign a
|
||||
in
|
||||
readInterval <<< Raw.asForeign
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Milliseconds where
|
||||
deserialize = flip bind (liftMaybe invalidDuration) <<< map Interval.toDuration <<< deserialize
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Seconds where
|
||||
deserialize = flip bind (liftMaybe invalidDuration) <<< map Interval.toDuration <<< deserialize
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Minutes where
|
||||
deserialize = flip bind (liftMaybe invalidDuration) <<< map Interval.toDuration <<< deserialize
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Hours where
|
||||
deserialize = flip bind (liftMaybe invalidDuration) <<< map Interval.toDuration <<< deserialize
|
||||
|
||||
-- | `interval`
|
||||
instance Deserialize Days where
|
||||
deserialize = flip bind (liftMaybe invalidDuration) <<< map Interval.toDuration <<< deserialize
|
||||
|
||||
-- | `int2`, `int4`
|
||||
instance Deserialize Int where
|
||||
@@ -176,6 +249,10 @@ instance Deserialize DateTime where
|
||||
let invalid = pure $ ForeignError $ "Not a valid ISO8601 string: `" <> s <> "`"
|
||||
liftMaybe invalid $ DateTime.ISO.toDateTime $ wrap s
|
||||
|
||||
-- | `timestamp`, `timestamptz`
|
||||
instance Deserialize Instant where
|
||||
deserialize = map Instant.fromDateTime <<< deserialize
|
||||
|
||||
-- | postgres `array`
|
||||
instance Deserialize a => Deserialize (Array a) where
|
||||
deserialize = traverse (deserialize <<< Raw.unsafeFromForeign) <=< F.readArray <<< Raw.asForeign
|
||||
|
||||
65
src/Pipes.Postgres.purs
Normal file
65
src/Pipes.Postgres.purs
Normal file
@@ -0,0 +1,65 @@
|
||||
module Pipes.Postgres where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Error.Class (class MonadError, class MonadThrow, catchError, throwError)
|
||||
import Control.Monad.Postgres (class MonadPostgres)
|
||||
import Control.Monad.Reader (class MonadAsk, ask)
|
||||
import Data.Maybe (Maybe(..))
|
||||
import Effect.Aff.Class (class MonadAff, liftAff)
|
||||
import Effect.Aff.Postgres.Client as Client
|
||||
import Effect.Aff.Postgres.Pool (Pool)
|
||||
import Effect.Aff.Postgres.Pool as Pool
|
||||
import Effect.Class (liftEffect)
|
||||
import Effect.Exception (Error)
|
||||
import Node.Buffer (Buffer)
|
||||
import Node.Stream.Object as O
|
||||
import Pipes ((>->))
|
||||
import Pipes.Core (Consumer, Producer)
|
||||
import Pipes.Node.Stream (fromReadable, fromWritable)
|
||||
import Pipes.Prelude as Pipes
|
||||
|
||||
stdin
|
||||
:: forall m s c ct
|
||||
. MonadAff m
|
||||
=> MonadError Error m
|
||||
=> MonadAsk Pool m
|
||||
=> MonadPostgres m s c ct
|
||||
=> String
|
||||
-> Consumer (Maybe Buffer) m Unit
|
||||
stdin q = do
|
||||
pool <- ask
|
||||
client <- liftAff $ Pool.connect pool
|
||||
stream <- liftEffect $ Client.execWithStdin q client
|
||||
liftAff $ void $ Client.exec "begin" client
|
||||
let
|
||||
releaseOnEOS Nothing = do
|
||||
liftAff $ void $ Client.exec "commit" client
|
||||
liftEffect $ Pool.release pool client
|
||||
pure Nothing
|
||||
releaseOnEOS (Just a) = pure (Just a)
|
||||
|
||||
pipe = Pipes.mapM releaseOnEOS >-> fromWritable (O.unsafeFromBufferWritable stream)
|
||||
err e = do
|
||||
liftAff $ void $ Client.exec "rollback" client
|
||||
liftEffect $ Pool.release pool client
|
||||
throwError e
|
||||
|
||||
catchError pipe err
|
||||
|
||||
stdout
|
||||
:: forall m s c ct
|
||||
. MonadAff m
|
||||
=> MonadThrow Error m
|
||||
=> MonadAsk Pool m
|
||||
=> MonadPostgres m s c ct
|
||||
=> String
|
||||
-> Producer (Maybe Buffer) m Unit
|
||||
stdout q = do
|
||||
pool <- ask
|
||||
client <- liftAff $ Pool.connect pool
|
||||
stream <- liftEffect $ Client.queryWithStdout q client
|
||||
let
|
||||
releaseOnEOS Nothing = liftEffect $ Pool.release pool client $> Nothing
|
||||
releaseOnEOS (Just a) = pure (Just a)
|
||||
fromReadable (O.unsafeFromBufferReadable stream) >-> Pipes.mapM releaseOnEOS
|
||||
37
test/Test.Data.Postgres.Interval.purs
Normal file
37
test/Test.Data.Postgres.Interval.purs
Normal file
@@ -0,0 +1,37 @@
|
||||
module Test.Data.Postgres.Interval where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Data.Postgres.Interval as Interval
|
||||
import Data.Time.Duration (Milliseconds(..))
|
||||
import Data.Traversable (for_)
|
||||
import Data.Tuple.Nested (type (/\), (/\))
|
||||
import Effect.Class (liftEffect)
|
||||
import Test.Spec (Spec, describe, it)
|
||||
import Test.Spec.Assertions (shouldEqual)
|
||||
|
||||
spec :: Spec Unit
|
||||
spec =
|
||||
describe "Data.Postgres.Interval" do
|
||||
it "parse & toRecord" do
|
||||
p <- liftEffect $ Interval.parse "3 days 04:05:06"
|
||||
Interval.toRecord p `shouldEqual` Interval.zero {days = 3, hours = 4, minutes = 5, seconds = 6}
|
||||
|
||||
it "make & toRecord" do
|
||||
let p = Interval.make $ Interval.zero {days = 3, hours = 4, minutes = 5, seconds = 6}
|
||||
Interval.toRecord p `shouldEqual` Interval.zero {days = 3, hours = 4, minutes = 5, seconds = 6}
|
||||
|
||||
describe "fromDuration" do
|
||||
for_
|
||||
[ Milliseconds 100.0 /\ Interval.zero {milliseconds = 100.0}
|
||||
, Milliseconds 1000.0 /\ Interval.zero {seconds = 1}
|
||||
, Milliseconds 1100.0 /\ Interval.zero {seconds = 1, milliseconds = 100.0}
|
||||
, Milliseconds 60000.0 /\ Interval.zero {minutes = 1}
|
||||
, Milliseconds 61100.0 /\ Interval.zero {minutes = 1, seconds = 1, milliseconds = 100.0}
|
||||
, Milliseconds 3600000.0 /\ Interval.zero {hours = 1}
|
||||
, Milliseconds 3661100.0 /\ Interval.zero {hours = 1, minutes = 1, seconds = 1, milliseconds = 100.0}
|
||||
, Milliseconds 86400000.0 /\ Interval.zero {days = 1}
|
||||
, Milliseconds 90061100.0 /\ Interval.zero {days = 1, hours = 1, minutes = 1, seconds = 1, milliseconds = 100.0}
|
||||
]
|
||||
\(i /\ o) -> it ("converts " <> show i) do
|
||||
Interval.toRecord (Interval.fromDuration i) `shouldEqual` o
|
||||
@@ -2,28 +2,28 @@ module Test.Data.Postgres where
|
||||
|
||||
import Prelude
|
||||
|
||||
import Control.Monad.Gen (chooseInt, elements, oneOf)
|
||||
import Control.Monad.Gen (chooseFloat, chooseInt, elements, oneOf)
|
||||
import Control.Parallel (parTraverse_)
|
||||
import Data.Array (intercalate)
|
||||
import Data.Array as Array
|
||||
import Data.Array.NonEmpty as Array.NonEmpty
|
||||
import Data.DateTime (DateTime(..), canonicalDate)
|
||||
import Data.DateTime.Instant as Instant
|
||||
import Data.Enum (toEnum)
|
||||
import Data.Foldable (fold)
|
||||
import Data.Identity (Identity)
|
||||
import Data.Int as Int
|
||||
import Data.Maybe (Maybe(..), fromJust, maybe)
|
||||
import Data.Maybe (Maybe(..), fromJust, fromMaybe)
|
||||
import Data.Newtype (class Newtype, unwrap, wrap)
|
||||
import Data.Number (abs) as Number
|
||||
import Data.Postgres (class Rep)
|
||||
import Data.Postgres.Interval (Interval)
|
||||
import Data.Postgres.Interval as Interval
|
||||
import Data.Postgres.Query.Builder as Q
|
||||
import Data.Postgres.Raw (Raw, jsNull)
|
||||
import Data.Postgres.Raw as Raw
|
||||
import Data.Postgres.Result (class FromRow)
|
||||
import Data.RFC3339String as DateTime.ISO
|
||||
import Data.String as String
|
||||
import Data.Time (Time(..))
|
||||
import Data.Time.Duration (class Duration, Days, Hours, Milliseconds, Minutes, Seconds)
|
||||
import Data.Traversable (for, sequence)
|
||||
import Data.Tuple.Nested ((/\))
|
||||
import Effect (Effect)
|
||||
@@ -35,20 +35,45 @@ import Effect.Unsafe (unsafePerformEffect)
|
||||
import Foreign (Foreign, unsafeToForeign)
|
||||
import Foreign.Object as Object
|
||||
import JS.BigInt (BigInt)
|
||||
import JS.BigInt as BigInt
|
||||
import Node.Buffer (Buffer)
|
||||
import Node.Buffer as Buffer
|
||||
import Partial.Unsafe (unsafePartial)
|
||||
import Simple.JSON (writeJSON)
|
||||
import Test.Common (withClient, withPoolClient)
|
||||
import Test.Common (withPoolClient)
|
||||
import Test.QuickCheck (class Arbitrary, arbitrary, randomSeed)
|
||||
import Test.QuickCheck.Gen (sample, vectorOf)
|
||||
import Test.Spec (Spec, SpecT, around, describe, it, parallel)
|
||||
import Test.Spec (Spec, SpecT, around, describe, it)
|
||||
import Test.Spec.Assertions (fail)
|
||||
|
||||
foreign import readBigInt64BE :: Buffer -> Effect BigInt
|
||||
foreign import dbg :: forall a. a -> Effect Unit
|
||||
|
||||
newtype GenIntervalSubMonth = GenIntervalSubMonth Interval
|
||||
|
||||
derive instance Newtype GenIntervalSubMonth _
|
||||
instance Arbitrary GenIntervalSubMonth where
|
||||
arbitrary = do
|
||||
days <- chooseInt 0 30
|
||||
hours <- chooseInt 0 23
|
||||
minutes <- chooseInt 0 59
|
||||
seconds <- chooseInt 0 59
|
||||
milliseconds <- chooseFloat 0.0 999.9
|
||||
pure $ wrap $ Interval.make $ Interval.zero {days = days, hours = hours, minutes = minutes, seconds = seconds, milliseconds = milliseconds}
|
||||
|
||||
newtype GenInterval = GenInterval Interval
|
||||
|
||||
derive instance Newtype GenInterval _
|
||||
instance Arbitrary GenInterval where
|
||||
arbitrary = do
|
||||
years <- chooseInt 0 10
|
||||
months <- chooseInt 0 11
|
||||
days <- chooseInt 0 30
|
||||
hours <- chooseInt 0 23
|
||||
minutes <- chooseInt 0 59
|
||||
seconds <- chooseInt 0 59
|
||||
milliseconds <- chooseFloat 0.0 999.9
|
||||
pure $ wrap $ Interval.make {years, months, days, hours, minutes, seconds, milliseconds}
|
||||
|
||||
newtype GenSmallInt = GenSmallInt Int
|
||||
|
||||
derive instance Newtype GenSmallInt _
|
||||
@@ -196,6 +221,17 @@ spec =
|
||||
around withPoolClient
|
||||
$ describe "Data.Postgres"
|
||||
$ do
|
||||
let
|
||||
durationFromGenInterval :: forall d. Semigroup d => Duration d => Newtype d Number => GenIntervalSubMonth -> d
|
||||
durationFromGenInterval = fromMaybe (wrap 0.0) <<< Interval.toDuration <<< unwrap
|
||||
durationEq :: forall d. Duration d => Newtype d Number => d -> d -> Boolean
|
||||
durationEq a b = Number.abs (unwrap a - unwrap b) <= 0.001
|
||||
check @Milliseconds @GenIntervalSubMonth { purs: "Milliseconds", sql: "interval", fromArb: durationFromGenInterval, isEq: durationEq}
|
||||
check @Seconds @GenIntervalSubMonth { purs: "Seconds", sql: "interval", fromArb: durationFromGenInterval, isEq: durationEq}
|
||||
check @Minutes @GenIntervalSubMonth { purs: "Minutes", sql: "interval", fromArb: durationFromGenInterval, isEq: durationEq}
|
||||
check @Hours @GenIntervalSubMonth { purs: "Hours", sql: "interval", fromArb: durationFromGenInterval, isEq: durationEq}
|
||||
check @Days @GenIntervalSubMonth { purs: "Days", sql: "interval", fromArb: durationFromGenInterval, isEq: durationEq}
|
||||
|
||||
check @Int @GenSmallInt { purs: "Int", sql: "int2", fromArb: unwrap, isEq: eq }
|
||||
check @Int { purs: "Int", sql: "int4", fromArb: identity, isEq: eq }
|
||||
check @String @GenString { purs: "String", sql: "text", fromArb: unwrap, isEq: eq }
|
||||
|
||||
@@ -23,6 +23,7 @@ import Node.EventEmitter as Event
|
||||
import Test.Control.Monad.Postgres as Test.Control.Monad.Postgres
|
||||
import Test.Data.Postgres as Test.Data.Postgres
|
||||
import Test.Data.Postgres.Custom as Test.Data.Postgres.Custom
|
||||
import Test.Data.Postgres.Interval as Test.Data.Postgres.Interval
|
||||
import Test.Effect.Postgres.Client as Test.Effect.Postgres.Client
|
||||
import Test.Effect.Postgres.Pool as Test.Effect.Postgres.Pool
|
||||
import Test.Spec.Reporter (specReporter)
|
||||
@@ -65,6 +66,7 @@ main = launchAff_ do
|
||||
$ runSpec [ specReporter ] do
|
||||
Test.Data.Postgres.Custom.spec
|
||||
Test.Data.Postgres.spec
|
||||
Test.Data.Postgres.Interval.spec
|
||||
Test.Effect.Postgres.Client.spec
|
||||
Test.Effect.Postgres.Pool.spec
|
||||
Test.Control.Monad.Postgres.spec
|
||||
|
||||
Reference in New Issue
Block a user