Skip to content

Commit 7992489

Browse files
committed
Select,Group,Order
1 parent 6f37c18 commit 7992489

File tree

9 files changed

+259
-75
lines changed

9 files changed

+259
-75
lines changed

Package.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ let package = Package(
2020
name: "CoreDataQueryInterface",
2121
dependencies: ["PredicateQI"],
2222
exclude: [
23+
"QueryBuilder+Group.swift.gyb",
2324
"QueryBuilder+Order.swift.gyb",
2425
"QueryBuilder+Select.swift.gyb"
2526
]
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//
2+
// NSSortDescriptor.swift
3+
// CoreDataQueryInterface
4+
//
5+
// Created by Gregory Higley on 2022-10-25.
6+
//
7+
8+
import Foundation
9+
import PredicateQI
10+
11+
public extension NSSortDescriptor {
12+
convenience init<M: NSObject, V: Expression>(objectKeyPath: KeyPath<Object<M>, V>, ascending: Bool) {
13+
let expression = Object<M>()[keyPath: objectKeyPath].pqiExpression
14+
self.init(key: expression.keyPath, ascending: ascending)
15+
}
16+
}

Sources/CoreDataQueryInterface/QueryBuilder+Group.swift

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,98 @@ public extension QueryBuilder {
2525
group(by: properties)
2626
}
2727

28+
func group<V: Expression>(by keyPath: KeyPath<Object<M>, V>, name: String, type: NSAttributeDescription.AttributeType) -> QueryBuilder<M, R> {
29+
let description = NSExpressionDescription()
30+
description.expression = Object<M>()[keyPath: keyPath].pqiExpression
31+
description.resultType = type
32+
description.name = name
33+
return group(by: description)
34+
}
35+
2836
func group<V: Expression>(by keyPath: KeyPath<Object<M>, V>) -> QueryBuilder<M, R> {
2937
let object = Object<M>()
3038
let expression = object[keyPath: keyPath]
3139
return group(by: "\(expression.pqiExpression)")
3240
}
33-
41+
42+
func group<V1: Expression, V2: Expression>(
43+
by keyPath1: KeyPath<Object<M>, V1>,
44+
_ keyPath2: KeyPath<Object<M>, V2>
45+
) -> QueryBuilder<M, R> {
46+
group(by: keyPath1)
47+
.group(by: keyPath2)
48+
}
49+
50+
func group<V1: Expression, V2: Expression, V3: Expression>(
51+
by keyPath1: KeyPath<Object<M>, V1>,
52+
_ keyPath2: KeyPath<Object<M>, V2>,
53+
_ keyPath3: KeyPath<Object<M>, V3>
54+
) -> QueryBuilder<M, R> {
55+
group(by: keyPath1)
56+
.group(by: keyPath2)
57+
.group(by: keyPath3)
58+
}
59+
60+
func group<V1: Expression, V2: Expression, V3: Expression, V4: Expression>(
61+
by keyPath1: KeyPath<Object<M>, V1>,
62+
_ keyPath2: KeyPath<Object<M>, V2>,
63+
_ keyPath3: KeyPath<Object<M>, V3>,
64+
_ keyPath4: KeyPath<Object<M>, V4>
65+
) -> QueryBuilder<M, R> {
66+
group(by: keyPath1)
67+
.group(by: keyPath2)
68+
.group(by: keyPath3)
69+
.group(by: keyPath4)
70+
}
71+
72+
func group<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression>(
73+
by keyPath1: KeyPath<Object<M>, V1>,
74+
_ keyPath2: KeyPath<Object<M>, V2>,
75+
_ keyPath3: KeyPath<Object<M>, V3>,
76+
_ keyPath4: KeyPath<Object<M>, V4>,
77+
_ keyPath5: KeyPath<Object<M>, V5>
78+
) -> QueryBuilder<M, R> {
79+
group(by: keyPath1)
80+
.group(by: keyPath2)
81+
.group(by: keyPath3)
82+
.group(by: keyPath4)
83+
.group(by: keyPath5)
84+
}
85+
86+
func group<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression, V6: Expression>(
87+
by keyPath1: KeyPath<Object<M>, V1>,
88+
_ keyPath2: KeyPath<Object<M>, V2>,
89+
_ keyPath3: KeyPath<Object<M>, V3>,
90+
_ keyPath4: KeyPath<Object<M>, V4>,
91+
_ keyPath5: KeyPath<Object<M>, V5>,
92+
_ keyPath6: KeyPath<Object<M>, V6>
93+
) -> QueryBuilder<M, R> {
94+
group(by: keyPath1)
95+
.group(by: keyPath2)
96+
.group(by: keyPath3)
97+
.group(by: keyPath4)
98+
.group(by: keyPath5)
99+
.group(by: keyPath6)
100+
}
101+
102+
func group<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression, V6: Expression, V7: Expression>(
103+
by keyPath1: KeyPath<Object<M>, V1>,
104+
_ keyPath2: KeyPath<Object<M>, V2>,
105+
_ keyPath3: KeyPath<Object<M>, V3>,
106+
_ keyPath4: KeyPath<Object<M>, V4>,
107+
_ keyPath5: KeyPath<Object<M>, V5>,
108+
_ keyPath6: KeyPath<Object<M>, V6>,
109+
_ keyPath7: KeyPath<Object<M>, V7>
110+
) -> QueryBuilder<M, R> {
111+
group(by: keyPath1)
112+
.group(by: keyPath2)
113+
.group(by: keyPath3)
114+
.group(by: keyPath4)
115+
.group(by: keyPath5)
116+
.group(by: keyPath6)
117+
.group(by: keyPath7)
118+
}
119+
34120
private func group(by properties: [FetchedProperty]) -> QueryBuilder<M, R> {
35121
var query = self
36122
query.propertiesToGroupBy.append(contentsOf: properties)
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
//
2+
// QueryBuilder+Group.swift
3+
// CoreDataQueryInterface
4+
//
5+
// Created by Gregory Higley on 2022-10-24.
6+
//
7+
%{
8+
9+
def args(items, fmt=lambda i: f'{i}', sep=', '):
10+
return sep.join(map(fmt, items))
11+
}%
12+
13+
import PredicateQI
14+
import XCTest
15+
16+
public extension QueryBuilder {
17+
func group(by properties: [NSPropertyDescription]) -> QueryBuilder<M, R> {
18+
group(by: properties.map(FetchedProperty.property))
19+
}
20+
21+
func group(by properties: NSPropertyDescription...) -> QueryBuilder<M, R> {
22+
group(by: properties)
23+
}
24+
25+
func group(by properties: [String]) -> QueryBuilder<M, R> {
26+
group(by: properties.map(FetchedProperty.string))
27+
}
28+
29+
func group(by properties: String...) -> QueryBuilder<M, R> {
30+
group(by: properties)
31+
}
32+
33+
func group<V: Expression>(by keyPath: KeyPath<Object<M>, V>, name: String, type: NSAttributeDescription.AttributeType) -> QueryBuilder<M, R> {
34+
let description = NSExpressionDescription()
35+
description.expression = Object<M>()[keyPath: keyPath].pqiExpression
36+
description.resultType = type
37+
description.name = name
38+
return group(by: description)
39+
}
40+
41+
func group<V: Expression>(by keyPath: KeyPath<Object<M>, V>) -> QueryBuilder<M, R> {
42+
let object = Object<M>()
43+
let expression = object[keyPath: keyPath]
44+
return group(by: "\(expression.pqiExpression)")
45+
}
46+
% for i in range(2, 8):
47+
48+
func group<${args(range(1, i + 1), lambda i: f'V{i}: Expression')}>(
49+
by ${args(range(1, i + 1), lambda i: f'keyPath{i}: KeyPath<Object<M>, V{i}>', ',\n _ ')}
50+
) -> QueryBuilder<M, R> {
51+
group(by: keyPath1)
52+
% for k in range(2, i + 1):
53+
.group(by: keyPath${k})
54+
% end
55+
}
56+
% end
57+
58+
private func group(by properties: [FetchedProperty]) -> QueryBuilder<M, R> {
59+
var query = self
60+
query.propertiesToGroupBy.append(contentsOf: properties)
61+
return query
62+
}
63+
}

Sources/CoreDataQueryInterface/QueryBuilder+Order.swift

Lines changed: 62 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -27,111 +27,111 @@ public extension QueryBuilder {
2727
order(by: sortDescriptors)
2828
}
2929

30-
func order<V>(_ direction: SortDirection = .ascending, by keyPath: KeyPath<M, V>) -> QueryBuilder<M, R> {
31-
let sortDescriptor = NSSortDescriptor(keyPath: keyPath, ascending: direction.isAscending)
30+
func order<V: Expression>(_ direction: SortDirection = .ascending, by keyPath: KeyPath<Object<M>, V>) -> QueryBuilder<M, R> {
31+
let sortDescriptor = NSSortDescriptor(objectKeyPath: keyPath, ascending: direction.isAscending)
3232
var query = self
3333
query.sortDescriptors.append(sortDescriptor)
3434
return query
3535
}
3636

37-
func order<V1, V2>(
37+
func order<V1: Expression, V2: Expression>(
3838
_ direction: SortDirection = .ascending,
39-
by keyPath1: KeyPath<M, V1>,
40-
_ keyPath2: KeyPath<M, V2>
39+
by keyPath1: KeyPath<Object<M>, V1>,
40+
_ keyPath2: KeyPath<Object<M>, V2>
4141
) -> QueryBuilder<M, R> {
4242
let sortDescriptors = [
43-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
44-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
43+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
44+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
4545
]
4646
return order(by: sortDescriptors)
4747
}
4848

49-
func order<V1, V2, V3>(
49+
func order<V1: Expression, V2: Expression, V3: Expression>(
5050
_ direction: SortDirection = .ascending,
51-
by keyPath1: KeyPath<M, V1>,
52-
_ keyPath2: KeyPath<M, V2>,
53-
_ keyPath3: KeyPath<M, V3>
51+
by keyPath1: KeyPath<Object<M>, V1>,
52+
_ keyPath2: KeyPath<Object<M>, V2>,
53+
_ keyPath3: KeyPath<Object<M>, V3>
5454
) -> QueryBuilder<M, R> {
5555
let sortDescriptors = [
56-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
57-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
58-
NSSortDescriptor(keyPath: keyPath3, ascending: direction.isAscending),
56+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
57+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
58+
NSSortDescriptor(objectKeyPath: keyPath3, ascending: direction.isAscending),
5959
]
6060
return order(by: sortDescriptors)
6161
}
6262

63-
func order<V1, V2, V3, V4>(
63+
func order<V1: Expression, V2: Expression, V3: Expression, V4: Expression>(
6464
_ direction: SortDirection = .ascending,
65-
by keyPath1: KeyPath<M, V1>,
66-
_ keyPath2: KeyPath<M, V2>,
67-
_ keyPath3: KeyPath<M, V3>,
68-
_ keyPath4: KeyPath<M, V4>
65+
by keyPath1: KeyPath<Object<M>, V1>,
66+
_ keyPath2: KeyPath<Object<M>, V2>,
67+
_ keyPath3: KeyPath<Object<M>, V3>,
68+
_ keyPath4: KeyPath<Object<M>, V4>
6969
) -> QueryBuilder<M, R> {
7070
let sortDescriptors = [
71-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
72-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
73-
NSSortDescriptor(keyPath: keyPath3, ascending: direction.isAscending),
74-
NSSortDescriptor(keyPath: keyPath4, ascending: direction.isAscending),
71+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
72+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
73+
NSSortDescriptor(objectKeyPath: keyPath3, ascending: direction.isAscending),
74+
NSSortDescriptor(objectKeyPath: keyPath4, ascending: direction.isAscending),
7575
]
7676
return order(by: sortDescriptors)
7777
}
7878

79-
func order<V1, V2, V3, V4, V5>(
79+
func order<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression>(
8080
_ direction: SortDirection = .ascending,
81-
by keyPath1: KeyPath<M, V1>,
82-
_ keyPath2: KeyPath<M, V2>,
83-
_ keyPath3: KeyPath<M, V3>,
84-
_ keyPath4: KeyPath<M, V4>,
85-
_ keyPath5: KeyPath<M, V5>
81+
by keyPath1: KeyPath<Object<M>, V1>,
82+
_ keyPath2: KeyPath<Object<M>, V2>,
83+
_ keyPath3: KeyPath<Object<M>, V3>,
84+
_ keyPath4: KeyPath<Object<M>, V4>,
85+
_ keyPath5: KeyPath<Object<M>, V5>
8686
) -> QueryBuilder<M, R> {
8787
let sortDescriptors = [
88-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
89-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
90-
NSSortDescriptor(keyPath: keyPath3, ascending: direction.isAscending),
91-
NSSortDescriptor(keyPath: keyPath4, ascending: direction.isAscending),
92-
NSSortDescriptor(keyPath: keyPath5, ascending: direction.isAscending),
88+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
89+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
90+
NSSortDescriptor(objectKeyPath: keyPath3, ascending: direction.isAscending),
91+
NSSortDescriptor(objectKeyPath: keyPath4, ascending: direction.isAscending),
92+
NSSortDescriptor(objectKeyPath: keyPath5, ascending: direction.isAscending),
9393
]
9494
return order(by: sortDescriptors)
9595
}
9696

97-
func order<V1, V2, V3, V4, V5, V6>(
97+
func order<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression, V6: Expression>(
9898
_ direction: SortDirection = .ascending,
99-
by keyPath1: KeyPath<M, V1>,
100-
_ keyPath2: KeyPath<M, V2>,
101-
_ keyPath3: KeyPath<M, V3>,
102-
_ keyPath4: KeyPath<M, V4>,
103-
_ keyPath5: KeyPath<M, V5>,
104-
_ keyPath6: KeyPath<M, V6>
99+
by keyPath1: KeyPath<Object<M>, V1>,
100+
_ keyPath2: KeyPath<Object<M>, V2>,
101+
_ keyPath3: KeyPath<Object<M>, V3>,
102+
_ keyPath4: KeyPath<Object<M>, V4>,
103+
_ keyPath5: KeyPath<Object<M>, V5>,
104+
_ keyPath6: KeyPath<Object<M>, V6>
105105
) -> QueryBuilder<M, R> {
106106
let sortDescriptors = [
107-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
108-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
109-
NSSortDescriptor(keyPath: keyPath3, ascending: direction.isAscending),
110-
NSSortDescriptor(keyPath: keyPath4, ascending: direction.isAscending),
111-
NSSortDescriptor(keyPath: keyPath5, ascending: direction.isAscending),
112-
NSSortDescriptor(keyPath: keyPath6, ascending: direction.isAscending),
107+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
108+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
109+
NSSortDescriptor(objectKeyPath: keyPath3, ascending: direction.isAscending),
110+
NSSortDescriptor(objectKeyPath: keyPath4, ascending: direction.isAscending),
111+
NSSortDescriptor(objectKeyPath: keyPath5, ascending: direction.isAscending),
112+
NSSortDescriptor(objectKeyPath: keyPath6, ascending: direction.isAscending),
113113
]
114114
return order(by: sortDescriptors)
115115
}
116116

117-
func order<V1, V2, V3, V4, V5, V6, V7>(
117+
func order<V1: Expression, V2: Expression, V3: Expression, V4: Expression, V5: Expression, V6: Expression, V7: Expression>(
118118
_ direction: SortDirection = .ascending,
119-
by keyPath1: KeyPath<M, V1>,
120-
_ keyPath2: KeyPath<M, V2>,
121-
_ keyPath3: KeyPath<M, V3>,
122-
_ keyPath4: KeyPath<M, V4>,
123-
_ keyPath5: KeyPath<M, V5>,
124-
_ keyPath6: KeyPath<M, V6>,
125-
_ keyPath7: KeyPath<M, V7>
119+
by keyPath1: KeyPath<Object<M>, V1>,
120+
_ keyPath2: KeyPath<Object<M>, V2>,
121+
_ keyPath3: KeyPath<Object<M>, V3>,
122+
_ keyPath4: KeyPath<Object<M>, V4>,
123+
_ keyPath5: KeyPath<Object<M>, V5>,
124+
_ keyPath6: KeyPath<Object<M>, V6>,
125+
_ keyPath7: KeyPath<Object<M>, V7>
126126
) -> QueryBuilder<M, R> {
127127
let sortDescriptors = [
128-
NSSortDescriptor(keyPath: keyPath1, ascending: direction.isAscending),
129-
NSSortDescriptor(keyPath: keyPath2, ascending: direction.isAscending),
130-
NSSortDescriptor(keyPath: keyPath3, ascending: direction.isAscending),
131-
NSSortDescriptor(keyPath: keyPath4, ascending: direction.isAscending),
132-
NSSortDescriptor(keyPath: keyPath5, ascending: direction.isAscending),
133-
NSSortDescriptor(keyPath: keyPath6, ascending: direction.isAscending),
134-
NSSortDescriptor(keyPath: keyPath7, ascending: direction.isAscending),
128+
NSSortDescriptor(objectKeyPath: keyPath1, ascending: direction.isAscending),
129+
NSSortDescriptor(objectKeyPath: keyPath2, ascending: direction.isAscending),
130+
NSSortDescriptor(objectKeyPath: keyPath3, ascending: direction.isAscending),
131+
NSSortDescriptor(objectKeyPath: keyPath4, ascending: direction.isAscending),
132+
NSSortDescriptor(objectKeyPath: keyPath5, ascending: direction.isAscending),
133+
NSSortDescriptor(objectKeyPath: keyPath6, ascending: direction.isAscending),
134+
NSSortDescriptor(objectKeyPath: keyPath7, ascending: direction.isAscending),
135135
]
136136
return order(by: sortDescriptors)
137137
}

Sources/CoreDataQueryInterface/QueryBuilder+Order.swift.gyb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,21 +32,21 @@ public extension QueryBuilder {
3232
order(by: sortDescriptors)
3333
}
3434

35-
func order<V>(_ direction: SortDirection = .ascending, by keyPath: KeyPath<M, V>) -> QueryBuilder<M, R> {
36-
let sortDescriptor = NSSortDescriptor(keyPath: keyPath, ascending: direction.isAscending)
35+
func order<V: Expression>(_ direction: SortDirection = .ascending, by keyPath: KeyPath<Object<M>, V>) -> QueryBuilder<M, R> {
36+
let sortDescriptor = NSSortDescriptor(objectKeyPath: keyPath, ascending: direction.isAscending)
3737
var query = self
3838
query.sortDescriptors.append(sortDescriptor)
3939
return query
4040
}
4141
% for i in range(2, 8):
4242

43-
func order<${args(range(1, i + 1), lambda i: f'V{i}')}>(
43+
func order<${args(range(1, i + 1), lambda i: f'V{i}: Expression')}>(
4444
_ direction: SortDirection = .ascending,
45-
by ${args(range(1, i + 1), lambda i: f'keyPath{i}: KeyPath<M, V{i}>', ',\n _ ')}
45+
by ${args(range(1, i + 1), lambda i: f'keyPath{i}: KeyPath<Object<M>, V{i}>', ',\n _ ')}
4646
) -> QueryBuilder<M, R> {
4747
let sortDescriptors = [
4848
% for k in range(1, i + 1):
49-
NSSortDescriptor(keyPath: keyPath${k}, ascending: direction.isAscending),
49+
NSSortDescriptor(objectKeyPath: keyPath${k}, ascending: direction.isAscending),
5050
% end
5151
]
5252
return order(by: sortDescriptors)

0 commit comments

Comments
 (0)