Home > Net >  Query parameter binding issue with illuminate/database and illuminate/queue
Query parameter binding issue with illuminate/database and illuminate/queue

Time:01-26

I'm using Illuminate\Queue outside of a Laravel app inside an add-on for a CMS. So the only instances of Laravel or Illuminate are these packages that I've required:

"illuminate/queue": "^8.83",
"illuminate/bus": "^8.83",
"illuminate/contracts": "^8.83"

I'm first trying to use the Database for the queue as the default driver since the CMS is database driven, then provide options to SQS etc. I've setup everything so the migrations create my queue tables and everything seems to be wired together when I make the following call to push something to the queue.

/** @var \Illuminate\Queue\QueueManager $queue */
$queue->push('test', ['foo' => 'bar']);

Then it ends in the following error. The parameter bindings are not working or something. It's leaving the ? in the values list.

SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"exp_dgq_jobs" ("queue", "attempts", "reserved_at", "available_at", "created_at"' at line 1 (SQL: insert into "exp_dgq_jobs" ("queue", "attempts", "reserved_at", "available_at", "created_at", "payload") values (default, 0, ?, 1674567590, 1674567590, {"uuid":"6bf7a17e-dda3-4fed-903a-8714e5a2d146","displayName":"test","job":"test","maxTries":null,"maxExceptions":null,"failOnTimeout":false,"backoff":null,"timeout":null,"data":{"foo":"bar"}}))

I've step debugged the whole request and it feels like a bug, but then again this is really the first time I've used Laravel or one of it's packages, so maybe I'm missing something? This function explicitly sets reserved_at to null, and the Connection->prepareBindings() method doesn't do anything with the ?, it just leaves it as that value, so the query fails.

protected function buildDatabaseRecord($queue, $payload, $availableAt, $attempts = 0)
    {
        return ['queue' => $queue, 'attempts' => $attempts, 'reserved_at' => null, 'available_at' => $availableAt, 'created_at' => $this->currentTime(), 'payload' => $payload];
    }

What am I missing? Everything just looks right to me an I'm kind of at a loss. I'm making this with PHP 7.4 in mind (for the time being). Maybe I'll try 8.1 to see if that changes anything with the Illuminate packages. Using MySQL 8 too.

Update: potentially relevant screenshot just before the error.

Update 2: I tried PHP 8.1 and latest Laravel 9 packages, didn't make a difference.

debugging

For more clarity on how I"m creating my QueueManager:

<?php $queue = new Queue;
        $queue->addConnection([
            'driver' => 'database',
            'table' => ee('db')->dbprefix . 'dgq_jobs',
            'queue' => 'default',
            'retry_after' => 90,
            'after_commit' => false,
        ]);

        $databaseConfig = $provider->make('DatabaseConfig');

        $queue->addConnector('database', function () use ($databaseConfig) {
            $pdo = new PDO(
                sprintf('mysql:host=%s; dbname=%s', $databaseConfig['host'], $databaseConfig['database']),
                $databaseConfig['username'],
                $databaseConfig['password']
            );
            $connection = new Connection($pdo);
            $connectionResolver = new ConnectionResolver(['default' => $connection]);
            $connectionResolver->setDefaultConnection('default');

            return new DatabaseConnector($connectionResolver);
        });

        return $queue->getQueueManager();

CodePudding user response:

I was able to reproduce the error you were seeing. I haven't looked too deeply but I think it may be due to the PDO object not setting up the connection exactly as the Illuminate Queue library expects.

This modification to using the Illuminate\Database library to create the connection solved the issue in my test environment:

$database = new \Illuminate\Database\Capsule\Manager;
$queue = new \Illuminate\Queue\Capsule\Manager;

$database->addConnection([
    'driver' => 'mysql',
    'host' => 'localhost',
    'database' => 'db_name',
    'username' => 'username',
    'password' => '',
    'charset' => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix' => '',
]);

$queue->addConnector('database', function () use ($database) {
    $connection = $database->getConnection();
    $connectionResolver = new \Illuminate\Database\ConnectionResolver(['default' => $connection]);
    $connectionResolver->setDefaultConnection('default');

    return new \Illuminate\Queue\Connectors\DatabaseConnector($connectionResolver);
});

$queue->addConnection([
    'driver' => 'database',
    'table' => 'jobs_table',
    'queue' => 'default',
    'retry_after' => 90,
    'after_commit' => false,
]);

$queue->getQueueManager()->push('SendEmail', ['message' => 'test']);
  • Related