CodeIgniter4 icon indicating copy to clipboard operation
CodeIgniter4 copied to clipboard

[QueryBuilder] The combination of the `setUpdateBatch()` and the `updateBatch()` is difficult to use.

Open ytetsuro opened this issue 4 years ago • 7 comments

The combination of the setUpdateBatch method and the updateBatch method is difficult to use.

If you try to use it, it will look like the following.

$builder->setUpdateBatch([
    [
        'id'          => 2,
        'name'        => 'SUBSTRING(name, 1)',
        'description' => 'SUBSTRING(description, 3)',
    ],
    [
        'id'          => 3,
        'name'        => 'SUBSTRING(name, 2)',
        'description' => 'SUBSTRING(description, 4)',
    ],
], 'id', false);

$builder->updateBatch(null, 'id', 100);
  1. updateBatch method hasn't escape argument.
  2. We have specified index as the second argument of the setUpdateBatch method, but we need to specify the same value for the second argument of updateBatch.
  3. In combination with 2, when using setUpdateBatch, you need to specify null as the first argument of the updateBatch method. It is difficult for a client to write such a code without knowing the implementation.

In my opinion, it would be easier for developers to use if they can write the following.

$builder->updateBatch([
    [
        'id'          => 2,
        'name'        => 'SUBSTRING(name, 1)',
        'description' => 'SUBSTRING(description, 3)',
    ],
    [
        'id'          => 3,
        'name'        => 'SUBSTRING(name, 2)',
        'description' => 'SUBSTRING(description, 4)',
    ],
], 'id', false, 100);

or

 $builder->setUpdateBatch([
    [
        'id'          => 2,
        'name'        => 'SUBSTRING(name, 1)',
        'description' => 'SUBSTRING(description, 3)',
    ],
    [
        'id'          => 3,
        'name'        => 'SUBSTRING(name, 2)',
        'description' => 'SUBSTRING(description, 4)',
    ],
], 'id', false);

$builder->updateBatch(100);

What do you think?

ytetsuro avatar Sep 26 '21 03:09 ytetsuro

In both cases, it is a breaking change in the public API of updateBatch().

kenjis avatar Sep 28 '21 04:09 kenjis

Thanks, response. You are right.

ytetsuro avatar Sep 28 '21 16:09 ytetsuro

@kenjis

I was wondering if the following code could be implemented without adding breaking change if the user has called setUpdateBatch at least once.

The concrete method is to change the behavior of updateBatch when the following conditions are met.

  • Only the first argument of updateBatch is specified.
  • A number is passed as the first argument of updateBatch.
  • QBSet is not empty.
 $builder->setUpdateBatch([
    [
        'id'          => 2,
        'name'        => 'SUBSTRING(name, 1)',
        'description' => 'SUBSTRING(description, 3)',
    ],
    [
        'id'          => 3,
        'name'        => 'SUBSTRING(name, 2)',
        'description' => 'SUBSTRING(description, 4)',
    ],
], 'id', false);

$builder->updateBatch(100);

ytetsuro avatar Oct 11 '21 13:10 ytetsuro

@ytetsuro I think the API you propose is better. It is easy to use.

But unfortunately, the first param of updateBatch() is ?array. https://github.com/codeigniter4/CodeIgniter4/blob/4576b12ed6b715937a991a91ce32174a19cadb93/system/Database/BaseBuilder.php#L1935

If you change it to accept int, it is breaking change. https://3v4l.org/oIIBP

kenjis avatar Oct 11 '21 23:10 kenjis

You could write code like this on PHP8:

$builder->updateBatch(batchSize: 100);

https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments

kenjis avatar Oct 11 '21 23:10 kenjis

Or how about this?

$builder->setUpdateBatch([
    [
        'id'          => 2,
        'name'        => 'SUBSTRING(name, 1)',
        'description' => 'SUBSTRING(description, 3)',
    ],
    [
        'id'          => 3,
        'name'        => 'SUBSTRING(name, 2)',
        'description' => 'SUBSTRING(description, 4)',
    ],
], 'id', false);

$builder->setBatchSize(100);
$builder->updateBatch();

kenjis avatar Oct 12 '21 10:10 kenjis

@kenjis

Thanks, response.

If you change it to accept int, it is breaking change.

Sure! I'm sorry.😞

You could write code like this on PHP8:

Oh! You are great! This is very readable.

Or how about this?

Thanks. I think very very well.😍 I will make this PR.

ytetsuro avatar Oct 21 '21 19:10 ytetsuro