Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Package `com.github.ezframework.javaquerybuilder.query`:
| `sql.AbstractSqlDialect` | Base SQL rendering logic |

**Key conventions**:

- Builder methods **always return `this`** (or the builder type) for fluent chaining.
- All SQL values must go through the parameterized SQL path — never concatenate user input into SQL strings.
- `Operator` is the single source of truth for supported operators; add new operators there first.
Expand Down Expand Up @@ -106,6 +107,7 @@ Copilot agents can persist project-scoped notes in `/memories/repo/` to carry co
The agent will store this under `/memories/repo/` and load it automatically in future sessions.

**Useful things to store**:

- Verified build commands and their quirks
- Project-specific conventions not obvious from the code
- Known gotchas (e.g., "always run `mvn checkstyle:check` before committing")
Expand Down
5 changes: 1 addition & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

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
Expand Down Expand Up @@ -393,7 +392,6 @@ 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.
Expand Down Expand Up @@ -499,7 +497,6 @@ SqlDialect.SQLITE.renderDelete(query);

`LIKE` values are automatically wrapped with `%` on both sides so `whereLike("name", "alice")` becomes `name LIKE ?` with parameter `%alice%`.


## License

MIT
MIT
44 changes: 22 additions & 22 deletions docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Main entry point for SELECT queries and static gateway to DML builders.
**Static factory methods**

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `insert()` | `InsertBuilder` | New `InsertBuilder` |
| `insertInto(String table)` | `InsertBuilder` | New `InsertBuilder` pre-set to `table` |
| `update()` | `UpdateBuilder` | New `UpdateBuilder` |
Expand All @@ -37,7 +37,7 @@ Main entry point for SELECT queries and static gateway to DML builders.
**SELECT builder methods**

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `from(String table)` | `QueryBuilder` | Set source table |
| `select(String... columns)` | `QueryBuilder` | Add columns to SELECT clause; omit for `SELECT *` |
| `distinct()` | `QueryBuilder` | Add `DISTINCT` to SELECT |
Expand Down Expand Up @@ -82,7 +82,7 @@ Main entry point for SELECT queries and static gateway to DML builders.
Lower-level SELECT builder that produces `SqlResult` directly (no `Query` intermediary).

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `from(String table)` | `SelectBuilder` | Set source table |
| `select(String... columns)` | `SelectBuilder` | Add SELECT columns |
| `distinct()` | `SelectBuilder` | Add `DISTINCT` |
Expand All @@ -102,7 +102,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
### `InsertBuilder`

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `into(String table)` | `InsertBuilder` | Set target table |
| `value(String col, Object val)` | `InsertBuilder` | Add a column/value pair |
| `build()` | `SqlResult` | Render with standard dialect |
Expand All @@ -113,7 +113,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
### `UpdateBuilder`

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `table(String table)` | `UpdateBuilder` | Set target table |
| `set(String col, Object val)` | `UpdateBuilder` | Add a SET pair |
| `whereEquals(col, val)` | `UpdateBuilder` | `WHERE col = ?` (AND) |
Expand All @@ -127,7 +127,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
### `DeleteBuilder`

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `from(String table)` | `DeleteBuilder` | Set target table |
| `whereEquals(col, val)` | `DeleteBuilder` | `WHERE col = ?` (AND) |
| `whereNotEquals(col, val)` | `DeleteBuilder` | `WHERE col != ?` (AND) |
Expand All @@ -147,7 +147,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
### `CreateBuilder`

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `table(String name)` | `CreateBuilder` | Set table name |
| `column(String name, String sqlType)` | `CreateBuilder` | Add column definition |
| `primaryKey(String name)` | `CreateBuilder` | Declare a primary key column |
Expand All @@ -164,7 +164,7 @@ Lower-level SELECT builder that produces `SqlResult` directly (no `Query` interm
Enum of comparison operators. See [Conditions](conditions) for the full table.

| Constant | SQL |
|----------|-----|
| ---------- | ----- |
| `EQ` | `= ?` |
| `NEQ` | `!= ?` |
| `GT` | `> ?` |
Expand All @@ -187,7 +187,7 @@ Enum of comparison operators. See [Conditions](conditions) for the full table.
### `Condition`

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `Condition(Operator op, Object value)` | Create a condition; `value` may be `null` |
| `getOperator()` | Returns the `Operator` |
| `getValue()` | Returns the comparison value (`null`, scalar, `List<?>`, or `Query`) |
Expand All @@ -198,7 +198,7 @@ Enum of comparison operators. See [Conditions](conditions) for the full table.
### `ConditionEntry`

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `ConditionEntry(String col, Condition cond, Connector connector)` | Create a condition entry |
| `getColumn()` | Column name (`null` for EXISTS-subquery conditions) |
| `getCondition()` | The wrapped `Condition` |
Expand All @@ -209,7 +209,7 @@ Enum of comparison operators. See [Conditions](conditions) for the full table.
### `Connector`

| Constant | SQL keyword |
|----------|-------------|
| ---------- | ------------- |
| `AND` | `AND` |
| `OR` | `OR` |

Expand All @@ -223,7 +223,7 @@ Immutable data holder produced by `QueryBuilder.build()`. All fields have
getters and setters; setters are used exclusively by the builders.

| Getter | Type | Description |
|--------|------|-------------|
| -------- | ------ | ------------- |
| `getTable()` | `String` | Source table name |
| `getSelectColumns()` | `List<String>` | Columns in SELECT clause; empty = `SELECT *` |
| `isDistinct()` | `boolean` | Whether `DISTINCT` is active |
Expand All @@ -244,7 +244,7 @@ getters and setters; setters are used exclusively by the builders.
### `JoinClause`

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `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` |
Expand All @@ -258,7 +258,7 @@ getters and setters; setters are used exclusively by the builders.
### `ScalarSelectItem`

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `ScalarSelectItem(Query subquery, String alias)` | Create a scalar SELECT item |
| `getSubquery()` | The subquery to embed |
| `getAlias()` | Column alias in SELECT clause |
Expand All @@ -283,7 +283,7 @@ public interface QueryableStorage {
### `SqlDialect`

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `STANDARD` | ANSI SQL (no identifier quoting) |
| `MYSQL` | MySQL: back-tick quoting; DELETE LIMIT supported |
| `SQLITE` | SQLite: double-quote quoting; DELETE LIMIT supported |
Expand All @@ -295,7 +295,7 @@ public interface QueryableStorage {
### `SqlResult`

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `getSql()` | `String` | Rendered SQL with `?` placeholders |
| `getParameters()` | `List<Object>` | Bind parameters in placeholder order |

Expand All @@ -311,7 +311,7 @@ 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 |
Expand All @@ -320,7 +320,7 @@ usage guide.
**Instance getters**

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `getDialect()` | `SqlDialect` | Configured SQL dialect |
| `getDefaultColumns()` | `String` | Default SELECT column expression |
| `getDefaultLimit()` | `int` | Default LIMIT; `-1` means none |
Expand All @@ -333,7 +333,7 @@ usage guide.
### `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 |
Expand All @@ -349,7 +349,7 @@ usage guide.
### `QueryBuilderException`

| Constructor | Description |
|-------------|-------------|
| ------------- | ------------- |
| `QueryBuilderException()` | No-message default |
| `QueryBuilderException(String message)` | Simple message |
| `QueryBuilderException(String message, Throwable cause)` | Wraps another exception |
Expand All @@ -360,7 +360,7 @@ usage guide.
### `QueryException`

| Constructor | Description |
|-------------|-------------|
| ------------- | ------------- |
| `QueryException()` | No-message default |
| `QueryException(String message)` | Simple message |
| `QueryException(String message, Throwable cause)` | Wraps another exception |
Expand All @@ -371,7 +371,7 @@ usage guide.
### `QueryRenderException`

| Constructor | Description |
|-------------|-------------|
| ------------- | ------------- |
| `QueryRenderException()` | No-message default |
| `QueryRenderException(String message)` | Simple message |
| `QueryRenderException(String message, Throwable cause)` | Wraps another exception |
Expand Down
10 changes: 5 additions & 5 deletions docs/conditions.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ conditions use `AND` by default; call the `orWhere*` variant to use `OR`.
`Operator` is the single source of truth for all supported comparison operators.

| Constant | SQL rendering | Notes |
|----------|---------------|-------|
| ---------- | --------------- | ------- |
| `EQ` | `col = ?` | Equality |
| `NEQ` | `col != ?` | Not equal |
| `GT` | `col > ?` | Greater than |
Expand Down Expand Up @@ -61,7 +61,7 @@ The table below maps every `QueryBuilder` `where*` method to its `Operator`
constant and the SQL it generates.

| Builder method | Operator | Generated SQL fragment |
|----------------|----------|------------------------|
| ---------------- | ---------- | ------------------------ |
| `whereEquals(col, val)` | `EQ` | `col = ?` |
| `orWhereEquals(col, val)` | `EQ` | `OR col = ?` |
| `whereNotEquals(col, val)` | `NEQ` | `col != ?` |
Expand Down Expand Up @@ -131,7 +131,7 @@ new QueryBuilder()
`Condition` pairs an `Operator` with its comparison value.

| Member | Type | Description |
|--------|------|-------------|
| -------- | ------ | ------------- |
| `Condition(Operator op, Object value)` | constructor | Create a condition; `value` may be `null` for `IS_NULL`, `IS_NOT_NULL`, `EXISTS` |
| `getOperator()` | `Operator` | The operator for this condition |
| `getValue()` | `Object` | The comparison value (`null`, scalar, `List<?>`, or `Query`) |
Expand All @@ -147,7 +147,7 @@ without a database.
`ConditionEntry` wraps a `Condition` with its column name and `Connector`.

| Member | Type | Description |
|--------|------|-------------|
| -------- | ------ | ------------- |
| `ConditionEntry(String column, Condition condition, Connector connector)` | constructor | Create a condition entry |
| `getColumn()` | `String` | The column name (`null` for `EXISTS_SUBQUERY` / `NOT_EXISTS_SUBQUERY`) |
| `getCondition()` | `Condition` | The wrapped condition |
Expand All @@ -158,6 +158,6 @@ without a database.
## Connector enum

| Constant | SQL keyword |
|----------|-------------|
| ---------- | ------------- |
| `AND` | `AND` |
| `OR` | `OR` |
10 changes: 5 additions & 5 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ 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 |
Expand Down Expand Up @@ -165,7 +165,7 @@ QueryBuilderDefaults.setGlobal(QueryBuilderDefaults.builder().build());
### `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 |
Expand All @@ -174,7 +174,7 @@ QueryBuilderDefaults.setGlobal(QueryBuilderDefaults.builder().build());
### `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 |
Expand All @@ -185,7 +185,7 @@ QueryBuilderDefaults.setGlobal(QueryBuilderDefaults.builder().build());
### `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 |
Expand All @@ -199,7 +199,7 @@ QueryBuilderDefaults.setGlobal(QueryBuilderDefaults.builder().build());
All three builders throw `NullPointerException` if `null` is passed.

| Builder | Method signature |
|---------|-----------------|
| --------- | ----------------- |
| `QueryBuilder` | `withDefaults(QueryBuilderDefaults defaults)` |
| `SelectBuilder` | `withDefaults(QueryBuilderDefaults defaults)` |
| `DeleteBuilder` | `withDefaults(QueryBuilderDefaults defaults)` |
8 changes: 4 additions & 4 deletions docs/dialects/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ parameterized `SqlResult`. Four built-in dialects are provided as constants
on the interface:

| Constant | Page | Identifier quoting | DELETE LIMIT | ILIKE | RETURNING |
|----------|------|--------------------|--------------|-------|-----------|
| ---------- | ------ | -------------------- | -------------- | ------- | ----------- |
| `SqlDialect.STANDARD` | [STANDARD]({{ site.baseurl }}/sql-dialects/standard/) | None (ANSI) | No | No | No |
| `SqlDialect.MYSQL` | [MySQL]({{ site.baseurl }}/sql-dialects/mysql/) | Back-tick `` ` `` | Yes | No | No |
| `SqlDialect.SQLITE` | [SQLite]({{ site.baseurl }}/sql-dialects/sqlite/) | Double-quote `"` | Yes | No | No |
Expand All @@ -38,7 +38,7 @@ The same `Query` produces different SQL across dialects due to identifier
quoting:

| Feature | STANDARD | MYSQL | SQLITE | POSTGRESQL |
|---------|----------|-------|--------|------------|
| --------- | ---------- | ------- | -------- | ------------ |
| Table quoting | `users` | `` `users` `` | `"users"` | `"users"` |
| Column quoting | `id` | `` `id` `` | `"id"` | `"id"` |
| DELETE LIMIT | No | Yes | Yes | No |
Expand All @@ -54,7 +54,7 @@ quoting:
rendered SQL string and the ordered bind-parameter list.

| Method | Returns | Description |
|--------|---------|-------------|
| -------- | --------- | ------------- |
| `getSql()` | `String` | The rendered SQL with `?` placeholders |
| `getParameters()` | `List<Object>` | Bind parameters in the order they appear in the SQL |

Expand Down Expand Up @@ -97,7 +97,7 @@ and `appendConditionFragment`.
## SqlDialect interface

| Member | Description |
|--------|-------------|
| -------- | ------------- |
| `SqlDialect.STANDARD` | ANSI SQL constant instance |
| `SqlDialect.MYSQL` | MySQL dialect constant instance |
| `SqlDialect.SQLITE` | SQLite dialect constant instance |
Expand Down
2 changes: 1 addition & 1 deletion docs/dialects/mysql.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ description: "MySQL dialect — back-tick identifier quoting and DELETE LIMIT su
Quoting is applied to SELECT and DELETE queries rendered through this dialect.

| Feature | Value |
|---------|-------|
| --------- | ------- |
| Identifier quoting | Back-tick `` ` `` |
| DELETE LIMIT | Supported |
| ILIKE | Not supported |
Expand Down
2 changes: 1 addition & 1 deletion docs/dialects/postgresql.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ and adds two PostgreSQL-specific features: case-insensitive `ILIKE` / `NOT ILIKE
operators on SELECT queries, and a `RETURNING` clause on `DELETE` statements.

| Feature | Value |
|---------|-------|
| --------- | ------- |
| Identifier quoting | Double-quote `"` |
| DELETE LIMIT | Not supported |
| ILIKE / NOT ILIKE | Supported |
Expand Down
2 changes: 1 addition & 1 deletion docs/dialects/sqlite.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ description: "SQLite dialect — double-quote identifier quoting and DELETE LIMI
supports the `LIMIT` clause on `DELETE` statements.

| Feature | Value |
|---------|-------|
| --------- | ------- |
| Identifier quoting | Double-quote `"` |
| DELETE LIMIT | Supported |
| ILIKE | Not supported |
Expand Down
Loading
Loading