You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

260 lines
5.7 KiB

  1. package dynamodb
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. simplejson "github.com/bitly/go-simplejson"
  7. )
  8. type Table struct {
  9. Server *Server
  10. Name string
  11. Key PrimaryKey
  12. }
  13. type AttributeDefinitionT struct {
  14. Name string `json:"AttributeName"`
  15. Type string `json:"AttributeType"`
  16. }
  17. type KeySchemaT struct {
  18. AttributeName string
  19. KeyType string
  20. }
  21. type ProjectionT struct {
  22. ProjectionType string
  23. }
  24. type GlobalSecondaryIndexT struct {
  25. IndexName string
  26. IndexSizeBytes int64
  27. ItemCount int64
  28. KeySchema []KeySchemaT
  29. Projection ProjectionT
  30. ProvisionedThroughput ProvisionedThroughputT
  31. }
  32. type LocalSecondaryIndexT struct {
  33. IndexName string
  34. IndexSizeBytes int64
  35. ItemCount int64
  36. KeySchema []KeySchemaT
  37. Projection ProjectionT
  38. }
  39. type ProvisionedThroughputT struct {
  40. NumberOfDecreasesToday int64
  41. ReadCapacityUnits int64
  42. WriteCapacityUnits int64
  43. }
  44. type StreamSpecificationT struct {
  45. StreamEnabled bool
  46. StreamViewType string
  47. }
  48. type TableDescriptionT struct {
  49. AttributeDefinitions []AttributeDefinitionT
  50. CreationDateTime float64
  51. ItemCount int64
  52. KeySchema []KeySchemaT
  53. GlobalSecondaryIndexes []GlobalSecondaryIndexT
  54. LocalSecondaryIndexes []LocalSecondaryIndexT
  55. ProvisionedThroughput ProvisionedThroughputT
  56. StreamSpecification StreamSpecificationT
  57. TableName string
  58. TableSizeBytes int64
  59. TableStatus string
  60. LatestStreamArn string
  61. LatestStreamLabel string
  62. }
  63. type describeTableResponse struct {
  64. Table TableDescriptionT
  65. }
  66. func findAttributeDefinitionByName(ads []AttributeDefinitionT, name string) *AttributeDefinitionT {
  67. for _, a := range ads {
  68. if a.Name == name {
  69. return &a
  70. }
  71. }
  72. return nil
  73. }
  74. func (a *AttributeDefinitionT) GetEmptyAttribute() *Attribute {
  75. switch a.Type {
  76. case "S":
  77. return NewStringAttribute(a.Name, "")
  78. case "N":
  79. return NewNumericAttribute(a.Name, "")
  80. case "B":
  81. return NewBinaryAttribute(a.Name, "")
  82. default:
  83. return nil
  84. }
  85. }
  86. func (t *TableDescriptionT) BuildPrimaryKey() (pk PrimaryKey, err error) {
  87. for _, k := range t.KeySchema {
  88. var attr *Attribute
  89. ad := findAttributeDefinitionByName(t.AttributeDefinitions, k.AttributeName)
  90. if ad == nil {
  91. return pk, errors.New("An inconsistency found in TableDescriptionT")
  92. }
  93. attr = ad.GetEmptyAttribute()
  94. if attr == nil {
  95. return pk, errors.New("An inconsistency found in TableDescriptionT")
  96. }
  97. switch k.KeyType {
  98. case "HASH":
  99. pk.KeyAttribute = attr
  100. case "RANGE":
  101. pk.RangeAttribute = attr
  102. }
  103. }
  104. return
  105. }
  106. func (s *Server) NewTable(name string, key PrimaryKey) *Table {
  107. return &Table{s, name, key}
  108. }
  109. func (s *Server) ListTables() ([]string, error) {
  110. var tables []string
  111. query := NewEmptyQuery()
  112. jsonResponse, err := s.queryServer(target("ListTables"), query)
  113. if err != nil {
  114. return nil, err
  115. }
  116. json, err := simplejson.NewJson(jsonResponse)
  117. if err != nil {
  118. return nil, err
  119. }
  120. response, err := json.Get("TableNames").Array()
  121. if err != nil {
  122. message := fmt.Sprintf("Unexpected response %s", jsonResponse)
  123. return nil, errors.New(message)
  124. }
  125. for _, value := range response {
  126. if t, ok := (value).(string); ok {
  127. tables = append(tables, t)
  128. }
  129. }
  130. return tables, nil
  131. }
  132. func (s *Server) CreateTable(tableDescription TableDescriptionT) (string, error) {
  133. query := NewEmptyQuery()
  134. query.AddCreateRequestTable(tableDescription)
  135. jsonResponse, err := s.queryServer(target("CreateTable"), query)
  136. if err != nil {
  137. return "unknown", err
  138. }
  139. json, err := simplejson.NewJson(jsonResponse)
  140. if err != nil {
  141. return "unknown", err
  142. }
  143. return json.Get("TableDescription").Get("TableStatus").MustString(), nil
  144. }
  145. func (s *Server) DeleteTable(tableDescription TableDescriptionT) (string, error) {
  146. query := NewEmptyQuery()
  147. query.AddDeleteRequestTable(tableDescription)
  148. jsonResponse, err := s.queryServer(target("DeleteTable"), query)
  149. if err != nil {
  150. return "unknown", err
  151. }
  152. json, err := simplejson.NewJson(jsonResponse)
  153. if err != nil {
  154. return "unknown", err
  155. }
  156. return json.Get("TableDescription").Get("TableStatus").MustString(), nil
  157. }
  158. func (t *Table) DescribeTable() (*TableDescriptionT, error) {
  159. return t.Server.DescribeTable(t.Name)
  160. }
  161. func (s *Server) DescribeTable(name string) (*TableDescriptionT, error) {
  162. q := NewEmptyQuery()
  163. q.addTableByName(name)
  164. jsonResponse, err := s.queryServer(target("DescribeTable"), q)
  165. if err != nil {
  166. return nil, err
  167. }
  168. var r describeTableResponse
  169. err = json.Unmarshal(jsonResponse, &r)
  170. if err != nil {
  171. return nil, err
  172. }
  173. return &r.Table, nil
  174. }
  175. func (s *Server) UpdateTable(tableDescription TableDescriptionT) (string, error) {
  176. query := NewEmptyQuery()
  177. query.AddUpdateRequestTable(tableDescription)
  178. jsonResponse, err := s.queryServer(target("UpdateTable"), query)
  179. if err != nil {
  180. return "unknown", err
  181. }
  182. json, err := simplejson.NewJson(jsonResponse)
  183. if err != nil {
  184. return "unknown", err
  185. }
  186. return json.Get("TableDescription").Get("TableStatus").MustString(), nil
  187. }
  188. func (t *Table) ListStreams(startArn string) ([]StreamListItemT, error) {
  189. return t.Server.ListTableStreams(t.Name, startArn)
  190. }
  191. func (t *Table) LimitedListStreams(startArn string, limit int64) ([]StreamListItemT, error) {
  192. return t.Server.LimitedListTableStreams(t.Name, startArn, limit)
  193. }
  194. func keyParam(k *PrimaryKey, hashKey string, rangeKey string) string {
  195. value := fmt.Sprintf("{\"HashKeyElement\":{%s}", keyValue(k.KeyAttribute.Type, hashKey))
  196. if k.RangeAttribute != nil {
  197. value = fmt.Sprintf("%s,\"RangeKeyElement\":{%s}", value,
  198. keyValue(k.RangeAttribute.Type, rangeKey))
  199. }
  200. return fmt.Sprintf("\"Key\":%s}", value)
  201. }
  202. func keyValue(key string, value string) string {
  203. return fmt.Sprintf("\"%s\":\"%s\"", key, value)
  204. }