Skip to content

πŸŽ‰ Jone v0.4.0

Latest

Choose a tag to compare

@Grandbusta Grandbusta released this 18 Jul 10:02
f453ec1

The query builder is complete! This release rounds out SELECT with joins, aggregations, grouping, CTEs, unions, derived tables, and row locking β€” plus a cleaner UPDATE, raw queries, TRUNCATE, and schema-qualified tables.

✨ What's New

Joins

  • Join (INNER), LeftJoin / LeftOuterJoin, RightJoin / RightOuterJoin, FullOuterJoin (PostgreSQL-only, capability-checked), and CrossJoin
  • Two ON forms β€” Join(table, left, right) for equality, Join(table, left, op, right) for anything else β€” plus JoinRaw for compound conditions with ?-bound args
  • Qualified identifiers everywhere: users.id now quotes as "users"."id" in every clause, and users.* works in column lists
  • Table aliasing with "orders as o" in joins and From() β€” self-joins included:
db.Select("users.name", "o.total").From("users").
    Join("orders as o", "users.id", "o.user_id").
    Where("o.total", ">", 100).
    Exec()
// SELECT "users"."name", "o"."total" FROM "users"
//   INNER JOIN "orders" AS "o" ON "users"."id" = "o"."user_id" WHERE "o"."total" > $1

Aggregations & Grouping

  • Count(), Sum(), Avg(), Min(), Max() β€” single-value queries honoring your WHERE conditions
  • GroupBy / GroupByRaw and the full HAVING family: Having, HavingRaw, HavingIn / HavingNotIn, HavingNull / HavingNotNull, HavingBetween / HavingNotBetween, HavingExists / HavingNotExists
  • Distinct() and PostgreSQL's DistinctOn() (capability-checked β€” a clear error on MySQL, not broken SQL)
  • All() β€” every matching row as []map[string]any, no *sql.Rows boilerplate

Subqueries: Derived Tables, CTEs, Unions

  • Name any builder with As("t") and select from it: From(sub) compiles FROM (SELECT ...) AS "t"
  • With(name, subquery) / WithRecursive(...) for common table expressions β€” builder or raw SQL bodies
  • Union / UnionAll with other builders or raw queries; OrderBy/Limit apply to the combined result
  • Placeholder numbering stays correct through any nesting β€” CTEs, FROM subqueries, joins, WHERE, HAVING, unions all continue the same sequence
totals := jone.Select("user_id").From("orders").GroupBy("user_id")
db.Select("*").From("totals").With("totals", totals).Exec()
// WITH "totals" AS (SELECT "user_id" FROM "orders" GROUP BY "user_id") SELECT * FROM "totals"

Row Locking

  • ForUpdate() / ForShare() with SkipLocked() / NoWait() β€” the classic job-queue claim is now one chain:
tx.Select("*").From("jobs").Where("status", "queued").
    OrderBy("created_at").ForUpdate().SkipLocked().First()

More WHERE Conditions

On Select, Update, and Delete β€” and inside condition groups β€” each with Or variants:

  • WhereNot for negated conditions and groups (NOT "col" = $1, NOT (...))
  • WhereBetween / WhereNotBetween
  • WhereExists / WhereNotExists with builder or raw subqueries
  • WhereLike / WhereILike β€” case sensitivity handled per dialect (PG LIKE/ILIKE, MySQL LIKE BINARY/LIKE)
  • Or variants completed for the existing family: OrWhereIn, OrWhereNotIn, OrWhereNull, OrWhereNotNull, OrWhereRaw

UPDATE

Set() is gone β€” pass the data straight to Update:

db.Update("users", map[string]any{"name": "Alice", "updated_at": jone.Fn.Now()}).Where("id", 1).Exec()
db.Update("users", user).Where("id", 1).Exec()          // struct with `db` tags
db.Update("books", "title", "New Title").Where("id", 42).Exec()  // single pair
db.Update("counters").Increment("views").Exec()          // new: Increment / Decrement

Raw Queries, Truncate, WithSchema

  • db.RawQuery("SELECT * FROM users WHERE age > ?", 21).All() β€” raw SQL with rows back as maps; ? rebinds to $n on PostgreSQL. (s.Raw() in migrations is unchanged.)
  • db.Truncate("sessions").Exec()
  • WithSchema("analytics") on every builder for schema-qualified tables β€” on SELECT it covers joined tables too

⚠️ Breaking Changes

  • Set() is removed β€” pass data directly: Update(table, map), Update(table, struct), or Update(table, column, value)
  • Custom dialects: SelectSQL now takes a single SubSelect struct, and the Dialect interface gained AggregateSQL, RawSQL, TruncateSQL, SupportsDistinctOn, and SupportsFullOuterJoin
  • QuoteIdentifier treats dots as qualification β€” users.id quotes as two identifiers now

πŸ“¦ Installation

go install github.com/Grandbusta/jone/cmd/jone@v0.4.0