purescript-selda icon indicating copy to clipboard operation
purescript-selda copied to clipboard

Add guide to the README

Open Kamirus opened this issue 4 years ago • 8 comments

Write an introductory guide explaining what selda can do, how to write some queries and how to use it in a real-life application.

Kamirus avatar Aug 28 '19 10:08 Kamirus

@JordanMartinez, do you have any suggestions on this topic? What should be included in the guide or maybe you had some problems using selda that you wished were explained in a README (or completely redesigned). Your opinion would be greatly appreciated :)

Kamirus avatar Aug 28 '19 10:08 Kamirus

Sure! Thanks for asking. Here's just the initial thoughts that come to mind.

I read over your thesis and looked through the test code to figure out how to use this library. It took a while to figure out, but I finally got there.

I'd say it needs to be redesigned to rely less upon your thesis. That paper does a good job explaining how you solve the problem, but it's not something a new user of this library needs to know right away.

Generally, "good" documentation is broken down into 4 levels:

  1. The Hook - why should I care? How is this library relevant to me? (i.e. your about statement but with a more detailed example showing exactly why a type-safe query is a really good thing)
  2. Getting Started - what dependencies do I need to install and how? How do I run a basic select query? (e.g. define a table, define the query, run the query)
  3. How-Tos / Tutorials - how do I do specific things? (use Auto/Default columns, use columns with newtyped types, use restrict, use aggregates functions, common patterns used, what errors can arise if I import the wrong function because it has the same name as a function in the correct module?)
  4. Implementation - what do I need to know in order to contribute? (e.g. what design decisions were made when implementing this and what are their tradeoffs? what are the main pieces to focus on?)

JordanMartinez avatar Aug 28 '19 15:08 JordanMartinez

Thanks for your detailed answer! We will start working on it as soon as we finish the current tasks

Kamirus avatar Aug 30 '19 08:08 Kamirus

Hi @JordanMartinez, I've made some progress. The README is slightly changed and it has a link to the guide (It is still WIP). I wanted to cover all the basics and essential features without explaining in-depth everything. If you have any opinions on that we would like to hear :wink:

Kamirus avatar Oct 14 '19 07:10 Kamirus

Sure. Here's some thoughts.

The Installation step in the ReadMe should also include the one-liner npm install pg decimal.js so people can run and install it. Ideally, purescript-postgresql-client would state that in their readme, but they don't. (When I originally tried this, I thought npm install decimal was the same thing as npm install decimal.js. Turns out it wasn't.)

I think the Setup section could be clearer about what must be true before the rest of that code will work. Stating this in a bullet point format will make it easier to see for a reader who is skimming through the guide:

  • a database named purspg exists
  • a user called init with password query has been created

If you add the commands one would run in bash as an example to set that up, it would be even better. However, there's a point where the reader should do their own research on how to do that if they don't know already.

Rather than using a people table as an initial introduction to tables, I would use metalanguage:

exampleTable :: Table 
          { autonumber :: Auto Int
          , someValue :: Int
          , valueWithDefault :: Default Int
          }
exampleTable = Table { name: "example_table" }

I wouldn't use this table in the rest of your examples. Rather, it would help explain what the column wrappers (i.e. Default, Auto) do.

Using a constraint constructor (Auto, Default) only affects insert operation. A column with Auto constraint cannot be inserted, while Default columns can be either omitted or provided. Other operations ignore these constraints and automatically unwrap it so queries return Int and not Auto Int.

I'd convert this paragraph into a table. Something like

Wrapper on insert...
None
(e.g. Int)
value is required
Default
(e.g. Default Int)
value is optional
Auto Int
(e.g. Auto Int)
value cannot be referenced

For the First Query part, I think it would be helpful to first see the SQL one would want to write, then show the PS code you would write to get the same result, and then show the outputted SQL the PS code creates.

Also, it would be helpful to see what the types are at various points (as long as they aren't too long). For example, rather than this

qNamesWithBalance
  ∷ ∀ s. FullQuery s { name ∷ Col s String , balance ∷ Col s (Maybe Int) }
qNamesWithBalance = 
  selectFrom people \{ id, name, age } → do
    { balance } ← leftJoin bankAccounts \acc → id .== acc.personId
    restrict $ id .> lit 1
    pure { name, balance }

you might have this:

qNamesWithBalance
  ∷ ∀ s. FullQuery s { name ∷ Col s String , balance ∷ Col s (Maybe Int) }
qNamesWithBalance = 
  selectFrom people leftJoinWhereAndSelectClauses
  where
  leftJoinWhereAndSelectClauses :: ?Full_Type_Goes_Here
  leftJoinWhereAndSelectClauses { id, name, age } = do
    { balance } ← leftJoin bankAccounts \acc → id .== acc.personId
    restrict $ id .> lit 1
    pure { name, balance } -- aka the SELECT statement

In the Type Errors section, perhaps show an example of code that is incorrect and highlight via a comment which part is incorrect. Then explain what error message it produces, why it's incorrect, and then give the corrected version. You already do this in the first part of it by referring back to the previous query (i.e. qCountBankAccountOwners), but it would be clearer if I saw the code again as an incorrect version rather than scrolling back up and having to figure out to reread it in light of your words.

I think overall it gives a good enough overview of the library. People will probably still need to read through your thesis to have a deeper understanding, but it is getting better.

JordanMartinez avatar Oct 15 '19 01:10 JordanMartinez

Thank you @JordanMartinez. I've applied some of your ideas :wink:

Kamirus avatar Oct 15 '19 18:10 Kamirus

I think that maybe few words about PG.Aff and PG.Class would be a good intro to the Execution section. What do you think?

paluh avatar Oct 21 '19 11:10 paluh

I think that also would be good to add a word in the same section about the fact that only backend which selda currently provides is the postgresql one and that insert and insert1 which are implemented in this context use RETURNING under the hood.

paluh avatar Nov 06 '19 08:11 paluh