Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get the underlying indicies for a Selector #148

Open
cdepillabout opened this issue Oct 4, 2020 · 0 comments
Open

get the underlying indicies for a Selector #148

cdepillabout opened this issue Oct 4, 2020 · 0 comments

Comments

@cdepillabout
Copy link
Contributor

I'd like to be able to get the underlying indices contained in a Selector.

It seems like the easiest thing to do here would be to expose the selectorIndex getter, possibly in Database.Selda.Unsafe.


My use-case for this is that I'd like to be able to programmatically generate the column name for a given selector and table.

I'd like to write a function like the following:

colNameFor :: Table t -> Selector t a -> SeldaUnsafe.QueryFragment
colNameFor tbl s =
  let colInfos = tableColumnInfos $ tableInfo tbl
      idx = selectorIndex s
      colInfo = colInfos !! idx
  in fromColName $ colName colInfo

I'd like to be able to have some minimal amount of schema checking when writing raw SQL.

For instance, I want to use a SELECT DISTINCT ON statement (which it appears Selda doesn't have support for).

I want to write a function like the following:

data Foo = Foo
  { name :: Text
  , a :: Text
  , b :: Text
  }

listFoos :: Query s (Row s Foo)
listFoos = do
  let colName' = colNameFor foosTable #name
      colA = colNameFor foosTable #a
      colB = colNameFor foosTable #b
      q =
        "SELECT DISTINCT ON ( " <> colName' <> ", " <> colA <> ", " <> colB <> ") * " <>
        "  FROM foos " <>
        "ORDER BY " <> colName' <> ", " <> colA <> ", " <> colB
      allColNames =
        fmap colName $ tableColumnInfos $ tableInfo foosTable
  rawQuery allColNames q

Using the colNameFor function is slightly safer than just writing something like the following:

listFoos' :: Query s (Row s Foo)
listFoos' = do
  let q =
        "SELECT DISTINCT ON ( name, a, b ) * " <>
        "  FROM foos " <>
        "ORDER BY name, a, b"
      allColNames =
        fmap colName $ tableColumnInfos $ tableInfo foosTable
  rawQuery allColNames q

colNameFor makes this listFoos slightly more robust in the case where columns have been renamed. When columns are renamed in the database, listFoos should fail to compile (because there will no longer be a matching IsLabel instance for the Table type), while listFoos' will continue to compile.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant