Skip to main content

swifql-custom-extensions

Create downstream custom SQL functions, fluent helpers, structural continuations, custom clause ownership, or reusable extension libraries for the canonical SQL module. The skill package keeps its historical routing identifier.

Informações da origem

Repositório
swiftstream/SQL
Última atividade na origem
17 de outubro de 2026 às 05:01
Idioma detectado do SKILL.md
inglês
Estrelas
302
Forks
19

Opções de instalação

Por padrão, está selecionado o prompt que primeiro revisa a origem. Você pode mudar para um comando direto ou baixar uma cópia local.

Revise os arquivos de origem

Leia o SKILL.md e os arquivos complementares exibidos pelo SkillsMP antes de decidir se vai instalar.

Explorador de arquivos
2 arquivos

Exibindo SKILL.md

SKILL.md
Instruções da origem · Visualização somente leitura
name
swifql-custom-extensions
description
Create downstream custom SQL functions, fluent helpers, structural continuations, custom clause ownership, or reusable extension libraries for the canonical SQL module. The skill package keeps its historical routing identifier.
license
LICENSE.txt
# Extend SQL Downstream Use this workflow when a consuming package or application needs reusable SQL composition that is not a built-in API. 1. Determine the SQL package version and source actually installed by the consumer before relying on extension APIs. 2. Classify the extension: custom SQL function, fluent helper, structural continuation, structural-value copy, custom clause ownership, or another compositional wrapper. 3. Classify a custom function as scalar/compositional or aggregate-style before choosing the primitive. For a scalar/compositional function, prefer `Fn.Name.custom(_:)` with `Fn.build(_:)`. For an aggregate-style function that needs aggregate arguments, DISTINCT ownership, aggregate-local ORDER BY, or builder control flow, use the installed version's public `Fn.aggregate` / `AggregateArgumentBuilder` surface when available. 4. If a helper means “continue this query,” use `structurallyAppending(_:)`. Do not assume flattening a framed root is equivalent to continuation. 5. If the goal is to copy the same structural value rather than continue it, keep that distinction explicit; `SQLableParts(parts: query.parts)` is the normal copy path. 6. Use public `SQLClauseOwner` and `SQLClauseKind` only when the extension genuinely owns clause semantics. Inspect the installed source/tests for the exact structural pattern before introducing custom ownership. 7. Keep dynamic or untrusted data on an explicit value/bind path. Ordinary scalar arguments should normally flow through their normal `SQLable` representation. If the installed package exposes bind-aware `SQLRaw` and a downstream helper truly needs caller-owned raw structure, keep that structure static/trusted and use labeled `\(bind:)` only for value data; never splice runtime values through ordinary String interpolation. The target database grammar must still permit a parameter in that exact position — bind-aware raw does not make placeholders legal where the database requires a literal or another grammar token. 8. Return composed results to the ordinary `SQLable` preparation pipeline. Do not add a second renderer, formatter, placeholder system, or bind collector. 9. Validate representative target-dialect output and the exact bind-value order. For a downstream exact binary operator helper, prefer the installed version's public grouped operator primitive instead of hand-building a raw binary expression: ```swift let expression = lhs.op(.custom("@?"), rhs) ``` Here `@?` is a fixed PostgreSQL operator token chosen by the extension author. The `.op` primitive itself is generic, groups the complete binary expression, and keeps `rhs` on the ordinary SQLable preparation/bind path. Prefer that typed path over raw SQL. Do not accept an untrusted runtime operator token, splice the RHS through ordinary String interpolation, invent punctuation-specific public constants for portability, or construct the internal SELECT postfix-request state directly. A custom scalar function with a runtime argument can stay on the normal value path: ```swift import SQL let runtimeValue = input let function = Fn.build( .custom("my_function"), body: runtimeValue.parts ) let prepared = SQL.select(function).prepare(.psql).splitted ``` For an aggregate-style downstream extension, prefer forwarding the public builder closure directly rather than flattening/re-parsing its rendered SQL: ```swift extension Fn.Name { static let weightedSum: Self = .init("weighted_sum") } extension Fn { static func weightedSum( @AggregateArgumentBuilder _ body: () -> AggregateArguments ) -> SQLable { aggregate(.weightedSum, body) } } let aggregate = Fn.weightedSum { DB.Column("value") DB.Column("weight") OrderBy(DB.Column("created_at"), .desc) } ``` The wrapper signature needs only `AggregateArgumentBuilder` and `AggregateArguments`; it should not name nested builder state types. Keep aggregate-local `OrderBy` outside `Distinct { ... }`. Do not introduce a second aggregate renderer or a fallback value-taking overload merely to forward the builder result. For continuation, prefer the structural API directly: ```swift let continued = query.structurallyAppending(fragment) ``` For a same-value copy where continuation is not intended: ```swift let copied = SQLableParts(parts: query.parts) ``` Do not stringify a dynamic value into raw SQL merely to make a custom extension easier to render. If the desired feature appears to require explicit raw structure, inspect the installed SQL composition model first; prefer ordinary `SQLPart` composition. On versions that expose bind-aware `SQLRaw`, a truly raw structural fragment may still keep runtime value data on standard preparation through labeled `\(bind:)`, but identifiers/operators/clauses remain structure rather than bind data, and the target database must permit a parameter in that exact grammar position.
Ver no GitHub