Skip to content

einride/spanner-aip-go

Repository files navigation

Spanner AIP Go

PkgGoDev GoReportCard Codecov

Add-on to the AIP Go SDK for implementing Cloud Spanner persistance for resource-oriented APIs.

Experimental: This library is under active development and breaking changes to config files, APIs and generated code are expected between releases.

Documentation

See https://aip.dev for the full AIP documentation and the Cloud Spanner documentation.

Usage

Installing

$ go get -u go.einride.tech/spanner-aip

Code generation config

Use a YAML config file to specify the schema to generate code from:

databases:
  - name: music
    schema:
      - "testdata/migrations/music/*.up.sql"
    package:
      name: musicdb
      path: ./internal/examples/musicdb

Code generation

$ go run go.einride.tech/spanner-aip generate

Reading data

Get

package main

import (
	"context"

	"cloud.google.com/go/spanner"
	"go.einride.tech/spanner-aip/internal/examples/musicdb"
)

func main() {
	ctx := context.Background()
	client, err := spanner.NewClient(
		ctx, "projects/<PROJECT>/instances/<INSTANCE>/databases/<DATABASE>",
	)
	if err != nil {
		panic(err) // TODO: Handle error.
	}
	singer, err := musicdb.Singers(client.Single()).Get(ctx, musicdb.SingersKey{
		SingerId: 42,
	})
	if err != nil {
		panic(err) // TODO: Handle error.
	}
	_ = singer // TODO: Use singer.
}

List

package main

import (
	"context"

	"cloud.google.com/go/spanner"
	"cloud.google.com/go/spanner/spansql"
	"go.einride.tech/spanner-aip/internal/examples/musicdb"
)

func main() {
	ctx := context.Background()
	client, err := spanner.NewClient(
		ctx, "projects/<PROJECT>/instances/<INSTANCE>/databases/<DATABASE>",
	)
	if err != nil {
		panic(err) // TODO: Handle error.
	}
	// SELECT * FROM Singers
	// WHERE LastName = "Sinatra"
	// ORDER BY FirstName DESC
	// LIMIT 5
	// OFFSET 10
	if err := musicdb.Singers(client.Single()).List(ctx, musicdb.ListQuery{
		Where: spansql.ComparisonOp{
			Op:  spansql.Eq,
			LHS: musicdb.Descriptor().Singers().LastName().ColumnID(),
			RHS: spansql.StringLiteral("Sinatra"),
		},
		Order: []spansql.Order{
			{Expr: musicdb.Descriptor().Singers().FirstName().ColumnID(), Desc: true},
		},
		Limit:  5,
		Offset: 10,
	}).Do(func(singer *musicdb.SingersRow) error {
		_ = singer // TODO: Use singer.
		return nil
	}); err != nil {
		panic(err) // TODO: Handle error.
	}
}