Skip to content

feat: Added support for upserting data#231

Open
puzzledpolymath wants to merge 20 commits into2.xfrom
feature/upsert
Open

feat: Added support for upserting data#231
puzzledpolymath wants to merge 20 commits into2.xfrom
feature/upsert

Conversation

@puzzledpolymath
Copy link
Copy Markdown
Contributor

@puzzledpolymath puzzledpolymath commented Jul 11, 2025

This pull request adds support for performing upsert queries. Ticket #50 is what sparked interest for this feature.

🔍 What was changed

  • Each driver (MySQL, Postgres, SQLite and SQLServer) compiler supports an UpsertQuery.
  • Differences between SQL dialects have been accounted for.

🤔 Why?

  1. Upsert allows developers to combine insert and update operations into a single command, reducing the need for explicit existence checks and multiple database calls.
  2. Modern databases support atomic upsert operations, which help maintain data integrity even in concurrent environments.
  3. Upsert reduces the number of database round-trips, eliminating separate existence checks followed by insert or update, likely leading to better performance, especially in high-volume scenarios.

📝 Checklist

📃 Documentation

Note that specifying conflict index column names is redundant and not required for MySQL.

PHP

$upsert = $this->database->upsert('users')
    ->conflicts('email')
    ->columns('email', 'name')
    ->values('adam@email.com', 'Adam')
    ->values('bill@email.com', 'Bill');
$upsert = $this->database->upsert('users')
    ->conflicts(['email'])
    ->values([
        ['email' => 'adam@email.com', 'name' => 'Adam'],
        ['email' => 'bill@email.com', 'name' => 'Bill'],
    ]);

MySQL

INSERT INTO `users` (`email`, `name`)
VALUES
    ('adam@email.com', 'Adam'),
    ('bill@email.com', 'Bill')
ON DUPLICATE KEY UPDATE
    `email` = VALUES(`email`),
    `name` = VALUES(`name`);

Postgres / SQLite

INSERT INTO `users` (`email`, `name`)
VALUES
    ('adam@email.com', 'Adam'),
    ('bill@email.com', 'Bill')
ON CONFLICT (`email`) DO UPDATE SET
    `email` = EXCLUDED.`email`,
    `name` = EXCLUDED.`name`

MSSQL

MERGE INTO [users] WITH (holdlock) AS [target] 
USING ( VALUES 
    ('adam@email.com', 'Adam'),
    ('bill@email.com', 'Bill') 
) AS [source] ([email], [name]) 
ON [target].[email] = [source].[email] 
WHEN MATCHED THEN 
    UPDATE SET 
        [target].[email] = [source].[email], 
        [target].[name] = [source].[name] 
WHEN NOT MATCHED THEN 
    INSERT ([email], [name]) 
    VALUES ([source].[email], [source].[name])

@cycle cycle deleted a comment from codecov bot Jul 11, 2025
@puzzledpolymath puzzledpolymath requested a review from a team as a code owner July 11, 2025 07:19
@cycle cycle deleted a comment from codecov bot Jul 11, 2025
@cycle cycle deleted a comment from codecov bot Jul 11, 2025
@cycle cycle deleted a comment from codecov bot Jul 11, 2025
@codecov
Copy link
Copy Markdown

codecov bot commented Jul 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 95.60%. Comparing base (279e3bb) to head (db915d7).

Additional details and impacted files
@@             Coverage Diff              @@
##                2.x     #231      +/-   ##
============================================
+ Coverage     95.40%   95.60%   +0.19%     
- Complexity     1913     1974      +61     
============================================
  Files           131      134       +3     
  Lines          5314     5552     +238     
============================================
+ Hits           5070     5308     +238     
  Misses          244      244              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@puzzledpolymath puzzledpolymath mentioned this pull request Jul 11, 2025
1 task
@puzzledpolymath puzzledpolymath changed the title Upsert feature feat: Added support for upserting data Apr 12, 2026
@puzzledpolymath
Copy link
Copy Markdown
Contributor Author

@cycle/core-contributors I've just recently merged 2.x updates, ensuring everything in this PR is up-to-date. I'd really like to see this make it's way into the codebase, as upsert functionality is something I've become accustomed to across other ORM's and languages, and something I feel others would appreciate. Let me know if there's anything further needed from me, to get this over the line.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants