From cb58a740ee9f130f953e408babbe804e18d74e31 Mon Sep 17 00:00:00 2001 From: ez-plugins Date: Sat, 18 Apr 2026 19:54:29 +0200 Subject: [PATCH 1/2] docs: improved readability --- README.md | 44 +++++++++ docs/api-reference.md | 58 ++++++++++-- docs/conditions.md | 6 +- docs/configuration.md | 205 ++++++++++++++++++++++++++++++++++++++++++ docs/exceptions.md | 20 ++--- docs/in-memory.md | 6 +- docs/index.md | 23 ++--- docs/installation.md | 2 +- docs/query-builder.md | 14 +-- docs/sql-dialects.md | 12 +-- docs/subqueries.md | 2 +- 11 files changed, 346 insertions(+), 46 deletions(-) create mode 100644 docs/configuration.md diff --git a/README.md b/README.md index 36af384..ffc5f88 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ A lightweight, fluent Java library for building parameterized SQL queries and filtering in-memory data, no runtime dependencies required. + ## Features - Fluent, readable builder API for SELECT, INSERT, UPDATE, DELETE, and CREATE TABLE @@ -14,6 +15,7 @@ A lightweight, fluent Java library for building parameterized SQL queries and fi - Subquery support: `WHERE col IN (SELECT ...)`, `WHERE EXISTS (SELECT ...)`, `WHERE NOT EXISTS`, derived-table `FROM (SELECT ...) AS alias`, JOIN subqueries, and scalar `(SELECT ...) AS alias` in SELECT - Column selection, `DISTINCT`, `GROUP BY`, `ORDER BY`, `LIMIT`, and `OFFSET` - SQL dialect support: Standard, MySQL, SQLite +- **Global and per-query configuration of defaults (e.g., dialect, columns, limit, LIKE wrapping) via `QueryBuilderDefaults`** - In-memory filtering via `QueryableStorage` - Zero runtime dependencies, pure Java 21+ @@ -391,6 +393,48 @@ new SelectBuilder() .build(); // → SqlResult ``` + +## Global and Per-Query Configuration + +You can preset the default SQL dialect, default columns, limit, offset, and LIKE wrapping for all queries using `QueryBuilderDefaults`. This is useful for enforcing a project-wide dialect (e.g., always use SQLite) or customizing builder defaults. + +### Set SQLite as the default dialect for all queries + +```java +import com.github.ezframework.javaquerybuilder.query.QueryBuilderDefaults; +import com.github.ezframework.javaquerybuilder.query.sql.SqlDialect; + +// Set at application startup: +QueryBuilderDefaults.setGlobal( + QueryBuilderDefaults.builder() + .dialect(SqlDialect.SQLITE) + .build() +); + +// All new QueryBuilder, SelectBuilder, and DeleteBuilder instances will use SQLite quoting by default: +SqlResult result = new QueryBuilder() + .select("id", "name") + .from("users") + .buildSql(); +// → SELECT id, name FROM "users" +``` + +### Override per query + +You can override the defaults for a single query using `.withDefaults()`: + +```java +SqlResult result = new QueryBuilder() + .withDefaults(QueryBuilderDefaults.builder(QueryBuilderDefaults.global()) + .dialect(SqlDialect.MYSQL) + .build()) + .from("users") + .buildSql(); +// → SELECT * FROM `users` +``` + +See the Javadoc for [`QueryBuilderDefaults`](src/main/java/com/github/ezframework/javaquerybuilder/query/QueryBuilderDefaults.java) for all configurable options. + ## SQL Dialects By default, `buildSql(table)` uses `SqlDialect.STANDARD` (no identifier quoting). Pass a second argument to use a different dialect: diff --git a/docs/api-reference.md b/docs/api-reference.md index 3558521..85bfe6b 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -1,6 +1,6 @@ --- title: API Reference -nav_order: 10 +nav_order: 11 description: "Complete public method tables for every class and interface in JavaQueryBuilder" --- @@ -70,8 +70,10 @@ Main entry point for SELECT queries and static gateway to DML builders. | `offset(int n)` | `QueryBuilder` | Set `OFFSET` | | `build()` | `Query` | Build a `Query` object (no SQL rendered yet) | | `buildSql()` | `SqlResult` | Render SELECT using table set via `from()`, standard dialect | +| `buildSql(SqlDialect)` | `SqlResult` | Render SELECT using table set via `from()`, specified dialect | | `buildSql(String table)` | `SqlResult` | Render SELECT for explicit `table`, standard dialect | | `buildSql(String table, SqlDialect)` | `SqlResult` | Render SELECT for explicit `table` and dialect | +| `withDefaults(QueryBuilderDefaults)` | `QueryBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` | --- @@ -91,6 +93,8 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm | `orderBy(String col, boolean asc)` | `SelectBuilder` | Add `ORDER BY` | | `limit(int n)` | `SelectBuilder` | Set `LIMIT` | | `offset(int n)` | `SelectBuilder` | Set `OFFSET` | +| `withDefaults(QueryBuilderDefaults)` | `SelectBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` | +| `build()` | `SqlResult` | Render SELECT using defaults dialect | | `build(SqlDialect)` | `SqlResult` | Render SELECT with given dialect | --- @@ -134,6 +138,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm | `whereIn(col, List)` | `DeleteBuilder` | `WHERE col IN (...)` (AND); throws `IllegalArgumentException` if list is null/empty | | `whereNotIn(col, List)` | `DeleteBuilder` | `WHERE col NOT IN (...)` (AND); throws `IllegalArgumentException` if list is null/empty | | `whereBetween(col, from, to)` | `DeleteBuilder` | `WHERE col BETWEEN ? AND ?` (AND) | +| `withDefaults(QueryBuilderDefaults)` | `DeleteBuilder` | Set per-instance configuration defaults; throws `NullPointerException` if `null` | | `build()` | `SqlResult` | Render with standard dialect | | `build(SqlDialect)` | `SqlResult` | Render with specified dialect | @@ -242,7 +247,7 @@ getters and setters; setters are used exclusively by the builders. |--------|-------------| | `JoinClause(Type, String table, String on)` | Plain-table join | | `JoinClause(Type, Query subquery, String alias, String on)` | Subquery (derived-table) join | -| `getType()` | `JoinClause.Type` — `INNER`, `LEFT`, `RIGHT`, or `CROSS` | +| `getType()` | `JoinClause.Type`: `INNER`, `LEFT`, `RIGHT`, or `CROSS` | Join type | | `getTable()` | Table name for plain-table join; `null` for subquery join | | `getSubquery()` | Subquery for derived-table join; `null` for plain-table join | | `getAlias()` | Alias for derived-table join | @@ -279,9 +284,9 @@ public interface QueryableStorage { | Member | Description | |--------|-------------| -| `STANDARD` | ANSI SQL — no identifier quoting | -| `MYSQL` | MySQL — back-tick quoting; DELETE LIMIT supported | -| `SQLITE` | SQLite — double-quote quoting; DELETE LIMIT supported | +| `STANDARD` | ANSI SQL (no identifier quoting) | +| `MYSQL` | MySQL: back-tick quoting; DELETE LIMIT supported | +| `SQLITE` | SQLite: double-quote quoting; DELETE LIMIT supported | | `render(Query)` | Render a SELECT query to `SqlResult` | | `renderDelete(Query)` | Render a DELETE query to `SqlResult` | @@ -296,6 +301,49 @@ public interface QueryableStorage { --- +## configuration + +### `QueryBuilderDefaults` + +Immutable configuration object. See [Configuration](configuration) for a full +usage guide. + +**Static methods** + +| Method | Returns | Description | +|--------|---------|-------------| +| `global()` | `QueryBuilderDefaults` | Current JVM-wide defaults instance | +| `setGlobal(defaults)` | `void` | Replace the JVM-wide defaults; throws `NullPointerException` if `null` | +| `builder()` | `Builder` | New builder pre-filled with canonical defaults | +| `builder(source)` | `Builder` | New builder copied from `source`; throws `NullPointerException` if `null` | + +**Instance getters** + +| Method | Returns | Description | +|--------|---------|-------------| +| `getDialect()` | `SqlDialect` | Configured SQL dialect | +| `getDefaultColumns()` | `String` | Default SELECT column expression | +| `getDefaultLimit()` | `int` | Default LIMIT; `-1` means none | +| `getDefaultOffset()` | `int` | Default OFFSET; `-1` means none | +| `getLikePrefix()` | `String` | Prefix for LIKE values | +| `getLikeSuffix()` | `String` | Suffix for LIKE values | + +--- + +### `QueryBuilderDefaults.Builder` + +| Method | Returns | Description | +|--------|---------|-------------| +| `dialect(SqlDialect)` | `Builder` | Set dialect; throws `NullPointerException` if `null` | +| `defaultColumns(String)` | `Builder` | Set default SELECT columns; throws `NullPointerException` if `null` | +| `defaultLimit(int)` | `Builder` | Set default LIMIT; pass `-1` to disable | +| `defaultOffset(int)` | `Builder` | Set default OFFSET; pass `-1` to disable | +| `likePrefix(String)` | `Builder` | Set LIKE prefix; throws `NullPointerException` if `null` | +| `likeSuffix(String)` | `Builder` | Set LIKE suffix; throws `NullPointerException` if `null` | +| `build()` | `QueryBuilderDefaults` | Build the immutable configuration object | + +--- + ## exception ### `QueryBuilderException` diff --git a/docs/conditions.md b/docs/conditions.md index 2474755..b7fe103 100644 --- a/docs/conditions.md +++ b/docs/conditions.md @@ -17,7 +17,7 @@ description: "Operators, Condition, ConditionEntry, Connector AND/OR, and the or ## Overview -Every `where*` call on a builder creates a `ConditionEntry` — a triple of: +Every `where*` call on a builder creates a `ConditionEntry` with three properties: - a **column name** (or `null` for EXISTS subquery conditions) - a **`Condition`** (operator + value) @@ -84,7 +84,7 @@ constant and the SQL it generates. ## AND vs OR connector -### Default — AND +### Default behavior (AND) All `where*` methods use `AND`: @@ -96,7 +96,7 @@ new QueryBuilder() // → WHERE role = ? AND active = ? ``` -### OR — use the `orWhere*` variant +### OR conditions ```java new QueryBuilder() diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 0000000..8c36f23 --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,205 @@ +--- +title: Configuration +nav_order: 8 +description: "QueryBuilderDefaults: global and per-query preset for dialect, columns, limit, offset, and LIKE wrapping" +--- + +# Configuration +{: .no_toc } + +## Table of contents +{: .no_toc .text-delta } + +1. TOC +{:toc} + +--- + +## Overview + +`QueryBuilderDefaults` is an immutable configuration object that holds the +defaults applied by every builder (`QueryBuilder`, `SelectBuilder`, +`DeleteBuilder`) when no explicit value is provided. + +You configure it once at application startup and every builder created +afterward automatically honours those settings. You can also override the +defaults for a single builder instance using `.withDefaults()`. + +**Configurable settings:** + +| Setting | Default | Description | +|---------|---------|-------------| +| `dialect` | `SqlDialect.STANDARD` | SQL dialect used for identifier quoting | +| `defaultColumns` | `"*"` | Column expression used in `SELECT` when none are specified | +| `defaultLimit` | `-1` (no limit) | `LIMIT` applied when the builder has no `.limit()` call | +| `defaultOffset` | `-1` (no offset) | `OFFSET` applied when the builder has no `.offset()` call | +| `likePrefix` | `"%"` | Prefix wrapped around values in `LIKE` conditions | +| `likeSuffix` | `"%"` | Suffix wrapped around values in `LIKE` conditions | + +--- + +## Setting a global dialect + +Call `QueryBuilderDefaults.setGlobal()` once at startup. All builders created +after the call will use the new defaults. + +```java +import com.github.ezframework.javaquerybuilder.query.QueryBuilderDefaults; +import com.github.ezframework.javaquerybuilder.query.sql.SqlDialect; + +// Use SQLite for every query in this application +QueryBuilderDefaults.setGlobal( + QueryBuilderDefaults.builder() + .dialect(SqlDialect.SQLITE) + .build() +); +``` + +After this call you no longer need to pass a dialect to `buildSql()`: + +```java +SqlResult result = new QueryBuilder() + .from("users") + .whereEquals("id", 1) + .buildSql(); +// SELECT * FROM "users" WHERE "id" = ? +``` + +--- + +## Full configuration example + +```java +QueryBuilderDefaults.setGlobal( + QueryBuilderDefaults.builder() + .dialect(SqlDialect.MYSQL) + .defaultColumns("id, name, created_at") + .defaultLimit(100) + .defaultOffset(0) + .likePrefix("%") + .likeSuffix("%") + .build() +); +``` + +--- + +## Per-query override + +Use `.withDefaults()` on any builder to override the global configuration for +that one query. Any explicit value you set on the builder (such as `.limit()`) +always beats the defaults. + +```java +// Override to use SQLite for this query only +SqlResult result = new QueryBuilder() + .withDefaults( + QueryBuilderDefaults.builder(QueryBuilderDefaults.global()) + .dialect(SqlDialect.SQLITE) + .build() + ) + .from("users") + .buildSql(); +// SELECT * FROM "users" +``` + +{: .note } +> `QueryBuilderDefaults.builder(source)` copies all settings from an existing +> instance so you only need to override the fields you want to change. + +--- + +## Explicit dialect argument always wins + +Passing a dialect directly to `buildSql()` or `build(SqlDialect)` takes +precedence over both the global defaults and any `.withDefaults()` setting. + +```java +QueryBuilderDefaults.setGlobal( + QueryBuilderDefaults.builder().dialect(SqlDialect.MYSQL).build() +); + +// Explicit argument beats the global setting +SqlResult result = new QueryBuilder() + .from("users") + .buildSql("users", SqlDialect.SQLITE); +// Uses SQLite quoting regardless of the global setting +``` + +--- + +## Custom LIKE wrapping + +`whereLike` wraps the value with `%` on both sides by default. Change the +wrapping globally or per query: + +```java +// No wrapping (exact LIKE match) +QueryBuilderDefaults.builder() + .likePrefix("") + .likeSuffix("") + .build(); + +// Suffix-only (starts-with search) +QueryBuilderDefaults.builder() + .likePrefix("") + .likeSuffix("%") + .build(); +``` + +--- + +## Restoring defaults + +`QueryBuilderDefaults.builder()` always starts from the canonical +out-of-the-box values. To reset the global configuration: + +```java +QueryBuilderDefaults.setGlobal(QueryBuilderDefaults.builder().build()); +``` + +--- + +## API summary + +### `QueryBuilderDefaults` (static methods) + +| Method | Returns | Description | +|--------|---------|-------------| +| `global()` | `QueryBuilderDefaults` | The current JVM-wide defaults instance | +| `setGlobal(defaults)` | `void` | Replace the JVM-wide defaults; throws `NullPointerException` if `null` | +| `builder()` | `Builder` | New builder pre-filled with canonical defaults | +| `builder(source)` | `Builder` | New builder copied from `source`; throws `NullPointerException` if `null` | + +### `QueryBuilderDefaults` (instance getters) + +| Method | Returns | Description | +|--------|---------|-------------| +| `getDialect()` | `SqlDialect` | The configured SQL dialect | +| `getDefaultColumns()` | `String` | Default SELECT column expression | +| `getDefaultLimit()` | `int` | Default LIMIT value; `-1` means none | +| `getDefaultOffset()` | `int` | Default OFFSET value; `-1` means none | +| `getLikePrefix()` | `String` | Prefix for LIKE values | +| `getLikeSuffix()` | `String` | Suffix for LIKE values | + +### `QueryBuilderDefaults.Builder` + +| Method | Returns | Description | +|--------|---------|-------------| +| `dialect(SqlDialect)` | `Builder` | Set dialect; throws `NullPointerException` if `null` | +| `defaultColumns(String)` | `Builder` | Set default SELECT columns; throws `NullPointerException` if `null` | +| `defaultLimit(int)` | `Builder` | Set default LIMIT; pass `-1` to disable | +| `defaultOffset(int)` | `Builder` | Set default OFFSET; pass `-1` to disable | +| `likePrefix(String)` | `Builder` | Set LIKE prefix; throws `NullPointerException` if `null` | +| `likeSuffix(String)` | `Builder` | Set LIKE suffix; throws `NullPointerException` if `null` | +| `build()` | `QueryBuilderDefaults` | Build the immutable configuration object | + +### Builders that support `withDefaults()` + +All three builders throw `NullPointerException` if `null` is passed. + +| Builder | Method signature | +|---------|-----------------| +| `QueryBuilder` | `withDefaults(QueryBuilderDefaults defaults)` | +| `SelectBuilder` | `withDefaults(QueryBuilderDefaults defaults)` | +| `DeleteBuilder` | `withDefaults(QueryBuilderDefaults defaults)` | diff --git a/docs/exceptions.md b/docs/exceptions.md index de54e23..6503ab2 100644 --- a/docs/exceptions.md +++ b/docs/exceptions.md @@ -1,6 +1,6 @@ --- title: Exceptions -nav_order: 9 +nav_order: 10 description: "Exception hierarchy, when each exception is thrown, and handling patterns" --- @@ -19,13 +19,13 @@ description: "Exception hierarchy, when each exception is thrown, and handling p The library defines three standalone checked exceptions in the `com.github.ezframework.javaquerybuilder.query.exception` package. -None extends the others — each signals a distinct failure mode. +None extends the others; each signals a distinct failure mode. ```text Exception - ├── QueryBuilderException — general builder or configuration error - ├── QueryException — query-level runtime error - └── QueryRenderException — SQL rendering error + ├── QueryBuilderException : general builder or configuration error + ├── QueryException : query-level runtime error + └── QueryRenderException : SQL rendering error ``` All three share the same four constructor signatures. @@ -57,7 +57,7 @@ try { ## QueryException -Thrown for runtime errors at the query level — for example, when a +Thrown for runtime errors at the query level, for example when a `QueryableStorage` implementation encounters an error during in-memory evaluation. @@ -82,7 +82,7 @@ try { ## QueryRenderException -Thrown when a `Query` cannot be rendered to SQL — for example, if required +Thrown when a `Query` cannot be rendered to SQL, for example if required fields are missing or the query state is inconsistent at render time. ```java @@ -114,7 +114,7 @@ try { List ids = store.query(q); } catch (QueryRenderException e) { - // Rendering failed — log and return a safe error response + // Rendering failed, log and return a safe error response } catch (QueryException e) { // In-memory evaluation failed @@ -130,12 +130,12 @@ Exception messages may contain internal column names or values. Map exceptions to safe, generic responses before returning them to external clients. ```java -// CORRECT — map to a safe API response +// CORRECT: map to a safe API response catch (QueryRenderException e) { return Response.serverError().entity("Query rendering error").build(); } -// WRONG — leaks internal details +// WRONG: leaks internal details catch (QueryRenderException e) { return Response.serverError().entity(e.getMessage()).build(); } diff --git a/docs/in-memory.md b/docs/in-memory.md index ef48c7b..dde83ec 100644 --- a/docs/in-memory.md +++ b/docs/in-memory.md @@ -1,6 +1,6 @@ --- title: In-Memory Filtering -nav_order: 8 +nav_order: 9 description: "Filtering in-memory collections with QueryableStorage" --- @@ -38,7 +38,7 @@ caller controls how records are loaded by ID after filtering. Each `ConditionEntry` in the `Query` holds a `Condition` with an `Operator` and a value. `Condition.matches(Map, String key)` evaluates the -condition against an attribute map — no SQL dialect or database connection is +condition against an attribute map. No SQL dialect or database connection is required. The `QueryableStorage` implementation is responsible for: @@ -153,7 +153,7 @@ List ids = store.query(q); | `EQ` | `Objects.equals(stored, value)` | | `NEQ` | `!Objects.equals(stored, value)` | | `GT` / `GTE` / `LT` / `LTE` | Numeric comparison; coerces `Long`/`Integer`/`Double` as needed | -| `LIKE` | `stored.toString().contains(value)` — substring match | +| `LIKE` | `stored.toString().contains(value)` (substring match) | | `NOT_LIKE` | Negated `LIKE` | | `IS_NULL` | `!map.containsKey(key) \|\| map.get(key) == null` | | `IS_NOT_NULL` / `EXISTS` | `map.containsKey(key) && map.get(key) != null` | diff --git a/docs/index.md b/docs/index.md index 53ccc1a..02bb48d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -19,20 +19,22 @@ No runtime dependencies required. ## Features -- **Fluent SELECT builder** — `from`, `select`, `distinct`, `where*`, +- **Fluent SELECT builder**: `from`, `select`, `distinct`, `where*`, `orderBy`, `groupBy`, `havingRaw`, `limit`, `offset` -- **DML builders** — `InsertBuilder`, `UpdateBuilder`, `DeleteBuilder`, `CreateBuilder` -- **Parameterized-only** — user values always go through `?` bind parameters; SQL injection +- **DML builders**: `InsertBuilder`, `UpdateBuilder`, `DeleteBuilder`, `CreateBuilder` +- **Parameterized-only**: user values always go through `?` bind parameters; SQL injection is structurally impossible -- **16 operators** — equality, comparison, `LIKE`, `NULL` checks, `IN`, `BETWEEN`, +- **16 operators**: equality, comparison, `LIKE`, `NULL` checks, `IN`, `BETWEEN`, `EXISTS`, and subquery operators -- **Subquery support** — `WHERE col IN (SELECT ...)`, `WHERE EXISTS (SELECT ...)`, +- **Subquery support**: `WHERE col IN (SELECT ...)`, `WHERE EXISTS (SELECT ...)`, `WHERE NOT EXISTS (SELECT ...)`, scalar `WHERE col = (SELECT ...)`, FROM-derived table, JOIN subquery, and scalar `SELECT` items -- **Three SQL dialects** — `STANDARD` (ANSI), `MYSQL` (back-tick quoting), `SQLITE` (double-quote) -- **In-memory filtering** — `QueryableStorage` functional interface applies the same `Query` +- **Three SQL dialects**: `STANDARD` (ANSI), `MYSQL` (back-tick quoting), `SQLITE` (double-quote) +- **Global and per-query configuration** via `QueryBuilderDefaults`: preset dialect, default + columns, limit, offset, and LIKE wrapping once at application startup +- **In-memory filtering**: `QueryableStorage` functional interface applies the same `Query` to flat-map collections without touching a database -- **Zero runtime dependencies** — pure Java 25+, nothing to shade or exclude +- **Zero runtime dependencies**: pure Java 25+, nothing to shade or exclude --- @@ -100,11 +102,12 @@ SqlResult update = QueryBuilder.update("users") | Page | What it covers | |------|----------------| | [Installation](installation) | Maven, Gradle, JitPack, GitHub Packages | -| [Query Builder](query-builder) | SELECT — `from`, `select`, `where*`, `orderBy`, `build` | +| [Query Builder](query-builder) | SELECT: `from`, `select`, `where*`, `orderBy`, `build` | | [DML Builders](dml-builders) | `InsertBuilder`, `UpdateBuilder`, `DeleteBuilder`, `CreateBuilder` | | [Conditions](conditions) | All 16 operators, `Condition`, `ConditionEntry`, `Connector` | | [Subqueries](subqueries) | All six subquery variants | | [SQL Dialects](sql-dialects) | `STANDARD`, `MYSQL`, `SQLITE`, `SqlResult`, dialect matrix | -| [In-Memory Filtering](in-memory) | `QueryableStorage` — filter collections without a database | +| [Configuration](configuration) | `QueryBuilderDefaults`: global and per-query dialect, columns, limit, LIKE wrapping | +| [In-Memory Filtering](in-memory) | `QueryableStorage`: filter collections without a database | | [Exceptions](exceptions) | Error hierarchy and handling patterns | | [API Reference](api-reference) | Full public-method tables for every class | diff --git a/docs/installation.md b/docs/installation.md index 899bf9a..37937f5 100644 --- a/docs/installation.md +++ b/docs/installation.md @@ -110,7 +110,7 @@ authenticate with a personal access token that has `read:packages` scope. ## Verifying the installation -Add this snippet to a test class — it should compile and run without errors: +Add this snippet to a test class. It should compile and run without errors: ```java import com.github.ezframework.javaquerybuilder.query.builder.QueryBuilder; diff --git a/docs/query-builder.md b/docs/query-builder.md index d362577..6041098 100644 --- a/docs/query-builder.md +++ b/docs/query-builder.md @@ -40,7 +40,7 @@ List params = result.getParameters(); ``` `QueryBuilder` is also the gateway to all DML builders via its static factory -methods — see [DML Builders](dml-builders). +methods. See [DML Builders](dml-builders). --- @@ -55,7 +55,7 @@ new QueryBuilder().from("orders") ## Selecting columns ```java -// SELECT * (default — no columns specified) +// SELECT * (default - no columns specified) new QueryBuilder().from("users") // SELECT id, name @@ -158,7 +158,7 @@ new QueryBuilder() ### HAVING -Pass a raw SQL fragment — no value interpolation; use static expressions only: +Pass a raw SQL fragment with no value interpolation. Use static expressions only: ```java .groupBy("category") @@ -185,7 +185,7 @@ Pass a raw SQL fragment — no value interpolation; use static expressions only: ## Building the result -### `build()` — returns a `Query` +### `build()` (returns a `Query`) `build()` produces a `Query` object which can be passed to a `SqlDialect` later, used for in-memory filtering with `QueryableStorage`, or inspected directly: @@ -197,7 +197,7 @@ Query q = new QueryBuilder() .build(); ``` -### `buildSql()` — returns a `SqlResult` +### `buildSql()` (returns a `SqlResult`) `buildSql()` renders the `Query` immediately using the standard ANSI dialect. Use the overloads to specify a table or dialect explicitly: @@ -239,7 +239,7 @@ See [Subqueries](subqueries) for full examples. ## Security Every value passed to a `where*` method is placed in the `?` bind-parameter -list of the rendered `SqlResult` — it is never concatenated into the SQL string. +list of the rendered `SqlResult`. It is never concatenated into the SQL string. ```java // Safe even if userInput contains SQL metacharacters @@ -256,5 +256,5 @@ SqlResult r = new QueryBuilder() {: .warning } > Column names and table names are **not** parameterized. Always use static, -> known-safe strings for those arguments — never forward user input as a +> known-safe strings for those arguments. Never forward user input as a > column or table name. diff --git a/docs/sql-dialects.md b/docs/sql-dialects.md index 4986874..1b7d6fc 100644 --- a/docs/sql-dialects.md +++ b/docs/sql-dialects.md @@ -41,14 +41,14 @@ SqlResult r1 = new QueryBuilder() .buildSql(); // → SELECT * FROM users WHERE id = ? -// MySQL — identifiers back-tick quoted +// MySQL: back-tick quoted identifiers SqlResult r2 = new QueryBuilder() .from("users") .whereEquals("id", 1) .buildSql(SqlDialect.MYSQL); // → SELECT * FROM `users` WHERE `id` = ? -// SQLite — identifiers double-quoted +// SQLite: double-quoted identifiers SqlResult r3 = new QueryBuilder() .from("users") .whereEquals("id", 1) @@ -96,15 +96,15 @@ Query q = new QueryBuilder() .limit(500) .build(); -// Standard — LIMIT ignored +// Standard: LIMIT ignored SqlResult std = SqlDialect.STANDARD.renderDelete(q); // → DELETE FROM sessions WHERE expired = ? -// MySQL — LIMIT honored +// MySQL: LIMIT honored SqlResult my = SqlDialect.MYSQL.renderDelete(q); // → DELETE FROM `sessions` WHERE `expired` = ? LIMIT 500 -// SQLite — LIMIT honored +// SQLite: LIMIT honored SqlResult sq = SqlDialect.SQLITE.renderDelete(q); // → DELETE FROM "sessions" WHERE "expired" = ? LIMIT 500 ``` @@ -129,7 +129,7 @@ The same `Query` produces different SQL across dialects due to identifier quotin `AbstractSqlDialect` implements the shared rendering logic for SELECT and DELETE queries. It is the base class for both `MySqlDialect` and `SqliteDialect`. -**Subquery parameter ordering** — parameters are collected depth-first in this +**Subquery parameter ordering**: parameters are collected depth-first in this order: 1. SELECT-list scalar subquery parameters (left to right) diff --git a/docs/subqueries.md b/docs/subqueries.md index ea70ddd..e446027 100644 --- a/docs/subqueries.md +++ b/docs/subqueries.md @@ -1,7 +1,7 @@ --- title: Subqueries nav_order: 6 -description: "All six subquery variants — IN, EXISTS, NOT EXISTS, scalar, FROM-derived table, JOIN, and scalar SELECT" +description: "All six subquery variants: IN, EXISTS, NOT EXISTS, scalar, FROM-derived table, JOIN, and scalar SELECT" --- # Subqueries From 70cbbf9b3e09129b5f99156771e2eb49a094987f Mon Sep 17 00:00:00 2001 From: ez-plugins Date: Sat, 18 Apr 2026 19:57:56 +0200 Subject: [PATCH 2/2] docs: fix markdown format --- docs/api-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api-reference.md b/docs/api-reference.md index 85bfe6b..7eee228 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -247,7 +247,7 @@ getters and setters; setters are used exclusively by the builders. |--------|-------------| | `JoinClause(Type, String table, String on)` | Plain-table join | | `JoinClause(Type, Query subquery, String alias, String on)` | Subquery (derived-table) join | -| `getType()` | `JoinClause.Type`: `INNER`, `LEFT`, `RIGHT`, or `CROSS` | Join type | +| `getType()` | `JoinClause.Type`: `INNER`, `LEFT`, `RIGHT`, or `CROSS` | | `getTable()` | Table name for plain-table join; `null` for subquery join | | `getSubquery()` | Subquery for derived-table join; `null` for plain-table join | | `getAlias()` | Alias for derived-table join |