Skip to content

Commit

Permalink
Merge pull request #19 from mappies/returnValue
Browse files Browse the repository at this point in the history
Added .returning()
  • Loading branch information
mappies authored Jul 14, 2024
2 parents 3724d9a + 0890245 commit 45b9b9d
Show file tree
Hide file tree
Showing 40 changed files with 1,182 additions and 73 deletions.
45 changes: 42 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,13 @@ let user1 = await nodenamo.get(1).from(User).execute<User>();

//Update the user
user1.name = 'This One';
await nodenamo.update(user1).from(User).execute();
/* Returns { items: [ User { id: 1, name: 'This One', email: '[email protected]' } ],
lastEvaluatedKey: undefined } */
let originalUser = await nodenamo.update(user1).from(User).returning(ReturnValue.AllOld).execute();
/* Returns User { id: 1, name: 'Some One', email: '[email protected]' } */

//List all users
let users = await nodenamo.list().from(User).execute<User>();
/* Returns { items: [ User { id: 1, name: 'This One', email: '[email protected]' } ],
lastEvaluatedKey: undefined } */

//Delete the user by id
await nodenamo.delete(1).from(User).execute();
Expand Down Expand Up @@ -193,6 +194,44 @@ where:
* `range` is the prefix value of a range key defined by `@DBColumn({range:true})`
* `indexName` is the name of an index to be used with the query.

### <a name='Update'>Update an object</a>

Get an object from DynamoDB by the object's ID

```javascript
// Update an object
await nodenamo.update(object).from(T).execute<T>();

// Update an object with a condition expression
await nodenamo.update(object).from(T).where(conditionExpression, expressionAttributeNames, expressionAttributeValues).execute<T>();

// Update an object and requesting for a return value.
import { ReturnValue } from 'nodenamo';

await nodenamo.update(object).from(T).returning(ReturnValue.AllOld).execute<T>();

// Update an object with a version check
await nodenamo.update(object).from(T).withVersionCheck().execute<T>();

/***
* All operations above can be chained together.
***/
await nodenamo.update(obj)
.from(T)
.where(conditionExpression, expressionAttributeNames, expressionAttributeValues)
.withVersionCheck()
.returning(ReturnValue.AllNew)
.execute<T>();

```

where:
* `obj` is an object retrieved from the <a href='#Get'>Get</a> or <a href='#List'>List</a> operations or an object created from a class decorated with `@DBTable()`
* `T` is a class decorated with `@DBTable()`
* `conditionExpression` is a string representing a conditional expression for DynamoDB's PUT operation. For example, `"#name = :name"`
* `expressionAttributeNames` is an object representing attribute names for the conditionExpression. For example, `{ '#name': 'name' }`
* `expressionAttributeValues` is an object representing attribute values for the conditionExpression. For example, `{ ':name': 'Some One' }`

### Delete an object<a name='Delete'></a>

Delete an object from DynamoDB by the object's ID.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "nodenamo",
"version": "2.1.0",
"version": "2.2.0",
"description": "A powerful ORM for DynamoDb",
"main": "dist/index.js",
"typings": "dist/index",
Expand Down
68 changes: 66 additions & 2 deletions spec/acceptance/customNameTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {assert as assert} from 'chai';
import { DBTable, DBColumn } from '../../src';
import { NodeNamo } from '../../src/nodeNamo';
import Config from './config';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { ReturnValue } from '../../src/interfaces/returnValue';

@DBTable({name:'nodenamo_acceptance_targetNameTest'})
class User
Expand Down Expand Up @@ -261,7 +261,9 @@ describe('Custom-name tests', function ()

user.name = 'This Three';
user['extra'] = 'invalid';
await nodenamo.update(user).from(User).execute();
let result = await nodenamo.update(user).from(User).execute();

assert.isUndefined(result);

user = await nodenamo.get(3).from(User).execute();
assert.deepEqual(user, { id: 3, name: 'This Three', account: 2000, created: 2018, department: 'development', enabled: false });
Expand Down Expand Up @@ -300,6 +302,31 @@ describe('Custom-name tests', function ()
assert.deepEqual(user, { id: 6, name: '', account: 3000, created: 2020, department: 'hr', enabled: true });
});

it('Update an item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.AllOld).execute();

assert.deepEqual(result, originalUser);
});

it('Update an item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newest Two'}).from(User).returning(ReturnValue.AllNew).execute();

assert.deepEqual(result, {...originalUser, name: 'Newest Two'});
});

it('Update an item - return None', async () =>
{
let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.None).execute();

assert.isUndefined(result);
});

it('On item', async () =>
{
let user = await nodenamo.get(6).from(User).execute<User>();
Expand All @@ -314,6 +341,43 @@ describe('Custom-name tests', function ()
assert.deepEqual(user, {id:6, name: 'Mr. Six', account: 3000, created: 2020, department: 'hr', enabled: true });
});

it('On item - return None', async () =>
{
let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - None'})
.returning(ReturnValue.None)
.execute();

assert.isUndefined(result);
});

it('On item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllOld'})
.returning(ReturnValue.AllOld)
.execute();

assert.deepEqual(result, originalUser);
});

it('On item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllNew'})
.returning(ReturnValue.AllNew)
.execute();

assert.deepEqual(result, {...originalUser, name: 'That name - AllNew'});
});

it('Delete an item', async () =>
{
assert.isDefined(await nodenamo.get(1).from(User).execute());
Expand Down
4 changes: 3 additions & 1 deletion spec/acceptance/globalTableTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,9 @@ describe('Global table tests', function ()
assert.deepEqual(book, { id: 2, title: 'Another Book' });

user.name = 'This Two';
await nodenamo.update(user).from(User).execute();
let result = await nodenamo.update(user).from(User).execute();

assert.isUndefined(result);

user = await nodenamo.get(2).from(User).execute();
assert.deepEqual(user, { id: 2, name: 'This Two' });
Expand Down
82 changes: 80 additions & 2 deletions spec/acceptance/hashRangePairTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {assert as assert} from 'chai';
import { DBTable, DBColumn } from '../../src';
import { NodeNamo } from '../../src/nodeNamo';
import Config from './config';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { ReturnValue } from '../../src/interfaces/returnValue';

@DBTable({name:'nodenamo_acceptance_hashRangePairTest'})
class User
Expand Down Expand Up @@ -283,7 +283,9 @@ describe('Hash-range pair tests', function ()

user.name = 'This Three';
user['extra'] = 'invalid';
await nodenamo.update(user).from(User).execute();
let result = await nodenamo.update(user).from(User).execute();

assert.isUndefined(result);

user = await nodenamo.get(3).from(User).execute();
assert.deepEqual(user, { id: 3, name: 'This Three', account: 2000, created: 2018, parentId: 300 });
Expand Down Expand Up @@ -361,6 +363,45 @@ describe('Hash-range pair tests', function ()
assert.deepEqual(user, { id: 6, name: '', account: 3000, created: 2020, parentId: 600 });
});

it('Update an item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.AllOld).execute();

assert.deepEqual(result, originalUser);
});

it('Update an item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newest Two'}).from(User).returning(ReturnValue.AllNew).execute();

assert.deepEqual(result, {...originalUser, name: 'Newest Two'});
});

it('Update an item - return None', async () =>
{
let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.None).execute();

assert.isUndefined(result);
});

it('Update an item - with all combinations', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Another Two'})
.from(User)
.where('#account=:account', {'#account': 'account'}, {':account': originalUser.account})
.returning(ReturnValue.AllOld)
.withVersionCheck()
.execute();

assert.deepEqual(result, originalUser);
});

it('On item', async () =>
{
let user = await nodenamo.get(6).from(User).execute<User>();
Expand All @@ -375,6 +416,43 @@ describe('Hash-range pair tests', function ()
assert.deepEqual(user, {id:6, name: 'Mr. Six', account: 3000, created: 2020, parentId: 600 });
});

it('On item - return None', async () =>
{
let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - None'})
.returning(ReturnValue.None)
.execute();

assert.isUndefined(result);
});

it('On item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllOld'})
.returning(ReturnValue.AllOld)
.execute();

assert.deepEqual(result, originalUser);
});

it('On item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllNew'})
.returning(ReturnValue.AllNew)
.execute();

assert.deepEqual(result, {...originalUser, name: 'That name - AllNew'});
});

it('Delete an item', async () =>
{
assert.isDefined(await nodenamo.get(1).from(User).execute());
Expand Down
82 changes: 80 additions & 2 deletions spec/acceptance/hashRangeTest.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {assert as assert} from 'chai';
import { DBTable, DBColumn } from '../../src';
import { NodeNamo } from '../../src/nodeNamo';
import Config from './config';
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { ReturnValue } from '../../src/interfaces/returnValue';

@DBTable({name:'nodenamo_acceptance_hashRangeTest'})
class User
Expand Down Expand Up @@ -361,7 +361,9 @@ describe('Hash-range tests', function ()

user.name = 'This Three';
user['extra'] = 'invalid';
await nodenamo.update(user).from(User).execute();
let result = await nodenamo.update(user).from(User).execute();

assert.isUndefined(result);

user = await nodenamo.get(3).from(User).execute();
assert.deepEqual(user, { id: 3, name: 'This Three', account: 2000, created: 2018 });
Expand Down Expand Up @@ -440,6 +442,45 @@ describe('Hash-range tests', function ()
assert.deepEqual(user, { id: 6, name: '', account: 3000, created: 2020 });
});

it('Update an item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.AllOld).execute();

assert.deepEqual(result, originalUser);
});

it('Update an item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Newest Two'}).from(User).returning(ReturnValue.AllNew).execute();

assert.deepEqual(result, {...originalUser, name: 'Newest Two'});
});

it('Update an item - return None', async () =>
{
let result = await nodenamo.update({id: 2, name: 'Newer Two'}).from(User).returning(ReturnValue.None).execute();

assert.isUndefined(result);
});

it('Update an item - with all combinations', async () =>
{
let originalUser = await nodenamo.get(2).from(User).execute<User>();

let result = await nodenamo.update({id: 2, name: 'Another Two'})
.from(User)
.where('#account=:account', {'#account': 'account'}, {':account': originalUser.account})
.returning(ReturnValue.AllOld)
.withVersionCheck()
.execute();

assert.deepEqual(result, originalUser);
});

it('On item', async () =>
{
let user = await nodenamo.get(6).from(User).execute<User>();
Expand All @@ -454,6 +495,43 @@ describe('Hash-range tests', function ()
assert.deepEqual(user, {id:6, name: 'Mr. Six', account: 3000, created: 2020});
});

it('On item - return None', async () =>
{
let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - None'})
.returning(ReturnValue.None)
.execute();

assert.isUndefined(result);
});

it('On item - return AllOld', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllOld'})
.returning(ReturnValue.AllOld)
.execute();

assert.deepEqual(result, originalUser);
});

it('On item - return AllNew', async () =>
{
let originalUser = await nodenamo.get(6).from(User).execute<User>();

let result = await nodenamo.on(6)
.from(User)
.set(['#name=:name'], {'#name': 'name'}, {':name': 'That name - AllNew'})
.returning(ReturnValue.AllNew)
.execute();

assert.deepEqual(result, {...originalUser, name: 'That name - AllNew'});
});

it('Delete an item', async () =>
{
assert.isDefined(await nodenamo.get(1).from(User).execute());
Expand Down
Loading

0 comments on commit 45b9b9d

Please sign in to comment.