Как добавить столбец минут к мгновенному значению в jOOQ

Дана такая таблица:

CREATE TABLE demo (
    id BIGINT PRIMARY KEY,
    offset_minutes INTEGER NOT NULL,
    scheduled_time TIMESTAMP WITH TIME ZONE
);

Я хочу обновить scheduled_time до указанного в приложении времени плюс offset_minutes. В простом SQL на PostgreSQL это будет выглядеть примерно так

UPDATE demo
SET scheduled_time =
    timestamp with time zone '2022-09-12T01:23:45Z' +
        offset_minutes * interval '1 minute'
WHERE id = 12345;

Как лучше всего выразить это в jOOQ независимым от СУБД способом?

Это противоположность обычному способу, которым люди хотят добавить минуты к значению времени, что хорошо освещено другими вопросами SO: в моем случае Instant предоставляется кодом, а количество минут находится в столбце базы данных, А не наоборот.

Лучшее, что мне удалось придумать, это вычислить количество минут с плавающей запятой, поскольку мы можем добавлять дни к Instants:

dslContext.update(DEMO)
    .set(DEMO.SCHEDULED_TIME,
        DSL.instant(instant).add(DEMO.OFFSET_MINUTES.div(24.0 * 60.0)))
    .where(DEMO.ID.eq(id))
    .execute();

В PostgreSQL jOOQ генерирует выражение SQL для значения предложения SET:

(timestamp with time zone '2022-09-12 01:23:45+00:00' +
    ("public"."demo"."offset_minutes" / 1.44E3) * interval '1 day')

Тот факт, что jOOQ генерирует interval '1 day', вселяет в меня надежду, что есть способ заставить его изменить day на minute и избежать вычислений с плавающей запятой. Я никогда не схожу с ума от выполнения вычислений с плавающей запятой для дискретных величин, если этого можно избежать.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
20
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ожидающие запросы функций

Решение вашей непосредственной проблемы

Ожидается запрос функции №6723 на добавление поддержки DSL::offsetDateTimeAdd, что позволит добавлять интервалы к TIMESTAMP WITH TIME ZONE типам данных.

Это по-прежнему не будет работать для Instant типов данных, где нам потребуется еще одна «перегрузка» для всех возможных вариантов арифметики даты и времени.

Оба они будут создавать множество новых методов в уже переполненном классе DSL, не добавляя много новой функциональности, учитывая, что они делают что-то похожее на существующие функции timestampAdd() или localDateTimeAdd(), просто предлагая то же самое для новых типов.

Более стратегическое, основательное изменение

В долгосрочной дорожной карте предлагается большое изменение №11088, которое позволит более четко разделить два обычных типа T и U, связанные с Field:

  • T является «типом JDBC», то есть типом, который понимает база данных (например, OffsetDateTime)
  • U является «типом пользователя», то есть типом, который вы хотите видеть в своем коде (например, Instant)

Таким образом, будет единственный метод, принимающий T = OffsetDateTime и любой произвольный тип U (например, Instant).

Обходной путь для вас прямо сейчас

Хотя выполнение вышеуказанных задач требует времени, вы всегда можете воспользоваться обычным аварийным люком и использовать простые шаблоны SQL. Например.

DSL.field("({0} + {1} * interval '1 minute')", 
    SQLDataType.INSTANT,
    DSL.instant(instant), 
    DEMO.OFFSET_MINUTES
);

Вы можете извлечь жестко закодированные аргументы (DSL.instant(instant) и DEMO.OFFSET_MINUTES) и создать повторно используемую функцию для вышеперечисленного и, таким образом, создать мини-библиотеку для недостающей функциональности в jOOQ.

Другие вопросы по теме