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  }