supabase-community / postgrest-swift Goto Github PK
View Code? Open in Web Editor NEWSwift client for PostgREST
License: MIT License
Swift client for PostgREST
License: MIT License
Currently you can't only write (INSERT) a db with RLS on using Swift.
Because INSERT also return a SELECT. Therefore a db for e.g. feedback can also read by everyone with the anon key. With a INSERT request you should be able to return a returning:“minimal“
too.
So you can write to a db where RLS with only INSERT = true is on.
When I compile in Xcode, it produces an error that says: "Failed to produce diagnostic for expression; please submit a bug report (https://swift.org/contributing/#reporting-bugs) and include the project"
Steps to reproduce the behavior, please provide code snippets or a repository:
It builds successfully.
Status 400 when attempting to query by array value
For example:
.from("posts").select(columns: "*").execute().value
.from("posts").select(columns: "*").contains(column: "members", value: userid).execute().value
Crate a table, RLS policy and query by array value
Should either return an empty array or results
OS: macOS Ventura 13.3
Version of supabase-ios: 0.2.1
When converting timestamp
or timestamptz
to Swift Date
type for values created using default (now() AT TIME ZONE 'utc'::text)
expression, the final value is nil
(as Date
is an optional type).
CREATE TABLE my_table (
id int8 NOT NULL,
title varchar(255) NOT NULL,
created_at timestamptz DEFAULT (now() AT TIME ZONE 'utc'::text) NOT NULL
);
INSERT INTO my_table (title) VALUES ('my title')
import Foundation
import Supabase
struct Todo: Codable, Identifiable, Equatable, Hashable {
let id: Int
var title: String
let createdAt: Date
enum CodingKeys: String, CodingKey {
case id
case title
case createdAt = "created_at"
}
init(id: Int, title: String, createdAt: Date) {
self.id = id
self.title = title
self.createdAt = createdAt
}
}
func getTodos() async throws -> [Todo] {
guard let response = try? await client.database.from("todos").select().execute(),
let todos = try? response.decoded(to: [Todo].self) else {
throw APIError.queryIssue
}
return todos
}
todos
collection should contain one object:
Link(
id: 1,
title: "my title",
createdAt: "2022-10-17T20:12:37+0000"
)
No screenshots.
0.0.6
I'm not sure, but it looks like this may be the culprit:
Currently, examples cover rudimentary applications, based on a simple Todo app concept, however it would be great to see how more complex queries can be fired, for example OUTER and INNER JOIN queries.
How do you create queries to accommodate nested structs (SQL relationships) in Swift?
https://gist.github.com/matthewmorek/d88cf8c1c93503588016f5ff0875d29b
Sample SQL to achieve using query builder:
SELECT json_agg(
json_build_object(
'id', l.id,
'url', l.url,
'title', l.title,
'category', json_build_object(
'id', c.id,
'name', c.name
)
)
) as links
FROM links l
JOIN categories c ON l.category_id = c.id
JSON output:
[
{
"id": "15979e27-c446-4395-aed6-7b1651777aba",
"url": "https://some.url/with/a/few/bits/",
"title": "link title",
"category": {
"id": "955ed84a-9c58-4a57-9e6a-75ece7c50cbd",
"name": "Category #1"
}
}
]
We need to setup a CI system using GitHub Actions, I thought of implementing the following steps, but it's open for other steps too:
swift build
swift test
Right now the PostgrestFilterBuilder mirrors the Javascript API design. This might work great there, but it's not the kind of descriptive semantics that Swift users are used to.
phfts(column: column, query: query, config: config)
Without knowing any context it is impossible to understand (and even then hard to read) what this expression does.
More descriptive function names would be great.
phrasetoFullTextSearch(column: String, query: String, config: String? = nil)
I have a query that searches if a string is into a column called email
. It works really well unless you search for emails that contain a +.
For example:
Both are valid emails and it should return the object.
Here's how I look for it:
queryBuilder.ilike(column: "email", value: "%[email protected]%")
Search in a column for a string that contains a +.
It should work with and without the +.
Hello, I have integrated Supabase-Swift to my project.
When I try to insert a row, I receive this error - > "All object keys must match"
Even if I include in my Codable Item values like id which is auto generated in db.
I'm using version 0.2.1
of this package via Swift Package Manager.
I have a user
table with a primary key of id
. I perform the following upsert
query:
let data = MyModel(id: "abc", name: "Bob")
let query = supabase.database.from("user").upsert(values: data, returning: .minimal).select()
do {
try await query.execute()
} catch {
print(error)
}
✅ With no records in my table, the upsert
succeeds by inserting a new row.
⛔️ If I immediately perform the same query again, I get a 409
error which means there's a conflict.
I assume this is because it's attempting to re-insert
the same record again without doing an update
instead.
Does upsert()
work for anyone else and I'm just doing it wrong? 😅
We are running a query with a gt
query on a timestamptz
field. We are passing a timestamptz
string, which we received from supabase into the query to fetch newer rows, however since the string contains a +
, the query will not be escaped correctly, as +
is an allowed character. In order for the query to work, +
needs to be escaped with %2B
, otherwise supabase will return an error.
If we escape the +
before passing it to postgrest-swift
, the escaped string gets escaped again, also resulting in an error.
Run the following code on a table with a received_at
field, which has the type timestamptz
.
let response = try await client.database.from("tasks")
.select()
.gt(column: "received_at", value: "2023-03-23T15:50:30.511743+00:00")
.order(column: "received_at")
.execute()
This will return the following error from the server:
{
"code": "22007",
"details": null,
"hint": null,
"message": "invalid input syntax for type timestamp with time zone: \"2023-03-23T15:50:31.511743 00:00\""
}
I'm not what the best approach would be. The easiest for this case would be to escape the +
internally, but I could expect this to be a breaking change and lead to other issues.
As the APIClient
on PostgrestClient
and the APIClient.delegate
are non-public, it is currently not possible to adjust the escaping behavior from outside the library. Have you considered making the library more configurable here?
If they would be exposed, I could implement the func client<T>(_ client: APIClient, makeURLForRequest request: Request<T>) throws -> URL?
on APIClientDelegate
to escape the string correctly.
The update
method always seems to 400. Spent over an hour trying to debug this but doesn't seem to be an issue on my end since select
and upsert
work fine.
struct Profile: Codable, Identifiable {
let id: Int
let created_at: Date
var name: String
var notes: String
var image: String
}
let profiles: [Profile] = try await client.database.from("profiles").select().execute().value ✅
try await client.database.from("profiles").upsert(values: profile).execute() ✅
try await client.database.from("profiles").update(values: profile).execute() ❌
// error -> "Response status code was unacceptable: 400."
Adding Async/Await would be a good idea now that it's gaining popularity & will have a good amount of backwards compatibility.
When building for the simulator and excluding arm64 architecture I get this error:
Could not find module 'PostgREST' for target 'x86_64-apple-ios-simulator'; found: arm64, arm64-apple-ios-simulator
I need to exclude arm64 to build other static libraries, but am hitting this error and can't build for the simulator.
PostgREST version: Master branch
iOS: 15.0
Xcode: Version 13.0 (13A233)
I'm read supabase doc for dart and code swiftui like this, but I get error, pls send me a example for update action
let val: Dictionary<String, Any> = ["username":"some username"]
let response = try supabaseClient.database.from("users").update(values: val).match(query: ["id": self.auth!.id.description]).execute()
typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
foreignTable
is now renamed to referencedTable
in the JS SDK. It would be nice to align symbol name in Swift SDK before the upcoming version update as well.
Here is the JS SDK implementation: supabase/postgrest-js#493 (comment)
The JS implementation is deprecating the existing foreignTable
parameter and adding referencedTable
so that there are no breaking changes, but since we are doing a major version upgrade, it should be fine to just rename foreignTable
to referencedTable
without deprecation.
Hello, i use this library to perform operations to my Supabase DB.
The filter function should has the value input as String.
It should be Any to support Boolean, Int etc..
I noticed that I never see the actual error that Postgrest returns, but instead get a generic statusCode: 400
error. I had to set breakpoints and print the response to see what was actually wrong.
After some digging through the code, I noticed that the problem is that the validateResponse
delegate method from APIClientDelegate
is never called on PostgrestAPIClientDelegate
. This is because the supabase-swift
package adds its own delegate, resulting in a MultiAPIClientDelegate
being set.
So far so good, but since supbase-swift
does not implement validateResponse
the default implementation from the Get
package gets called, which throws this generic error and the custom implementation from PostgrestAPIClientDelegate
never gets called.
The easy way to fix this, is to give PostgrestAPIClientDelegate
precedence to whatever delegate is passed to PostgrestClient.init
, but I could imagine this having other unforeseen consequences.
The change would simply be to change the line 32 in PostgrestClient.swift
from this:
$0.delegate = MultiAPIClientDelegate([customDelegate, PostgrestAPIClientDelegate()])
to this:
$0.delegate = MultiAPIClientDelegate([PostgrestAPIClientDelegate(), customDelegate])
Alternatively, the SupabaseClient
could implement the validateResponse
method and just not do any validation.
What do you think? I'm happy to submit a PR, but don't feel either approach is perfect.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.