{"id":47978720,"url":"https://github.com/zoobz-io/soy","last_synced_at":"2026-04-04T10:59:38.260Z","repository":{"id":322526998,"uuid":"1030570163","full_name":"zoobz-io/soy","owner":"zoobz-io","description":"Type-safe SQL query builder for Go with schema validation","archived":false,"fork":false,"pushed_at":"2026-03-26T21:23:00.000Z","size":13889,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-04T10:59:32.199Z","etag":null,"topics":["go","golang","orm","query-builder","sql","zoobzio"],"latest_commit_sha":null,"homepage":"https://soy.zoobz.io","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zoobz-io.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-01T21:53:19.000Z","updated_at":"2026-03-26T21:20:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/zoobz-io/soy","commit_stats":null,"previous_names":["zoobzio/cereal","zoobz-io/soy"],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/zoobz-io/soy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoobz-io%2Fsoy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoobz-io%2Fsoy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoobz-io%2Fsoy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoobz-io%2Fsoy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zoobz-io","download_url":"https://codeload.github.com/zoobz-io/soy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zoobz-io%2Fsoy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31397056,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","orm","query-builder","sql","zoobzio"],"created_at":"2026-04-04T10:59:36.677Z","updated_at":"2026-04-04T10:59:38.250Z","avatar_url":"https://github.com/zoobz-io.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# soy\n\n[![CI Status](https://github.com/zoobz-io/soy/workflows/CI/badge.svg)](https://github.com/zoobz-io/soy/actions/workflows/ci.yml)\n[![codecov](https://codecov.io/gh/zoobz-io/soy/graph/badge.svg?branch=main)](https://codecov.io/gh/zoobz-io/soy)\n[![Go Report Card](https://goreportcard.com/badge/github.com/zoobz-io/soy)](https://goreportcard.com/report/github.com/zoobz-io/soy)\n[![CodeQL](https://github.com/zoobz-io/soy/workflows/CodeQL/badge.svg)](https://github.com/zoobz-io/soy/security/code-scanning)\n[![Go Reference](https://pkg.go.dev/badge/github.com/zoobz-io/soy.svg)](https://pkg.go.dev/github.com/zoobz-io/soy)\n[![License](https://img.shields.io/github/license/zoobz-io/soy)](LICENSE)\n[![Go Version](https://img.shields.io/github/go-mod/go-version/zoobz-io/soy)](go.mod)\n[![Release](https://img.shields.io/github/v/release/zoobz-io/soy)](https://github.com/zoobz-io/soy/releases)\n\nType-safe SQL query builder for Go with schema validation and multi-database support.\n\nExtract schema from struct tags, validate queries at initialization, execute with zero reflection.\n\n## Schema Once, Query Forever\n\n```go\ntype User struct {\n    ID    int64  `db:\"id\" type:\"bigserial primary key\"`\n    Email string `db:\"email\" type:\"text unique not null\"`\n    Name  string `db:\"name\" type:\"text\"`\n}\n\n// Schema extracted and validated here — once\nusers, _ := soy.New[User](db, \"users\", postgres.New())\n\n// Every query after: type-safe, zero reflection, validated fields\nuser, _ := users.Select().\n    Where(\"email\", \"=\", \"email_param\").\n    Exec(ctx, map[string]any{\"email_param\": \"alice@example.com\"})\n// Returns *User, not interface{}\n```\n\nField names validated against struct tags. Type-safe results. No reflection on the hot path.\n\n## Install\n\n```bash\ngo get github.com/zoobz-io/soy\n```\n\nRequires Go 1.24+.\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n    \"context\"\n    \"fmt\"\n    \"log\"\n\n    \"github.com/jmoiron/sqlx\"\n    _ \"github.com/lib/pq\"\n    \"github.com/zoobz-io/astql/pkg/postgres\"\n    \"github.com/zoobz-io/soy\"\n)\n\ntype User struct {\n    ID    int64  `db:\"id\" type:\"bigserial primary key\"`\n    Email string `db:\"email\" type:\"text unique not null\"`\n    Name  string `db:\"name\" type:\"text\"`\n    Age   int    `db:\"age\" type:\"int\"`\n}\n\nfunc main() {\n    db, _ := sqlx.Connect(\"postgres\", \"postgres://localhost/mydb?sslmode=disable\")\n    defer db.Close()\n\n    // Create instance — schema validated here\n    users, _ := soy.New[User](db, \"users\", postgres.New())\n    ctx := context.Background()\n\n    // Insert\n    created, _ := users.Insert().Exec(ctx, \u0026User{\n        Email: \"alice@example.com\",\n        Name:  \"Alice\",\n        Age:   30,\n    })\n    fmt.Printf(\"Created: %d\\n\", created.ID)\n\n    // Select one\n    user, _ := users.Select().\n        Where(\"email\", \"=\", \"email_param\").\n        Exec(ctx, map[string]any{\"email_param\": \"alice@example.com\"})\n    fmt.Printf(\"Found: %s\\n\", user.Name)\n\n    // Query many\n    all, _ := users.Query().\n        Where(\"age\", \"\u003e=\", \"min_age\").\n        OrderBy(\"name\", \"asc\").\n        Limit(10).\n        Exec(ctx, map[string]any{\"min_age\": 18})\n    fmt.Printf(\"Users: %d\\n\", len(all))\n\n    // Update\n    updated, _ := users.Modify().\n        Set(\"age\", \"new_age\").\n        Where(\"id\", \"=\", \"user_id\").\n        Exec(ctx, map[string]any{\"new_age\": 31, \"user_id\": created.ID})\n    fmt.Printf(\"Updated age: %d\\n\", updated.Age)\n\n    // Aggregate\n    count, _ := users.Count().\n        Where(\"age\", \"\u003e=\", \"min_age\").\n        Exec(ctx, map[string]any{\"min_age\": 18})\n    fmt.Printf(\"Count: %.0f\\n\", count)\n}\n```\n\n## Capabilities\n\n| Feature           | Description                                                                           | Docs                                        |\n| ----------------- | ------------------------------------------------------------------------------------- | ------------------------------------------- |\n| Type-Safe Queries | Generics return `*T` or `[]*T`, not `interface{}`                                     | [Queries](docs/3.guides/1.queries.md)       |\n| Schema Validation | Field names checked against struct tags at init                                       | [Concepts](docs/2.learn/2.concepts.md)      |\n| Multi-Database    | PostgreSQL, MariaDB, SQLite, SQL Server via [ASTQL](https://github.com/zoobz-io/astql) | [Quickstart](docs/2.learn/1.quickstart.md)  |\n| Fluent Builders   | Chainable API for SELECT, INSERT, UPDATE, DELETE                                      | [Mutations](docs/3.guides/2.mutations.md)   |\n| Aggregates        | COUNT, SUM, AVG, MIN, MAX with FILTER clauses                                         | [Aggregates](docs/3.guides/3.aggregates.md) |\n| Window Functions  | ROW_NUMBER, RANK, LAG, LEAD, and more                                                 | [API](docs/5.reference/1.api.md)            |\n| Compound Queries  | UNION, INTERSECT, EXCEPT                                                              | [Compound](docs/3.guides/5.compound.md)     |\n| Safety Guards     | DELETE/UPDATE require WHERE; prevents accidents                                       | [Concepts](docs/2.learn/2.concepts.md)      |\n\n## Why soy?\n\n- **Zero reflection on hot path** — all introspection happens once at `New()`\n- **Type-safe results** — queries return `*T` or `[]*T`, never `interface{}`\n- **Schema validation at init** — field name typos caught immediately, not at runtime\n- **Multi-database parity** — same API across PostgreSQL, MariaDB, SQLite, SQL Server\n- **Safety by default** — DELETE/UPDATE require WHERE; prevents accidental full-table operations\n- **Minimal dependencies** — sqlx plus purpose-built libraries (astql, sentinel, atom)\n\n## Type-Safe Database Layer\n\nSoy enables a pattern: **define types once, query safely everywhere**.\n\nYour struct definitions become the contract. [Sentinel](https://github.com/zoobz-io/sentinel) extracts metadata from struct tags. [ASTQL](https://github.com/zoobz-io/astql) validates queries against that schema. Soy wraps it all in a fluent API.\n\n```go\n// Your domain type — the single source of truth\ntype Order struct {\n    ID        int64     `db:\"id\" type:\"bigserial primary key\"`\n    UserID    int64     `db:\"user_id\" type:\"bigint not null\" references:\"users(id)\"`\n    Total     float64   `db:\"total\" type:\"numeric(10,2) not null\"`\n    Status    string    `db:\"status\" type:\"text\" check:\"status IN ('pending','paid','shipped')\"`\n    CreatedAt time.Time `db:\"created_at\" type:\"timestamptz default now()\"`\n}\n\n// Soy validates against the schema\norders, _ := soy.New[Order](db, \"orders\", postgres.New())\n\n// Invalid field? Caught at init, not runtime\norders.Select().Where(\"totla\", \"=\", \"x\")  // Error: field \"totla\" not found\n```\n\nThree packages, one type definition, complete safety from struct tags to SQL execution.\n\n## Documentation\n\n- [Overview](docs/1.overview.md) — what soy does and why\n- **Learn**\n  - [Quickstart](docs/2.learn/1.quickstart.md) — get started in minutes\n  - [Concepts](docs/2.learn/2.concepts.md) — queries, conditions, builders\n- **Guides**\n  - [Queries](docs/3.guides/1.queries.md) — SELECT with filtering and ordering\n  - [Mutations](docs/3.guides/2.mutations.md) — INSERT, UPDATE, DELETE\n  - [Aggregates](docs/3.guides/3.aggregates.md) — COUNT, SUM, AVG, MIN, MAX\n  - [Specs](docs/3.guides/4.specs.md) — JSON-serializable query definitions\n  - [Compound Queries](docs/3.guides/5.compound.md) — UNION, INTERSECT, EXCEPT\n- **Cookbook**\n  - [Pagination](docs/4.cookbook/1.pagination.md) — LIMIT/OFFSET patterns\n  - [Vector Search](docs/4.cookbook/2.pgvector.md) — pgvector similarity queries\n- **Reference**\n  - [API](docs/5.reference/1.api.md) — complete function documentation\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzoobz-io%2Fsoy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzoobz-io%2Fsoy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzoobz-io%2Fsoy/lists"}