Skip to content

Commit dbaff96

Browse files
committed
RealtimeFilterValue & RealtimeFilter
1 parent aa08d01 commit dbaff96

File tree

1 file changed

+62
-20
lines changed

1 file changed

+62
-20
lines changed

Sources/Realtime/RealtimeChannel+AsyncAwait.swift

Lines changed: 62 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,33 +6,71 @@
66
//
77

88
import Foundation
9-
import PostgREST
109

11-
public enum RealtimeChannelV2Filter {
12-
case eq(column: String, value: any URLQueryRepresentable)
13-
case neq(column: String, value: any URLQueryRepresentable)
14-
case gt(column: String, value: any URLQueryRepresentable)
15-
case gte(column: String, value: any URLQueryRepresentable)
16-
case lt(column: String, value: any URLQueryRepresentable)
17-
case lte(column: String, value: any URLQueryRepresentable)
18-
case `in`(column: String, values: [any URLQueryRepresentable])
10+
/// A value that can be used to filter Realtime changes in a channel.
11+
public protocol RealtimeFilterValue {
12+
var rawValue: String { get }
13+
}
14+
15+
extension String: RealtimeFilterValue {
16+
public var rawValue: String { self }
17+
}
18+
19+
extension Int: RealtimeFilterValue {
20+
public var rawValue: String { "\(self)" }
21+
}
22+
23+
extension Double: RealtimeFilterValue {
24+
public var rawValue: String { "\(self)" }
25+
}
26+
27+
extension Bool: RealtimeFilterValue {
28+
public var rawValue: String { "\(self)" }
29+
}
30+
31+
extension UUID: RealtimeFilterValue {
32+
public var rawValue: String { uuidString }
33+
}
34+
35+
extension Date: RealtimeFilterValue {
36+
public var rawValue: String {
37+
let formatter = ISO8601DateFormatter()
38+
formatter.formatOptions = [.withInternetDateTime, .withFractionalSeconds]
39+
return formatter.string(from: self)
40+
}
41+
}
42+
43+
extension Array: RealtimeFilterValue where Element: RealtimeFilterValue {
44+
public var rawValue: String {
45+
map(\.rawValue).joined(separator: ",")
46+
}
47+
}
48+
49+
public enum RealtimeFilter {
50+
case eq(_ column: String, value: any RealtimeFilterValue)
51+
case neq(_ column: String, value: any RealtimeFilterValue)
52+
case gt(_ column: String, value: any RealtimeFilterValue)
53+
case gte(_ column: String, value: any RealtimeFilterValue)
54+
case lt(_ column: String, value: any RealtimeFilterValue)
55+
case lte(_ column: String, value: any RealtimeFilterValue)
56+
case `in`(_ column: String, values: [any RealtimeFilterValue])
1957

2058
var value: String {
2159
switch self {
2260
case let .eq(column, value):
23-
return "\(column)=eq.\(value.queryValue)"
61+
return "\(column)=eq.\(value.rawValue)"
2462
case let .neq(column, value):
25-
return "\(column)=neq.\(value.queryValue)"
63+
return "\(column)=neq.\(value.rawValue)"
2664
case let .gt(column, value):
27-
return "\(column)=gt.\(value.queryValue)"
65+
return "\(column)=gt.\(value.rawValue)"
2866
case let .gte(column, value):
29-
return "\(column)=gte.\(value.queryValue)"
67+
return "\(column)=gte.\(value.rawValue)"
3068
case let .lt(column, value):
31-
return "\(column)=lt.\(value.queryValue)"
69+
return "\(column)=lt.\(value.rawValue)"
3270
case let .lte(column, value):
33-
return "\(column)=lte.\(value.queryValue)"
71+
return "\(column)=lte.\(value.rawValue)"
3472
case let .in(column, values):
35-
return "\(column)=in.(\(values.map(\.queryValue).joined(separator: ",")))"
73+
return "\(column)=in.(\(values.map(\.rawValue)))"
3674
}
3775
}
3876
}
@@ -58,7 +96,7 @@ extension RealtimeChannelV2 {
5896
_: InsertAction.Type,
5997
schema: String = "public",
6098
table: String? = nil,
61-
filter: RealtimeChannelV2Filter? = nil
99+
filter: RealtimeFilter? = nil
62100
) -> AsyncStream<InsertAction> {
63101
postgresChange(event: .insert, schema: schema, table: table, filter: filter?.value)
64102
.compactErase()
@@ -70,6 +108,7 @@ extension RealtimeChannelV2 {
70108
deprecated,
71109
message: "Use the new filter syntax instead."
72110
)
111+
@_disfavoredOverload
73112
public func postgresChange(
74113
_: InsertAction.Type,
75114
schema: String = "public",
@@ -85,7 +124,7 @@ extension RealtimeChannelV2 {
85124
_: UpdateAction.Type,
86125
schema: String = "public",
87126
table: String? = nil,
88-
filter: RealtimeChannelV2Filter? = nil
127+
filter: RealtimeFilter? = nil
89128
) -> AsyncStream<UpdateAction> {
90129
postgresChange(event: .update, schema: schema, table: table, filter: filter?.value)
91130
.compactErase()
@@ -97,6 +136,7 @@ extension RealtimeChannelV2 {
97136
deprecated,
98137
message: "Use the new filter syntax instead."
99138
)
139+
@_disfavoredOverload
100140
public func postgresChange(
101141
_: UpdateAction.Type,
102142
schema: String = "public",
@@ -112,7 +152,7 @@ extension RealtimeChannelV2 {
112152
_: DeleteAction.Type,
113153
schema: String = "public",
114154
table: String? = nil,
115-
filter: RealtimeChannelV2Filter? = nil
155+
filter: RealtimeFilter? = nil
116156
) -> AsyncStream<DeleteAction> {
117157
postgresChange(event: .delete, schema: schema, table: table, filter: filter?.value)
118158
.compactErase()
@@ -124,6 +164,7 @@ extension RealtimeChannelV2 {
124164
deprecated,
125165
message: "Use the new filter syntax instead."
126166
)
167+
@_disfavoredOverload
127168
public func postgresChange(
128169
_: DeleteAction.Type,
129170
schema: String = "public",
@@ -139,7 +180,7 @@ extension RealtimeChannelV2 {
139180
_: AnyAction.Type,
140181
schema: String = "public",
141182
table: String? = nil,
142-
filter: RealtimeChannelV2Filter? = nil
183+
filter: RealtimeFilter? = nil
143184
) -> AsyncStream<AnyAction> {
144185
postgresChange(event: .all, schema: schema, table: table, filter: filter?.value)
145186
}
@@ -150,6 +191,7 @@ extension RealtimeChannelV2 {
150191
deprecated,
151192
message: "Use the new filter syntax instead."
152193
)
194+
@_disfavoredOverload
153195
public func postgresChange(
154196
_: AnyAction.Type,
155197
schema: String = "public",

0 commit comments

Comments
 (0)