Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Reusing existing row decoder on aliased queries #332

Copy link
Copy link
@aveltras

Description

@aveltras
Issue body actions

Hi,

I'm trying to factorize some of my row decoding code and I'm wondering if something like the following is possible.

The following currently doesn't work because of overlapping instances (and maybe further errors down the road).

decodeUser ::
  forall pfx.
  ( KnownSymbol (AppendSymbol pfx "uid"),
    KnownSymbol (AppendSymbol pfx "email"),
    KnownSymbol (AppendSymbol pfx "fullname"),
    KnownSymbol (AppendSymbol pfx "position"),
    KnownSymbol (AppendSymbol pfx "location")
  ) =>
  DecodeRow
    '[ (AppendSymbol pfx "uid") ::: 'NotNull 'PGuuid,
       (AppendSymbol pfx "email") ::: 'NotNull 'PGtext,
       (AppendSymbol pfx "fullname") ::: 'NotNull 'PGtext,
       (AppendSymbol pfx "position") ::: 'Null 'PGtext,
       (AppendSymbol pfx "location") ::: 'Null 'PGtext
     ]
    User
decodeUser = do
  userId :: UserId <- fromLabel @(AppendSymbol pfx "uid")
  email <- unsafeAddress <$> fromLabel @(AppendSymbol pfx "email")
  fullName :: FullName <- fromLabel @(AppendSymbol pfx "fullname")
  position <- fromLabel @(AppendSymbol pfx "position")
  location <- fromLabel @(AppendSymbol pfx "location")
  pure $ User userId email $ PersonalInfo fullName (fromMaybe "" position) (fromMaybe "" location)

With the following schema

type UserTable =
  '[ "user_pk" ::: 'PrimaryKey '["uid"],
     "user_uk_email" ::: 'Unique '["email"],
     "user_fk_picture" ::: 'ForeignKey '["picture"] "public" "file" '["uid"]
   ]
    :=> '[ "uid" ::: 'NoDef :=> 'NotNull 'PGuuid,
           "email" ::: 'NoDef :=> 'NotNull 'PGtext,
           "created_at" ::: 'NoDef :=> 'NotNull 'PGtimestamptz,
           "updated_at" ::: 'NoDef :=> 'NotNull 'PGtimestamptz,
           "fullname" ::: 'NoDef :=> 'NotNull 'PGtext,
           "picture" ::: 'NoDef :=> 'Null 'PGuuid,
           "position" ::: 'NoDef :=> 'Null 'PGtext,
           "location" ::: 'NoDef :=> 'Null 'PGtext
         ]

And the following type

data User = User
  { id :: UserId,
    email :: EmailAddress,
    info :: PersonalInfo
  }

The intended use case is to be able to decode two different users for the same row, one would have all its columns prefixed by otheruser_ for example and the other one would have no prefix or "" as prefix.

In the decoder for the final type, I would then be able to decode both users as follow:

decoder = do
  userA <- decoderUser @""
  userB <- decoderUser @"otheruser_"
  pure $ MyFinalType userA userB
Reactions are currently unavailable

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.