github.com/smugmug/godynamo@v0.0.0-20151122084750-7913028f6623/endpoints/query/query.go (about) 1 // Support for the DynamoDB Query endpoint. 2 // 3 // example use: 4 // 5 // tests/query-livestest.go 6 // 7 package query 8 9 import ( 10 "encoding/json" 11 "errors" 12 "github.com/smugmug/godynamo/authreq" 13 "github.com/smugmug/godynamo/aws_const" 14 "github.com/smugmug/godynamo/conf" 15 "github.com/smugmug/godynamo/types/attributestoget" 16 "github.com/smugmug/godynamo/types/attributevalue" 17 "github.com/smugmug/godynamo/types/aws_strings" 18 "github.com/smugmug/godynamo/types/capacity" 19 "github.com/smugmug/godynamo/types/condition" 20 "github.com/smugmug/godynamo/types/expressionattributenames" 21 "github.com/smugmug/godynamo/types/item" 22 ) 23 24 const ( 25 ENDPOINT_NAME = "Query" 26 QUERY_ENDPOINT = aws_const.ENDPOINT_PREFIX + ENDPOINT_NAME 27 OP_EQ = aws_strings.OP_EQ 28 OP_LE = aws_strings.OP_LE 29 OP_LT = aws_strings.OP_LT 30 OP_GE = aws_strings.OP_GE 31 OP_GT = aws_strings.OP_GT 32 OP_BEGINS_WITH = aws_strings.OP_BEGINS_WITH 33 OP_BETWEEN = aws_strings.OP_BETWEEN 34 LIMIT = 10000 // limit of query unless set 35 ) 36 37 type ComparisonOperator string 38 39 // These are here for backward compatibility 40 type KeyConditions condition.Conditions 41 type KeyCondition condition.Condition 42 43 type Query struct { 44 AttributesToGet attributestoget.AttributesToGet `json:",omitempty"` 45 ConditionalOperator string `json:",omitempty"` 46 ConsistentRead bool // false is sane default 47 ExclusiveStartKey attributevalue.AttributeValueMap `json:",omitempty"` 48 ExpressionAttributeNames expressionattributenames.ExpressionAttributeNames `json:",omitempty"` 49 ExpressionAttributeValues attributevalue.AttributeValueMap `json:",omitempty"` 50 FilterExpression string `json:",omitempty"` 51 IndexName string `json:",omitempty"` 52 KeyConditions condition.Conditions 53 Limit uint64 `json:",omitempty"` 54 ProjectionExpression string `json:",omitempty"` 55 QueryFilter condition.Conditions `json:",omitempty"` 56 ReturnConsumedCapacity string `json:",omitempty"` 57 ScanIndexForward *bool `json:",omitempty"` 58 Select string `json:",omitempty"` 59 TableName string 60 } 61 62 // NewQuery returns a pointer to an instantiation of the Query struct. 63 func NewQuery() *Query { 64 q := new(Query) 65 q.AttributesToGet = attributestoget.NewAttributesToGet() 66 q.ExclusiveStartKey = attributevalue.NewAttributeValueMap() 67 q.ExpressionAttributeNames = expressionattributenames.NewExpressionAttributeNames() 68 q.ExpressionAttributeValues = attributevalue.NewAttributeValueMap() 69 q.KeyConditions = condition.NewConditions() 70 q.QueryFilter = condition.NewConditions() 71 return q 72 } 73 74 type Request Query 75 76 type Response struct { 77 ConsumedCapacity *capacity.ConsumedCapacity `json:",omitempty"` 78 Count uint64 79 Items []item.Item `json:",omitempty"` 80 LastEvaluatedKey attributevalue.AttributeValueMap `json:",omitempty"` 81 ScannedCount uint64 `json:",omitempty"` 82 } 83 84 func NewResponse() *Response { 85 r := new(Response) 86 r.ConsumedCapacity = capacity.NewConsumedCapacity() 87 r.Items = make([]item.Item, 0) 88 r.LastEvaluatedKey = attributevalue.NewAttributeValueMap() 89 return r 90 } 91 92 // These implementations of EndpointReq use a parameterized conf. 93 94 func (query *Query) EndpointReqWithConf(c *conf.AWS_Conf) ([]byte, int, error) { 95 if query == nil { 96 return nil, 0, errors.New("query.(Query)EndpointReqWithConf: receiver is nil") 97 } 98 if !conf.IsValid(c) { 99 return nil, 0, errors.New("query.EndpointReqWithConf: c is not valid") 100 } 101 // returns resp_body,code,err 102 reqJSON, json_err := json.Marshal(query) 103 if json_err != nil { 104 return nil, 0, json_err 105 } 106 return authreq.RetryReqJSON_V4WithConf(reqJSON, QUERY_ENDPOINT, c) 107 } 108 109 func (req *Request) EndpointReqWithConf(c *conf.AWS_Conf) ([]byte, int, error) { 110 if req == nil { 111 return nil, 0, errors.New("query.(Request)EndpointReqWithConf: receiver is nil") 112 } 113 query := Query(*req) 114 return query.EndpointReqWithConf(c) 115 } 116 117 // These implementations of EndpointReq use the global conf. 118 119 func (query *Query) EndpointReq() ([]byte, int, error) { 120 if query == nil { 121 return nil, 0, errors.New("query.(Query)EndpointReq: receiver is nil") 122 } 123 return query.EndpointReqWithConf(&conf.Vals) 124 } 125 126 func (req *Request) EndpointReq() ([]byte, int, error) { 127 if req == nil { 128 return nil, 0, errors.New("query.(Request)EndpointReq: receiver is nil") 129 } 130 query := Query(*req) 131 return query.EndpointReqWithConf(&conf.Vals) 132 } 133 134 // ValidOp determines if an operation is in the approved list. 135 func ValidOp(op string) bool { 136 return (op == OP_EQ || 137 op == OP_LE || 138 op == OP_LT || 139 op == OP_GE || 140 op == OP_GT || 141 op == OP_BEGINS_WITH || 142 op == OP_BETWEEN) 143 }