Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: add columns query param to insert and upsert methods #205

Merged
merged 3 commits into from
Dec 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions Sources/PostgREST/PostgrestQueryBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,11 @@ public final class PostgrestQueryBuilder: PostgrestBuilder {
if !prefersHeaders.isEmpty {
$0.request.headers["Prefer"] = prefersHeaders.joined(separator: ",")
}

// TODO: How to do this in Swift?
// if (Array.isArray(values)) {
// const columns = values.reduce((acc, x) => acc.concat(Object.keys(x)), [] as string[])
// if (columns.length > 0) {
// const uniqueColumns = [...new Set(columns)].map((column) => `"${column}"`)
// this.url.searchParams.set('columns', uniqueColumns.join(','))
// }
// }
if let body = $0.request.body, let jsonObject = try JSONSerialization.jsonObject(with: body) as? [[String: Any]] {
let allKeys = jsonObject.flatMap(\.keys)
let uniqueKeys = Set(allKeys).sorted()
$0.request.query.append(URLQueryItem(name: "columns", value: uniqueKeys.joined(separator: ",")))
}
}

return PostgrestFilterBuilder(self)
Expand Down Expand Up @@ -118,6 +114,12 @@ public final class PostgrestQueryBuilder: PostgrestBuilder {
if !prefersHeaders.isEmpty {
$0.request.headers["Prefer"] = prefersHeaders.joined(separator: ",")
}

if let body = $0.request.body, let jsonObject = try JSONSerialization.jsonObject(with: body) as? [[String: Any]] {
let allKeys = jsonObject.flatMap(\.keys)
let uniqueKeys = Set(allKeys).sorted()
$0.request.query.append(URLQueryItem(name: "columns", value: uniqueKeys.joined(separator: ",")))
}
}
return PostgrestFilterBuilder(self)
}
Expand Down
59 changes: 52 additions & 7 deletions Tests/PostgRESTTests/BuildURLRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,43 @@ import XCTest
import FoundationNetworking
#endif

struct User: Encodable {
var email: String
var username: String?
}

@MainActor
final class BuildURLRequestTests: XCTestCase {
let url = URL(string: "https://example.supabase.co")!

struct TestCase: Sendable {
let name: String
var record = false
let record: Bool
let file: StaticString
let line: UInt
let build: @Sendable (PostgrestClient) async throws -> PostgrestBuilder

init(
name: String,
record: Bool = false,
file: StaticString = #file,
line: UInt = #line,
build: @escaping @Sendable (PostgrestClient) async throws -> PostgrestBuilder
) {
self.name = name
self.record = record
self.file = file
self.line = line
self.build = build
}
}

func testBuildRequest() async throws {
let runningTestCase = ActorIsolated(TestCase?.none)

let encoder = PostgrestClient.Configuration.jsonEncoder
encoder.outputFormatting = .sortedKeys

let client = PostgrestClient(
url: url,
schema: nil,
Expand All @@ -39,12 +63,15 @@ final class BuildURLRequestTests: XCTestCase {
as: .curl,
named: runningTestCase.name,
record: runningTestCase.record,
testName: "testBuildRequest()"
file: runningTestCase.file,
testName: "testBuildRequest()",
line: runningTestCase.line
)
}

return (Data(), URLResponse())
}
},
encoder: encoder
)

let testCases: [TestCase] = [
Expand All @@ -55,7 +82,16 @@ final class BuildURLRequestTests: XCTestCase {
},
TestCase(name: "insert new user") { client in
try await client.from("users")
.insert(["email": "[email protected]"])
.insert(User(email: "[email protected]"))
},
TestCase(name: "bulk insert users") { client in
try await client.from("users")
.insert(
[
User(email: "[email protected]"),
User(email: "[email protected]", username: "johndoe2"),
]
)
},
TestCase(name: "call rpc") { client in
try await client.rpc("test_fcn", params: ["KEY": "VALUE"])
Expand Down Expand Up @@ -89,11 +125,20 @@ final class BuildURLRequestTests: XCTestCase {
},
TestCase(name: "test upsert not ignoring duplicates") { client in
try await client.from("users")
.upsert(["email": "[email protected]"])
.upsert(User(email: "[email protected]"))
},
TestCase(name: "bulk upsert") { client in
try await client.from("users")
.upsert(
[
User(email: "[email protected]"),
User(email: "[email protected]", username: "johndoe2"),
]
)
},
TestCase(name: "test upsert ignoring duplicates") { client in
try await client.from("users")
.upsert(["email": "[email protected]"], ignoreDuplicates: true)
.upsert(User(email: "[email protected]"), ignoreDuplicates: true)
},
TestCase(name: "query with + character") { client in
await client.from("users")
Expand All @@ -110,7 +155,7 @@ final class BuildURLRequestTests: XCTestCase {
await client.schema("storage")
.from("objects")
.select()
}
},
]

for testCase in testCases {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
curl \
--request POST \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "X-Client-Info: postgrest-swift/x.y.z" \
--data "[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\",\"username\":\"johndoe2\"}]" \
"https://example.supabase.co/users?columns=email,username"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
curl \
--request POST \
--header "Accept: application/json" \
--header "Content-Type: application/json" \
--header "Prefer: resolution=merge-duplicates,return=representation" \
--header "X-Client-Info: postgrest-swift/x.y.z" \
--data "[{\"email\":\"[email protected]\"},{\"email\":\"[email protected]\",\"username\":\"johndoe2\"}]" \
"https://example.supabase.co/users?columns=email,username"