blogschema

package
v0.10.0 Latest Latest
Warning

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

Go to latest
Published: Aug 5, 2026 License: MIT Imports: 2 Imported by: 0

Documentation

Overview

Package blogschema is the schema definition for the blog example: the single source of truth that an author, or an agent, edits.

It lives in its own package because the declarations here and the model structs generated from them share names — blogschema.Post is the table declaration, blog.Post is the row struct. Keeping them apart is what lets both be called Post.

Index

Constants

This section is empty.

Variables

View Source
var Author = schema.Table("authors",
	schema.UUIDv7("id").PrimaryKey(),

	schema.Ref("org", Org).OnDelete(schema.Cascade).Filterable().Expandable().
		Inverse("authors").
		InverseExpandable(schema.ExpandOrder("name")),
	schema.Text("email").Unique().Searchable(),
	schema.Text("name").Searchable().Sortable(),

	schema.Text("password_hash").Hidden(),
	schema.Timestamps(),
).
	Index("org_id").
	Expose(schema.REST{
		Path:            "/authors",
		Ops:             schema.CRUD | schema.OpList,
		DefaultPageSize: 25,
		MaxPageSize:     100,
	})

Author is a person who writes posts.

View Source
var Org = schema.Table("orgs",
	schema.UUIDv7("id").PrimaryKey(),
	schema.Text("name").Searchable().Sortable(),
	schema.Text("slug").Unique().Filterable(),
	schema.Timestamps(),
).
	Describe("A tenant. Every other table is scoped to one.").
	Expose(schema.REST{Ops: schema.OpRead | schema.OpList})

Org is a tenant. Everything else hangs off it.

View Source
var Post = schema.Table("posts",
	schema.UUIDv7("id").PrimaryKey(),
	schema.Ref("org", Org).OnDelete(schema.Cascade),
	schema.Ref("author", Author).OnDelete(schema.Restrict).Filterable().Expandable().
		Inverse("posts").
		InverseExpandable(schema.ExpandOrder("-published_at"), schema.ExpandLimit(2)),

	schema.Text("title").Searchable().Sortable(),
	schema.Text("body").Searchable(),
	schema.Enum("status", "draft", "review", "published").
		Default(schema.Value("draft")).
		Filterable().
		Sortable(),

	schema.BigInt("view_count").Default(schema.Value(0)).Filterable().Sortable().ReadOnly(),
	schema.Timestamp("published_at").Nullable().Filterable().Sortable(),

	schema.Timestamps(),
	schema.SoftDelete(),
).
	Index("org_id", "status").
	Index("author_id").
	Check("published_posts_have_a_date",
		"status <> 'published' OR published_at IS NOT NULL").
	Describe("A blog post.").
	Expose(schema.REST{
		Path:            "/posts",
		Ops:             schema.OpCreate | schema.OpRead | schema.OpUpdate | schema.OpList,
		DefaultPageSize: 20,
		MaxPageSize:     100,
		MaxFilters:      12,
		MaxSortTerms:    4,

		MaxOffset: 5000,
	})

Post is the table the dynamic data views are built over: filterable by status and author, sortable by several columns, full-text searchable, and groupable for the dashboard.

Functions

func SqlbProject

func SqlbProject() codegen.Project

SqlbProject tells `sqlb generate` what this example emits and where.

It replaces a cmd/gen/main.go that was thirty lines of flag parsing around this literal, and — more to the point — it removes the -dir argument that main had to be given. Paths here resolve against the module root, which for this example is the repository root, so "example/blog" means the same thing whether the command is run from a shell, from the //go:generate directive in schema.go, or from CI.

The blog example emits Go only. It is the short path from a schema to a server; example/tasks is the one that adds the TypeScript, Dart and CLI clients.

It also declares an EjectDir, which no real project has to: `sqlb eject` defaults to "ejected" beside the generated code and this is exactly that path. It is written out because this example is where the exit is kept current — `mise run eject-check` diffs the committed package against what the schema would produce now, and pgtest/eject_test.go serves it beside the generated resources and compares the answers (ADR-0042).

Types

This section is empty.

Jump to

Keyboard shortcuts

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