Skip to content

Latest commit

 

History

History
279 lines (244 loc) · 6.14 KB

README.md

File metadata and controls

279 lines (244 loc) · 6.14 KB

dynamodb-update-expression

A small library providing the solution to generate DynamoDB update expression by comparing the original data with update/remove JSON object. Updated for better efficiency and speed from the original library.

dynamodbUpdateExpression.getUpdateExpression(original, update, [options]);

See the options available below:

Installation

npm install dynamodb-update-expression --save

Usage

var dynamodbUpdateExpression = require("dynamodb-update-expression");

var updateExpression = dynamodbUpdateExpression.getUpdateExpression(
  original,
  update
);
var removeExpression = dynamodbUpdateExpression.getRemoveExpression(
  original,
  remove
);

Where original, update, and remove should be a JSON object.

For example:

Original JSON:

var original = {
  firstName: "John",
  lastName: "Doe",
  phones: ["1111-2222-333", "5555-4444-555"],
  family: [
    {
      id: 1,
      role: "father"
    }
  ],
  profile: {
    jobTitle: "Manager",
    company: "ACME Inc",
    business: {
      license: "ABCD-123-LIC",
      website: "www.acme.com"
    }
  }
};

Update JSON:

var updates = {
  lastName: "L. Doe", // Will be updated
  // List of primitives
  phones: [
    "1111-2222-333", // Original will be MERGED with this list
    "2222-4444-555"
  ],
  // List of object
  family: [
    {
      id: 2,
      role: "mother"
    } // Original will be REPLACED by this (because of: deepmerge library bug)
  ],
  // Nested Object
  profile: {
    office: "1234 Market Street", // Add this element
    business: {
      website: "www.acmeinc.com", // Update this element
      phone: "111222333" // Add this element
    },
    company: "" // Remove this element because it is an empty string
  }
};

Remove JSON:

var removes = {
  phones: [
    "1111-2222-333" // Will remove this number
  ],
  profile: {
    business: {
      website: "www.acmeinc.com", // Will remove this element
      phone: "111222333" // Won't be removed (not exists in original)
    }
  }
};

Output

Sample output

The returned "updateExpression" object should be:

{
    "UpdateExpression": "SET #lastName = :lastName, #phones = :phones, #family = :family, #profilebusinesswebsite = :profilebusinesswebsite, #profilebusinessphone = :profilebusinessphone, #profileoffice = :profileoffice REMOVE #profilecompany",
    "ExpressionAttributeNames": {
        "#lastName": "lastName",
        "#phones": "phones",
        "#family": "family",
        "#profilebusinesswebsite": "profile.business.website",
        "#profilebusinessphone": "profile.business.phone",
        "#profileoffice": "profile.office",
        "#profilecompany": "profile.company"
    },
    "ExpressionAttributeValues": {
        ":lastName": "L. Doe",
        ":phones": [
            "1111-2222-333",
            "5555-4444-555",
            "2222-4444-555"
        ],
        ":family": [
            {
                "id": 2,
                "role": "mother"
            }
        ],
        ":profilebusinesswebsite": "www.acmeinc.com",
        ":profilebusinessphone": "111222333",
        ":profileoffice": "1234 Market Street"
    }
}

The returned "removeExpression" object should be:

{
    "UpdateExpression": "REMOVE #family, #profile.#business.#website SET #phones = :phones",
    "ExpressionAttributeNames": {
        "#profile": "profile",
        "#business": "business",
        "#website": "website",
        "#family": "family",
        "#phones": "phones"
    },
    "ExpressionAttributeValues": {
        ":phones": [
            "5555-4444-555",
            "9999-8888-777"
        ]
    }
}

Options

options.arrayMerge (only for update)

= default All values in any array will be merged.

= replaceMerge

Replace all values in any array of "original" object by the values inside "update" object

For example:

let original = {
  firstName: "John",
  lastName: "Doe",
  phones: ["1111-2222-333", "5555-4444-555", "9999-8888-777"],
  family: [
    {
      id: 1,
      role: "father"
    }
  ],
  profile: {
    jobTitle: "Manager",
    company: "ACME Inc",
    business: {
      license: "ABCD-123-LIC",
      website: "www.acme.com"
    }
  }
};

let updates = {
  lastName: "L. Doe", // Will be updated
  // List of primitives
  phones: [
    "3333-6666-777", // Original will be MERGED with this list
    "2222-4444-555"
  ],
  // List of object
  family: [
    {
      id: 1,
      role: "brother"
    },
    {
      id: 2,
      role: "mother"
    } // Original will be REPLACED by this (because of: deepmerge library bug)
  ],
  // Nested Object
  profile: {
    office: "1234 Market Street", // Add this element
    business: {
      website: "www.acmeinc.com", // Update this element
      phone: "111222333" // Add this element
    },
    company: "" // Remove this element because it is an empty string
  }
};

Result:

{ firstName: 'John',
  lastName: 'Doe',
  phones: [],
  family: [],
  profile:
   { jobTitle: 'Manager',
     company: 'ACME Inc',
     business: { license: 'ABCD-123-LIC', website: 'www.acme.com' } } }
Test Result {
    "UpdateExpression": "SET #lastName = :lastName, #phones = :phones, #family = :family, #profile.#business.#website = :profilebusinesswebsite, #profile.#business.#phone = :profilebusinessphone, #profile.#office = :profileoffice REMOVE #profile.#company",
    "ExpressionAttributeNames": {
        "#lastName": "lastName",
        "#phones": "phones",
        "#family": "family",
        "#profile": "profile",
        "#business": "business",
        "#website": "website",
        "#phone": "phone",
        "#office": "office",
        "#company": "company"
    },
    "ExpressionAttributeValues": {
        ":lastName": "L. Doe",
        ":phones": [
            "3333-6666-777",
            "2222-4444-555"
        ],
        ":family": [
            {
                "id": 1,
                "role": "brother"
            },
            {
                "id": 2,
                "role": "mother"
            }
        ],
        ":profilebusinesswebsite": "www.acmeinc.com",
        ":profilebusinessphone": "111222333",
        ":profileoffice": "1234 Market Street"
    }
}

Tests

mocha test.js

Contributing