func (c *ConditionList) AddKeyAttribute(attr AttributeDefinition) {
	c.keyAttributes[attr.Name] = attr.Type
}
AddKeyAttribute adds to attribute to keyAttributes.
package dynamodb
import (
	"fmt"
	"strings"
	SDK "github.com/aws/aws-sdk-go/service/dynamodb"
	"github.com/evalphobia/aws-sdk-go-wrapper/private/pointers"
)
type ConditionList struct {
	keyAttributes map[string]string
	conditions    map[string]*Condition
	filters       map[string]*Condition
	index        string
	limit        int64
	startKey     map[string]*SDK.AttributeValue
	isConsistent bool
	isDesc       bool  
}
func NewConditionList(keyAttributes map[string]string) *ConditionList {
	return &ConditionList{
		keyAttributes: keyAttributes,
		conditions:    make(map[string]*Condition),
		filters:       make(map[string]*Condition),
	}
}
func (c *ConditionList) HasCondition() bool {
	return len(c.conditions) != 0
}
func (c *ConditionList) HasFilter() bool {
	return len(c.filters) != 0
}
func (c *ConditionList) HasIndex() bool {
	return c.index != ""
}
func (c *ConditionList) HasLimit() bool {
	return c.limit != 0
}
func (c *ConditionList) SetLimit(i int64) {
	c.limit = i
}
func (c *ConditionList) SetIndex(v string) {
	c.index = v
}
func (c *ConditionList) SetConsistent(b bool) {
	c.isConsistent = b
}
func (c *ConditionList) SetDesc(b bool) {
	c.isDesc = b
}
func (c *ConditionList) SetStartKey(startKey map[string]*SDK.AttributeValue) {
	c.startKey = startKey
}
func (c *ConditionList) AndEQ(key string, val interface{}) {
	c.setCondition(conditionEQ, key, val)
}
func (c *ConditionList) AndLE(key string, val interface{}) {
	c.setCondition(conditionLE, key, val)
}
func (c *ConditionList) AndLT(key string, val interface{}) {
	c.setCondition(conditionLT, key, val)
}
func (c *ConditionList) AndGE(key string, val interface{}) {
	c.setCondition(conditionGE, key, val)
}
func (c *ConditionList) AndGT(key string, val interface{}) {
	c.setCondition(conditionGT, key, val)
}
func (c *ConditionList) AndBETWEEN(key string, from, to interface{}) {
	c.setCondition(conditionBETWEEN, key, from, to)
}
func (c *ConditionList) setCondition(condition, key string, val interface{}, subVal ...interface{}) {
	if _, ok := c.conditions[key]; ok {
		return
	}
	cond := newCondition(condition, key, val)
	if len(subVal) == 1 {
		cond.SubValue = subVal[0]
	}
	c.conditions[key] = cond
}
func (c *ConditionList) FilterEQ(key string, val interface{}) {
	c.setFilter(conditionEQ, key, val)
}
func (c *ConditionList) FilterLE(key string, val interface{}) {
	c.setFilter(conditionLE, key, val)
}
func (c *ConditionList) FilterLT(key string, val interface{}) {
	c.setFilter(conditionLT, key, val)
}
func (c *ConditionList) FilterGE(key string, val interface{}) {
	c.setFilter(conditionGE, key, val)
}
func (c *ConditionList) FilterGT(key string, val interface{}) {
	c.setFilter(conditionGT, key, val)
}
func (c *ConditionList) FilterBETWEEN(key string, from, to interface{}) {
	c.setFilter(conditionBETWEEN, key, from, to)
}
func (c *ConditionList) setFilter(condition, key string, val interface{}, subVal ...interface{}) {
	if _, ok := c.filters[key]; ok {
		return
	}
	cond := newCondition(condition, key, val)
	cond.isFilter = true
	if len(subVal) == 1 {
		cond.SubValue = subVal[0]
	}
	c.filters[key] = cond
}
func (c *ConditionList) FormatCondition() *string {
	return c.formatCondition(c.conditions)
}
func (c *ConditionList) FormatFilter() *string {
	return c.formatCondition(c.filters)
}
func (c *ConditionList) formatCondition(conditions map[string]*Condition) *string {
	max := len(conditions)
	if max == 0 {
		return nil
	}
	i := 1
	expression := make([]string, 0, max)
	for key, cond := range conditions {
		exp := cond.expression(key)
		if i < max {
			exp = exp + " " + cond.operator()
		}
		expression = append(expression, exp)
		i++
	}
	e := strings.Join(expression, " ")
	return &e
}
func (c *ConditionList) FormatValues() map[string]*SDK.AttributeValue {
	attrs := c.keyAttributes
	m := make(map[string]*SDK.AttributeValue)
	for k, cond := range c.getMergedConditions() {
		typ, ok := attrs[k]
		if !ok {
			continue
		}
		key := cond.valueName()
		m[key] = newAttributeValue(typ, cond.Value)
		if cond.SubValue != nil {
			sub := cond.subValueName()
			m[sub] = newAttributeValue(typ, cond.SubValue)
		}
	}
	return m
}
func (c *ConditionList) FormatNames() map[string]*string {
	attrs := c.keyAttributes
	m := make(map[string]*string)
	for _, cond := range c.getMergedConditions() {
		if _, ok := attrs[cond.Key]; !ok {
			continue
		}
		m[cond.keyName()] = pointers.String(cond.Key)
	}
	return m
}
func (c *ConditionList) getMergedConditions() map[string]*Condition {
	list := make(map[string]*Condition)
	for k, v := range c.filters {
		list[k] = v
	}
	for k, v := range c.conditions {
		list[k] = v
	}
	return list
}