Skip to content

120 support insertorignoreusing #183

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

Merged
merged 3 commits into from
Dec 28, 2024
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
25 changes: 8 additions & 17 deletions docs/compatibility-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Union orders / Union aggregates / Union groupBy
Expression / raw

### Joins
crossJoin / join / joinSub? / leftJoin / leftJoinSub?
crossJoin / join / joinSub / lateralJoin / leftJoin / leftJoinSub

#### Unsupported join clauses
rightJoin / rightJoinSub / joinWhere?
Expand Down Expand Up @@ -103,7 +103,7 @@ limit / offset / take / skip
when

### Insert statements
insert / insertOrIgnore / insertUsing / insertGetId
insert / insertOrIgnore / insertUsing / insertOrIgnoreUsing / insertGetId

### Update statements
update / updateOrInsert / upsert /
Expand Down Expand Up @@ -183,14 +183,14 @@ updateExistingPivot /

## <a name="artisan"></a> Artisan commands
The following database-related artisan commands are supported:
make:model / db / db:wipe /
make:migration / migrate:install / migrate /
db / db:monitor / db:show / db:table / db:wipe /
make:migration / make:model / migrate:install / migrate /
migrate:fresh / migrate:refresh / migrate:reset / migrate:rollback /
migrate:status / convert:migrations

The following database-related artisan commands are NOT support at this time:

db:monitor / db:show / db:table / schema:dump
schema:dump

## <a name="testing"></a> Testing

Expand All @@ -207,16 +207,6 @@ castAsJson (dummy method)
## <a name="database-connection"></a> Database connection
escape

## Console commands
The following database related console commands are compatible with vanilla Laravel:

db:monitor / db:seed / db:wipe
make:migrate / migrate /
migrate:fresh / migrate:install / migrate:refresh / migrate:reset / migrate:rollback / migrate:status

### Incompatible console commands
db:show / db:table

## <a name="known-incompatibilities"></a> Known incompatibilities
Not all features can be made compatible. Known issues are listed below:

Expand All @@ -241,8 +231,9 @@ These methods don't work as ArangoDB requires you to declare the locking mechani
### Raw SQL
Any raw SQL needs to be replaced by raw AQL.

### Separate read and write connections
Aranguent currently doesn't support the combination of a separate read and write connection
### Database replication: separate read and write connections
ArangoDB offers a cluster setup for high availability instead of replication and as such
doesn't support the combination of a separate read and write connection.

### Transactions
[At the beginning of a transaction you must declare collections that are used in (write) statements.](transactions.md)
Expand Down
35 changes: 35 additions & 0 deletions src/Query/Concerns/CompilesDataManipulations.php
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,41 @@ public function compileInsertUsing(IlluminateQueryBuilder $query, array $columns
return $aql;
}

/**
* Compile an insert statement using a subquery into SQL.
*
* @param IlluminateQueryBuilder $query
* @param array<mixed> $columns
* @param string $sql
* @return string
*/
public function compileInsertOrIgnoreUsing(IlluminateQueryBuilder $query, array $columns, string $sql)
{
$table = $this->wrapTable($query->from);

$insertDoc = '';
if (empty($columns) || $columns === ['*']) {
$insertDoc = 'docDoc';
}


if ($insertDoc === '') {
$insertValues = [];
foreach ($columns as $column) {
$insertValues[$column] = $this->normalizeColumnReferences($query, $column, 'docs');
}
$insertDoc = $this->generateAqlObject($insertValues);
}

$aql = /** @lang AQL */ 'LET docs = ' . $sql
. ' FOR docDoc IN docs'
. ' INSERT ' . $insertDoc . ' INTO ' . $table
. ' OPTIONS { ignoreErrors: true }'
. ' RETURN NEW._key';

return $aql;
}

/**
* @param array<mixed> $values
* @return string
Expand Down
27 changes: 27 additions & 0 deletions tests/Query/InsertTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,30 @@

expect($user->surname)->toBe('Baelish');
});

test('insertOrIgnoreUsing', function () {
// Let's give Baelish a user, what could possibly go wrong? Everyone trusts him...
$baelishes = DB::table('characters')
->where('surname', 'Baelish');

DB::table('users')->insertOrIgnoreUsing(['name', 'surname'], $baelishes);

$user = DB::table('users')->where("surname", "=", "Baelish")->first();

expect($user->surname)->toBe('Baelish');
});

test("insertOrIgnoreUsing doesn't error on duplicates", function () {
// Let's give Baelish a user, what could possibly go wrong? Everyone trusts him...
$baelish = DB::table('characters')
->where('surname', 'Baelish');

DB::table('users')->insertUsing(['name', 'surname'], $baelish);

// Let's do it again.
DB::table('users')->insertOrIgnoreUsing(['name', 'surname'], $baelish);

$user = DB::table('users')->where("surname", "=", "Baelish")->first();

expect($user->surname)->toBe('Baelish');
});
Loading