Skip to content

Instantly share code, notes, and snippets.

Avatar

Steve Coffman StevenACoffman

View GitHub Profile
@StevenACoffman
StevenACoffman / apollo-sandbox-sri.go
Last active June 22, 2023 15:37
Get latest Apollo Sandbox Playground and SRI
View apollo-sandbox-sri.go
// Gets the latest Apollo Embedded Sandbox Playground URL from the CDN S3 bucket
//
// To get the Subresource Integrity check, `go run main.go` and take what that outputs and run like this:
// CDN_FILE=https://embeddable-sandbox.cdn.apollographql.com/58165cf7452dbad480c7cb85e7acba085b3bac1d/embeddable-sandbox.umd.production.min.js
// curl -s $CDN_FILE | openssl dgst -sha256 -binary | openssl base64 -A; echo
package main
import (
"encoding/xml"
View pgx-sqlc-etc.md

sqlc isn’t an ORM, but it implements one of the most useful features of one – mapping a query back into a struct without the need for boilerplate. If you have query with a SELECT * or RETURNING *, it knows which fields a table is supposed to have, and emits the result to a standard struct representing its records. All queries for a particular table that return its complete set of fields get to share the same output struct.

Rather than implement its own partially-complete SQL parser, sqlc uses PGAnalyze’s excellent pg_query_go, which bakes in the same query parser that Postgres really uses. It’s never given me trouble so far – even complex queries with unusual Postgres embellishments work.

This query parsing also gives you some additional pre-runtime code verification. It won’t protect you against logical bugs, but it won’t compile invalid SQL queries, which is a far shot better than the guarantees you get with SQL-in-Go-strings. And thanks to SQL’s declarative nature, it tends to produce fewer bugs than com

@StevenACoffman
StevenACoffman / golangci.yaml
Created March 28, 2023 13:45 — forked from cristaloleg/golangci.yaml
Go linters configuration, the right version.
View golangci.yaml
# See: https://olegk.dev/go-linters-configuration-the-right-version
run:
# Depends on your hardware, my laptop can survive 8 threads.
concurrency: 8
# I really care about the result, so I'm fine to wait for it.
timeout: 30m
# Fail if the error was met.
@StevenACoffman
StevenACoffman / dial-pq-via-ssh.go
Created March 26, 2023 16:13 — forked from vinzenz/dial-pq-via-ssh.go
Use postgres via SSH in Golang
View dial-pq-via-ssh.go
package main
import (
"database/sql"
"database/sql/driver"
"fmt"
"net"
"os"
"time"
@StevenACoffman
StevenACoffman / example_test.go
Last active February 7, 2023 22:44
Golang Testify go-cmp Partial Equal
View example_test.go
package main
import (
"fmt"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/stretchr/testify/assert"
@StevenACoffman
StevenACoffman / slog_console_handler.go
Last active March 26, 2023 23:09 — forked from wijayaerick/slog_console_handler.go
Example ConsoleHandler for golang.org/x/exp/slog Logger
View slog_console_handler.go
// ConsoleHandler formats slog.Logger output in console format, a bit similar with Uber's zap
// ConsoleEncoder or Apex's CLI log
// The log format is designed to be human-readable.
//
// Performance can definitely be improved, however it's not my priority as
// this should only be used in development environment.
//
// e.g. log output:
// • ./main.go:21 Debug message {"hello":"world","!BADKEY":"bad kv"}
// ℹ ./main.go:217 Info message {"with_key_1":"with_value_1","group_1":{"with_key_2":"with_value_2","hello":"world"}}
View test.go
RunParallel(t, TestCase{
Steps: []TestStep{
{
Query: `
query getWorksheet($id: ObjectId!) {
worksheet(id: $id) {
id
label
name
}
@StevenACoffman
StevenACoffman / main.go
Created September 2, 2022 18:26 — forked from pteich/main.go
Example for using go's sync.errgroup together with signal detection signal.Notify to stop all running goroutines
View main.go
package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"os"
@StevenACoffman
StevenACoffman / TypesInGraphQLvsGo.md
Created August 22, 2022 17:19
Differences in the Type System in GraphQL vs Go
View TypesInGraphQLvsGo.md

Something worth pointing out is that the GraphQL and Go type systems have some pretty glaring differences, and, at least for me, it can be hard to know which mental model to reason with when working with Go code generated from a GraphQL schema. For instance, GraphQL requires explicitly stating that a type implements an interface in order for it to be used as that interface type.

Here's a list of type system differences:

  • Unions exist in GraphQL, but not Go, so they are somewhat mocked through Go interfaces
    • The Is{UnionName}() signpost functions leverage the Go compiler to help alleviate some of the confusion here
    • Without the signposts, a programmer implementing a query resolver would need likely need to jump to the GraphQL schema to figure out what types are included in the union
  • Interfaces in GraphQL differ from Go interfaces in two key ways
    • A GraphQL interface definition includes only fields, where Go interfaces contain methods
  • Getter functions are generated to preserve the
@StevenACoffman
StevenACoffman / testing_module_updates.md
Last active August 18, 2022 21:36
Testing Go module updates
View testing_module_updates.md

So when we updated a few Go libraries, we wanted to run all the relevant tests... but not ALL tests. I thought this shell script one of my co-workers (@csilvers) used was very clever and handy:

git grep -l -e opentelemetry -e otelsql  '*.go' | grep -v testdata | xargs -n1 dirname | sed 's,^,./,' | sort -u | xargs gotestsum

Walking through what it does:

  • git-grep -l, --files-with-matches, -e <pattern>
  • grep -v, --invert-match Invert the sense of matching, to select non-matching lines. (exclude testdata dir matches)
  • xargs -n max-args Use at most max-args arguments per command line. Fewer than max-args arguments will be used if the size (see the -s option) is exceeded, unless the -x option is given, in which case xargs will