Skip to content

Commit 572d728

Browse files
committed
put item
1 parent d85dee2 commit 572d728

23 files changed

+374
-10
lines changed

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616
"license": "ISC",
1717
"dependencies": {
1818
"aws-sdk": "git+https://[email protected]/lucasmafra/aws-sdk-js.git",
19-
"commander": "^2.11.0"
19+
"commander": "^2.11.0",
20+
"dynamodb-marshaler": "^2.0.0"
2021
},
2122
"devDependencies": {
2223
"@types/chai": "^4.1.2",

playground/test.ts

+14
Original file line numberDiff line numberDiff line change
@@ -67,9 +67,23 @@ async function queryOnIndexTest() {
6767
console.log('QUERY ON INDEX', users.data)
6868
}
6969

70+
async function putTest() {
71+
const user = await User
72+
.save({
73+
74+
name: 'Maithe',
75+
companyName: 'AppSimples',
76+
hiringDate: 1520748807000,
77+
age: 22,
78+
})
79+
.execute()
80+
console.log('PUT', user.data)
81+
}
82+
7083
scanTest()
7184
queryTest()
7285
getTest()
7386
batchGetTest()
7487
scanOnIndexTest()
7588
queryOnIndexTest()
89+
putTest()

src/chaining/common/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export abstract class Chaining<ChainingKind> {
1313
}
1414

1515
export * from './with-attributes'
16+
export * from './with-condition'
1617
export * from './paginate'
1718
export * from './filter'
1819
export * from './all-results'

src/chaining/common/with-condition.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import Expression from '../../expressions/expression'
2+
import { Chaining, CommonWithAttributes } from './'
3+
4+
export type WithConditionType = 'withCondition'
5+
6+
export interface WithCondition {
7+
expression: Expression
8+
}
9+
10+
export class CommonWithCondition<ChainingKind> extends Chaining<ChainingKind | WithConditionType> {
11+
12+
private _withCondition: WithCondition
13+
14+
constructor(
15+
withCondition: WithCondition,
16+
currentStack: Array<Chaining<ChainingKind>>,
17+
) {
18+
super('withCondition', currentStack)
19+
this._withCondition = withCondition
20+
this._stack.push(this)
21+
}
22+
23+
}
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
import { buildGetInput, get} from '../../../database-operations/get'
3+
import { EntitySchema } from '../../../schema'
4+
import { Chaining, Filter, Paginate, WithAttributes } from '../../common'
5+
import { GetChainingKind } from './'
6+
import { Get } from './get'
7+
8+
function extractFromStack<KeySchema>(stack: Array<Chaining<GetChainingKind>>): {
9+
getMetadata: Get<KeySchema>,
10+
withAttributes?: WithAttributes,
11+
} {
12+
const getMetadata = (stack[0] as any)._get
13+
let withAttributes: WithAttributes | undefined
14+
for (const current of stack) {
15+
switch ((current as any)._kind) {
16+
case 'withAttributes': withAttributes = (current as any)._withAttributes
17+
}
18+
}
19+
return { getMetadata, withAttributes }
20+
}
21+
22+
export function execute<Entity, KeySchema>(
23+
stack: Array<Chaining<GetChainingKind>>,
24+
) {
25+
const { getMetadata, withAttributes } = extractFromStack<KeySchema>(stack)
26+
const getInput = buildGetInput(getMetadata, withAttributes)
27+
return get<Entity, KeySchema>(getInput)
28+
}

src/chaining/save/batch-write/get.ts

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { EntitySchema } from '../../../schema'
2+
import { Chaining } from '../../common'
3+
import { GetChainingKind } from './'
4+
import { execute } from './execute'
5+
import { DynamoGetWithAttributes } from './with-attributes'
6+
7+
export type GetType = 'get'
8+
9+
export interface Get<KeySchema> {
10+
schema: EntitySchema,
11+
key: KeySchema,
12+
}
13+
14+
export class DynamoGet<
15+
Entity,
16+
KeySchema
17+
> extends Chaining<GetChainingKind> {
18+
19+
protected _get: Get<KeySchema>
20+
21+
constructor(
22+
get: Get<KeySchema>,
23+
) {
24+
super('get')
25+
this._get = get
26+
this._stack.push(this)
27+
}
28+
29+
public withAttributes<K extends keyof Entity>(attributes: K[]) {
30+
return new DynamoGetWithAttributes<Pick<Entity, K>, KeySchema>(
31+
attributes, this._stack,
32+
)
33+
}
34+
35+
public execute() {
36+
return execute<Entity, KeySchema>(this._stack)
37+
}
38+
39+
}
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { WithAttributesType } from '../../common'
2+
import { GetType } from './get'
3+
4+
export type GetChainingKind = GetType | WithAttributesType
5+
6+
export { DynamoGet } from './get'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { randomGenerator } from '../../../expressions/random-generator'
2+
import { Chaining, CommonWithAttributes } from '../../common'
3+
import { GetChainingKind } from './'
4+
import { execute } from './execute'
5+
6+
export class DynamoGetWithAttributes<
7+
Entity,
8+
KeySchema
9+
> extends CommonWithAttributes<GetChainingKind> {
10+
11+
constructor(
12+
attributes: string[],
13+
currentStack: Array<Chaining<GetChainingKind>>,
14+
) {
15+
super(attributes, currentStack)
16+
}
17+
18+
public execute() {
19+
return execute<Entity, KeySchema>(this._stack)
20+
}
21+
22+
}

src/chaining/save/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './put'

src/chaining/save/put/execute.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
import { buildPutInput, put } from '../../../database-operations/put'
3+
import { EntitySchema } from '../../../schema'
4+
import { Chaining, WithCondition } from '../../common'
5+
import { PutChainingKind } from './'
6+
import { Put } from './put'
7+
8+
function extractFromStack<Entity>(stack: Array<Chaining<PutChainingKind>>): {
9+
putMetadata: Put<Entity>,
10+
withCondition?: WithCondition,
11+
} {
12+
const putMetadata = (stack[0] as any)._put
13+
let withCondition: WithCondition | undefined
14+
for (const current of stack) {
15+
switch ((current as any)._kind) {
16+
case 'withCondition': withCondition = (current as any)._withCondition
17+
}
18+
}
19+
return { putMetadata, withCondition }
20+
}
21+
22+
export function execute<Entity>(
23+
stack: Array<Chaining<PutChainingKind>>,
24+
) {
25+
const { putMetadata, withCondition } = extractFromStack<Entity>(stack)
26+
const putInput = buildPutInput(putMetadata, withCondition)
27+
return put<Entity>(putInput)
28+
}

src/chaining/save/put/index.ts

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { WithConditionType } from '../../common'
2+
import { PutType } from './put'
3+
4+
export type PutChainingKind = PutType | WithConditionType
5+
6+
export { DynamoPut } from './put'

src/chaining/save/put/put.ts

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import Expression from '../../../expressions/expression'
2+
import { EntitySchema } from '../../../schema'
3+
import { Chaining } from '../../common'
4+
import { PutChainingKind } from './'
5+
import { execute } from './execute'
6+
import { DynamoPutWithCondition } from './with-condition'
7+
export type PutType = 'put'
8+
9+
export interface Put<Entity> {
10+
schema: EntitySchema,
11+
item: Entity,
12+
}
13+
14+
export class DynamoPut<
15+
Entity
16+
> extends Chaining<PutChainingKind> {
17+
18+
protected _put: Put<Entity>
19+
20+
constructor(
21+
put: Put<Entity>,
22+
) {
23+
super('put')
24+
this._put = put
25+
this._stack.push(this)
26+
}
27+
28+
public withCondition(expression: Expression) {
29+
return new DynamoPutWithCondition<Entity>({ expression }, this._stack)
30+
}
31+
32+
public execute() {
33+
return execute<Entity>(this._stack)
34+
}
35+
36+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Chaining, CommonWithCondition, WithCondition } from '../../common'
2+
import { PutChainingKind } from './'
3+
import { execute } from './execute'
4+
export type PutType = 'put'
5+
6+
export class DynamoPutWithCondition<
7+
Entity
8+
> extends CommonWithCondition<PutChainingKind> {
9+
10+
constructor(
11+
withCondition: WithCondition,
12+
currentStack: Array<Chaining<PutChainingKind>>,
13+
) {
14+
super(withCondition, currentStack)
15+
}
16+
17+
public execute() {
18+
return execute<Entity>(this._stack)
19+
}
20+
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
import { WithAttributes } from '../../chaining/common'
3+
import { Get } from '../../chaining/find/get/get'
4+
import { EntitySchema } from '../../schema'
5+
import { buildKey, projectionExpression } from '../helpers'
6+
7+
export function buildGetInput<KeySchema>(
8+
get: Get<KeySchema>,
9+
withAttributes?: WithAttributes,
10+
): DynamoDB.GetItemInput {
11+
const input: DynamoDB.GetItemInput = {
12+
TableName: get.schema.tableName,
13+
Key: buildKey(get.key),
14+
}
15+
if (withAttributes) {
16+
input.ProjectionExpression = projectionExpression(withAttributes.attributes)
17+
input.ExpressionAttributeNames = withAttributes.expressionAttributeNames
18+
}
19+
return input
20+
}
+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
import DynamoToPromise from '../dynamo-to-promise'
3+
4+
const dynamoPromise = new DynamoToPromise(new DynamoDB.DocumentClient({
5+
region: 'localhost',
6+
endpoint: 'http://localhost:8000',
7+
}))
8+
9+
export interface GetResult<TableModel, KeySchema> {
10+
data: TableModel
11+
}
12+
13+
export async function get<
14+
Entity, KeySchema
15+
>(getInput: DynamoDB.GetItemInput): Promise<GetResult<Entity, KeySchema>> {
16+
const getOutput = await dynamoPromise.getItem(getInput)
17+
if (!getOutput.Item) {
18+
throw new Error('ItemNotFound')
19+
}
20+
const result: GetResult<Entity, KeySchema> = {
21+
data: getOutput.Item as any,
22+
}
23+
return result
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './build-get-input'
2+
export * from './get'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
const marshalItem = require('dynamodb-marshaler').marshalItem
3+
import { WithCondition } from '../../chaining/common/with-condition'
4+
import { Put } from '../../chaining/save/put/put'
5+
import Expression from '../../expressions/expression'
6+
import { resolveExpression } from '../../expressions/resolve-expression'
7+
import { EntitySchema } from '../../schema'
8+
export function buildPutInput<Table>(
9+
put: Put<Table>,
10+
conditionalExpression?: WithCondition,
11+
): DynamoDB.PutItemInput {
12+
const input: DynamoDB.PutItemInput = {
13+
TableName: put.schema.tableName,
14+
Item: marshalItem(put.item),
15+
}
16+
if (conditionalExpression) {
17+
const expression = resolveExpression((conditionalExpression.expression as any).stack)
18+
input.ConditionExpression = expression.resolvedExpression
19+
input.ExpressionAttributeNames = expression.expressionAttributeNames
20+
input.ExpressionAttributeValues = expression.expressionAttributeValues
21+
}
22+
return input
23+
}

src/database-operations/put/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './build-put-input'
2+
export * from './put'

src/database-operations/put/put.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { DynamoDB } from 'aws-sdk'
2+
import DynamoToPromise from '../dynamo-to-promise'
3+
4+
const dynamoPromise = new DynamoToPromise(new DynamoDB.DocumentClient({
5+
region: 'localhost',
6+
endpoint: 'http://localhost:8000',
7+
}))
8+
9+
export interface PutResult<TableModel> {
10+
data: TableModel
11+
}
12+
13+
export async function put<
14+
Entity
15+
>(putInput: DynamoDB.PutItemInput): Promise<PutResult<Entity>> {
16+
const putOutput = await dynamoPromise.put(putInput)
17+
const result: PutResult<Entity> = {
18+
data: putInput.Item as any,
19+
}
20+
return result
21+
}

0 commit comments

Comments
 (0)