database
database copied to clipboard
Upsert feature
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?
- Upsert allows developers to combine insert and update operations into a single command, reducing the need for explicit existence checks and multiple database calls.
- Modern databases support atomic upsert operations, which help maintain data integrity even in concurrent environments.
- 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
- Closes #50
- How was this tested:
- [x] Unit tests added
📃 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('[email protected]', 'Adam')
->values('[email protected]', 'Bill');
$upsert = $this->database->upsert('users')
->conflicts(['email'])
->values([
['email' => '[email protected]', 'name' => 'Adam'],
['email' => '[email protected]', 'name' => 'Bill'],
]);
MySQL
INSERT INTO `users` (`email`, `name`)
VALUES
('[email protected]', 'Adam'),
('[email protected]', 'Bill')
ON DUPLICATE KEY UPDATE
`email` = VALUES(`email`),
`name` = VALUES(`name`);
Postgres / SQLite
INSERT INTO `users` (`email`, `name`)
VALUES
('[email protected]', 'Adam'),
('[email protected]', 'Bill')
ON CONFLICT (`email`) DO UPDATE SET
`email` = EXCLUDED.`email`,
`name` = EXCLUDED.`name`
MSSQL
MERGE INTO [users] WITH (holdlock) AS [target]
USING ( VALUES
('[email protected]', 'Adam'),
('[email protected]', '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])
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests.
:white_check_mark: Project coverage is 95.61%. Comparing base (3d7ee35) to head (c53a6f0).
Additional details and impacted files
@@ Coverage Diff @@
## 2.x #231 +/- ##
============================================
+ Coverage 95.42% 95.61% +0.19%
- Complexity 1896 1957 +61
============================================
Files 131 134 +3
Lines 5285 5523 +238
============================================
+ Hits 5043 5281 +238
Misses 242 242
:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.
:rocket: New features to boost your workflow:
- :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.