Skip to content

Commit 83c0815

Browse files
committed
Add examples for Client.With*() methods
fixes #288
1 parent a7d2f40 commit 83c0815

9 files changed

+433
-78
lines changed

example_test.go

+62-26
Original file line numberDiff line numberDiff line change
@@ -18,42 +18,78 @@ package gel_test
1818

1919
import (
2020
"context"
21-
"testing"
21+
"errors"
22+
"log"
2223

2324
gel "github.com/geldata/gel-go"
25+
"github.com/geldata/gel-go/gelerr"
2426
"github.com/geldata/gel-go/geltypes"
27+
"github.com/geldata/gel-go/internal/testserver"
2528
)
2629

2730
var (
31+
// Define identifiers that are used in examples, but keep them in their own
32+
// file. This way the definition is not included in the example. This keeps
33+
// examples concise.
2834
ctx context.Context
2935
client *gel.Client
36+
id geltypes.UUID
3037
)
3138

32-
// [Link properties] are treated as fields in the linked to struct, and the @
33-
// is omitted from the field's tag.
34-
//
35-
// [Link properties]: https://www.edgedb.com/docs/guides/link_properties
36-
func Example_linkProperty() {
37-
var result []struct {
38-
Name string `gel:"name"`
39-
Friends []struct {
40-
Name string `gel:"name"`
41-
Strength geltypes.OptionalFloat64 `gel:"strength"`
42-
} `gel:"friends"`
39+
func isDuplicateDatabaseDefinitionError(err error) bool {
40+
var gelErr gelerr.Error
41+
return errors.As(err, &gelErr) &&
42+
gelErr.Category(gelerr.DuplicateDatabaseDefinitionError)
43+
}
44+
45+
func init() {
46+
ctx = context.Background()
47+
48+
opts := testserver.Options()
49+
var err error
50+
client, err = gel.CreateClient(opts)
51+
if err != nil {
52+
log.Fatal(err)
4353
}
4454

45-
_ = client.Query(
46-
ctx,
47-
`select Person {
48-
name,
49-
friends: {
50-
name,
51-
@strength,
52-
}
53-
}`,
54-
&result,
55-
)
56-
}
55+
err = client.Execute(ctx, "create empty branch examples")
56+
if err != nil && !isDuplicateDatabaseDefinitionError(err) {
57+
log.Fatal(err)
58+
}
5759

58-
// TestNil makes this not a whole file example. // https://go.dev/blog/examples
59-
func TestNil(t *testing.T) {}
60+
opts.Database = ""
61+
opts.Branch = "examples"
62+
client, err = gel.CreateClient(opts)
63+
if err != nil {
64+
log.Fatal(err)
65+
}
66+
67+
err = client.Execute(ctx, `
68+
START MIGRATION TO {
69+
module default {
70+
# ExampleClient_WithGlobals
71+
global used_everywhere: int64;
72+
73+
type User {};
74+
type Product {};
75+
}
76+
};
77+
POPULATE MIGRATION;
78+
COMMIT MIGRATION;
79+
`)
80+
if err != nil {
81+
log.Fatal(err)
82+
}
83+
84+
// The server sends warnings in response to both parse and execute. We
85+
// don't want the same warning to show up twice in
86+
// ExampleClient_WithWarningHandler, so make sure this query is cached
87+
// before the example is run.
88+
err = client.
89+
// Don't log the warning.
90+
WithWarningHandler(func(_ []error) error { return nil }).
91+
Execute(ctx, `SELECT _warn_on_call()`)
92+
if err != nil {
93+
log.Fatal(err)
94+
}
95+
}

gelcfg/options.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ import (
2727
// WarningHandler takes an error slice that represent warnings and optionally
2828
// returns an error. This can be used to log warnings, increment metrics,
2929
// promote warnings to errors by returning them etc.
30+
//
31+
// See [github.com/geldata/gel-go.Client.WithWarningHandler] for an example.
3032
type WarningHandler = func([]error) error
3133

32-
// LogWarnings is a [WarningHandler] that logs warnings.
34+
// LogWarnings is a [WarningHandler] that logs warnings using [log.Println].
3335
func LogWarnings(errors []error) error {
3436
for _, err := range errors {
3537
log.Println("Gel warning:", err.Error())
@@ -173,6 +175,8 @@ const (
173175
)
174176

175177
// ModuleAlias is an alias name and module name pair.
178+
//
179+
// See [github.com/geldata/gel-go.Client.WithModuleAliases] for example usage.
176180
type ModuleAlias struct {
177181
Alias string
178182
Module string

gelcfg/queryoptions.go

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ func NewQueryOptions() QueryOptions {
2424

2525
// QueryOptions controls limitations that the server can impose on
2626
// queries.
27+
//
28+
// See [github.com/geldata/gel-go.Client.WithQueryOptions] for example usage.
2729
type QueryOptions struct {
2830
fromFactory bool
2931

gelcfg/retryoptions.go

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ func NewRetryOptions() RetryOptions {
4545
// RetryOptions configures how failed transactions or queries outside of
4646
// transactions are retried. Use [NewRetryOptions] to get a default
4747
// RetryOptions value instead of creating one yourself.
48+
//
49+
// See [github.com/geldata/gel-go.Client.WithRetryOptions] for an example.
4850
type RetryOptions struct {
4951
fromFactory bool
5052
txConflict RetryRule

gelcfg/retryrule.go

+2
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ func NewRetryRule() RetryRule {
5757
// should be tried again based on [RetryRule.Attempts] and the amount of time
5858
// to wait before retrying is determined by [RetryRule.Backoff].
5959
// The default retry rule is 3 attempts and exponential backoff with jitter.
60+
//
61+
// See [github.com/geldata/gel-go.Client.WithRetryOptions] for an example.
6062
type RetryRule struct {
6163
// fromFactory indicates that a RetryOptions value was created using
6264
// NewRetryOptions() and not created directly. Requiring users to use the

gelcfg/txoptions.go

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ func NewTxOptions() TxOptions {
3737
}
3838

3939
// TxOptions configures how transactions behave.
40+
//
41+
// See [github.com/geldata/gel-go.Client.WithTxOptions] for an example.
4042
type TxOptions struct {
4143
// fromFactory indicates that a TxOptions value was created using
4244
// NewTxOptions() and not created directly with TxOptions{}.

options.go

+39-51
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,8 @@ import (
2626
gelerrint "github.com/geldata/gel-go/internal/gelerr"
2727
)
2828

29-
// WithTxOptions returns a shallow copy of the client
30-
// with the TxOptions set to opts.
31-
func (c Client) WithTxOptions(
32-
opts gelcfg.TxOptions,
33-
) *Client { // nolint:gocritic
29+
// WithTxOptions returns a copy of c with the [gelcfg.TxOptions] set to opts.
30+
func (c Client) WithTxOptions(opts gelcfg.TxOptions) *Client { //nolint:gocritic,lll
3431
if !opts.IsValid() {
3532
panic("TxOptions not created with NewTxOptions() are not valid")
3633
}
@@ -40,11 +37,9 @@ func (c Client) WithTxOptions(
4037
return &c
4138
}
4239

43-
// WithRetryOptions returns a shallow copy of the client
40+
// WithRetryOptions returns a copy of c
4441
// with the RetryOptions set to opts.
45-
func (c Client) WithRetryOptions( // nolint:gocritic
46-
opts gelcfg.RetryOptions,
47-
) *Client {
42+
func (c Client) WithRetryOptions(opts gelcfg.RetryOptions) *Client { //nolint:gocritic,lll
4843
if !opts.IsValid() {
4944
panic("RetryOptions not created with NewRetryOptions() are not valid")
5045
}
@@ -62,15 +57,13 @@ func (c *Client) copyPool() {
6257
c.pool = &pool
6358
}
6459

65-
// WithConfig returns a shallow copy of the client
60+
// WithConfig returns a copy of c
6661
// with configuration values set to cfg.
67-
// Equivalent to using the edgeql configure session command.
68-
// For available configuration parameters refer to the [Config documentation].
62+
// This is equivalent to using the edgeql configure session command.
63+
// For available configuration parameters refer to the [config documentation].
6964
//
70-
// [Config documentation]: https://docs.geldata.com/reference/stdlib/cfg#ref-std-cfg
71-
func (c Client) WithConfig( // nolint:gocritic
72-
cfg map[string]interface{},
73-
) *Client {
65+
// [config documentation]: https://docs.geldata.com/reference/stdlib/cfg#ref-std-cfg
66+
func (c Client) WithConfig(cfg map[string]interface{}) *Client { //nolint:gocritic,lll
7467
state := gel.CopyState(c.pool.State)
7568

7669
var config map[string]interface{}
@@ -90,8 +83,7 @@ func (c Client) WithConfig( // nolint:gocritic
9083
return &c
9184
}
9285

93-
// WithoutConfig returns a shallow copy of the client
94-
// with keys unset from the configuration.
86+
// WithoutConfig returns a copy of c with keys unset from the configuration.
9587
func (c Client) WithoutConfig(key ...string) *Client { // nolint:gocritic
9688
state := gel.CopyState(c.pool.State)
9789

@@ -107,11 +99,9 @@ func (c Client) WithoutConfig(key ...string) *Client { // nolint:gocritic
10799
return &c
108100
}
109101

110-
// WithModuleAliases returns a shallow copy of the client
111-
// with module name aliases set to aliases.
112-
func (c Client) WithModuleAliases( // nolint:gocritic
113-
aliases ...gelcfg.ModuleAlias,
114-
) *Client {
102+
// WithModuleAliases returns a copy of c with module name aliases set to
103+
// aliases.
104+
func (c Client) WithModuleAliases(aliases ...gelcfg.ModuleAlias) *Client { //nolint:gocritic,lll
115105
state := gel.CopyState(c.pool.State)
116106

117107
var a []interface{}
@@ -129,11 +119,8 @@ func (c Client) WithModuleAliases( // nolint:gocritic
129119
return &c
130120
}
131121

132-
// WithoutModuleAliases returns a shallow copy of the client
133-
// with aliases unset.
134-
func (c Client) WithoutModuleAliases( // nolint:gocritic
135-
aliases ...string,
136-
) *Client {
122+
// WithoutModuleAliases returns a copy of c with aliases unset.
123+
func (c Client) WithoutModuleAliases(aliases ...string) *Client { //nolint:gocritic,lll
137124
state := gel.CopyState(c.pool.State)
138125

139126
if a, ok := state["aliases"]; ok {
@@ -159,10 +146,12 @@ func (c Client) WithoutModuleAliases( // nolint:gocritic
159146
return &c
160147
}
161148

162-
// WithGlobals sets values for global variables for the returned client.
163-
func (c Client) WithGlobals( // nolint:gocritic
164-
globals map[string]interface{},
165-
) *Client {
149+
// WithGlobals returns a copy of c with its global variables updated from
150+
// globals.
151+
//
152+
// WithGlobals does not remove variables that are not mentioned in globals.
153+
// Instead use [Client.WithoutGlobals].
154+
func (c Client) WithGlobals(globals map[string]interface{}) *Client { //nolint:gocritic,lll
166155
state := gel.CopyState(c.pool.State)
167156

168157
var g map[string]interface{}
@@ -182,8 +171,8 @@ func (c Client) WithGlobals( // nolint:gocritic
182171
return &c
183172
}
184173

185-
// WithoutGlobals unsets values for global variables for the returned client.
186-
func (c Client) WithoutGlobals(globals ...string) *Client { // nolint:gocritic
174+
// WithoutGlobals returns a copy of c with the specified global names unset.
175+
func (c Client) WithoutGlobals(globals ...string) *Client { //nolint:gocritic
187176
state := gel.CopyState(c.pool.State)
188177

189178
if c, ok := state["globals"]; ok {
@@ -198,31 +187,31 @@ func (c Client) WithoutGlobals(globals ...string) *Client { // nolint:gocritic
198187
return &c
199188
}
200189

201-
// WithWarningHandler sets the warning handler for the returned client. If
202-
// warningHandler is nil gelcfg.LogWarnings is used.
203-
func (c Client) WithWarningHandler( // nolint:gocritic
204-
warningHandler gelcfg.WarningHandler,
205-
) *Client {
206-
if warningHandler == nil {
207-
warningHandler = gelcfg.LogWarnings
190+
// WithWarningHandler returns a copy of c with its [gelcfg.WarningHandler] set
191+
// to handler. If handler is nil, [gelcfg.LogWarnings] is used.
192+
func (c Client) WithWarningHandler(handler gelcfg.WarningHandler) *Client { //nolint:gocritic,lll
193+
if handler == nil {
194+
handler = gelcfg.LogWarnings
208195
}
209196

210197
c.copyPool()
211-
c.pool.QueryConfig.WarningHandler = warningHandler
198+
c.pool.QueryConfig.WarningHandler = handler
212199
return &c
213200
}
214201

215-
// WithQueryOptions sets the [gelcfg.QueryOptions] for the returned Client.
216-
func (c Client) WithQueryOptions(
217-
options gelcfg.QueryOptions,
218-
) *Client { // nolint:gocritic
202+
// WithQueryOptions returns a copy of c with its gelcfg.Queryoptions set to
203+
// opts.
204+
func (c Client) WithQueryOptions(opts gelcfg.QueryOptions) *Client { //nolint:gocritic,lll
219205
c.copyPool()
220-
c.pool.QueryConfig.QueryOptions = options
206+
c.pool.QueryConfig.QueryOptions = opts
221207
return &c
222208
}
223209

224-
// WithQueryTag returns a copy of the client with the [sys::QueryStats] tag
225-
// set.
210+
// WithQueryTag returns a copy of c with the [sys::QueryStats] tag set.
211+
//
212+
// sys::QueryStats only records the tag from the first time a query is run.
213+
// Running the query again with a different tag will not change the tag in the
214+
// sys::QueryStats entry.
226215
//
227216
// [sys::QueryStats]: https://docs.geldata.com/reference/stdlib/sys#type::sys::QueryStats
228217
func (c Client) WithQueryTag(tag string) (*Client, error) {
@@ -247,8 +236,7 @@ func (c Client) WithQueryTag(tag string) (*Client, error) {
247236
return &c, nil
248237
}
249238

250-
// WithoutQueryTag returns a copy of the client with the [sys::QueryStats] tag
251-
// removed.
239+
// WithoutQueryTag returns a copy of c with the [sys::QueryStats] tag removed.
252240
//
253241
// [sys::QueryStats]: https://docs.geldata.com/reference/stdlib/sys#type::sys::QueryStats
254242
func (c Client) WithoutQueryTag() *Client {

0 commit comments

Comments
 (0)