Skip to content

Commit 6d24496

Browse files
fmoorscotttrinh
andauthored
Add examples for Client.With*() methods (#353)
fixes #288 Co-authored-by: Scott Trinh <scott@scotttrinh.com>
1 parent 308430c commit 6d24496

18 files changed

+641
-204
lines changed

.golangci.yml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,10 +263,15 @@ issues:
263263

264264
# Excluding configuration per-path, per-linter, per-text and per-source
265265
exclude-rules:
266-
# Exclude doc links
267-
- linters:
266+
# Don't complain about doc link urls that are more then 80 characters
267+
- source: "^// \\[.*\\]: http"
268+
linters:
268269
- lll
269-
source: "^// \\[.*\\]: http"
270+
271+
# Don't complain about using our own deprecated gelcfg.Options.Database.
272+
- source: "\\.Database[ ,)]"
273+
linters:
274+
- staticcheck
270275

271276
# Independently from option `exclude` we use default exclude patterns,
272277
# it can be disabled by this option. To list all

client.go

Lines changed: 42 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,26 @@ import (
2020
"context"
2121

2222
"github.com/geldata/gel-go/gelcfg"
23+
"github.com/geldata/gel-go/gelerr"
2324
"github.com/geldata/gel-go/geltypes"
2425
gel "github.com/geldata/gel-go/internal/client"
2526
)
2627

2728
// CreateClient returns a new client. The client connects lazily. Call
28-
// Client.EnsureConnected() to force a connection.
29+
// [Client.EnsureConnected] to force a connection.
30+
//
31+
// Instead of providing connection details directly, we recommend connecting
32+
// using projects locally, and environment variables for remote instances,
33+
// providing an empty [gelcfg.Options] struct here.
34+
// [Read more] about the recommended ways to configure client connections.
35+
//
36+
// [Read more]: https://docs.geldata.com/reference/clients/connection
2937
func CreateClient(opts gelcfg.Options) (*Client, error) { // nolint:gocritic,lll
3038
return CreateClientDSN("", opts)
3139
}
3240

33-
// CreateClientDSN returns a new client. See also CreateClient.
41+
// CreateClientDSN returns a new Client. We recommend using [CreateClient] for
42+
// most use cases.
3443
//
3544
// dsn is either an instance name or a [DSN].
3645
//
@@ -51,7 +60,11 @@ type Client struct {
5160
pool *gel.Pool
5261
}
5362

54-
// EnsureConnected forces the client to connect if it hasn't already.
63+
// EnsureConnected forces the client to connect if it hasn't already. This can
64+
// be used to ensure that your program will fail early in the case that the
65+
// [configured connection parameters] are not correct.
66+
//
67+
// [configured connection parameters]: https://docs.geldata.com/reference/clients/connection
5568
func (c *Client) EnsureConnected(ctx context.Context) error {
5669
return c.pool.EnsureConnected(ctx)
5770
}
@@ -62,11 +75,7 @@ func (c *Client) EnsureConnected(ctx context.Context) error {
6275
func (c *Client) Close() error { return c.pool.Close() }
6376

6477
// Execute an EdgeQL command (or commands).
65-
func (c *Client) Execute(
66-
ctx context.Context,
67-
cmd string,
68-
args ...interface{},
69-
) error {
78+
func (c *Client) Execute(ctx context.Context, cmd string, args ...interface{}) error { //nolint:lll
7079
conn, err := c.pool.Acquire(ctx)
7180
if err != nil {
7281
return err
@@ -91,12 +100,7 @@ func (c *Client) Execute(
91100
}
92101

93102
// Query runs a query and returns the results.
94-
func (c *Client) Query(
95-
ctx context.Context,
96-
cmd string,
97-
out interface{},
98-
args ...interface{},
99-
) error {
103+
func (c *Client) Query(ctx context.Context, cmd string, out interface{}, args ...interface{}) error { //nolint:lll
100104
conn, err := c.pool.Acquire(ctx)
101105
if err != nil {
102106
return err
@@ -115,16 +119,15 @@ func (c *Client) Query(
115119
return gel.FirstError(err, c.pool.Release(conn, err))
116120
}
117121

118-
// QuerySingle runs a singleton-returning query and returns its element.
119-
// If the query executes successfully but doesn't return a result
120-
// a NoDataError is returned. If the out argument is an optional type the out
121-
// argument will be set to missing instead of returning a NoDataError.
122-
func (c *Client) QuerySingle(
123-
ctx context.Context,
124-
cmd string,
125-
out interface{},
126-
args ...interface{},
127-
) error {
122+
// needed for dock link [gelerr.NoDataError]
123+
var _ = gelerr.NoDataError
124+
125+
// QuerySingle runs a singleton-returning query and returns its element. If
126+
// the query executes successfully but doesn't return a result a
127+
// [gelerr.NoDataError] is returned. If the out
128+
// argument is an optional type the out argument will be set to missing instead
129+
// of returning a NoDataError.
130+
func (c *Client) QuerySingle(ctx context.Context, cmd string, out interface{}, args ...interface{}) error { //nolint:lll
128131
conn, err := c.pool.Acquire(ctx)
129132
if err != nil {
130133
return err
@@ -143,13 +146,8 @@ func (c *Client) QuerySingle(
143146
return gel.FirstError(err, c.pool.Release(conn, err))
144147
}
145148

146-
// QueryJSON runs a query and return the results as JSON.
147-
func (c *Client) QueryJSON(
148-
ctx context.Context,
149-
cmd string,
150-
out *[]byte,
151-
args ...interface{},
152-
) error {
149+
// QueryJSON runs a query and returns the results as JSON.
150+
func (c *Client) QueryJSON(ctx context.Context, cmd string, out *[]byte, args ...interface{}) error { //nolint:lll
153151
conn, err := c.pool.Acquire(ctx)
154152
if err != nil {
155153
return err
@@ -170,13 +168,8 @@ func (c *Client) QueryJSON(
170168

171169
// QuerySingleJSON runs a singleton-returning query.
172170
// If the query executes successfully but doesn't have a result
173-
// a NoDataError is returned.
174-
func (c *Client) QuerySingleJSON(
175-
ctx context.Context,
176-
cmd string,
177-
out interface{},
178-
args ...interface{},
179-
) error {
171+
// a [gelerr.NoDataError] is returned.
172+
func (c *Client) QuerySingleJSON(ctx context.Context, cmd string, out interface{}, args ...interface{}) error { //nolint:lll
180173
conn, err := c.pool.Acquire(ctx)
181174
if err != nil {
182175
return err
@@ -196,12 +189,7 @@ func (c *Client) QuerySingleJSON(
196189
}
197190

198191
// QuerySQL runs a SQL query and returns the results.
199-
func (c *Client) QuerySQL(
200-
ctx context.Context,
201-
cmd string,
202-
out interface{},
203-
args ...interface{},
204-
) error {
192+
func (c *Client) QuerySQL(ctx context.Context, cmd string, out interface{}, args ...interface{}) error { //nolint:lll
205193
conn, err := c.pool.Acquire(ctx)
206194
if err != nil {
207195
return err
@@ -221,11 +209,7 @@ func (c *Client) QuerySQL(
221209
}
222210

223211
// ExecuteSQL executes a SQL command (or commands).
224-
func (c *Client) ExecuteSQL(
225-
ctx context.Context,
226-
cmd string,
227-
args ...interface{},
228-
) error {
212+
func (c *Client) ExecuteSQL(ctx context.Context, cmd string, args ...interface{}) error { //nolint:lll
229213
conn, err := c.pool.Acquire(ctx)
230214
if err != nil {
231215
return err
@@ -249,11 +233,16 @@ func (c *Client) ExecuteSQL(
249233
return gel.FirstError(err, c.pool.Release(conn, err))
250234
}
251235

252-
// Tx runs action in a transaction retrying failed attempts.
236+
// Tx runs action in a transaction retrying failed attempts. Queries must be
237+
// executed on the [geltypes.Tx] that is passed to action. Queries executed on
238+
// the client in a geltypes.TxBlock will not run in the transaction and will be
239+
// applied immediately.
253240
//
254-
// Retries are governed by [gelcfg.RetryOptions] and [gelcfg.RetryRule].
255-
// retry options can be set using [Client.WithRetryOptions].
256-
// See [gelcfg.RetryRule] for more details on how they work.
241+
// The geltypes.TxBlock may be re-run if any of the queries fail in a way that
242+
// might succeed on subsequent attempts. Retries are governed by
243+
// [gelcfg.RetryOptions] and [gelcfg.RetryRule]. Retry options can be set
244+
// using [Client.WithRetryOptions]. See [gelcfg.RetryRule] for more details on
245+
// how they work.
257246
func (c *Client) Tx(ctx context.Context, action geltypes.TxBlock) error {
258247
conn, err := c.pool.Acquire(ctx)
259248
if err != nil {

client_examples_test.go

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
// This source file is part of the Gel open source project.
2+
//
3+
// Copyright Gel Data Inc. and the Gel authors.
4+
//
5+
// Licensed under the Apache License, Version 2.0 (the "License");
6+
// you may not use this file except in compliance with the License.
7+
// You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing, software
12+
// distributed under the License is distributed on an "AS IS" BASIS,
13+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
// See the License for the specific language governing permissions and
15+
// limitations under the License.
16+
17+
package gel_test
18+
19+
import (
20+
"fmt"
21+
"log"
22+
23+
gel "github.com/geldata/gel-go"
24+
)
25+
26+
func ExampleCreateClient() {
27+
client, err := gel.CreateClient(opts)
28+
if err != nil {
29+
log.Fatal(err)
30+
}
31+
32+
var result int64
33+
err = client.QuerySingle(ctx, `SELECT 1`, &result)
34+
if err != nil {
35+
fmt.Println(err)
36+
}
37+
38+
fmt.Println(result)
39+
// Output: 1
40+
}
41+
42+
func ExampleClient_Execute() {
43+
err := client.Execute(ctx, "INSERT Product")
44+
if err != nil {
45+
log.Fatal(err)
46+
}
47+
48+
// Output:
49+
}
50+
51+
func ExampleClient_ExecuteSQL() {
52+
err := client.ExecuteSQL(ctx, `INSERT INTO "Product" DEFAULT VALUES`)
53+
if err != nil {
54+
log.Fatal(err)
55+
}
56+
57+
// Output:
58+
}
59+
60+
func ExampleClient_Query() {
61+
var output []struct {
62+
Result int64 `gel:"result"`
63+
}
64+
65+
err := client.Query(ctx, `SELECT {result := 2 + 2}`, &output)
66+
if err != nil {
67+
log.Fatal(err)
68+
}
69+
70+
fmt.Print(output)
71+
// Output: [{4}]
72+
}
73+
74+
func ExampleClient_QueryJSON() {
75+
var output []byte
76+
err := client.QueryJSON(ctx, `SELECT {result := 2 + 2}`, &output)
77+
if err != nil {
78+
log.Fatal(err)
79+
}
80+
81+
fmt.Println(string(output))
82+
// Output: [{"result" : 4}]
83+
}
84+
85+
func ExampleClient_QuerySQL() {
86+
var output []struct {
87+
Result int32 `gel:"result"`
88+
}
89+
90+
err := client.QuerySQL(ctx, `SELECT 2 + 2 AS result`, &output)
91+
if err != nil {
92+
log.Fatal(err)
93+
}
94+
95+
fmt.Println(output)
96+
// Output: [{4}]
97+
}
98+
99+
func ExampleClient_QuerySingle() {
100+
var output struct {
101+
Result int64 `gel:"result"`
102+
}
103+
104+
err := client.QuerySingle(ctx, `SELECT {result := 2 + 2}`, &output)
105+
if err != nil {
106+
log.Fatal(err)
107+
}
108+
109+
fmt.Print(output)
110+
// Output: {4}
111+
}
112+
113+
func ExampleClient_QuerySingleJSON() {
114+
var output []byte
115+
err := client.QuerySingleJSON(ctx, `SELECT {result := 2 + 2}`, &output)
116+
if err != nil {
117+
log.Fatal(err)
118+
}
119+
120+
fmt.Println(string(output))
121+
// Output: {"result" : 4}
122+
}

connect_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func TestAuth(t *testing.T) {
3838
Port: opts.Port,
3939
User: "user_with_password",
4040
Password: types.NewOptionalStr("secret"),
41-
Database: opts.Database, //nolint:staticcheck // SA1019
41+
Database: opts.Database,
4242
TLSOptions: opts.TLSOptions,
4343
})
4444
require.NoError(t, err)
@@ -123,7 +123,7 @@ func TestConnectTimeout(t *testing.T) {
123123
Port: opts.Port,
124124
User: opts.User,
125125
Password: opts.Password,
126-
Database: opts.Database, //nolint:staticcheck // SA1019
126+
Database: opts.Database,
127127
ConnectTimeout: 2 * time.Nanosecond,
128128
WaitUntilAvailable: 1 * time.Nanosecond,
129129
})

0 commit comments

Comments
 (0)