Skip to content

fix: onConflict parameter ignored in upsert #20

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

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
22 changes: 18 additions & 4 deletions lib/src/mock_supabase_http_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -434,13 +434,27 @@ class MockSupabaseHttpClient extends BaseClient {
? List<Map<String, dynamic>>.from(data)
: [Map<String, dynamic>.from(data)];

// Get the onConflict columns
final onConflictColumns =
(request.url.queryParameters['on_conflict'] ?? 'id')
.split(',')
.map((e) => e.trim())
.toList();

// Upsert each item
final results = items.map((item) {
final id = item['id'];
if (id != null) {
final index =
_database[tableKey]!.indexWhere((dbItem) => dbItem['id'] == id);
// Check if all onConflictColumns are set in item
final shouldUpdate =
onConflictColumns.every((column) => item[column] != null);

if (shouldUpdate) {
// Find the index for an item that matches all onConflictColumns
final index = _database[tableKey]!.indexWhere((dbItem) =>
onConflictColumns
.every((column) => dbItem[column] == item[column]));

if (index != -1) {
// Update the item in the database
_database[tableKey]![index] = {
..._database[tableKey]![index],
...item
Expand Down
43 changes: 43 additions & 0 deletions test/mock_supabase_http_client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,49 @@ void main() {
expect(postsUfterUpdate.first, {'id': 1, 'title': 'Updated post'});
});

test('Upsert with single onConflict column, not id', () async {
final data = {'user_id': 1, 'name': 'John Doe'};
const table = 'users';
// Insert a record
await mockSupabase.from(table).insert(data);
final users = await mockSupabase.from(table).select();
expect(users.first, data);

final updatedData = {
...data,
'name': 'James Bond',
};
await mockSupabase.from(table).upsert(
updatedData,
onConflict: 'user_id',
);
final usersAfterUpdate =
await mockSupabase.from(table).select().eq('user_id', 1);
expect(usersAfterUpdate.length, 1);
expect(usersAfterUpdate.first, updatedData);
});

test('Upsert with multiple onConflict columns', () async {
final data = {'user': 2, 'post': 1, 'title': 'Initial post'};
// Test upserting a record
await mockSupabase.from('posts').insert(data);
final posts = await mockSupabase.from('posts').select();
expect(posts.first, data);

final updatedData = {
...data,
'title': 'Updated post',
};
await mockSupabase.from('posts').upsert(
updatedData,
onConflict: 'user, post',
);
final postsAfterUpdate =
await mockSupabase.from('posts').select().eq('user', 2).eq('post', 1);
expect(postsAfterUpdate.length, 1);
expect(postsAfterUpdate.first, updatedData);
});

test('Upsert then select', () async {
// Test upserting a record
await mockSupabase
Expand Down