Skip to content

Commit

Permalink
Get entity and table without using query funcs (#48)
Browse files Browse the repository at this point in the history
* Complete parameters for table operations

* Complete parameters in entity operations

* Complete parameters in query table operation

* Added get entity operation

* Added get table operation

* Included test recordings

* Fixed merge little mess

* Fix travis
  • Loading branch information
mcardosos committed May 4, 2017
1 parent 186f113 commit 8411265
Show file tree
Hide file tree
Showing 7 changed files with 554 additions and 10 deletions.
77 changes: 69 additions & 8 deletions storage/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,64 @@ type EntityOptions struct {
RequestID string `header:"x-ms-client-request-id"`
}

// GetEntityOptions includes options for a get entity operation
type GetEntityOptions struct {
Select []string
RequestID string `header:"x-ms-client-request-id"`
}

// Get gets the referenced entity. Which properties to get can be
// specified using the select option.
// See:
// https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/query-entities
// https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/querying-tables-and-entities
func (e *Entity) Get(timeout uint, ml MetadataLevel, options *GetEntityOptions) error {
if ml == EmptyPayload {
return errEmptyPayload
}
// RowKey and PartitionKey could be lost if not included in the query
// As those are the entity identifiers, it is best if they are not lost
rk := e.RowKey
pk := e.PartitionKey

query := url.Values{
"timeout": {strconv.FormatUint(uint64(timeout), 10)},
}
headers := e.Table.tsc.client.getStandardHeaders()
headers[headerAccept] = string(ml)

if options != nil {
if len(options.Select) > 0 {
query.Add("$select", strings.Join(options.Select, ","))
}
headers = mergeHeaders(headers, headersFromStruct(*options))
}

uri := e.Table.tsc.client.getEndpoint(tableServiceName, e.buildPath(), query)
resp, err := e.Table.tsc.client.exec(http.MethodGet, uri, headers, nil, e.Table.tsc.auth)
if err != nil {
return err
}
defer readAndCloseBody(resp.body)

if err = checkRespCode(resp.statusCode, []int{http.StatusOK}); err != nil {
return err
}

respBody, err := ioutil.ReadAll(resp.body)
if err != nil {
return err
}
err = json.Unmarshal(respBody, e)
if err != nil {
return err
}
e.PartitionKey = pk
e.RowKey = rk

return nil
}

// Insert inserts the referenced entity in its table.
// The function fails if there is an entity with the same
// PartitionKey and RowKey in the table.
Expand Down Expand Up @@ -224,15 +282,18 @@ func (e *Entity) UnmarshalJSON(data []byte) error {
e.RowKey = stringFromMap(props, rowKeyNode)

// deserialize timestamp
str, ok := props["Timestamp"].(string)
if !ok {
return fmt.Errorf(errorTemplate, "Timestamp casting error")
}
t, err := time.Parse(time.RFC3339Nano, str)
if err != nil {
return fmt.Errorf(errorTemplate, err)
timeStamp, ok := props["Timestamp"]
if ok {
str, ok := timeStamp.(string)
if !ok {
return fmt.Errorf(errorTemplate, "Timestamp casting error")
}
t, err := time.Parse(time.RFC3339Nano, str)
if err != nil {
return fmt.Errorf(errorTemplate, err)
}
e.TimeStamp = t
}
e.TimeStamp = t
delete(props, "Timestamp")
delete(props, "Timestamp@odata.type")

Expand Down
46 changes: 46 additions & 0 deletions storage/entity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,52 @@ type StorageEntitySuite struct{}

var _ = chk.Suite(&StorageEntitySuite{})

func (s *StorageEntitySuite) TestGet(c *chk.C) {
cli := getTableClient(c)
rec := cli.client.appendRecorder(c)
defer rec.Stop()

table := cli.GetTableReference(tableName(c))

err := table.Create(30, EmptyPayload, nil)
c.Assert(err, chk.IsNil)
defer table.Delete(30, nil)

entity := table.GetEntityReference("mypartitionkey", "myrowkey")

props := map[string]interface{}{
"AmountDue": 200.23,
"CustomerCode": uuid.FromStringOrNil("c9da6455-213d-42c9-9a79-3e9149a57833"),
"CustomerSince": time.Date(1992, time.December, 20, 21, 55, 0, 0, time.UTC),
"IsActive": true,
"NumberOfOrders": int64(255),
}
entity.Properties = props
err = entity.Insert(EmptyPayload, nil)
c.Assert(err, chk.IsNil)

err = entity.Get(30, FullMetadata, &GetEntityOptions{
Select: []string{"IsActive"},
})
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 1)

err = entity.Get(30, FullMetadata, &GetEntityOptions{
Select: []string{
"AmountDue",
"CustomerCode",
"CustomerSince",
"IsActive",
"NumberOfOrders",
}})
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 5)

err = entity.Get(30, FullMetadata, nil)
c.Assert(err, chk.IsNil)
c.Assert(entity.Properties, chk.HasLen, 5)
}

const (
validEtag = "W/\"datetime''2017-04-01T01%3A07%3A23.8881885Z''\""
)
Expand Down
253 changes: 253 additions & 0 deletions storage/recordings/StorageEntitySuite/TestGet.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
---
version: 1
rwmutex: {}
interactions:
- request:
body: |
{"TableName":"table26storageentitysuitetestget"}
form: {}
headers:
Accept:
- application/json;odata=nometadata
Accept-Charset:
- UTF-8
Authorization:
- SharedKey golangrocksonazure:WSKjrlxzsHVqJxVBAM3GHKdqJuaffs6+cjliU1X7+rc=
Content-Length:
- "49"
Content-Type:
- application/json
Prefer:
- return-no-content
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:28 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/Tables?timeout=30
method: POST
response:
body: ""
headers:
Cache-Control:
- no-cache
Content-Length:
- "0"
Dataserviceid:
- https://golangrocksonazure.table.core.windows.net/Tables('table26storageentitysuitetestget')
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Location:
- https://golangrocksonazure.table.core.windows.net/Tables('table26storageentitysuitetestget')
Preference-Applied:
- return-no-content
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca395-0002-0077-53d1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 204 No Content
code: 204
- request:
body: '{"AmountDue":200.23,"CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerCode@odata.type":"Edm.Guid","CustomerSince":"1992-12-20T21:55:00Z","CustomerSince@odata.type":"Edm.DateTime","IsActive":true,"NumberOfOrders":"255","NumberOfOrders@odata.type":"Edm.Int64","PartitionKey":"mypartitionkey","RowKey":"myrowkey"}'
form: {}
headers:
Accept:
- application/json;odata=nometadata
Accept-Charset:
- UTF-8
Authorization:
- SharedKey golangrocksonazure:wcHFp+gr7ZpvZFiASYHDhBYHrlGYf6fYfsMJ3s4tNI0=
Content-Length:
- "323"
Content-Type:
- application/json
Prefer:
- return-no-content
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:30 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget
method: POST
response:
body: ""
headers:
Cache-Control:
- no-cache
Content-Length:
- "0"
Dataserviceid:
- https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey='mypartitionkey',RowKey='myrowkey')
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Etag:
- W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'"
Location:
- https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey='mypartitionkey',RowKey='myrowkey')
Preference-Applied:
- return-no-content
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca3bc-0002-0077-74d1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 204 No Content
code: 204
- request:
body: ""
form: {}
headers:
Accept:
- application/json;odata=fullmetadata
Authorization:
- SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU=
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:30 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?%24select=IsActive&timeout=30
method: GET
response:
body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element&$select=IsActive","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","IsActive":true}'
headers:
Cache-Control:
- no-cache
Content-Type:
- application/json;odata=fullmetadata;streaming=true;charset=utf-8
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Etag:
- W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'"
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca3c5-0002-0077-7bd1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 200 OK
code: 200
- request:
body: ""
form: {}
headers:
Accept:
- application/json;odata=fullmetadata
Authorization:
- SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU=
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:30 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?%24select=AmountDue%2CCustomerCode%2CCustomerSince%2CIsActive%2CNumberOfOrders&timeout=30
method: GET
response:
body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element&$select=AmountDue,CustomerCode,CustomerSince,IsActive,NumberOfOrders","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}'
headers:
Cache-Control:
- no-cache
Content-Type:
- application/json;odata=fullmetadata;streaming=true;charset=utf-8
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Etag:
- W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'"
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca3dc-0002-0077-0ed1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 200 OK
code: 200
- request:
body: ""
form: {}
headers:
Accept:
- application/json;odata=fullmetadata
Authorization:
- SharedKey golangrocksonazure:TXUHWsilHY7Ef/c17zf5K7yTAYVBJauUBGKNBcSGjHU=
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:30 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget%28PartitionKey=%27mypartitionkey%27,%20RowKey=%27myrowkey%27%29?timeout=30
method: GET
response:
body: '{"odata.metadata":"https://golangrocksonazure.table.core.windows.net/$metadata#table26storageentitysuitetestget/@Element","odata.type":"golangrocksonazure.table26storageentitysuitetestget","odata.id":"https://golangrocksonazure.table.core.windows.net/table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","odata.etag":"W/\"datetime''2017-04-21T19%3A01%3A30.1231644Z''\"","odata.editLink":"table26storageentitysuitetestget(PartitionKey=''mypartitionkey'',RowKey=''myrowkey'')","PartitionKey":"mypartitionkey","RowKey":"myrowkey","Timestamp@odata.type":"Edm.DateTime","Timestamp":"2017-04-21T19:01:30.1231644Z","AmountDue":200.23,"CustomerCode@odata.type":"Edm.Guid","CustomerCode":"c9da6455-213d-42c9-9a79-3e9149a57833","CustomerSince@odata.type":"Edm.DateTime","CustomerSince":"1992-12-20T21:55:00Z","IsActive":true,"NumberOfOrders@odata.type":"Edm.Int64","NumberOfOrders":"255"}'
headers:
Cache-Control:
- no-cache
Content-Type:
- application/json;odata=fullmetadata;streaming=true;charset=utf-8
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Etag:
- W/"datetime'2017-04-21T19%3A01%3A30.1231644Z'"
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca3e3-0002-0077-15d1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 200 OK
code: 200
- request:
body: ""
form: {}
headers:
Accept:
- application/json;odata=nometadata
Authorization:
- SharedKey golangrocksonazure:voKWr7ShBYDaJfiGJ6tEcHNivtP4arHfBkOIVbL250w=
Prefer:
- return-no-content
User-Agent:
- Go/go1.8 (amd64-windows) azure-storage-go/0.1.0 api-version/2016-05-31 table
X-Ms-Date:
- Fri, 21 Apr 2017 19:01:30 GMT
X-Ms-Version:
- 2016-05-31
url: https://golangrocksonazure.table.core.windows.net/Tables%28%27table26storageentitysuitetestget%27%29?timeout=30
method: DELETE
response:
body: ""
headers:
Cache-Control:
- no-cache
Content-Length:
- "0"
Date:
- Fri, 21 Apr 2017 19:01:29 GMT
Server:
- Windows-Azure-Table/1.0 Microsoft-HTTPAPI/2.0
X-Content-Type-Options:
- nosniff
X-Ms-Request-Id:
- 01dca3f2-0002-0077-24d1-ba87f8000000
X-Ms-Version:
- 2016-05-31
status: 204 No Content
code: 204
Loading

0 comments on commit 8411265

Please sign in to comment.