Skip to content

Commit

Permalink
feat(postgres): add delete to collection key
Browse files Browse the repository at this point in the history
  • Loading branch information
calebmer committed Oct 9, 2016
1 parent 03185a9 commit 76c6a84
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 0 deletions.
36 changes: 36 additions & 0 deletions src/postgres/inventory/collection/PGCollectionKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,42 @@ class PGCollectionKey implements CollectionKey<PGObjectType.Value> {
return objectToMap(result.rows[0]['object'])
}
)

/**
* Deletes a value in our Postgres database using a given key. If no value
* could be deleted, an error will be thrown.
*
* This method, unlike many others in Postgres collections, is not batched.
*/
public delete = (
!this._pgClass.isDeletable
? null
: async (context: mixed, key: PGObjectType.Value): Promise<PGObjectType.Value> => {
// First things first, we need to get our Postgres client from the
// context. This means first verifying our client exists on the
// context.
if (!isPGContext(context)) throw isPGContext.error()
const { client } = context

// This is a pretty simple query. Delete the row that matches our key
// and return the deleted row.
const query = sql.compile(sql.query`
with deleted as (
delete from ${sql.identifier(this._pgNamespace.name, this._pgClass.name)}
where ${this._getSQLKeyCondition(key)}
returning *
)
select row_to_json(x) as object from deleted as x
`)()

const result = await client.query(query)

if (result.rowCount < 1)
throw new Error(`No values were deleted in collection '${this._collection.name}' using key '${this.name}'.`)

return objectToMap(result.rows[0]['object'])
}
)
}

export default PGCollectionKey
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,44 @@ test('update fails when trying to update a value that does not exist', async ()
expect(error.message).toBe('No values were updated in collection \'people\' using key \'email\'.')
}
})

test('delete will delete things from the database', async () => {
await client.query(`
insert into c.person (id, name, email, about) values
(1, 'John Smith', '[email protected]', null),
(2, 'Sara Smith', '[email protected]', null),
(3, 'Budd Deey', '[email protected]', 'Just a friendly human');
`)

await client.query(`
insert into c.compound_key (person_id_1, person_id_2) values
(1, 2),
(2, 1),
(3, 2),
(3, 1);
`)

const selectQuery = `
select row_to_json(x) as object from c.compound_key as x
union all
select row_to_json(x) as object from c.person as x
`

const { rows: initialRows } = await client.query(selectQuery)

const values = await Promise.all([
collectionKey1.delete({ client }, new Map([['person_id_1', 1], ['person_id_2', 2]])),
collectionKey1.delete({ client }, new Map([['person_id_1', 2], ['person_id_2', 1]])),
collectionKey1.delete({ client }, new Map([['person_id_1', 3], ['person_id_2', 1]])),
collectionKey2.delete({ client }, new Map([['email', '[email protected]']])),
])

expect(values.map(mapToObject)).toEqual([
{ 'person_id_1': 1, 'person_id_2': 2 },
{ 'person_id_1': 2, 'person_id_2': 1 },
{ 'person_id_1': 3, 'person_id_2': 1 },
{ 'id': 1, 'name': 'John Smith', 'email': '[email protected]', 'about': null, 'created_at': values[3].get('created_at') },
])

expect((await client.query(selectQuery)).rows).toEqual([initialRows[2], initialRows[5], initialRows[6]])
})

0 comments on commit 76c6a84

Please sign in to comment.