Buffer
Introduction
Buffer
represents DynamoDB's Binary data type (marshalled as "B").
When storing an Item, Buffer
attribute accept following types:
ArrayBuffer
Blob
Buffer
DataView
File
Int8Array
Uint8Array
Uint8ClampedArray
Int16Array
Uint16Array
Int32Array
Uint32Array
Float32Array
Float64Array
BigInt64Array
BigUint64Array
However when retrieved it is always a Buffer
.
Define a Buffer
- DynamoQL
- produced type
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
order: Buffer,
score: {
type: Buffer,
}
} as const);
interface IUserSchema {
id: string,
order: Buffer,
score?: Buffer
}
Options
- primaryIndex
top-level only
boolean which markes attribute as HASH key and makes attribute as required, default is false
.
A Schema can have only one primaryIndex.
import { Schema } from "dynamoql";
const userSchema = new Schema({
id: {
type: Buffer,
primaryIndex: true,
},
} as const);
- sortKey
top-level only
boolean which markes attribute as RANGE key and makes attribute as required, default is false
.
A Schema can have only one sortKey.
import { Schema } from "dynamoql";
const userSchema = new Schema({
countryCode: {
type: Buffer,
primaryIndex: true,
},
cityCode: {
type: Buffer,
sortKey: true
}
} as const);
- LSI
top-level only
defines a Local Secondary Index.
LSI option is an object where you must provide:
indexName
which should be unique across the Schema.project
which may beALL
|KEYS
or string[] where strings are attriubute names defined in the Schema.
import { Schema } from "dynamoql";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
},
image: {
type: Buffer,
LSI: {
indexName: "image-index",
project: "ALL"
}
}
} as const);
- GSI
top-level only
defines a Global Secondary Index.
GSI option is an object where you must provide:
indexName
which should be unique across the Schema.project
which may beALL
|KEYS
or string[] where strings are attriubute names defined in the Schema.
import { Schema } from "dynamoql";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
},
image: {
type: Buffer,
GSI: {
indexName: "image-index",
project: "ALL"
}
}
} as const);
for composite table (HASH and RANGE) you must provide another attribute with GSI:
indexName
which must be one of defined GSI indexName.sortKey
true.
import { Schema } from "dynamoql";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
},
image: {
type: Buffer,
GSI: {
indexName: "image-index",
project: "ALL"
}
},
order: {
type: Buffer,
GSI: {
indexName: "image-index",
sortKey: true
}
}
} as const);
- required
boolean which makes attribute as required or optionnal, default is false
when type is defined with an Object.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
score: {
type: Buffer,
required: true
}
} as const);
- default
To set a default value for an attribute use default
option.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
score: {
type: Buffer,
default: Buffer.from("Hello WORLD")
}
} as const);
With this configuration when you put
an Item into your table, your Item will contain score attribute with 5 as value.
default
must be a Buffer.
Otherwise it will throw an error during dev time and runtime.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
score: {
type: Buffer,
default: "some-score" // DynamoQLInvalidTypeException: "score" expected to be "B" received "S".
}
} as const);
default
can also be a (async) function which accepts one argument (put Item value) and must return a Buffer.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
score: {
type: Buffer,
default: (item: Record<string, any>)=> {
if(item.moderator) {
return Buffer.from(item.id)
}
}
}
} as const);
- validate
validate option allows you to manually validate provided value in put
and update
commands.
To return an error you should return a string which explains value invalidity. Any other returned value is considered as valid.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
image: {
type: Buffer,
validate: (self: Buffer)=> {
if(self.byteLength < 10) {
return "Invalid image"
}
}
}
} as const);
- min
define minimum binary size.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
score: {
type: Buffer,
min: 1
}
} as const);
- max
define maximum binary size.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
score: {
type: Buffer,
max: 89
}
} as const);
- set
To modify a value before storing it use set
option.
set (async) function accepts 3 arguments:
self
provided value.item
entier put Item object.setterInfo
an optionnal value provided inside in put, batchPut, batchWrite, transactWrite command's options.
set
will not be called if attribute doesn't exists in put Item object.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
score: {
type: Buffer,
set: (self: Buffer, item: Record<string, any>, setterInfo?: any)=> {
if(item.moderator && setterInfo?.someCondition) {
return Buffer.from("Hello WORLD")
}
return self
}
}
} as const);
- get
When reteving an Item we can transform field's value with get option.
get (async) function accepts 3 arguments:
self
retrieved value.item
entier retrieved Item object.getterInfo
an optionnal value provided inside get, batchGet, transactGet, query, scan command's options.
get
can return anything.
get
will not be called if attribute doesn't exists in stored Item.
import { Schema } from "dynamoql";
import { randomUUID } from "crypto";
const userSchema = new Schema({
id: {
type: String,
primaryIndex: true,
default: randomUUID
},
moderator: Boolean,
image: {
type: Buffer,
items: String,
get: (self: Buffer, item: Record<string, any>, getterInfo?: any)=> {
if(getterInfo.someCondition) {
return {
format: "png",
size: self.byteLength
}
}
return self
}
}
} as const);
get
returned value's type affects Item type when retriving Item(s) from DynamoDB.
- description
add any information to the Schema for your personal usage.
Condition expression
Condition expression are not part of Schema but they are based on your defined Schema.
They are used in various DynamoDB operations to check for some condition(s).
DynamoQL supports all DynamoDB Condition expression.
- equals
{
image: Buffer.from("image:png")
}
or
{
image: {
$eq: Buffer.from("image:png")
}
}
- not equals
{
image: {
$neq: Buffer.from("image:png")
}
}
- attribute exists
$exists
can be true
or false
.
{
image: {
$exists: true
}
}
- includes
Checks if stored binary value contains provided value.
{
image: {
$includes: Buffer.from("png")
}
}
- binary length
Checks for stored binary value's length.
{
image: {
$size: 1024
}
}
$size
can also be any valid numeric comparison operator.
{
image: {
$size: {
$gt: 1024
}
}
}
Possible operators are $eq, $neq, $gt, $gte, $lt, $lte, $in, $between.
- attribute type
Checks for stored attribute type.
{
image: {
$type: Buffer
}
}
$type
can be String, Number, Boolean, Null, Buffer, Object, Array, or {type: Set, items: String | Number | Buffer }
- starts with
Checks if stored binary value starts with provided value.
{
image: {
$startsWith: Buffer.from("image:gif")
}
}
- greather than
Lexicographically compares if stored binary value is greather than provided value.
{
image: {
$gt: "Joh"
}
}
- greather than or equal
Lexicographically compares if stored binary value is greather than or equal provided value.
{
image: {
$gte: "Joh"
}
}
- little than
Lexicographically compares if stored binary value is little than provided value.
{
image: {
$lt: "Joh"
}
}
- little than or equal
Lexicographically compares if stored binary value is little than or equal provided value.
{
image: {
$lte: "Joh"
}
}
- between
Lexicographically compares if stored binary value is greather than or equal value1
AND is little than or equal value2
.
{
image: {
$between: [value1, value2]
}
}
- in
Checks if provided array includes stored binary value.
{
image: {
$in: ["Steve", 214, "Sara", false, Buffer.from("image:png"), "Mike", null]
}
}
- AND
Checks for multiple conditions. Condition is valid if ALL specified conditions are satisfied.
{
image: {
$and: [
{
$size: 4
},
{
$includes: Buffer.from("png")
}
]
}
}
shorthand style
{
image: {
$size: 4,
$includes: Buffer.from("png")
}
}
- OR
Checks for multiple conditions. Condition is valid if at least one of specified conditions is satisfied.
{
image: {
$or: [
{
$size: 6
},
{
$includes: Buffer.from("png")
}
]
}
}
- NOT
Condition is valid if specified condition is NOT satisfied.
{
image: {
$not: {
$includes: Buffer.from("png")
}
}
}
$not
accepts any Condition expression.
When multiple conditions are provided inside $not: {} they are considered as $and condition.
{
image: {
$not: {
$size: 6,
$includes: Buffer.from("png")
}
}
}
longhand equivalent is:
{
image: {
$not: {
$and: [
{
$size: 6
},
{
$includes: Buffer.from("png")
}
]
}
}
}
To improve developper experience, when ArrayBuffer
Blob
DataView
or File
are used inside Conditionnal or Update expressions, intentionnally TS will complain about provided value type.
They are still valid types and you can safely ignore TS error message with // @ts-ignore.
Update expressions
Like Condition expression, Update expressions are not part of Schema, but they are based on defined Schema.
Update expressions are used in update
, transactUpdate
and transactWrite
operations.
DynamoQL supports all DynamoDB update operations.
- set
$set
replaces stored binary value by provided binary value.
{
image: {
$set: Buffer.from("image:png")
}
}
shorthand version is
{
image: Buffer.from("image:png")
}
- if not exists
$ifNotExists
sets provided binary value if attribute do not exists in stored item.
$ifNotExists
dont affects Condition expression and is attribute specific.
If attribute exists, stored value stays unchanged.
{
image: {
$ifNotExists: Buffer.from("image:png")
}
}