Skip to content
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

Added InsertBulkQuery #24

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ $result = $repository->getByQuery($query);
## Advanced Topics

* [Active Record](docs/active-record.md)
* [Auto Discovering Relationship](docs/auto-discovering-relationship.md)
* [The Literal Object](docs/the-literal-object.md)
* [Soft Delete](docs/softdelete.md)
* [Caching the Results](docs/cache.md)
Expand Down
69 changes: 66 additions & 3 deletions docs/updating-the-database.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
Once you have defined the model, (see [Getting Started](getting-started-model.md)) you can start to interact with the database
and doing queries, updates, and deletes.

## Update

Update a single record is simple as:

```php
Expand All @@ -14,7 +16,9 @@ $repository->save($users);

This code will update the record with the ID 10 and set the name to "New name".

The idea is to insert a new record. If you don't set the ID, the library will assume that you are inserting a new record.
## Insert

If you don't set the ID, the library will assume that you are inserting a new record.

```php
<?php
Expand All @@ -23,7 +27,7 @@ $users->name = "New name";
$repository->save($users);
```

## Advanced Cases
## Using the UpdateQuery (Special Cases)

In some cases you need to update multiples records at once. See an example:

Expand All @@ -37,4 +41,63 @@ $updateQuery->set('fld3', 'C');
$updateQuery->where('fld1 > :id', ['id' => 10]);
```

This code will update the table `test` and set the fields `fld1`, `fld2`, and `fld3` to `A`, `B`, and `C` respectively where the `fld1` is greater than 10.
This code will update the table `test` and set the fields `fld1`, `fld2`, and `fld3` to `A`, `B`, and `C`
respectively where the `fld1` is greater than 10.

## Insert records with InsertQuery

You can insert records using the `InsertQuery` object. See an example:

```php
<?php
$insertQuery = new \ByJG\MicroOrm\InsertQuery();
$insertQuery->table('test');
$insertQuery->set('fld1', 'A');
$insertQuery->set('fld2', 'B');
$insertQuery->set('fld3', 'C');
```

## Insert records from another select

You can insert records from another select using the `InsertSelectQuery` object. See an example:

```php
<?php

// Define the query to select the records
$query = new QueryBasic();
$query->table('table2');
$query->field('fldA');
$query->field('fldB');
$query->field('fldC');
$query->where('fldA = :valueA', ['valueA' => 1]);

// Define the insert select query
$insertSelectQuery = new \ByJG\MicroOrm\InsertSelectQuery();
$insertSelectQuery->table('test');
$insertSelectQuery->fields(['fld1', 'fld2', 'fld3']);
$insertSelectQuery->fromQuery($query); // The query to select the records
```

## Insert records in batch

You can insert records in batch using the `InsertBulkQuery` object. See an example:

```php
<?php
$insertBulk = new InsertBulkQuery('test', ['fld1', 'fld2']);
$insertBulk->values(['fld1' => 'A', 'fld2' => 'B']);
$insertBulk->values(['fld1' => 'D', 'fld2' => 'E']);
$insertBulk->values(['fld1' => 'G', 'fld2' => 'H']);
```

## Delete records

You can delete records using the `DeleteQuery` object. See an example:

```php
<?php
$deleteQuery = new \ByJG\MicroOrm\DeleteQuery();
$deleteQuery->table('test');
$deleteQuery->where('fld1 = :value', ['value' => 'A']);
```
109 changes: 109 additions & 0 deletions src/InsertBulkQuery.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php

namespace ByJG\MicroOrm;

use ByJG\AnyDataset\Db\DbFunctionsInterface;
use ByJG\MicroOrm\Exception\OrmInvalidFieldsException;
use ByJG\MicroOrm\Interface\QueryBuilderInterface;
use InvalidArgumentException;

class InsertBulkQuery extends Updatable
{
protected array $fields = [];

protected ?QueryBuilderInterface $query = null;

protected ?SqlObject $sqlObject = null;

public function __construct(string $table, array $fieldNames)
{
$this->table($table);

foreach ($fieldNames as $fieldname) {
$this->fields[$fieldname] = [];
}
}


public static function getInstance(string $table, array $fieldNames): static
{
return new InsertBulkQuery($table, $fieldNames);
}

/**
* @throws OrmInvalidFieldsException
*/
public function values(array $values, bool $allowNonMatchFields = true): static
{
if (array_diff(array_keys($this->fields), array_keys($values))) {
throw new OrmInvalidFieldsException('The provided values do not match the expected fields');
}

if (!$allowNonMatchFields && array_diff(array_keys($values), array_keys($this->fields))) {
throw new OrmInvalidFieldsException('The provided values contain more fields than expected');
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Incomplete error context for extra fields category Error Handling

Tell me more
What is the issue?

The error message does not specify which extra fields were provided.

Why this matters

Without knowing which fields are extra, developers will have difficulty identifying the source of the validation failure.

💡 Does this comment miss the mark? Tell us why and Korbit will adapt to your team’s feedback.
💬 Chat with Korbit by mentioning @korbit-ai.

}

foreach (array_keys($this->fields) as $field) {
$this->fields[$field][] = $values[$field];
}

return $this;
}

/**
* @param DbFunctionsInterface|null $dbHelper
* @return SqlObject
* @throws OrmInvalidFieldsException
*/
public function build(DbFunctionsInterface $dbHelper = null): SqlObject
{
if (empty($this->fields)) {
throw new OrmInvalidFieldsException('You must specify the fields for insert');
}

$tableStr = $this->table;
if (!is_null($dbHelper)) {
$tableStr = $dbHelper->delimiterTable($tableStr);
}

// Extract column names
$columns = array_keys($this->fields);

// Get the number of rows
$rowCount = count(current($this->fields));

// Initialize placeholders and parameters
$placeholders = [];
$params = [];

// Build placeholders and populate $params
for ($i = 0; $i < $rowCount; $i++) {
$rowPlaceholders = [];
foreach ($columns as $j => $col) {
$paramKey = "p{$i}_$j"; // Generate the parameter key
$rowPlaceholders[] = ":$paramKey"; // Add to row placeholders
$params[$paramKey] = $this->fields[$col][$i]; // Map parameter key to value
}
$placeholders[] = '(' . implode(', ', $rowPlaceholders) . ')'; // Add row placeholders to query
}

if (!is_null($dbHelper)) {
$columns = $dbHelper->delimiterField($columns);
}

// Construct the final SQL query
$sql = sprintf(
"INSERT INTO %s (%s) VALUES %s",
$tableStr,
implode(', ', $columns),
implode(', ', $placeholders)
);

return new SqlObject(ORMHelper::processLiteral($sql), $params);
}

public function convert(?DbFunctionsInterface $dbDriver = null): QueryBuilderInterface
{
throw new InvalidArgumentException('It is not possible to convert an InsertBulkQuery to a Query');
}
}
101 changes: 0 additions & 101 deletions src/InsertMultipleQuery.php

This file was deleted.

Loading
Loading