@@ -48,6 +48,14 @@ public struct SwiftLanguage: Language2 {
4848 try declaration ( for: migrations, options: options)
4949
5050 for query in queries {
51+ if case let . model( model) = query. input, !model. isTable {
52+ try declaration ( for: model, isOutput: false , options: options)
53+ }
54+
55+ if case let . model( model) = query. output, !model. isTable {
56+ try declaration ( for: model, isOutput: true , options: options)
57+ }
58+
5159 try declaration ( for: query, options: options)
5260 }
5361 }
@@ -91,88 +99,68 @@ public struct SwiftLanguage: Language2 {
9199 for query: GeneratedQuery ,
92100 options: GenerationOptions
93101 ) throws -> DeclSyntax {
94- let query = try StructDeclSyntax (
95- name: TokenSyntax . identifier ( query. name) ,
96- inheritanceClause: InheritanceClauseSyntax {
97- InheritedTypeSyntax ( type: TypeSyntax ( " DatabaseQuery " ) )
98- }
99- ) {
100- switch query. input {
101- case . model( let model) where !model. isTable:
102- try declaration ( for: model, isOutput: false , options: options)
103- case . some( let type) :
104- try typealiasDecl ( named: " Input " , for: type)
105- case nil :
106- try TypeAliasDeclSyntax ( " typealias Input = () " )
107- }
108-
109- switch query. output {
110- case . model( let model) where !model. isTable:
111- try declaration ( for: model, isOutput: true , options: options)
112- try outputTypeAlias ( cardinality: query. outputCardinality)
113- case . some( let type) :
114- try typealiasDecl ( named: " Row " , for: type)
115- try outputTypeAlias ( cardinality: query. outputCardinality)
116- case nil :
117- try TypeAliasDeclSyntax ( " typealias Row = () " )
118- try TypeAliasDeclSyntax ( " typealias Output = () " )
119- }
120-
121- try VariableDeclSyntax ( " var transactionKind: Feather.TransactionKind " ) {
122- query. isReadOnly ? " .read " : " .write "
123- }
124-
125- FunctionDeclSyntax (
126- name: " execute " ,
127- signature: FunctionSignatureSyntax (
128- parameterClause: FunctionParameterClauseSyntax (
129- parameters: [
130- FunctionParameterSyntax (
131- firstName: " with " ,
132- secondName: " input " ,
133- type: IdentifierTypeSyntax ( name: " Input " ) ,
134- trailingComma: TokenSyntax . commaToken ( )
135- ) ,
136- FunctionParameterSyntax (
137- firstName: " tx " ,
138- type: IdentifierTypeSyntax ( name: " borrowing Feather.Transaction " )
139- )
140- ]
141- ) ,
142- effectSpecifiers: FunctionEffectSpecifiersSyntax (
143- throwsClause: ThrowsClauseSyntax (
144- throwsSpecifier: TokenSyntax . keyword ( . throws)
145- )
146- ) ,
147- returnClause: ReturnClauseSyntax ( type: IdentifierTypeSyntax ( name: " Output " ) )
148- )
149- ) {
150- let sql = stringLiteral ( of: query. sourceSql, multiline: true )
151- let statementBinding : TokenSyntax = . keyword( query. input == nil ? . let : . var)
152- " \( statementBinding) statement = try Feather.Statement( \( sql) , \n transaction: tx \n ) "
102+ let inputTypeName = inputTypeName ( for: query)
103+ let outputTypeName = outputTypeName ( for: query)
104+ let queryTypeName = " DatabaseQuery< \( inputTypeName) , \( outputTypeName) > "
105+
106+ let query = try VariableDeclSyntax ( " var \( raw: query. name) : \( raw: queryTypeName) " ) {
107+ FunctionCallExprSyntax (
108+ calledExpression: DeclReferenceExprSyntax (
109+ baseName: . identifier( " DatabaseQueryImpl< \( inputTypeName) , \( outputTypeName) > " )
110+ ) ,
111+ leftParen: . leftParenToken( ) ,
112+ arguments: LabeledExprListSyntax {
113+ LabeledExprSyntax (
114+ label: nil ,
115+ colon: nil ,
116+ expression: DeclReferenceExprSyntax (
117+ baseName: query. isReadOnly ? " .read " : " .write "
118+ ) ,
119+ trailingComma: TokenSyntax . commaToken ( )
120+ )
121+ LabeledExprSyntax (
122+ label: TokenSyntax . identifier ( " database " ) ,
123+ colon: TokenSyntax . colonToken ( ) ,
124+ expression: DeclReferenceExprSyntax ( baseName: . identifier( " database " ) ) ,
125+ trailingComma: nil
126+ )
127+ } ,
128+ rightParen: . rightParenToken( ) ,
129+ trailingClosure: ClosureExprSyntax (
130+ signature: ClosureSignatureSyntax (
131+ parameterClause: . simpleInput( . init {
132+ ClosureShorthandParameterSyntax ( name: " input " )
133+ ClosureShorthandParameterSyntax ( name: " transaction " )
134+ } )
135+ )
136+ ) {
137+ let sql = stringLiteral ( of: query. sourceSql, multiline: true )
138+ let statementBinding : TokenSyntax = . keyword( query. input == nil ? . let : . var)
139+ " \( statementBinding) statement = try Feather.Statement( \( sql) , \n transaction: tx \n ) "
153140
154- if let input = query. input {
155- switch input {
156- case let . builtin( _, isArray) :
157- bind ( field: nil , isArray: isArray)
158- case . model( let model) :
159- for field in model. fields. values {
160- bind ( field: field. name, isArray: field. isArray)
141+ if let input = query. input {
142+ switch input {
143+ case let . builtin( _, isArray) :
144+ bind ( field: nil , isArray: isArray)
145+ case . model( let model) :
146+ for field in model. fields. values {
147+ bind ( field: field. name, isArray: field. isArray)
148+ }
161149 }
162150 }
163- }
164151
165- if query. output == nil {
166- " _ = try statement.step() "
167- } else {
168- switch query. outputCardinality {
169- case . single:
170- " return try statement.fetchOne(of: Row.self) "
171- case . many:
172- " return try statement.fetchMany(of: Row.self) "
152+ if query. output == nil {
153+ " _ = try statement.step() "
154+ } else {
155+ switch query. outputCardinality {
156+ case . single:
157+ " return try statement.fetchOne(of: Row.self) "
158+ case . many:
159+ " return try statement.fetchMany(of: Row.self) "
160+ }
173161 }
174162 }
175- }
163+ )
176164 }
177165
178166 return DeclSyntax ( query)
@@ -187,6 +175,21 @@ public struct SwiftLanguage: Language2 {
187175 }
188176 }
189177
178+ private static func inputTypeName( for query: GeneratedQuery ) -> String {
179+ return query. input? . description ?? " () "
180+ }
181+
182+ private static func outputTypeName( for query: GeneratedQuery ) -> String {
183+ if let output = query. output {
184+ switch query. outputCardinality {
185+ case . single: " \( output) ? "
186+ case . many: " [ \( output) ] "
187+ }
188+ } else {
189+ " () "
190+ }
191+ }
192+
190193 private static func declaration(
191194 for model: GeneratedModel ,
192195 isOutput: Bool ,
0 commit comments