Typesafe dynamic filtering/ordering/paging

Open
#8 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Stale
Tech stack
fsharp, sql

Research direction

The issue names no repository files or tests. Start by locating the SQL<...> generated-type path described here and trace how output columns are exposed. Done means eligible single-SELECT queries support type-safe By values, ordering, paging, and a command that preserves the applied clauses.

Written by the indexing model from the issue text.

Description

enhancement

Right now there is no way to dynamically order queries.

This makes the library unsuitable for applications that let the user sort a paged table of records.
That's a lot of applications!

This should be solvable without giving up type safety. Here's the design I have in mind:

Any command that consists of a single SELECT statement which is not known to be a single-row SELECT should be dynamically orderable.

e.g.

type MyQuery = SQL<"select Column1, 1+1 as Column2 from SomeTable">

This means that it gets the following extra stuff in its generated type:

  • A nested type MyQuery.By with a private constructor and an overrided ToString().
  • Static getters MyQuery.By.Column1 and MyQuery.By.Column2, which return instances of MyQuery.By
  • A static method MyQuery.By.OfString("Column1") which checks that the passed string is one of the statically known output column names. MyQuery.By.OfString(MyQuery.By.Column2.ToString()) should work.
  • A static OrderBy method taking a MyQuery.By and a DU Ascending|Descending and returning a MyQuery.OrderedQuery
  • MyQuery.OrderedQuery has an instance method ThenBy taking another by+direction, Page taking limit+offset
  • MyQuery.OrderedQuery has an instance Command method which is like the regular MyQuery.Command(param1 = ...) method, but includes the orderings applied so far

Hypothetical usage:

type MyQuery = SQL<"select Column1, 1+1 as Column2 from SomeTable where Name like @name">

let example (conn : ConnectionContext) =
    MyQuery
        .OrderBy(MyQuery.By.Column1, Ascending)
        .ThenBy(MyQuery.By.Column2, Descending)
        .Page(25, 50)
        .Command(name = "%a%")
        .Execute(conn)

I think it would be OK to limit to one ThenBy clause. Orderings more complicated than that don't make much sense to generate dynamically.

Thoughts?

Dominant language
F#
Stars
680
Forks
23
PR merge metrics
No merged PRs in 30d

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from fsprojects/Rezoom.SQL

All issues in fsprojects/Rezoom.SQL

Similar issues

More Compilers issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.