Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/jferrl/yowrap

Lightweight Go package designed to effortlessly wrap the Spanner Ecosystem Yo package for enhanced functionality
https://github.com/jferrl/yowrap

Last synced: about 6 hours ago
JSON representation

Lightweight Go package designed to effortlessly wrap the Spanner Ecosystem Yo package for enhanced functionality

Awesome Lists containing this project

README

        

# 🌮 yowrap 🌮

[![GoDoc](https://img.shields.io/static/v1?label=godoc&message=reference&color=blue)](https://pkg.go.dev/github.com/jferrl/yowrap)
[![Test Status](https://github.com/jferrl/yowrap/workflows/tests/badge.svg)](https://github.com/jferrl/yowrap/actions?query=workflow%3Atests)
[![codecov](https://codecov.io/gh/jferrl/yowrap/branch/main/graph/badge.svg?token=68I4BZF235)](https://codecov.io/gh/jferrl/yowrap)
[![Go Report Card](https://goreportcard.com/badge/github.com/jferrl/yowrap)](https://goreportcard.com/report/github.com/jferrl/yowrap)

Lightweight Go package designed to effortlessly wrap the [Yo](https://github.com/cloudspannerecosystem/yo) package for enhanced functionality.

## Context

[Yo](https://github.com/cloudspannerecosystem/yo) is a command-line tool that generates Go code from SQL DDL files. The generated code is used to interact with Google Cloud Spanner databases, representing the table and a set of methods to interact with the table.

Yo is a great tool to generate the boilerplate code needed to interact with a Google Cloud Spanner database. However, the generated code is not intended to be modified by the user, as it is overwritten every time the `yo` tool is executed. This pkg is designed to extend the generated code functionality creating a more capable model.

This package is designed to be used in conjunction with the `yo` tool, not as a replacement.

See [Yo](https://github.com/cloudspannerecosystem/yo) for more information about the `yo` tool.

## Features

- **Commit transaction**: This feature allows the client to commit a model transaction directly from the model instance without using the spanner.Mutation outside the model. Now, the model has the responsibility of writing the changes to the database.
- **Custom model hooks**: This feature allows the client to define custom hooks that will be executed before or after a specific method is called. This is useful for adding custom logic to the model methods.
- **Inheric model methods**: All the method signatures from the generated code are inherited by the model. This allows the client to call the generated methods directly from the model instance.

## Usage

Use `yowrap` as a wrapper for the generated model but committing the transaction outside the model. This mantains the ability to use the generated methods-

```go
package main

import (
"context"
"fmt"
"log"

"cloud.google.com/go/spanner"
"github.com/jferrl/yowrap"
)

func main() {
spannerClient, err := spanner.NewClient(ctx, "projects/my-project/instances/my-instance/databases/my-database")
if err != nil {
log.Fatalf("Failed to create a Spanner client: %v", err)
}
defer spannerClient.Close()

// Go struct generated by the yo tool
user := &User{
ID: 1,
Name: "John Doe",
Email: " [email protected]",
}

// Create a new user model
user := yowrap.NewModel(user)

mut := user.Insert(ctx)

_, err = spannerClient.Apply(ctx, []*spanner.Mutation{mut})
if err != nil {
log.Fatalf("Failed to apply the mutation: %v", err)
}
}
```

Use `yowrap` as a wrapper for the generated model and commit the transaction directly from the model.

```go

package main

import (
"context"
"fmt"
"log"

"cloud.google.com/go/spanner"
"github.com/jferrl/yowrap"
)

func main() {
spannerClient, err := spanner.NewClient(ctx, "projects/my-project/instances/my-instance/databases/my-database")
if err != nil {
log.Fatalf("Failed to create a Spanner client: %v", err)
}
defer spannerClient.Close()

// Go struct generated by the yo tool
user := &User{
ID: 1,
Name: "John Doe",
Email: " [email protected]",
}

// Create a new user model
user := yowrap.NewModel(user, yowrap.WithSpannerClientOption(spannerClient))

// Commit the transaction
_, err = user.Apply(ctx, yowrap.Insert)
if err != nil {
log.Fatalf("Failed to insert and commit the user: %v", err)
}
}
```

Use `yowrap` with a custom hook.

```go

package main

import (
"context"
"fmt"
"log"

"cloud.google.com/go/spanner"
"github.com/jferrl/yowrap"
)

func main() {
spannerClient, err := spanner.NewClient(ctx, "projects/my-project/instances/my-instance/databases/my-database")
if err != nil {
log.Fatalf("Failed to create a Spanner client: %v", err)
}
defer spannerClient.Close()

// Go struct generated by the yo tool
user := &User{
ID: 1,
Name: "John Doe",
Email: " [email protected]",
}

// Create a new user model
user := yowrap.NewModel(user, yowrap.WithSpannerClientOption(spannerClient))

// Add a custom hook
user.On(yowrap.BeforeInsert, func(_ context.Context, m *yowrap.Model[*user.User], _ *spanner.ReadWriteTransaction) error {
log.Println("Before insert")
return nil
})

// Commit the transaction
_, err = user.Apply(ctx, yowrap.Insert)
if err != nil {
log.Fatalf("Failed to insert and commit the user: %v", err)
}
}
```

## License

Copyright 2024, jferrl

yowrap is released under the MIT license.