Skip to content

Commit 9e475dc

Browse files
authored
Merge pull request #49 from assembly-winston/addContexts
Added ctx arguments to execute
2 parents d395489 + bbd1ae5 commit 9e475dc

File tree

4 files changed

+80
-18
lines changed

4 files changed

+80
-18
lines changed

execute.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package postgrest
22

33
import (
44
"bytes"
5+
"context"
56
"encoding/json"
67
"errors"
78
"fmt"
@@ -25,14 +26,14 @@ type ExecuteError struct {
2526
Message string `json:"message"`
2627
}
2728

28-
func executeHelper(client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) ([]byte, countType, error) {
29+
func executeHelper(ctx context.Context, client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) ([]byte, countType, error) {
2930
if client.ClientError != nil {
3031
return nil, 0, client.ClientError
3132
}
3233

3334
readerBody := bytes.NewBuffer(body)
3435
baseUrl := path.Join(append([]string{client.Transport.baseURL.Path}, urlFragments...)...)
35-
req, err := http.NewRequest(method, baseUrl, readerBody)
36+
req, err := http.NewRequestWithContext(ctx, method, baseUrl, readerBody)
3637
if err != nil {
3738
return nil, 0, fmt.Errorf("error creating request: %s", err.Error())
3839
}
@@ -86,17 +87,17 @@ func executeHelper(client *Client, method string, body []byte, urlFragments []st
8687
return respBody, count, nil
8788
}
8889

89-
func executeString(client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) (string, countType, error) {
90-
resp, count, err := executeHelper(client, method, body, urlFragments, headers, params)
90+
func executeString(ctx context.Context, client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) (string, countType, error) {
91+
resp, count, err := executeHelper(ctx, client, method, body, urlFragments, headers, params)
9192
return string(resp), count, err
9293
}
9394

94-
func execute(client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) ([]byte, countType, error) {
95-
return executeHelper(client, method, body, urlFragments, headers, params)
95+
func execute(ctx context.Context, client *Client, method string, body []byte, urlFragments []string, headers map[string]string, params map[string]string) ([]byte, countType, error) {
96+
return executeHelper(ctx, client, method, body, urlFragments, headers, params)
9697
}
9798

98-
func executeTo(client *Client, method string, body []byte, to interface{}, urlFragments []string, headers map[string]string, params map[string]string) (countType, error) {
99-
resp, count, err := executeHelper(client, method, body, urlFragments, headers, params)
99+
func executeTo(ctx context.Context, client *Client, method string, body []byte, to interface{}, urlFragments []string, headers map[string]string, params map[string]string) (countType, error) {
100+
resp, count, err := executeHelper(ctx, client, method, body, urlFragments, headers, params)
100101

101102
if err != nil {
102103
return count, err

filterbuilder.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package postgrest
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"regexp"
@@ -21,19 +22,38 @@ type FilterBuilder struct {
2122
// ExecuteString runs the PostgREST query, returning the result as a JSON
2223
// string.
2324
func (f *FilterBuilder) ExecuteString() (string, int64, error) {
24-
return executeString(f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
25+
return executeString(context.Background(), f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
26+
}
27+
28+
// ExecuteStringWithContext runs the PostgREST query, returning the result as
29+
// a JSON string.
30+
func (f *FilterBuilder) ExecuteStringWithContext(ctx context.Context) (string, int64, error) {
31+
return executeString(ctx, f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
2532
}
2633

2734
// Execute runs the PostgREST query, returning the result as a byte slice.
2835
func (f *FilterBuilder) Execute() ([]byte, int64, error) {
29-
return execute(f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
36+
return execute(context.Background(), f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
37+
}
38+
39+
// ExecuteWithContext runs the PostgREST query with the given context,
40+
// returning the result as a byte slice.
41+
func (f *FilterBuilder) ExecuteWithContext(ctx context.Context) ([]byte, int64, error) {
42+
return execute(ctx, f.client, f.method, f.body, []string{f.tableName}, f.headers, f.params)
3043
}
3144

3245
// ExecuteTo runs the PostgREST query, encoding the result to the supplied
3346
// interface. Note that the argument for the to parameter should always be a
3447
// reference to a slice.
3548
func (f *FilterBuilder) ExecuteTo(to interface{}) (countType, error) {
36-
return executeTo(f.client, f.method, f.body, to, []string{f.tableName}, f.headers, f.params)
49+
return executeTo(context.Background(), f.client, f.method, f.body, to, []string{f.tableName}, f.headers, f.params)
50+
}
51+
52+
// ExecuteToWithContext runs the PostgREST query with the given context,
53+
// encoding the result to the supplied interface. Note that the argument for
54+
// the to parameter should always be a reference to a slice.
55+
func (f *FilterBuilder) ExecuteToWithContext(ctx context.Context, to interface{}) (countType, error) {
56+
return executeTo(ctx, f.client, f.method, f.body, to, []string{f.tableName}, f.headers, f.params)
3757
}
3858

3959
var filterOperators = []string{"eq", "neq", "gt", "gte", "lt", "lte", "like", "ilike", "is", "in", "cs", "cd", "sl", "sr", "nxl", "nxr", "adj", "ov", "fts", "plfts", "phfts", "wfts"}
@@ -158,7 +178,7 @@ func (f *FilterBuilder) Contains(column string, value []string) *FilterBuilder {
158178
}
159179

160180
valueString := fmt.Sprintf("{%s}", strings.Join(newValue, ","))
161-
181+
162182
f.params[column] = "cs." + valueString
163183
return f
164184
}
@@ -170,7 +190,7 @@ func (f *FilterBuilder) ContainedBy(column string, value []string) *FilterBuilde
170190
}
171191

172192
valueString := fmt.Sprintf("{%s}", strings.Join(newValue, ","))
173-
193+
174194
f.params[column] = "cd." + valueString
175195
return f
176196
}

filterbuilder_test.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package postgrest
22

33
import (
4+
"context"
45
"encoding/json"
56
"net/http"
67
"sort"
78
"testing"
9+
"time"
810

911
"github.com/jarcoal/httpmock"
1012
"github.com/stretchr/testify/assert"
@@ -120,6 +122,25 @@ func TestFilterBuilder_Limit(t *testing.T) {
120122
assert.Equal(countType(len(users)), count, "expected count to be %v", len(users))
121123
}
122124

125+
func TestFilterBuilder_ContextCanceled(t *testing.T) {
126+
c := createClient(t)
127+
assert := assert.New(t)
128+
129+
if mockResponses {
130+
httpmock.Activate()
131+
defer httpmock.DeactivateAndReset()
132+
}
133+
134+
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Nanosecond)
135+
defer cancel()
136+
137+
time.Sleep(1 * time.Nanosecond)
138+
139+
_, _, err := c.From("users").Select("id, name, email", "exact", false).Limit(1, "").ExecuteWithContext(ctx)
140+
// This test should immediately fail on a canceled context.
141+
assert.Error(err)
142+
}
143+
123144
func TestFilterBuilder_Order(t *testing.T) {
124145
c := createClient(t)
125146
assert := assert.New(t)

querybuilder.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package postgrest
22

33
import (
4+
"context"
45
"encoding/json"
56
"fmt"
67
"strings"
@@ -16,22 +17,41 @@ type QueryBuilder struct {
1617
params map[string]string
1718
}
1819

19-
// ExecuteString runs the Postgrest query, returning the result as a JSON
20+
// ExecuteString runs the PostgREST query, returning the result as a JSON
2021
// string.
2122
func (q *QueryBuilder) ExecuteString() (string, int64, error) {
22-
return executeString(q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
23+
return executeString(context.Background(), q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
24+
}
25+
26+
// ExecuteStringWithContext runs the PostgREST query, returning the result as
27+
// a JSON string.
28+
func (q *QueryBuilder) ExecuteStringWithContext(ctx context.Context) (string, int64, error) {
29+
return executeString(ctx, q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
2330
}
2431

2532
// Execute runs the Postgrest query, returning the result as a byte slice.
2633
func (q *QueryBuilder) Execute() ([]byte, int64, error) {
27-
return execute(q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
34+
return execute(context.Background(), q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
35+
}
36+
37+
// ExecuteWithContext runs the PostgREST query with the given context,
38+
// returning the result as a byte slice.
39+
func (q *QueryBuilder) ExecuteWithContext(ctx context.Context) ([]byte, int64, error) {
40+
return execute(ctx, q.client, q.method, q.body, []string{q.tableName}, q.headers, q.params)
2841
}
2942

30-
// ExecuteTo runs the Postgrest query, encoding the result to the supplied
43+
// ExecuteTo runs the PostgREST query, encoding the result to the supplied
3144
// interface. Note that the argument for the to parameter should always be a
3245
// reference to a slice.
3346
func (q *QueryBuilder) ExecuteTo(to interface{}) (int64, error) {
34-
return executeTo(q.client, q.method, q.body, to, []string{q.tableName}, q.headers, q.params)
47+
return executeTo(context.Background(), q.client, q.method, q.body, to, []string{q.tableName}, q.headers, q.params)
48+
}
49+
50+
// ExecuteToWithContext runs the PostgREST query with the given context,
51+
// encoding the result to the supplied interface. Note that the argument for
52+
// the to parameter should always be a reference to a slice.
53+
func (q *QueryBuilder) ExecuteToWithContext(ctx context.Context, to interface{}) (int64, error) {
54+
return executeTo(ctx, q.client, q.method, q.body, to, []string{q.tableName}, q.headers, q.params)
3555
}
3656

3757
// Select performs vertical filtering.

0 commit comments

Comments
 (0)