Building weird commands

I’m very new to both ROM and Sequel but it seem like what I’m trying to do is very non-standard so I might as well ask.

What I’m trying to do

I’m using sqlite. It has this non-standard syntax for updates:

update doodads
set status = 'in_progress'
from (
  select * from doodads
  where status = 'pending' and category = ?
  order by random()
  limit 1
)
returning *

It finds a random unprocessed doodad, marks is as being processed and returns it. All in one query.

Bits and pieces

It is my understanding so in order to do that I need a custom ROM command. Let’s call it Reserve.

I guess, I can make it inherit from Update. Maybe?

And in it I need to implement execute. I somehow need to get the category in. Is it an argument to the method?

In execute I need to build the query. I found that relation.dataset is a Sequel dataset. However, it doesn’t look like there’s native support for update ... from (...).

My current best is the following, it s not quite right:

relation.dataset
  .from(
    relation.dataset
    .where(category: category, status: 'pending')
    .order{ Sequel.function(:random) }
    .limit(1)
  )
  .returning
  .update(status: 'in_progress')

This seem to produce the following SQL (paraphrased):

UPDATE (
  SELECT *
  FROM `doodads`
  WHERE ((`category` = 'category') AND (`status` = 'pending'))
  ORDER BY random()
  LIMIT 1
) AS 't1'
SET `status` = 'in_progress'
RETURNING *

As you can see, it has the right parts but overall query is not even syntactically correct.

So… Please help me bend it into shape suing Sequel APIs. Alternatively, how can I give it some raw SQL?

Do I even need a command here or should I use something else instead?