Documentation
¶
Overview ¶
Package expr provides a transpiler that converts Common Expression Language (CEL) expressions to Amazon DynamoDB expressions.
The transpiler is implemented as a visitor that walks the CEL Abstract Syntax Tree (AST) and builds a DynamoDB expression for use in database operations. This package is designed to be used with the official AWS Go SDK v2 DynamoDB expression package to bridge the use of CEL and Protocol Buffers with DynamoDB.
Index ¶
- func Condition(ast *cel.Ast) (expression.ConditionBuilder, error)
- func Filter(ast *cel.Ast) (expression.ConditionBuilder, error)
- func KeyCondition(ast *cel.Ast) (expression.KeyConditionBuilder, error)
- func MessageFieldVariables(msg proto.Message) []cel.EnvOption
- func MessageVariable(name string, msg proto.Message) []cel.EnvOption
- func NewEnv(opts ...cel.EnvOption) (*cel.Env, error)
- func Projection(ast *cel.Ast) (expression.ProjectionBuilder, error)
- func Update(ast *cel.Ast) (expression.UpdateBuilder, error)
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Condition ¶
func Condition(ast *cel.Ast) (expression.ConditionBuilder, error)
ConditionExpression converts a CEL AST into a DynamoDB condition expression.
Example ¶
Demonstrates converting a CEL AST to a DynamoDB Condition expression.
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/google/cel-go/cel"
celtypes "github.com/google/cel-go/common/types"
"github.com/picatz/dynabuf/expr"
)
func main() {
env, err := expr.NewEnv(
cel.Variable("name", celtypes.StringType),
cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
)
if err != nil {
panic(err)
}
ast, issues := env.Compile(`name == "bob" && "urgent" in tags`)
if issues != nil && issues.Err() != nil {
panic(issues.Err())
}
cond, err := expr.Condition(ast)
if err != nil {
panic(err)
}
dynamoExpr, err := expression.NewBuilder().WithCondition(cond).Build()
if err != nil {
panic(err)
}
fmt.Println(*dynamoExpr.Condition())
fmt.Println(dynamoExpr.Names())
fmt.Println(len(dynamoExpr.Values()))
fmt.Println(dynamoExpr.Values()[":0"])
fmt.Println(dynamoExpr.Values()[":1"])
}
Output: (#0 = :0) AND (:1 IN (#1)) map[#0:name #1:tags] 2 &{bob {}} &{urgent {}}
func Filter ¶
func Filter(ast *cel.Ast) (expression.ConditionBuilder, error)
Filter converts a CEL AST into a DynamoDB filter expression.
Example ¶
Demonstrates converting a CEL AST into a DynamoDB filter expression.
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/google/cel-go/cel"
celtypes "github.com/google/cel-go/common/types"
"github.com/picatz/dynabuf/expr"
)
func main() {
env, err := expr.NewEnv(
cel.Variable("severity", celtypes.StringType),
cel.Variable("status", celtypes.StringType),
cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
)
if err != nil {
panic(err)
}
ast, issues := env.Compile(`severity == "critical" && status == "open"`)
if issues != nil && issues.Err() != nil {
panic(issues.Err())
}
cond, err := expr.Filter(ast)
if err != nil {
panic(err)
}
condExpr, err := expression.NewBuilder().WithFilter(cond).Build()
if err != nil {
panic(err)
}
_ = dynamodb.QueryInput{
TableName: aws.String("example-table"),
FilterExpression: condExpr.Filter(),
ExpressionAttributeNames: condExpr.Names(),
ExpressionAttributeValues: condExpr.Values(),
}
fmt.Println(*condExpr.Filter())
fmt.Println(condExpr.Names())
fmt.Println(len(condExpr.Values()))
fmt.Println(condExpr.Values()[":0"])
fmt.Println(condExpr.Values()[":1"])
}
Output: (#0 = :0) AND (#1 = :1) map[#0:severity #1:status] 2 &{critical {}} &{open {}}
func KeyCondition ¶
func KeyCondition(ast *cel.Ast) (expression.KeyConditionBuilder, error)
KeyCondition converts a CEL AST into a DynamoDB key condition expression.
Example ¶
Demonstrates converting a CEL AST into a DynamoDB key condition expression.
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/google/cel-go/cel"
celtypes "github.com/google/cel-go/common/types"
"github.com/picatz/dynabuf/expr"
)
func main() {
env, err := expr.NewEnv(
cel.Variable("user", celtypes.StringType), // partition key
cel.Variable("order", celtypes.StringType), // sort key
)
if err != nil {
panic(err)
}
ast, issues := env.Compile(`user == "User#123" && begins_with(order, "Order#")`)
if issues != nil && issues.Err() != nil {
panic(issues.Err())
}
keyCond, err := expr.KeyCondition(ast)
if err != nil {
panic(err)
}
keyCondExpr, err := expression.NewBuilder().WithKeyCondition(keyCond).Build()
if err != nil {
panic(err)
}
fmt.Println(*keyCondExpr.KeyCondition())
fmt.Println(keyCondExpr.Names())
fmt.Println(len(keyCondExpr.Values()))
fmt.Println(keyCondExpr.Values()[":0"])
}
Output: (#0 = :0) AND (begins_with (#1, :1)) map[#0:user #1:order] 2 &{User#123 {}}
func MessageFieldVariables ¶
MessageFieldVariables creates environment options for each field in a proto message. Fields are exposed as variables using their JSON names, because that's how they are stored in DynamoDB when coverted using protojson.
func MessageVariable ¶
MessageVariable creates an environment option for using a whole proto message as a variable.
func Projection ¶
func Projection(ast *cel.Ast) (expression.ProjectionBuilder, error)
Projection converts a CEL AST into a DynamoDB projection expression.
Example ¶
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/google/cel-go/cel"
celtypes "github.com/google/cel-go/common/types"
"github.com/picatz/dynabuf/expr"
)
func main() {
env, err := expr.NewEnv(
cel.Variable("name", celtypes.StringType),
cel.Variable("age", celtypes.IntType),
cel.Variable("email", celtypes.StringType),
)
if err != nil {
panic(err)
}
ast, issues := env.Compile(`["name", "age", "email"]`)
if issues != nil && issues.Err() != nil {
panic(issues.Err())
}
proj, err := expr.Projection(ast)
if err != nil {
panic(err)
}
projExpr, err := expression.NewBuilder().WithProjection(proj).Build()
if err != nil {
panic(err)
}
_ = dynamodb.QueryInput{
TableName: aws.String("example-table"),
ProjectionExpression: projExpr.Projection(),
ExpressionAttributeNames: projExpr.Names(),
}
fmt.Println(*projExpr.Projection())
fmt.Println(projExpr.Names())
}
Output: #0, #1, #2 map[#0:name #1:age #2:email]
func Update ¶
func Update(ast *cel.Ast) (expression.UpdateBuilder, error)
Update converts a CEL AST into a DynamoDB update expression.
Example ¶
package main
import (
"fmt"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression"
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
"github.com/google/cel-go/cel"
celtypes "github.com/google/cel-go/common/types"
"github.com/picatz/dynabuf/expr"
)
func main() {
env, err := expr.NewEnv(
cel.Variable("views", celtypes.IntType),
cel.Variable("likes", celtypes.IntType),
cel.Variable("tags", celtypes.NewListType(celtypes.StringType)),
)
if err != nil {
panic(err)
}
ast, issues := env.Compile(`add("views", 1)`)
if issues != nil && issues.Err() != nil {
panic(issues.Err())
}
update, err := expr.Update(ast)
if err != nil {
panic(err)
}
updateExpr, err := expression.NewBuilder().WithUpdate(update).Build()
if err != nil {
panic(err)
}
_ = dynamodb.UpdateItemInput{
TableName: aws.String("example-table"),
UpdateExpression: updateExpr.Update(),
ExpressionAttributeNames: updateExpr.Names(),
ExpressionAttributeValues: updateExpr.Values(),
}
fmt.Println(*updateExpr.Update())
fmt.Println(updateExpr.Names())
fmt.Println(len(updateExpr.Values()))
fmt.Println(updateExpr.Values()[":0"])
}
Output: ADD #0 :0 map[#0:views] 1 &{1 {}}
Types ¶
This section is empty.