gajus / slonik-utilities

Utilities for manipulating data in PostgreSQL database using Slonik.
Other
32 stars 8 forks source link

Add "dictionary" query method #5

Open gajus opened 5 years ago

gajus commented 5 years ago

I find myself often repeating this pattern:

const dictionary = {};

const cinemaForeignSeatTypes = await connection.any(sql`
  SELECT fuid, id
  FROM cinema_foreign_seat_type
  WHERE cinema_id = ${cinemaId}
`);

for (const cinemaForeignSeatType of cinemaForeignSeatTypes) {
  dictionary[cinemaForeignSeatType.fuid] = cinemaForeignSeatType.id;
}

I think this pattern appears often enough to mandate for a convenience method dictionary, i.e.

const cinemaForeignSeatTypeDictionary = await connection.dictionary(sql`
  SELECT fuid, id
  FROM cinema_foreign_seat_type
  WHERE cinema_id = ${cinemaId}
`);

Object.keys(cinemaForeignSeatTypeDictionary); // `fuid` values
Object.values(cinemaForeignSeatTypeDictionary); // `id` values
gajus commented 5 years ago

This should also throw an error if keys are duplicate.

Sharaal commented 5 years ago

Maybe it's worth to make it more flexible by adding a formatter which formats the rows before returning them?

e.g.:

const formatter = rows => 
  rows.reduce(
    (obj, value) => {
      obj[value.id] = value
      return obj
    },
    {}
  )

const dictionary = await connection.any(
  sql`
    SELECT fuid, id
    FROM cinema_foreign_seat_type
    WHERE cinema_id = ${cinemaId}
  `,
  formatter
);

And giving a few formatter for few standard use cases like these { id: row } transformation or the more specialised use case if { firstColumn: secondColumn } transformation.

gajus commented 5 years ago

The reason this has remained an open issue is because it feels like an overly specialised feature, that likely better belongs in an abstraction such as https://github.com/gajus/slonik-utilities