Skip to content

Instantly share code, notes, and snippets.

@yfuruyama
Created June 20, 2019 07:01
Show Gist options
  • Save yfuruyama/90b7a08e0dff1cbe1b67f73ef6c240b2 to your computer and use it in GitHub Desktop.
Save yfuruyama/90b7a08e0dff1cbe1b67f73ef6c240b2 to your computer and use it in GitHub Desktop.
package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"time"
"google.golang.org/api/option"
gtransport "google.golang.org/api/transport/grpc"
sppb "google.golang.org/genproto/googleapis/spanner/v1"
"google.golang.org/grpc"
)
func main() {
var project string
var instance string
var database string
flag.StringVar(&project, "project", "", "")
flag.StringVar(&instance, "instance", "", "")
flag.StringVar(&database, "database", "", "")
flag.Parse()
if project == "" || instance == "" || database == "" {
flag.Usage()
os.Exit(1)
}
ctx := context.Background()
// create gRPC connection
allOpts := []option.ClientOption{
option.WithEndpoint("spanner.googleapis.com:443"),
option.WithGRPCDialOption(
grpc.WithUnaryInterceptor(loggingInterceptor),
),
}
conn, err := gtransport.Dial(ctx, allOpts...)
if err != nil {
log.Fatal(err)
}
rpcClient := sppb.NewSpannerClient(conn)
// create session
dbPath := fmt.Sprintf("projects/%s/instances/%s/databases/%s", project, instance, database)
session, err := rpcClient.CreateSession(ctx, &sppb.CreateSessionRequest{
Database: dbPath,
})
if err != nil {
log.Fatal(err)
}
// begin
txn, err := rpcClient.BeginTransaction(ctx, &sppb.BeginTransactionRequest{
Session: session.Name,
Options: &sppb.TransactionOptions{
Mode: &sppb.TransactionOptions_ReadWrite_{
ReadWrite: &sppb.TransactionOptions_ReadWrite{},
},
},
})
if err != nil {
log.Fatal(err)
}
// update
_, err = rpcClient.ExecuteSql(ctx, &sppb.ExecuteSqlRequest{
Session: session.Name,
Transaction: &sppb.TransactionSelector{
Selector: &sppb.TransactionSelector_Id{
Id: txn.Id,
},
},
Sql: fmt.Sprintf("UPDATE t1 SET Content = '%s' WHERE Id = 1", time.Now()),
QueryMode: sppb.ExecuteSqlRequest_NORMAL,
})
if err != nil {
log.Fatal(err)
}
// commit
_, err = rpcClient.Commit(ctx, &sppb.CommitRequest{
Session: session.Name,
Transaction: &sppb.CommitRequest_TransactionId{
TransactionId: txn.Id,
},
})
if err != nil {
log.Fatal(err)
}
// query
req := &sppb.ExecuteSqlRequest{
Session: session.Name,
Transaction: nil,
Sql: "SELECT Content FROM t1 WHERE Id = 1",
QueryMode: sppb.ExecuteSqlRequest_NORMAL,
}
results, err := rpcClient.ExecuteSql(ctx, req)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Query result: %s\n", results.Rows[0].Values[0].GetStringValue())
}
func loggingInterceptor(
ctx context.Context,
method string,
req interface{},
reply interface{},
cc *grpc.ClientConn,
invoker grpc.UnaryInvoker,
opts ...grpc.CallOption,
) error {
fmt.Printf("Invoke RPC: %s\n", method)
return invoker(ctx, method, req, reply, cc, opts...)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment