From 02b3f8da0744c915fd5282dfe13210bf2644e462 Mon Sep 17 00:00:00 2001 From: Evert Pot Date: Thu, 27 Oct 2022 01:45:42 -0400 Subject: [PATCH] ETags on entries. Just doing some experimentation with caching. No rush to merge --- README.md | 2 +- src/db-types.ts | 1 + src/entry/controller/item.ts | 12 ++++----- src/entry/formats/hal.ts | 3 +++ src/entry/service.ts | 26 ++++++++++++------- .../20221027052445_entry_version.ts | 24 +++++++++++++++++ src/types.ts | 3 ++- 7 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 src/migrations/20221027052445_entry_version.ts diff --git a/README.md b/README.md index 07a096f..c82ea0f 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ mysql> FLUSH PRIVILEGES; Populate the database using knex, which should add tables automatically.
``` -knex --knexfile src/knexfile.ts migrate:latest +make knex-migrate ``` This should populate your database with the required tables. diff --git a/src/db-types.ts b/src/db-types.ts index a5925a3..384d1c6 100644 --- a/src/db-types.ts +++ b/src/db-types.ts @@ -31,6 +31,7 @@ export type EntriesRecord = { billable: number; created_at: Date; modified_at: Date; + version: number; } export type PeopleRecord = { diff --git a/src/entry/controller/item.ts b/src/entry/controller/item.ts index 64f3ab6..253fdb6 100644 --- a/src/entry/controller/item.ts +++ b/src/entry/controller/item.ts @@ -18,13 +18,13 @@ class Entry extends Controller { const person = await personService.findById( +ctx.params.personId, ); - - ctx.response.body = hal.item( - await entryService.findById( - person, - +ctx.params.entryId, - ) + const entry = await entryService.findById( + person, + +ctx.params.entryId, ); + + ctx.response.body = hal.item(entry); + ctx.response.headers.set('ETag', '"' + entry.version + '"'); } async put(ctx: Context) { diff --git a/src/entry/formats/hal.ts b/src/entry/formats/hal.ts index ed9bfec..64ec874 100644 --- a/src/entry/formats/hal.ts +++ b/src/entry/formats/hal.ts @@ -50,6 +50,9 @@ export function item(entry: Entry) { href: entry.person.href } }, + _headers: { + ETag: '"' + entry.version + '"', + }, description: entry.description, date: entry.date, minutes: entry.minutes, diff --git a/src/entry/service.ts b/src/entry/service.ts index 84f642b..d59d42d 100644 --- a/src/entry/service.ts +++ b/src/entry/service.ts @@ -135,13 +135,15 @@ export async function create(entry: NewEntry): Promise { description: entry.description, billable: entry.billable, created_at: new Date(), - modified_at: new Date() + modified_at: new Date(), + version: 1, }); return { ...entry, id: result[0], href: `/person/${entry.person.id}/entry/${result[0]}`, + version: 1, createdAt: new Date(), modifiedAt: new Date() }; @@ -150,14 +152,17 @@ export async function create(entry: NewEntry): Promise { export async function update(entry: Entry): Promise { - await knex('entries').update({ - project_id: entry.project.id, - date: entry.date, - minutes: entry.minutes, - description: entry.description, - billable: entry.billable, - modified_at: new Date() - }).where({id: entry.id}); + await knex('entries') + .update({ + project_id: entry.project.id, + date: entry.date, + minutes: entry.minutes, + description: entry.description, + billable: entry.billable, + modified_at: new Date(), + }) + .increment('version', 1) + .where({id: entry.id}); } @@ -180,7 +185,8 @@ function mapRecord(input: EntriesRecord, project: Project, person: Person): Entr description: input.description, billable: !!input.billable, createdAt: input.created_at, - modifiedAt: input.modified_at + modifiedAt: input.modified_at, + version: input.version, }; } diff --git a/src/migrations/20221027052445_entry_version.ts b/src/migrations/20221027052445_entry_version.ts new file mode 100644 index 0000000..859068f --- /dev/null +++ b/src/migrations/20221027052445_entry_version.ts @@ -0,0 +1,24 @@ +import { Knex } from 'knex'; + + +export async function up(knex: Knex): Promise { + + await knex.schema.alterTable('entries', table => { + + table.integer('version').unsigned().notNullable().defaultTo(1); + + }); + +} + + +export async function down(knex: Knex): Promise { + + await knex.schema.alterTable('entries', table => { + + table.dropColumn('version'); + + }); + +} + diff --git a/src/types.ts b/src/types.ts index cfc0fd7..ea4650a 100644 --- a/src/types.ts +++ b/src/types.ts @@ -50,8 +50,9 @@ export type Entry = { modifiedAt: Date; createdAt: Date; + version: number; } export type NewEntry = - Omit; + Omit;