@@ -6,13 +6,16 @@ import StructuredQueriesSupport
66/// directly interpolated into the string. This most commonly occurs when using the `#sql` macro,
77/// which takes values of this type.
88public struct QueryFragment : Hashable , Sendable {
9- // TODO: Call this 'Element' and make 'QueryFragment' a collection of them?
9+ /// A segment of a query fragment.
1010 public enum Segment : Hashable , Sendable {
11+ /// A raw SQL fragment.
1112 case sql( String )
13+
14+ /// A binding.
1215 case binding( QueryBinding )
1316 }
1417
15- // TODO: Make 'private(set)' and add APIs to support extensibility like 'indent()'?
18+ /// An array of segments backing this query fragment.
1619 public internal( set) var segments : [ Segment ] = [ ]
1720
1821 fileprivate init ( segments: [ Segment ] ) {
@@ -53,6 +56,24 @@ public struct QueryFragment: Hashable, Sendable {
5356 query += rhs
5457 return query
5558 }
59+
60+ /// Returns a prepared SQL string and associated bindings for this query.
61+ ///
62+ /// - Parameter template: Prepare a template string for a binding at a given 1-based offset.
63+ /// - Returns: A SQL string and array of associated bindings.
64+ public func prepare(
65+ _ template: ( _ offset: Int ) -> String
66+ ) -> ( sql: String , bindings: [ QueryBinding ] ) {
67+ segments. enumerated ( ) . reduce ( into: ( sql: " " , bindings: [ QueryBinding] ( ) ) ) {
68+ switch $1. element {
69+ case . sql( let sql) :
70+ $0. sql. append ( sql)
71+ case . binding( let binding) :
72+ $0. sql. append ( template ( $1. offset + 1 ) )
73+ $0. bindings. append ( binding)
74+ }
75+ }
76+ }
5677}
5778
5879extension QueryFragment : CustomDebugStringConvertible {
@@ -119,7 +140,6 @@ extension QueryFragment: ExpressibleByStringInterpolation {
119140 fileprivate var segments : [ Segment ] = [ ]
120141
121142 public init ( literalCapacity: Int , interpolationCount: Int ) {
122- // TODO: Should all the segments' strings share the same contiguous storage as substring/span?
123143 segments. reserveCapacity ( interpolationCount)
124144 }
125145
0 commit comments