@@ -119,6 +119,7 @@ extension TableMacro: ExtensionMacro {
119119 . map { $0. rewritten ( selfRewriter) }
120120 var columnQueryOutputType = columnQueryValueType
121121 var isPrimaryKey = primaryKey == nil && identifier. text == " id "
122+ var isColumnGroup = false
122123 var isEphemeral = false
123124 var isGenerated = false
124125
@@ -127,9 +128,10 @@ extension TableMacro: ExtensionMacro {
127128 let attribute = attribute. as ( AttributeSyntax . self) ,
128129 let attributeName = attribute. attributeName. as ( IdentifierTypeSyntax . self) ? . name. text
129130 else { continue }
131+ isColumnGroup = isColumnGroup || attributeName == " Columns "
130132 isEphemeral = isEphemeral || attributeName == " Ephemeral "
131133 guard
132- attributeName == " Column " || isEphemeral,
134+ attributeName == " Column " || isEphemeral || isColumnGroup ,
133135 case . argumentList( let arguments) = attribute. arguments
134136 else { continue }
135137
@@ -271,7 +273,18 @@ extension TableMacro: ExtensionMacro {
271273 }
272274
273275 let defaultValue = binding. initializer? . value. rewritten ( selfRewriter)
274- if isGenerated {
276+ if isColumnGroup {
277+ columnsProperties. append (
278+ """
279+ public let \( identifier) = \( moduleName) .ColumnGroup< \
280+ QueryValue, \
281+ \( raw: columnQueryValueType? . trimmedDescription ?? " _ " ) \
282+ >( \
283+ keyPath: \\ QueryValue. \( identifier) \
284+ )
285+ """
286+ )
287+ } else if isGenerated {
275288 columnsProperties. append (
276289 """
277290 public var \( identifier) : \( moduleName) .GeneratedColumn< \
@@ -624,8 +637,8 @@ extension TableMacro: MemberMacro {
624637 }
625638 let type = IdentifierTypeSyntax ( name: declaration. name. trimmed)
626639 var allColumns : [ ( name: TokenSyntax , type: TypeSyntax ? , default: ExprSyntax ? ) ] = [ ]
627- var allColumnNames : [ TokenSyntax ] = [ ]
628- var writableColumns : [ TokenSyntax ] = [ ]
640+ var allColumnNames : [ Column ] = [ ]
641+ var writableColumns : [ Column ] = [ ]
629642 var selectedColumns : [ TokenSyntax ] = [ ]
630643 var columnsProperties : [ DeclSyntax ] = [ ]
631644 var decodings : [ String ] = [ ]
@@ -661,11 +674,12 @@ extension TableMacro: MemberMacro {
661674 StringLiteralExprSyntax ( content: identifier. text. trimmingBackticks ( ) )
662675 )
663676 var columnQueryValueType =
664- ( binding. typeAnnotation? . type. trimmed
665- ?? binding. initializer? . value. literalType)
666- . map { $0. rewritten ( selfRewriter) }
677+ ( binding. typeAnnotation? . type. trimmed
678+ ?? binding. initializer? . value. literalType)
679+ . map { $0. rewritten ( selfRewriter) }
667680 var columnQueryOutputType = columnQueryValueType
668681 var isPrimaryKey = primaryKey == nil && identifier. text == " id "
682+ var isColumnGroup = false
669683 var isEphemeral = false
670684 var isGenerated = false
671685
@@ -674,9 +688,10 @@ extension TableMacro: MemberMacro {
674688 let attribute = attribute. as ( AttributeSyntax . self) ,
675689 let attributeName = attribute. attributeName. as ( IdentifierTypeSyntax . self) ? . name. text
676690 else { continue }
691+ isColumnGroup = isColumnGroup || attributeName == " Columns "
677692 isEphemeral = isEphemeral || attributeName == " Ephemeral "
678693 guard
679- attributeName == " Column " || isEphemeral,
694+ attributeName == " Column " || isEphemeral || isColumnGroup ,
680695 case . argumentList( let arguments) = attribute. arguments
681696 else { continue }
682697
@@ -768,7 +783,21 @@ extension TableMacro: MemberMacro {
768783 }
769784
770785 let defaultValue = binding. initializer? . value. rewritten ( selfRewriter)
771- if isGenerated {
786+ if isColumnGroup {
787+ columnsProperties. append (
788+ """
789+ public let \( identifier) = \( moduleName) .ColumnGroup< \
790+ QueryValue, \
791+ \( raw: columnQueryValueType? . trimmedDescription ?? " _ " ) \
792+ >( \
793+ keyPath: \\ QueryValue. \( identifier) \
794+ )
795+ """
796+ )
797+ allColumns. append ( ( identifier, columnQueryValueType, defaultValue) )
798+ allColumnNames. append ( . group( identifier) )
799+ writableColumns. append ( . group( identifier) )
800+ } else if isGenerated {
772801 columnsProperties. append (
773802 """
774803 public var \( identifier) : \( moduleName) .GeneratedColumn< \
@@ -786,7 +815,7 @@ extension TableMacro: MemberMacro {
786815 """
787816 )
788817 allColumns. append ( ( identifier, columnQueryValueType, defaultValue) )
789- allColumnNames. append ( identifier)
818+ allColumnNames. append ( . single ( identifier) )
790819 } else {
791820 columnsProperties. append (
792821 """
@@ -800,8 +829,8 @@ extension TableMacro: MemberMacro {
800829 """
801830 )
802831 allColumns. append ( ( identifier, columnQueryValueType, defaultValue) )
803- allColumnNames. append ( identifier)
804- writableColumns. append ( identifier)
832+ allColumnNames. append ( . single ( identifier) )
833+ writableColumns. append ( . single ( identifier) )
805834 }
806835 let decodedType = columnQueryValueType? . asNonOptionalType ( )
807836 if let defaultValue {
@@ -1049,10 +1078,10 @@ extension TableMacro: MemberMacro {
10491078 public typealias QueryValue = \( type. trimmed)
10501079 \( columnsProperties, separator: " \n " )
10511080 public static var allColumns: [any \( moduleName) .TableColumnExpression] { \
1052- [ \( allColumnNames. map { " QueryValue .columns. \( $0 ) " as ExprSyntax } , separator: " , " ) ]
1081+ [ \( allColumnNames. map { $0 . columns ( . all ) } , separator: " , " ) ].flatMap( \\ .self)
10531082 }
10541083 public static var writableColumns: [any \( moduleName) .WritableTableColumnExpression] { \
1055- [ \( writableColumns. map { " QueryValue .columns. \( $0 ) " as ExprSyntax } , separator: " , " ) ]
1084+ [ \( writableColumns. map { $0 . columns ( . writable ) } , separator: " , " ) ].flatMap( \\ .self)
10561085 }
10571086 public var queryFragment: QueryFragment {
10581087 " \( raw: selectedColumns. map { #"\(self. \#( $0) )"# } . joined ( separator: " , " ) ) "
@@ -1066,7 +1095,7 @@ extension TableMacro: MemberMacro {
10661095 public init(
10671096 \( raw: selectionInitArguments)
10681097 ) {
1069- self.allColumns = [ \( allColumnNames , separator: " , " ) ]
1098+ self.allColumns = [ \( selectedColumns , separator: " , " ) ]
10701099 }
10711100 }
10721101 """ ,
@@ -1130,4 +1159,24 @@ extension TableMacro: MemberAttributeMacro {
11301159 """
11311160 ]
11321161 }
1162+
1163+ fileprivate enum Column {
1164+ case single( TokenSyntax )
1165+ case group( TokenSyntax )
1166+
1167+ enum Kind : String {
1168+ case all
1169+ case writable
1170+ }
1171+
1172+ func columns( _ kind: Kind ) -> ExprSyntax {
1173+ switch self {
1174+ case . single( let column) :
1175+ return " [QueryValue.columns. \( column) ] "
1176+
1177+ case . group( let columns) :
1178+ return #" \#( moduleName) .ColumnGroup. \#( raw: kind) Columns(keyPath: \QueryValue. \#( columns) )"#
1179+ }
1180+ }
1181+ }
11331182}
0 commit comments