generated from tpl/purs
fix: client, result bindings
This commit is contained in:
parent
753d14fdd9
commit
d7916683d7
24
spago.lock
24
spago.lock
@ -3,6 +3,7 @@ workspace:
|
|||||||
pg:
|
pg:
|
||||||
path: ./
|
path: ./
|
||||||
dependencies:
|
dependencies:
|
||||||
|
- aff-promise
|
||||||
- bifunctors
|
- bifunctors
|
||||||
- control
|
- control
|
||||||
- datetime
|
- datetime
|
||||||
@ -15,6 +16,8 @@ workspace:
|
|||||||
- mmorph
|
- mmorph
|
||||||
- newtype
|
- newtype
|
||||||
- node-buffer
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- nullable
|
||||||
- precise-datetime
|
- precise-datetime
|
||||||
- prelude
|
- prelude
|
||||||
- simple-json
|
- simple-json
|
||||||
@ -27,6 +30,7 @@ workspace:
|
|||||||
- spec-quickcheck
|
- spec-quickcheck
|
||||||
build_plan:
|
build_plan:
|
||||||
- aff
|
- aff
|
||||||
|
- aff-promise
|
||||||
- ansi
|
- ansi
|
||||||
- arraybuffer-types
|
- arraybuffer-types
|
||||||
- arrays
|
- arrays
|
||||||
@ -66,6 +70,7 @@ workspace:
|
|||||||
- mmorph
|
- mmorph
|
||||||
- newtype
|
- newtype
|
||||||
- node-buffer
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
- nonempty
|
- nonempty
|
||||||
- now
|
- now
|
||||||
- nullable
|
- nullable
|
||||||
@ -122,6 +127,13 @@ packages:
|
|||||||
- tailrec
|
- tailrec
|
||||||
- transformers
|
- transformers
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
|
aff-promise:
|
||||||
|
type: registry
|
||||||
|
version: 4.0.0
|
||||||
|
integrity: sha256-Kq5EupbUpXeUXx4JqGQE7/RTTz/H6idzWhsocwlEFhM=
|
||||||
|
dependencies:
|
||||||
|
- aff
|
||||||
|
- foreign
|
||||||
ansi:
|
ansi:
|
||||||
type: registry
|
type: registry
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
@ -540,6 +552,18 @@ packages:
|
|||||||
- nullable
|
- nullable
|
||||||
- st
|
- st
|
||||||
- unsafe-coerce
|
- unsafe-coerce
|
||||||
|
node-event-emitter:
|
||||||
|
type: registry
|
||||||
|
version: 3.0.0
|
||||||
|
integrity: sha256-Qw0MjsT4xRH2j2i4K8JmRjcMKnH5z1Cw39t00q4LE4w=
|
||||||
|
dependencies:
|
||||||
|
- effect
|
||||||
|
- either
|
||||||
|
- functions
|
||||||
|
- maybe
|
||||||
|
- nullable
|
||||||
|
- prelude
|
||||||
|
- unsafe-coerce
|
||||||
nonempty:
|
nonempty:
|
||||||
type: registry
|
type: registry
|
||||||
version: 7.0.0
|
version: 7.0.0
|
||||||
|
@ -4,6 +4,7 @@ package:
|
|||||||
strict: true
|
strict: true
|
||||||
pedantic_packages: true
|
pedantic_packages: true
|
||||||
dependencies:
|
dependencies:
|
||||||
|
- aff-promise
|
||||||
- bifunctors
|
- bifunctors
|
||||||
- control
|
- control
|
||||||
- datetime
|
- datetime
|
||||||
@ -16,6 +17,8 @@ package:
|
|||||||
- mmorph
|
- mmorph
|
||||||
- newtype
|
- newtype
|
||||||
- node-buffer
|
- node-buffer
|
||||||
|
- node-event-emitter
|
||||||
|
- nullable
|
||||||
- precise-datetime
|
- precise-datetime
|
||||||
- prelude
|
- prelude
|
||||||
- simple-json
|
- simple-json
|
||||||
|
@ -1,23 +0,0 @@
|
|||||||
module Data.Postgres.Geometry where
|
|
||||||
|
|
||||||
import Prelude
|
|
||||||
|
|
||||||
import Data.Generic.Rep (class Generic)
|
|
||||||
import Data.Newtype (class Newtype)
|
|
||||||
import Data.Show.Generic (genericShow)
|
|
||||||
|
|
||||||
newtype Point = Point { x :: Number, y :: Number }
|
|
||||||
|
|
||||||
derive instance Newtype Point _
|
|
||||||
derive instance Generic Point _
|
|
||||||
derive instance Eq Point
|
|
||||||
instance Show Point where
|
|
||||||
show = genericShow
|
|
||||||
|
|
||||||
newtype Circle = Circle { center :: Point, radius :: Number }
|
|
||||||
|
|
||||||
derive instance Newtype Circle _
|
|
||||||
derive instance Generic Circle _
|
|
||||||
derive instance Eq Circle
|
|
||||||
instance Show Circle where
|
|
||||||
show = genericShow
|
|
@ -72,6 +72,10 @@ unsafeSerializeCoerce = pure <<< Raw.unsafeFromForeign <<< F.unsafeToForeign
|
|||||||
instance Serialize Raw where
|
instance Serialize Raw where
|
||||||
serialize = pure
|
serialize = pure
|
||||||
|
|
||||||
|
-- | Serializes as `Null`.
|
||||||
|
instance Serialize Unit where
|
||||||
|
serialize _ = serialize Null
|
||||||
|
|
||||||
instance Serialize Null where
|
instance Serialize Null where
|
||||||
serialize _ = unsafeSerializeCoerce null_
|
serialize _ = unsafeSerializeCoerce null_
|
||||||
|
|
||||||
@ -110,6 +114,14 @@ instance Serialize a => Serialize (Array a) where
|
|||||||
instance Deserialize Raw where
|
instance Deserialize Raw where
|
||||||
deserialize = pure
|
deserialize = pure
|
||||||
|
|
||||||
|
-- | Note: this will always succeed, discarding
|
||||||
|
-- | the actual raw value yielded.
|
||||||
|
-- |
|
||||||
|
-- | To explicitly deserialize NULL values and fail
|
||||||
|
-- | when the value is non-null, use `Null`.
|
||||||
|
instance Deserialize Unit where
|
||||||
|
deserialize _ = pure unit
|
||||||
|
|
||||||
instance Deserialize Null where
|
instance Deserialize Null where
|
||||||
deserialize = map (const Null) <<< F.readNullOrUndefined <<< Raw.unsafeToForeign
|
deserialize = map (const Null) <<< F.readNullOrUndefined <<< Raw.unsafeToForeign
|
||||||
|
|
||||||
|
8
src/Effect.Aff.Postgres.Client.js
Normal file
8
src/Effect.Aff.Postgres.Client.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/** @type {(c: import('pg').Client) => () => Promise<void>} */
|
||||||
|
export const connectImpl = c => () => c.connect()
|
||||||
|
|
||||||
|
/** @type {(c: import('pg').Client) => () => Promise<void>} */
|
||||||
|
export const endImpl = c => () => c.end()
|
||||||
|
|
||||||
|
/** @type {(q: import('pg').QueryConfig) => (c: import('pg').Client) => () => Promise<import('pg').QueryResult>} */
|
||||||
|
export const queryImpl = q => c => () => c.query(q)
|
55
src/Effect.Aff.Postgres.Client.purs
Normal file
55
src/Effect.Aff.Postgres.Client.purs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
module Effect.Aff.Postgres.Client where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Control.Promise (Promise)
|
||||||
|
import Control.Promise as Promise
|
||||||
|
import Data.Maybe (Maybe(..))
|
||||||
|
import Data.Nullable (Nullable, toNullable)
|
||||||
|
import Data.Postgres.Raw (Raw)
|
||||||
|
import Data.Tuple.Nested (type (/\), (/\))
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Aff (Aff)
|
||||||
|
import Effect.Postgres.Client (Client)
|
||||||
|
import Effect.Postgres.Result (Result)
|
||||||
|
import Record (insert, modify)
|
||||||
|
import Type.Prelude (Proxy(..))
|
||||||
|
|
||||||
|
type QueryRaw = { text :: String, values :: Array Raw, name :: Nullable String, rowMode :: String }
|
||||||
|
|
||||||
|
foreign import connectImpl :: Client -> Effect (Promise Unit)
|
||||||
|
foreign import endImpl :: Client -> Effect (Promise Unit)
|
||||||
|
foreign import queryImpl :: QueryRaw -> Client -> Effect (Promise Result)
|
||||||
|
|
||||||
|
newtype Query = Query { text :: String, values :: Array Raw, name :: Maybe String }
|
||||||
|
|
||||||
|
queryToRaw :: Query -> QueryRaw
|
||||||
|
queryToRaw (Query r) =
|
||||||
|
let
|
||||||
|
name = Proxy @"name"
|
||||||
|
rowMode = Proxy @"rowMode"
|
||||||
|
in
|
||||||
|
insert rowMode "array"
|
||||||
|
$ modify name toNullable
|
||||||
|
$ r
|
||||||
|
|
||||||
|
class AsQuery a where
|
||||||
|
asQuery :: a -> Query
|
||||||
|
|
||||||
|
instance AsQuery Query where
|
||||||
|
asQuery = identity
|
||||||
|
|
||||||
|
instance AsQuery String where
|
||||||
|
asQuery text = Query { text, values: [], name: Nothing }
|
||||||
|
|
||||||
|
instance AsQuery (String /\ Array Raw) where
|
||||||
|
asQuery (text /\ values) = Query { text, values, name: Nothing }
|
||||||
|
|
||||||
|
connect :: Client -> Aff Unit
|
||||||
|
connect = Promise.toAffE <<< connectImpl
|
||||||
|
|
||||||
|
end :: Client -> Aff Unit
|
||||||
|
end = Promise.toAffE <<< endImpl
|
||||||
|
|
||||||
|
query :: forall q. AsQuery q => q -> Client -> Aff Result
|
||||||
|
query q = Promise.toAffE <<< queryImpl (queryToRaw $ asQuery q)
|
23
src/Effect.Postgres.Client.js
Normal file
23
src/Effect.Postgres.Client.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {Client} from 'pg'
|
||||||
|
|
||||||
|
/** @typedef {{statementTimeout: unknown, queryTimeout: unknown, idleInTransactionTimeout: unknown, connectionTimeout: unknown, applicationName: string}} ClientConfigExtra */
|
||||||
|
|
||||||
|
/** @type {(_: {unwrapMillis: (_m: unknown) => number}) => (cfg: import('pg').ClientConfig & ClientConfigExtra) => () => Client} */
|
||||||
|
export const makeImpl = ({unwrapMillis}) => cfg => () => {
|
||||||
|
if ('statementTimeout' in cfg) {
|
||||||
|
cfg.statement_timeout = unwrapMillis(cfg.statementTimeout)
|
||||||
|
}
|
||||||
|
if ('queryTimeout' in cfg) {
|
||||||
|
cfg.query_timeout = unwrapMillis(cfg.queryTimeout)
|
||||||
|
}
|
||||||
|
if ('idleInTransactionTimeout' in cfg) {
|
||||||
|
cfg.idle_in_transaction_session_timeout = unwrapMillis(cfg.idleInTransactionTimeout)
|
||||||
|
}
|
||||||
|
if ('connectionTimeout' in cfg) {
|
||||||
|
cfg.connectionTimeoutMillis = unwrapMillis(cfg.connectionTimeout)
|
||||||
|
}
|
||||||
|
if ('applicationName' in cfg) {
|
||||||
|
cfg.application_name = cfg.applicationName
|
||||||
|
}
|
||||||
|
return new Client(cfg)
|
||||||
|
}
|
70
src/Effect.Postgres.Client.purs
Normal file
70
src/Effect.Postgres.Client.purs
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
module Effect.Postgres.Client where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Data.Maybe (Maybe)
|
||||||
|
import Data.Newtype (unwrap)
|
||||||
|
import Data.Nullable (Nullable)
|
||||||
|
import Data.Nullable as Nullable
|
||||||
|
import Data.Postgres (modifyPgTypes)
|
||||||
|
import Data.Time.Duration (Milliseconds)
|
||||||
|
import Effect (Effect)
|
||||||
|
import Effect.Exception (Error)
|
||||||
|
import Effect.Uncurried (EffectFn1, mkEffectFn1)
|
||||||
|
import Foreign (Foreign, unsafeToForeign)
|
||||||
|
import Node.EventEmitter (EventHandle(..))
|
||||||
|
import Node.EventEmitter.UtilTypes (EventHandle1, EventHandle0)
|
||||||
|
import Prim.Row (class Union)
|
||||||
|
import Record (modify)
|
||||||
|
import Type.Prelude (Proxy(..))
|
||||||
|
|
||||||
|
foreign import data Client :: Type
|
||||||
|
foreign import makeImpl :: { unwrapMillis :: Milliseconds -> Number } -> Foreign -> Effect Client
|
||||||
|
|
||||||
|
type Notification =
|
||||||
|
{ processId :: Number
|
||||||
|
, channel :: String
|
||||||
|
, payload :: Maybe String
|
||||||
|
}
|
||||||
|
|
||||||
|
type NotificationRaw =
|
||||||
|
{ processId :: Number
|
||||||
|
, channel :: String
|
||||||
|
, payload :: Nullable String
|
||||||
|
}
|
||||||
|
|
||||||
|
type Config r =
|
||||||
|
( user :: String
|
||||||
|
, password :: String
|
||||||
|
, host :: String
|
||||||
|
, port :: Number
|
||||||
|
, database :: String
|
||||||
|
, connectionString :: String
|
||||||
|
, applicationName :: String
|
||||||
|
, statementTimeout :: Milliseconds
|
||||||
|
, queryTimeout :: Milliseconds
|
||||||
|
, connectionTimeout :: Milliseconds
|
||||||
|
, idleInTransactionTimeout :: Milliseconds
|
||||||
|
| r
|
||||||
|
)
|
||||||
|
|
||||||
|
make :: forall r trash. Union r trash (Config ()) => Record r -> Effect Client
|
||||||
|
make r = do
|
||||||
|
modifyPgTypes
|
||||||
|
makeImpl { unwrapMillis: unwrap } $ unsafeToForeign r
|
||||||
|
|
||||||
|
error :: EventHandle1 Client Error
|
||||||
|
error = EventHandle "end" mkEffectFn1
|
||||||
|
|
||||||
|
notice :: EventHandle1 Client Error
|
||||||
|
notice = EventHandle "notice" mkEffectFn1
|
||||||
|
|
||||||
|
end :: EventHandle0 Client
|
||||||
|
end = EventHandle "end" identity
|
||||||
|
|
||||||
|
notification :: EventHandle Client (Notification -> Effect Unit) (EffectFn1 NotificationRaw Unit)
|
||||||
|
notification =
|
||||||
|
let
|
||||||
|
payload = Proxy @"payload"
|
||||||
|
in
|
||||||
|
EventHandle "notification" (\f -> mkEffectFn1 $ f <<< modify payload Nullable.toMaybe)
|
5
src/Effect.Postgres.Result.js
Normal file
5
src/Effect.Postgres.Result.js
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
/** @type {(_: import('pg').QueryResult) => Array<unknown>} */
|
||||||
|
export const rows = r => r.rows
|
||||||
|
|
||||||
|
/** @type {(_: import('pg').QueryResult) => number | null} */
|
||||||
|
export const rowsAffectedImpl = r => r.rowCount
|
17
src/Effect.Postgres.Result.purs
Normal file
17
src/Effect.Postgres.Result.purs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
module Effect.Postgres.Result where
|
||||||
|
|
||||||
|
import Prelude
|
||||||
|
|
||||||
|
import Data.Int as Int
|
||||||
|
import Data.Maybe (Maybe)
|
||||||
|
import Data.Nullable (Nullable)
|
||||||
|
import Data.Nullable as Nullable
|
||||||
|
import Data.Postgres.Raw (Raw)
|
||||||
|
|
||||||
|
foreign import data Result :: Type
|
||||||
|
|
||||||
|
foreign import rowsAffectedImpl :: Result -> Nullable Number
|
||||||
|
foreign import rows :: Result -> Array (Array Raw)
|
||||||
|
|
||||||
|
rowsAffected :: Result -> Maybe Int
|
||||||
|
rowsAffected = Int.fromNumber <=< Nullable.toMaybe <<< rowsAffectedImpl
|
@ -1,4 +1,7 @@
|
|||||||
module Effect.Pg where
|
module Effect.Postgres where
|
||||||
|
|
||||||
import Prelude
|
import Prelude
|
||||||
|
|
||||||
|
import Data.Time.Duration (Milliseconds)
|
||||||
|
|
||||||
|
foreign import data Pool :: Type
|
||||||
|
@ -59,15 +59,15 @@ spec =
|
|||||||
describe "JSON" do
|
describe "JSON" do
|
||||||
describe "Record" do
|
describe "Record" do
|
||||||
it "deserialize" $
|
it "deserialize" $
|
||||||
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array {"foo" :: String}) -> unsafePerformEffect do
|
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array { "foo" :: String }) -> unsafePerformEffect do
|
||||||
let
|
let
|
||||||
obj = {a, b, c}
|
obj = { a, b, c }
|
||||||
json = writeJSON obj
|
json = writeJSON obj
|
||||||
act :: JSON _ <- smash $ deserialize $ asRaw json
|
act :: JSON _ <- smash $ deserialize $ asRaw json
|
||||||
pure $ obj ==? unwrap act
|
pure $ obj ==? unwrap act
|
||||||
it "serialize" $
|
it "serialize" $
|
||||||
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array {"foo" :: String}) -> unsafePerformEffect do
|
quickCheck \(a /\ b /\ c :: Int /\ String /\ Array { "foo" :: String }) -> unsafePerformEffect do
|
||||||
let obj = {a, b, c}
|
let obj = { a, b, c }
|
||||||
act <- smash $ serialize $ JSON obj
|
act <- smash $ serialize $ JSON obj
|
||||||
pure $ asRaw (writeJSON obj) ==? act
|
pure $ asRaw (writeJSON obj) ==? act
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user