Skip to content
Closed
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 Sources/StructuredQueriesCore/Bind.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ public struct BindQueryExpression<QueryValue: QueryBindable>: QueryExpression {
base.queryFragment
}
}

extension BindQueryExpression: Sendable where QueryValue: Sendable {}
4 changes: 2 additions & 2 deletions Sources/StructuredQueriesCore/CaseExpression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
/// // LEFT JOIN "reminders" ON "remindersLists"."id" = "reminders"."remindersListID"
/// // GROUP BY "remindersLists"."id"
/// ```
public struct Case<Base, QueryValue: _OptionalPromotable> {
public struct Case<Base, QueryValue: _OptionalPromotable>: Sendable {
var base: QueryFragment?

/// Creates a SQL `CASE` expression builder.
Expand Down Expand Up @@ -76,7 +76,7 @@ public struct Case<Base, QueryValue: _OptionalPromotable> {
}

/// A `CASE` expression builder.
public struct Cases<Base, QueryValue: _OptionalProtocol>: QueryExpression {
public struct Cases<Base, QueryValue: _OptionalProtocol>: QueryExpression, Sendable {
var base: QueryFragment?
var cases: [QueryFragment]

Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Collation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
/// Values of this type are supplied to ``QueryExpression/collate(_:)`` to describe how a string
/// should be compared in a query.
public struct Collation: QueryExpression {
public struct Collation: QueryExpression, Hashable, Sendable {
public typealias QueryValue = Never

/// Initializes a collating sequence name from a query fragment.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ extension RangeReplaceableCollection {
}

package init<each Q: QueryExpression>(_ elements: repeat each Q)
where Element == any QueryExpression {
where Element == any QueryExpression & Sendable {
self.init()
for element in repeat each elements {
append(element)
append(SQLQueryExpression(element))
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/StructuredQueriesCore/Optional.swift
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ extension Optional: Table where Wrapped: Table {
}

fileprivate subscript<Member: QueryRepresentable>(
member _: KeyPath<Member, Member> & Sendable,
column keyPath: KeyPath<Wrapped, Member.QueryOutput> & Sendable
member _: KeyPath<Member, Member>,
column keyPath: KeyPath<Wrapped, Member.QueryOutput>
) -> Member.QueryOutput? {
self?[keyPath: keyPath]
}
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/QueryExpression.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// A type that represents a full or partial SQL query.
public protocol QueryExpression<QueryValue>: Sendable {
public protocol QueryExpression<QueryValue> {
/// The Swift data type representation of the expression's SQL data type.
///
/// For example, a `TEXT` expression may be represented as a `String` query value.
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/SQLQueryExpression.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
///
/// It is not common to interact with this type directly. A value of this type is returned from the
/// `#sql` macro. See <doc:SafeSQLStrings> for more information.
public struct SQLQueryExpression<QueryValue>: Statement {
public struct SQLQueryExpression<QueryValue>: Statement, Sendable {
public typealias From = Never

public let queryFragment: QueryFragment
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/// A conflict resolution algorithm.
public struct ConflictResolution: QueryExpression {
public struct ConflictResolution: QueryExpression, Hashable, Sendable {
public typealias QueryValue = Never

/// The `ABORT` conflict resolution algorithm.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// Creates a common table expression that can be used to factor subqueries, or create hierarchical
/// or recursive queries of trees and graphs.
public struct With<QueryValue>: Statement {
public struct With<QueryValue>: Statement, Sendable {
public typealias From = Never

var ctes: [CommonTableExpressionClause]
Expand Down Expand Up @@ -37,7 +37,7 @@ public struct With<QueryValue>: Statement {
}
}

public struct CommonTableExpressionClause: QueryExpression {
public struct CommonTableExpressionClause: QueryExpression, Sendable {
public typealias QueryValue = ()
let tableName: QueryFragment
let select: QueryFragment
Expand Down
8 changes: 4 additions & 4 deletions Sources/StructuredQueriesCore/Statements/CompoundSelect.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extension PartialSelectStatement {
public func union(
all: Bool = false,
_ other: some PartialSelectStatement<QueryValue>
) -> some PartialSelectStatement<QueryValue> {
) -> some PartialSelectStatement<QueryValue> & Sendable {
CompoundSelect(lhs: self, operator: all ? .unionAll : .union, rhs: other)
}

Expand All @@ -25,7 +25,7 @@ extension PartialSelectStatement {
/// - Returns: A compound select statement.
public func intersect<F, J>(
_ other: some SelectStatement<QueryValue, F, J>
) -> some PartialSelectStatement<QueryValue> {
) -> some PartialSelectStatement<QueryValue> & Sendable {
CompoundSelect(lhs: self, operator: .intersect, rhs: other)
}

Expand All @@ -38,12 +38,12 @@ extension PartialSelectStatement {
/// - Returns: A compound select statement.
public func except<F, J>(
_ other: some SelectStatement<QueryValue, F, J>
) -> some PartialSelectStatement<QueryValue> {
) -> some PartialSelectStatement<QueryValue> & Sendable {
CompoundSelect(lhs: self, operator: .except, rhs: other)
}
}

private struct CompoundSelect<QueryValue>: PartialSelectStatement {
private struct CompoundSelect<QueryValue>: PartialSelectStatement, Sendable {
typealias From = Never
typealias Joins = Never

Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Statements/Delete.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ extension PrimaryKeyedTable {
/// This type of statement is constructed from ``Table/delete()`` and ``Where/delete()``.
///
/// To learn more, see <doc:DeleteStatements>.
public struct Delete<From: Table, Returning> {
public struct Delete<From: Table, Returning>: Sendable {
var `where`: [QueryFragment] = []
var returning: [QueryFragment] = []

Expand Down
4 changes: 2 additions & 2 deletions Sources/StructuredQueriesCore/Statements/Insert.swift
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ extension PrimaryKeyedTable {
}
}

private enum InsertValues {
private enum InsertValues: Sendable {
case `default`
case values([[QueryFragment]])
case select(QueryFragment)
Expand All @@ -611,7 +611,7 @@ private enum InsertValues {
/// functions.
///
/// To learn more, see <doc:InsertStatements>.
public struct Insert<Into: Table, Returning> {
public struct Insert<Into: Table, Returning>: Sendable {
var conflictResolution: ConflictResolution?
var columnNames: [String]
var conflictTargetColumnNames: [String]
Expand Down
30 changes: 17 additions & 13 deletions Sources/StructuredQueriesCore/Statements/Select.swift
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ extension Table {

public struct _SelectClauses: Sendable {
var distinct = false
var columns: [any QueryExpression] = []
var columns: [any QueryExpression & Sendable] = []
var joins: [_JoinClause] = []
var `where`: [QueryFragment] = []
var group: [QueryFragment] = []
Expand All @@ -316,7 +316,7 @@ public struct _SelectClauses: Sendable {
#if compiler(>=6.1)
@dynamicMemberLookup
#endif
public struct Select<Columns, From: Table, Joins> {
public struct Select<Columns, From: Table, Joins>: Sendable {
// NB: A parameter pack compiler crash forces us to heap-allocate this storage.
@CopyOnWrite var clauses = _SelectClauses()

Expand All @@ -325,7 +325,7 @@ public struct Select<Columns, From: Table, Joins> {
set { clauses.distinct = newValue }
_modify { yield &clauses.distinct }
}
fileprivate var columns: [any QueryExpression] {
fileprivate var columns: [any QueryExpression & Sendable] {
get { clauses.columns }
set { clauses.columns = newValue }
_modify { yield &clauses.columns }
Expand Down Expand Up @@ -363,7 +363,7 @@ public struct Select<Columns, From: Table, Joins> {

fileprivate init(
distinct: Bool,
columns: [any QueryExpression],
columns: [any QueryExpression & Sendable],
joins: [_JoinClause],
where: [QueryFragment],
group: [QueryFragment],
Expand Down Expand Up @@ -1405,7 +1405,7 @@ extension Select: SelectStatement {
var query: QueryFragment = "SELECT"
let columns =
columns.isEmpty
? [From.columns.queryFragment] + joins.map { $0.table.columns.queryFragment }
? [From.columns.queryFragment] + joins.map(\.columns)
: columns.map(\.queryFragment)
if distinct {
query.append(" DISTINCT")
Expand Down Expand Up @@ -1444,7 +1444,7 @@ extension Select: SelectStatement {
public typealias SelectOf<From: Table, each Join: Table> =
Select<(), From, (repeat each Join)>

public struct _JoinClause: QueryExpression {
public struct _JoinClause: QueryExpression, Sendable {
public typealias QueryValue = Never

struct Operator {
Expand All @@ -1456,34 +1456,38 @@ public struct _JoinClause: QueryExpression {
}

let `operator`: QueryFragment?
let table: any Table.Type
let tableName: String
let tableAlias: String?
let constraint: QueryFragment
let columns: QueryFragment

init(
init<T: Table>(
operator: Operator?,
table: any Table.Type,
table: T.Type,
constraint: some QueryExpression<Bool>
) {
self.operator = `operator`?.queryFragment
self.table = table
self.tableName = table.tableName
self.tableAlias = table.tableAlias
self.constraint = constraint.queryFragment
self.columns = table.columns.queryFragment
}

public var queryFragment: QueryFragment {
var query: QueryFragment = ""
if let `operator` {
query.append("\(`operator`) ")
}
query.append("JOIN \(quote: table.tableName) ")
if let tableAlias = table.tableAlias {
query.append("JOIN \(quote: tableName) ")
if let tableAlias {
query.append("AS \(quote: tableAlias) ")
}
query.append("ON \(constraint)")
return query
}
}

public struct _LimitClause: QueryExpression {
public struct _LimitClause: QueryExpression, Sendable {
public typealias QueryValue = Never

let maxLength: QueryFragment
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Statements/Update.swift
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ extension PrimaryKeyedTable {
/// ``Where/update(or:set:)``.
///
/// To learn more, see <doc:UpdateStatements>.
public struct Update<From: Table, Returning> {
public struct Update<From: Table, Returning>: Sendable {
var conflictResolution: ConflictResolution?
var updates: Updates<From>
var `where`: [QueryFragment] = []
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Statements/Values.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
///
/// While not particularly useful on its own it can act as a helpful starting point for recursive
/// common table expressions and other subqueries. See <doc:CommonTableExpressions> for more.
public struct Values<QueryValue>: PartialSelectStatement {
public struct Values<QueryValue>: PartialSelectStatement, Sendable {
public typealias From = Never

let values: [QueryFragment]
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Statements/Where.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ extension Table {
#if compiler(>=6.1)
@dynamicMemberLookup
#endif
public struct Where<From: Table> {
public struct Where<From: Table>: Sendable {
public static func + (lhs: Self, rhs: Self) -> Self {
Where(predicates: (lhs.predicates + rhs.predicates).removingDuplicates())
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/StructuredQueriesCore/TableAlias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ public struct TableAlias<
let base: Base

subscript<Member: QueryRepresentable>(
member _: KeyPath<Member, Member> & Sendable,
column keyPath: KeyPath<Base, Member.QueryOutput> & Sendable
member _: KeyPath<Member, Member>,
column keyPath: KeyPath<Base, Member.QueryOutput>
) -> Member.QueryOutput {
base[keyPath: keyPath]
}
Expand Down
11 changes: 5 additions & 6 deletions Sources/StructuredQueriesCore/TableColumn.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,24 +25,23 @@ public protocol TableColumnExpression<Root, Value>: QueryExpression where Value
/// Don't create instances of this value directly. Instead, use the `@Table` and `@Column` macros to
/// generate values of this type.
public struct TableColumn<Root: Table, Value: QueryRepresentable & QueryBindable>:
TableColumnExpression,
Sendable
where Value.QueryOutput: Sendable {
TableColumnExpression
{
public typealias QueryValue = Value

public let name: String

public let defaultValue: Value.QueryOutput?

let _keyPath: KeyPath<Root, Value.QueryOutput> & Sendable
let _keyPath: KeyPath<Root, Value.QueryOutput>

public var keyPath: KeyPath<Root, Value.QueryOutput> {
_keyPath
}

public init(
_ name: String,
keyPath: KeyPath<Root, Value.QueryOutput> & Sendable,
keyPath: KeyPath<Root, Value.QueryOutput>,
default defaultValue: Value.QueryOutput? = nil
) {
self.name = name
Expand All @@ -52,7 +51,7 @@ where Value.QueryOutput: Sendable {

public init(
_ name: String,
keyPath: KeyPath<Root, Value.QueryOutput> & Sendable,
keyPath: KeyPath<Root, Value.QueryOutput>,
default defaultValue: Value? = nil
) where Value == Value.QueryOutput {
self.name = name
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesCore/Updates.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
///
/// To learn more, see <doc:UpdateStatements>.
@dynamicMemberLookup
public struct Updates<Base: Table> {
public struct Updates<Base: Table>: Sendable {
private var updates: [(String, QueryFragment)] = []

init(_ body: (inout Self) -> Void) {
Expand Down
2 changes: 1 addition & 1 deletion Sources/StructuredQueriesMacros/TableMacro.swift
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,7 @@ extension TableMacro: ExtensionMacro {
\(declaration.attributes.availability)extension \(type)\
\(conformances.isEmpty ? "" : ": \(conformances, separator: ", ")") {\
\(typeAliases, separator: "\n")
public static let columns = TableColumns()
public static var columns: TableColumns { TableColumns() }
public static let tableName = \(tableName)\(letSchemaName)\(initDecoder)\(initFromOther)
}
"""
Expand Down
Loading