protogorm

package module
v0.0.7 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 3, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

protogorm

A buf plugin for turning your wire type into a gorm schema with free CRUD and protoc interop.

protogorm reads (protogorm.v1.model) + (protogorm.v1.db) proto annotations and you get:

  1. Tags - gorm struct tags injected into the structs protoc-gen-go already made. The .pb.go struct is the table. While this is more-so a cool feature of gorm, proto derived gorm tags is a game changer.
  2. Support - gorm.gen.go beside your generated package: TableName, timestamp hooks, Redact (returns a clone with secret fields cleared, never mutates the row you loaded), AllModels in one slice, and a serializer that stores google.protobuf.Timestamp as a real time column.
  3. Store - store.gen.go of typed CRUD methods (plus any annotated queries) on your Store type, in whatever package that lives.

Annotate

import "protogorm/v1/options.proto";

message User {
  option (protogorm.v1.model) = {
    table: "users"
    order_by: "created_at DESC"
    queries: [{
      name: "GetUserByEmail"
      kind: QUERY_KIND_GET
      where: "email = ?"
      params: ["email string"]
    }]
  };
  string id = 1 [(protogorm.v1.db) = {tag: "primaryKey"}];
  string email = 2 [(protogorm.v1.db) = {tag: "uniqueIndex"}];
  string hash = 3 [(protogorm.v1.db) = {redact: true}];
  google.protobuf.Timestamp created_at = 4 [(protogorm.v1.db) = {tag: "autoCreateTime"}];
}

A single string pk named id gets a uuid filled in on create when empty. Fields typed as another model become relations. Maps, lists, and message fields serialize to json columns. Timestamps get real time columns per dialect (datetime on sqlite, timestamptz on postgres).

Run

After buf generate, feed it the image and tell it where things go:

buf build -o - | go run github.com/nickheyer/protogorm/cmd/protogorm \
    -support pkg/proto \
    -store internal/db/store.gen.go:db \
    -inject pkg/proto

-support mirrors protoc-gen-go paths=source_relative layout. -store wants path:package and expects a Store struct with a db *gorm.DB field in that package. -inject rewrites the tags in place, which is why this runs after buf and not inside it: a protoc plugin cannot touch another plugin's output.

Support and store generation also work as a plain protoc plugin for setups that prefer it:

# buf.gen.yaml
  - local: protoc-gen-protogorm
    out: pkg/proto
    opt: [paths=source_relative]
  - local: protoc-gen-protogorm
    out: internal/db
    opt: [store=db]

Injection still runs after, via protogorm -inject.

Runtime scrubbing

protogorm.Scrub(msg) walks any proto message tree and clears every populated redact: true field, returning how many it caught. Wire it as an interceptor backstop so a handler that forgets Redact() still cannot leak a secret:

if n := protogorm.Scrub(resp.Any().(proto.Message)); n > 0 {
    log.Error("redact backstop caught %d secret fields on %s", n, procedure)
}

Testing

Generator output is locked by golden files under internal/generator/testdata. After changing the generator, inspect the diff and refresh with:

go test ./internal/generator -run TestGolden -update

Vendoring the options

Until the buf registry lets me register (?) my plugin, copy proto/protogorm/v1/options.proto into your buf module and exclude it from your own Go generation. Your runtime never imports it, only the generator reads it.

Documentation

Overview

Ships the annotation schema inside the go module

Runtime backstop clearing redact fields from outbound messages

Index

Constants

View Source
const OptionsPath = "protogorm/v1/options.proto"

Import path consumers use for the schema

Variables

View Source
var OptionsProto []byte

Source of the annotation schema

Functions

func Scrub added in v0.0.2

func Scrub(m proto.Message) int

Clears every populated redact field in the message tree

Types

This section is empty.

Directories

Path Synopsis
cmd
protoc-gen-protogorm command
Protoc plugin emitting gorm support and store crud code
Protoc plugin emitting gorm support and store crud code
protogorm command
Reads a buf image and emits every gorm artifact
Reads a buf image and emits every gorm artifact
gen
internal
generator
Parses buf descriptor images into file descriptors
Parses buf descriptor images into file descriptors
testproto
Compiles proto sources into descriptor images for tests
Compiles proto sources into descriptor images for tests

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL