From b33059c6153693cc21724bb89695de86caaadc24 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sat, 18 Jan 2025 18:05:10 +0900 Subject: [PATCH 01/74] Create DataTime functions for Interval enum --- .../ldbc/statement/functions/DateTime.scala | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala new file mode 100644 index 000000000..54f83c7e6 --- /dev/null +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -0,0 +1,43 @@ +package ldbc.statement.functions + +import java.time.* + +/** + * Provide functions that can be used to manipulate temporal values provided by MySQL. + * + * @see https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html + */ +trait DateTime +object DateTime: + + /** + * Extracts the date part of a date or datetime expression. + * + * @see https://dev.mysql.com/doc/refman/8.0/ja/expressions.html#temporal-intervals + * + * {{{ + * INTERVAL expr unit + * }}} + */ + enum Interval[A](expr: A, val unit: String): + def statement: String = s"INTERVAL $expr $unit" + case MICROSECOND(expr: Int) extends Interval(expr, "MICROSECOND") + case SECOND(expr: Int) extends Interval(expr, "SECOND") + case MINUTE(expr: Int) extends Interval(expr, "MINUTE") + case HOUR(expr: Int) extends Interval(expr, "HOUR") + case DAY(expr: Int) extends Interval(expr, "DAY") + case WEEK(expr: Int) extends Interval(expr, "WEEK") + case MONTH(expr: Int) extends Interval(expr, "MONTH") + case QUARTER(expr: Int) extends Interval(expr, "QUARTER") + case YEAR(expr: Int) extends Interval(expr, "YEAR") + case SECOND_MICROSECOND(expr: String) extends Interval(expr, "SECOND_MICROSECOND") + case MINUTE_MICROSECOND(expr: String) extends Interval(expr, "MINUTE_MICROSECOND") + case MINUTE_SECOND(expr: String) extends Interval(expr, "MINUTE_SECOND") + case HOUR_MICROSECOND(expr: String) extends Interval(expr, "HOUR_MICROSECOND") + case HOUR_SECOND(expr: String) extends Interval(expr, "HOUR_SECOND") + case HOUR_MINUTE(expr: String) extends Interval(expr, "HOUR_MINUTE") + case DAY_MICROSECOND(expr: String) extends Interval(expr, "DAY_MICROSECOND") + case DAY_SECOND(expr: String) extends Interval(expr, "DAY_SECOND") + case DAY_MINUTE(expr: String) extends Interval(expr, "DAY_MINUTE") + case DAY_HOUR(expr: String) extends Interval(expr, "DAY_HOUR") + case YEAR_MONTH(expr: YearMonth) extends Interval(expr, "YEAR_MONTH") From 4bc528feb3f4d2816840378105f75a00ba1a6ca2 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sat, 18 Jan 2025 23:40:43 +0900 Subject: [PATCH 02/74] Added ADDDATE functions --- .../ldbc/statement/functions/DateTime.scala | 34 ++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 54f83c7e6..c852fee19 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1,13 +1,45 @@ +/** + * Copyright (c) 2023-2024 by Takahiko Tominaga + * This software is licensed under the MIT License (MIT). + * For more information see LICENSE or https://opensource.org/licenses/MIT + */ + package ldbc.statement.functions import java.time.* +import ldbc.dsl.codec.* +import ldbc.statement.Column + /** * Provide functions that can be used to manipulate temporal values provided by MySQL. * * @see https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html */ -trait DateTime +trait DateTime: + + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => ADDDATE(p.birthDate, DateTime.Interval.YEAR(1))) + * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM person + * }}} + */ + def ADDDATE[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = + Column(s"ADDDATE(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) + + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) + * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM person + * }}} + */ + def ADDDATE(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"ADDDATE('${date.toString}', ${interval.statement})") + object DateTime: /** From 91541ee04cea7fe7ea81de4ec84e2f4384260402 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sat, 18 Jan 2025 23:40:53 +0900 Subject: [PATCH 03/74] Create DateTimeTest --- .../statement/functions/DateTimeTest.scala | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala new file mode 100644 index 000000000..cf42ce8c8 --- /dev/null +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -0,0 +1,31 @@ +/** + * Copyright (c) 2023-2024 by Takahiko Tominaga + * This software is licensed under the MIT License (MIT). + * For more information see LICENSE or https://opensource.org/licenses/MIT + */ + +package ldbc.statement.functions + +import java.time.* + +import ldbc.statement.Column +import ldbc.statement.functions.DateTime.* + +import org.scalatest.flatspec.AnyFlatSpec + +class DateTimeTest extends AnyFlatSpec, DateTime: + + private val c1 = Column.Impl[LocalDate]("local_date") + private val c2 = Column.Impl[Option[LocalDate]]("local_date") + + it should "Statement generated using the ADDDATE function matches the specified string." in { + assert(ADDDATE(c1, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") + assert(ADDDATE(c1, Interval.MONTH(1)).name == "ADDDATE(local_date, INTERVAL 1 MONTH)") + assert(ADDDATE(c1, Interval.YEAR(1)).name == "ADDDATE(local_date, INTERVAL 1 YEAR)") + assert(ADDDATE(c2, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") + assert(ADDDATE(c2, Interval.MONTH(1)).name == "ADDDATE(local_date, INTERVAL 1 MONTH)") + assert(ADDDATE(c2, Interval.YEAR(1)).name == "ADDDATE(local_date, INTERVAL 1 YEAR)") + assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.DAY(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 DAY)") + assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.MONTH(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 MONTH)") + assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 YEAR)") + } From ef667b06b45b3bdd1df36823b4a40c0901596e22 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 17:47:53 +0900 Subject: [PATCH 04/74] Added ADDTIME functions --- .../ldbc/statement/functions/DateTime.scala | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c852fee19..08528d612 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -40,6 +40,31 @@ trait DateTime: def ADDDATE(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"ADDDATE('${date.toString}', ${interval.statement})") + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => ADDTIME(p.time, LocalTime.of(1, 1, 1, 1))) + * // SELECT ADDDATE(time, '01:01:01.000000001') FROM person + * }}} + */ + def ADDTIME[A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + column: Column[A], + time: LocalTime + ): Column[A] = + Column(s"ADDTIME(${column.name}, '${time.toString}')")(using column.decoder, column.encoder) + + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => ADDDATE(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) + * // SELECT ADDDATE('01:01:01.000000001', '01:01:01.000000001') FROM person + * }}} + */ + def ADDTIME(dateTime: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, time: LocalTime): Column[LocalTime] = + Column(s"ADDTIME('${dateTime.toString}', '${time.toString}')") + object DateTime: /** From 3c4b5374dd8179ea6a48e18bf4e31782463ca10c Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 17:48:05 +0900 Subject: [PATCH 05/74] Create DateTime ADDTIME Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index cf42ce8c8..4dc7b8af7 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -17,7 +17,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c1 = Column.Impl[LocalDate]("local_date") private val c2 = Column.Impl[Option[LocalDate]]("local_date") - + private val c3 = Column.Impl[LocalTime]("local_time") + private val c4 = Column.Impl[Option[LocalTime]]("local_time") + it should "Statement generated using the ADDDATE function matches the specified string." in { assert(ADDDATE(c1, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") assert(ADDDATE(c1, Interval.MONTH(1)).name == "ADDDATE(local_date, INTERVAL 1 MONTH)") @@ -29,3 +31,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.MONTH(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 MONTH)") assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 YEAR)") } + + it should "Statement generated using the ADDTIME function matches the specified string." in { + assert(ADDTIME(c3, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") + assert(ADDTIME(c4, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") + assert(ADDTIME(LocalTime.of(1, 1, 1), LocalTime.of(1, 1, 1, 1)).name == "ADDTIME('01:01:01', '01:01:01.000000001')") + } From 5c57dfe20e3a74f0c967a4ef489f8d35684b2c95 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:13:02 +0900 Subject: [PATCH 06/74] Added CONVERT_TZ functions --- .../ldbc/statement/functions/DateTime.scala | 52 +++++++++++++++++-- 1 file changed, 49 insertions(+), 3 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 08528d612..6a7b1192f 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -25,6 +25,9 @@ trait DateTime: * TableQuery[Person].select(p => ADDDATE(p.birthDate, DateTime.Interval.YEAR(1))) * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM person * }}} + * + * @param column The column to which the addition is to be performed. + * @param interval The interval to be added to the column. */ def ADDDATE[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = Column(s"ADDDATE(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) @@ -36,6 +39,9 @@ trait DateTime: * TableQuery[Person].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM person * }}} + * + * @param date The date to which the addition is to be performed. + * @param interval The interval to be added to the date. */ def ADDDATE(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"ADDDATE('${date.toString}', ${interval.statement})") @@ -45,8 +51,11 @@ trait DateTime: * * {{{ * TableQuery[Person].select(p => ADDTIME(p.time, LocalTime.of(1, 1, 1, 1))) - * // SELECT ADDDATE(time, '01:01:01.000000001') FROM person + * // SELECT ADDTIME(time, '01:01:01.000000001') FROM person * }}} + * + * @param column The column to which the addition is to be performed. + * @param time The time to be added to the column. */ def ADDTIME[A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]]( column: Column[A], @@ -58,13 +67,50 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[Person].select(p => ADDDATE(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) - * // SELECT ADDDATE('01:01:01.000000001', '01:01:01.000000001') FROM person + * TableQuery[Person].select(p => ADDTIME(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) + * // SELECT ADDTIME('01:01:01.000000001', '01:01:01.000000001') FROM person * }}} + * + * @param dateTime The date time to which the addition is to be performed. + * @param time The time to be added to the date time. */ def ADDTIME(dateTime: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, time: LocalTime): Column[LocalTime] = Column(s"ADDTIME('${dateTime.toString}', '${time.toString}')") + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => CONVERT_TZ(p.timestampe, LocalTime.of(0, 0), LocalTime.of(9, 0))) + * // SELECT CONVERT_TZ(timestampe, '+00:00', '+09:00') FROM person + * }}} + * + * @param column The column to which the addition is to be performed. + * @param from The time zone from which the conversion is to be performed. + * @param to The time zone to which the conversion is to be performed. + */ + def CONVERT_TZ[A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime]]( + column: Column[A], + from: LocalTime, + to: LocalTime + ): Column[A] = + Column(s"CONVERT_TZ(${column.name}, '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')")(using column.decoder, column.encoder) + + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(p => CONVERT_TZ(LocalDateTime.of(2025, 1, 1), LocalTime.of(0, 0), LocalTime.of(9, 0))) + * // SELECT CONVERT_TZ('2025-01-01', '+00:00', '+09:00') FROM person + * }}} + * + * @param dateTime The date time to which the addition is to be performed. + * @param from The time zone from which the conversion is to be performed. + * @param to The time zone to which the conversion is to be performed. + */ + def CONVERT_TZ(dateTime: LocalDateTime | OffsetDateTime | ZonedDateTime, from: LocalTime, to: LocalTime): Column[LocalDateTime] = + Column(s"CONVERT_TZ('${dateTime.toString}', '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')") + object DateTime: /** From 0925a3196b54a58a80be2d514715b706fc7a3ff2 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:13:08 +0900 Subject: [PATCH 07/74] Create DateTime CONVERT_TZ Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 4dc7b8af7..3edec121d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -19,6 +19,8 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c2 = Column.Impl[Option[LocalDate]]("local_date") private val c3 = Column.Impl[LocalTime]("local_time") private val c4 = Column.Impl[Option[LocalTime]]("local_time") + private val c5 = Column.Impl[LocalDateTime]("local_date_time") + private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") it should "Statement generated using the ADDDATE function matches the specified string." in { assert(ADDDATE(c1, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") @@ -37,3 +39,10 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(ADDTIME(c4, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") assert(ADDTIME(LocalTime.of(1, 1, 1), LocalTime.of(1, 1, 1, 1)).name == "ADDTIME('01:01:01', '01:01:01.000000001')") } + + + it should "Statement generated using the CONVERT_TZ function matches the specified string." in { + assert(CONVERT_TZ(c5, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") + assert(CONVERT_TZ(c6, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") + assert(CONVERT_TZ(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ('2021-01-01T00:00', '+0:0', '+9:0')") + } From eee07b0f6e9635ddc42f785c789ba62c3f6f7da3 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:18:18 +0900 Subject: [PATCH 08/74] Added CURDATE functions --- .../ldbc/statement/functions/DateTime.scala | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 6a7b1192f..8c4d8771e 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -39,7 +39,7 @@ trait DateTime: * TableQuery[Person].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM person * }}} - * + * * @param date The date to which the addition is to be performed. * @param interval The interval to be added to the date. */ @@ -53,7 +53,7 @@ trait DateTime: * TableQuery[Person].select(p => ADDTIME(p.time, LocalTime.of(1, 1, 1, 1))) * // SELECT ADDTIME(time, '01:01:01.000000001') FROM person * }}} - * + * * @param column The column to which the addition is to be performed. * @param time The time to be added to the column. */ @@ -70,7 +70,7 @@ trait DateTime: * TableQuery[Person].select(p => ADDTIME(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) * // SELECT ADDTIME('01:01:01.000000001', '01:01:01.000000001') FROM person * }}} - * + * * @param dateTime The date time to which the addition is to be performed. * @param time The time to be added to the date time. */ @@ -84,7 +84,7 @@ trait DateTime: * TableQuery[Person].select(p => CONVERT_TZ(p.timestampe, LocalTime.of(0, 0), LocalTime.of(9, 0))) * // SELECT CONVERT_TZ(timestampe, '+00:00', '+09:00') FROM person * }}} - * + * * @param column The column to which the addition is to be performed. * @param from The time zone from which the conversion is to be performed. * @param to The time zone to which the conversion is to be performed. @@ -103,7 +103,7 @@ trait DateTime: * TableQuery[Person].select(p => CONVERT_TZ(LocalDateTime.of(2025, 1, 1), LocalTime.of(0, 0), LocalTime.of(9, 0))) * // SELECT CONVERT_TZ('2025-01-01', '+00:00', '+09:00') FROM person * }}} - * + * * @param dateTime The date time to which the addition is to be performed. * @param from The time zone from which the conversion is to be performed. * @param to The time zone to which the conversion is to be performed. @@ -111,6 +111,16 @@ trait DateTime: def CONVERT_TZ(dateTime: LocalDateTime | OffsetDateTime | ZonedDateTime, from: LocalTime, to: LocalTime): Column[LocalDateTime] = Column(s"CONVERT_TZ('${dateTime.toString}', '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')") + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(_ => CURDATE) + * // SELECT CURDATE() FROM person + * }}} + */ + def CURDATE(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column("CURDATE()") + object DateTime: /** From 2b9c7d5953ca11d23d37ef52ee1490d141eb279b Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:18:23 +0900 Subject: [PATCH 09/74] Create DateTime CURDATE Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 3edec121d..7c64d2b4d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -40,9 +40,12 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(ADDTIME(LocalTime.of(1, 1, 1), LocalTime.of(1, 1, 1, 1)).name == "ADDTIME('01:01:01', '01:01:01.000000001')") } - it should "Statement generated using the CONVERT_TZ function matches the specified string." in { assert(CONVERT_TZ(c5, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") assert(CONVERT_TZ(c6, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") assert(CONVERT_TZ(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ('2021-01-01T00:00', '+0:0', '+9:0')") } + + it should "Statement generated using the CURDATE function matches the specified string." in { + assert(CURDATE.name == "CURDATE()") + } From 3eee429bdc5784e6b8f4de7e701f2c8053cac509 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:19:44 +0900 Subject: [PATCH 10/74] Added CURTIME functions --- .../main/scala/ldbc/statement/functions/DateTime.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 8c4d8771e..ebfc0f061 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -121,6 +121,16 @@ trait DateTime: */ def CURDATE(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column("CURDATE()") + /** + * Function to perform addition on a specified date type column. + * + * {{{ + * TableQuery[Person].select(_ => CURTIME) + * // SELECT CURTIME() FROM person + * }}} + */ + def CURTIME(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column("CURTIME()") + object DateTime: /** From ea4c165a9008cb8688f8bbb5c4f84e2b17e5020a Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:19:50 +0900 Subject: [PATCH 11/74] Create DateTime CURTIME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 7c64d2b4d..58f26c38d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -49,3 +49,7 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the CURDATE function matches the specified string." in { assert(CURDATE.name == "CURDATE()") } + + it should "Statement generated using the CURTIME function matches the specified string." in { + assert(CURTIME.name == "CURTIME()") + } From 7eab29f05a1f9bcb28203b6ee1bacc7817d7d439 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:31:27 +0900 Subject: [PATCH 12/74] Added DATE functions --- .../ldbc/statement/functions/DateTime.scala | 66 +++++++++++++------ 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index ebfc0f061..9175f4fa1 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -22,8 +22,8 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[Person].select(p => ADDDATE(p.birthDate, DateTime.Interval.YEAR(1))) - * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM person + * TableQuery[DateTime].select(p => ADDDATE(p.birthDate, DateTime.Interval.YEAR(1))) + * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM date_time * }}} * * @param column The column to which the addition is to be performed. @@ -36,8 +36,8 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[Person].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) - * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM person + * TableQuery[DateTime].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) + * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM date_time * }}} * * @param date The date to which the addition is to be performed. @@ -50,8 +50,8 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[Person].select(p => ADDTIME(p.time, LocalTime.of(1, 1, 1, 1))) - * // SELECT ADDTIME(time, '01:01:01.000000001') FROM person + * TableQuery[DateTime].select(p => ADDTIME(p.time, LocalTime.of(1, 1, 1, 1))) + * // SELECT ADDTIME(time, '01:01:01.000000001') FROM date_time * }}} * * @param column The column to which the addition is to be performed. @@ -67,8 +67,8 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[Person].select(p => ADDTIME(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) - * // SELECT ADDTIME('01:01:01.000000001', '01:01:01.000000001') FROM person + * TableQuery[DateTime].select(p => ADDTIME(LocalTime.of(1, 1, 1, 1), LocalTime.of(1, 1, 1, 1))) + * // SELECT ADDTIME('01:01:01.000000001', '01:01:01.000000001') FROM date_time * }}} * * @param dateTime The date time to which the addition is to be performed. @@ -78,11 +78,11 @@ trait DateTime: Column(s"ADDTIME('${dateTime.toString}', '${time.toString}')") /** - * Function to perform addition on a specified date type column. + * Function to convert a date-time value dt from the time zone specified by from_tz to the time zone specified by to_tz. * * {{{ - * TableQuery[Person].select(p => CONVERT_TZ(p.timestampe, LocalTime.of(0, 0), LocalTime.of(9, 0))) - * // SELECT CONVERT_TZ(timestampe, '+00:00', '+09:00') FROM person + * TableQuery[DateTime].select(p => CONVERT_TZ(p.timestampe, LocalTime.of(0, 0), LocalTime.of(9, 0))) + * // SELECT CONVERT_TZ(timestampe, '+00:00', '+09:00') FROM date_time * }}} * * @param column The column to which the addition is to be performed. @@ -97,11 +97,11 @@ trait DateTime: Column(s"CONVERT_TZ(${column.name}, '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')")(using column.decoder, column.encoder) /** - * Function to perform addition on a specified date type column. + * Function to convert a date-time value dt from the time zone specified by from_tz to the time zone specified by to_tz. * * {{{ - * TableQuery[Person].select(p => CONVERT_TZ(LocalDateTime.of(2025, 1, 1), LocalTime.of(0, 0), LocalTime.of(9, 0))) - * // SELECT CONVERT_TZ('2025-01-01', '+00:00', '+09:00') FROM person + * TableQuery[DateTime].select(p => CONVERT_TZ(LocalDateTime.of(2025, 1, 1), LocalTime.of(0, 0), LocalTime.of(9, 0))) + * // SELECT CONVERT_TZ('2025-01-01', '+00:00', '+09:00') FROM date_time * }}} * * @param dateTime The date time to which the addition is to be performed. @@ -112,24 +112,50 @@ trait DateTime: Column(s"CONVERT_TZ('${dateTime.toString}', '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')") /** - * Function to perform addition on a specified date type column. + * Function to return the current date as 'YYYY-MM-DD' format. * * {{{ - * TableQuery[Person].select(_ => CURDATE) - * // SELECT CURDATE() FROM person + * TableQuery[DateTime].select(_ => CURDATE) + * // SELECT CURDATE() FROM date_time * }}} */ def CURDATE(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column("CURDATE()") /** - * Function to perform addition on a specified date type column. + * Function to return the current time in 'hh:mm:ss' format. * * {{{ - * TableQuery[Person].select(_ => CURTIME) - * // SELECT CURTIME() FROM person + * TableQuery[DateTime].select(_ => CURTIME) + * // SELECT CURTIME() FROM date_time * }}} */ def CURTIME(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column("CURTIME()") + + /** + * Function to extract the date portion of a date or date-time expression. + * + * {{{ + * TableQuery[DateTime].select(p => DATE(p.timestamp)) + * // SELECT DATE(timestamp) FROM date_time + * }}} + * + * @param column Date or date/time column from which to extract the date portion + */ + def DATE[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"DATE(${column.name})") + + /** + * Function to extract the date portion of a date or date-time expression. + * + * {{{ + * TableQuery[DateTime].select(_ => DATE(LocalDateTime.of(2025, 1, 1, 1, 1))) + * // SELECT DATE('2025-01-01T01:01') FROM date_time + * }}} + * @param date + * The date or date-time expression from which the date portion is to be extracted. + */ + def DATE(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime): Column[LocalDate] = + Column(s"DATE('${date.toString}')") object DateTime: From e3d5a11ca2b29e9e75ec064d73ec812b1d1b81bb Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:31:34 +0900 Subject: [PATCH 13/74] Create DateTime DATE Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 58f26c38d..bc0476e89 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -53,3 +53,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the CURTIME function matches the specified string." in { assert(CURTIME.name == "CURTIME()") } + + it should "Statement generated using the DATE function matches the specified string." in { + assert(DATE(c5).name == "DATE(local_date_time)") + assert(DATE(c6).name == "DATE(local_date_time)") + assert(DATE(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "DATE('2021-01-01T00:00')") + } From 4c30a98fa14d16325ee6b7250be7b9c309f0236d Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:50:28 +0900 Subject: [PATCH 14/74] Added DATE_FORMAT functions --- .../ldbc/statement/functions/DateTime.scala | 81 +++++++++++++++---- 1 file changed, 66 insertions(+), 15 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 9175f4fa1..c13242f26 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -26,8 +26,10 @@ trait DateTime: * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM date_time * }}} * - * @param column The column to which the addition is to be performed. - * @param interval The interval to be added to the column. + * @param column + * The column to which the addition is to be performed. + * @param interval + * The interval to be added to the column. */ def ADDDATE[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = Column(s"ADDDATE(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) @@ -40,8 +42,10 @@ trait DateTime: * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM date_time * }}} * - * @param date The date to which the addition is to be performed. - * @param interval The interval to be added to the date. + * @param date + * The date to which the addition is to be performed. + * @param interval + * The interval to be added to the date. */ def ADDDATE(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"ADDDATE('${date.toString}', ${interval.statement})") @@ -54,8 +58,10 @@ trait DateTime: * // SELECT ADDTIME(time, '01:01:01.000000001') FROM date_time * }}} * - * @param column The column to which the addition is to be performed. - * @param time The time to be added to the column. + * @param column + * The column to which the addition is to be performed. + * @param time + * The time to be added to the column. */ def ADDTIME[A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]]( column: Column[A], @@ -71,8 +77,10 @@ trait DateTime: * // SELECT ADDTIME('01:01:01.000000001', '01:01:01.000000001') FROM date_time * }}} * - * @param dateTime The date time to which the addition is to be performed. - * @param time The time to be added to the date time. + * @param dateTime + * The date time to which the addition is to be performed. + * @param time + * The time to be added to the date time. */ def ADDTIME(dateTime: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, time: LocalTime): Column[LocalTime] = Column(s"ADDTIME('${dateTime.toString}', '${time.toString}')") @@ -85,9 +93,12 @@ trait DateTime: * // SELECT CONVERT_TZ(timestampe, '+00:00', '+09:00') FROM date_time * }}} * - * @param column The column to which the addition is to be performed. - * @param from The time zone from which the conversion is to be performed. - * @param to The time zone to which the conversion is to be performed. + * @param column + * The column to which the addition is to be performed. + * @param from + * The time zone from which the conversion is to be performed. + * @param to + * The time zone to which the conversion is to be performed. */ def CONVERT_TZ[A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime]]( column: Column[A], @@ -104,9 +115,12 @@ trait DateTime: * // SELECT CONVERT_TZ('2025-01-01', '+00:00', '+09:00') FROM date_time * }}} * - * @param dateTime The date time to which the addition is to be performed. - * @param from The time zone from which the conversion is to be performed. - * @param to The time zone to which the conversion is to be performed. + * @param dateTime + * The date time to which the addition is to be performed. + * @param from + * The time zone from which the conversion is to be performed. + * @param to + * The time zone to which the conversion is to be performed. */ def CONVERT_TZ(dateTime: LocalDateTime | OffsetDateTime | ZonedDateTime, from: LocalTime, to: LocalTime): Column[LocalDateTime] = Column(s"CONVERT_TZ('${dateTime.toString}', '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')") @@ -139,7 +153,8 @@ trait DateTime: * // SELECT DATE(timestamp) FROM date_time * }}} * - * @param column Date or date/time column from which to extract the date portion + * @param column + * Date or date/time column from which to extract the date portion */ def DATE[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"DATE(${column.name})") @@ -157,6 +172,42 @@ trait DateTime: def DATE(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime): Column[LocalDate] = Column(s"DATE('${date.toString}')") + /** + * Function to format a date value according to the format string. + * @see https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_date-format + * + * {{{ + * TableQuery[DateTime].select(p => DATE_FORMAT(p.timestamp, "%Y-%m-%d")) + * // SELECT DATE_FORMAT(timestamp, '%Y-%m-%d') FROM date_time + * }}} + * + * @param column + * The column to be formatted. + * @param format + * The format string. + */ + def DATE_FORMAT[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + column: Column[A], + format: String + )(using Decoder[String], Encoder[String]): Column[String] = + Column(s"DATE_FORMAT(${column.name}, '$format')") + + /** + * Function to format a date value according to the format string. + * + * {{{ + * TableQuery[DateTime].select(_ => DATE_FORMAT(LocalDate.of(2025, 1, 1), "%Y-%m-%d")) + * // SELECT DATE_FORMAT('2025-01-01', '%Y-%m-%d') FROM date_time + * }}} + * + * @param date + * The date or date-time expression to be formatted. + * @param format + * The format string. + */ + def DATE_FORMAT(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, format: String): Column[String] = + Column(s"DATE_FORMAT('${date.toString}', '$format')") + object DateTime: /** From 5ff3e3b2e88c4a8e45149e66cd608336298aaf99 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:50:33 +0900 Subject: [PATCH 15/74] Create DateTime DATE_FORMAT Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index bc0476e89..ce24399e8 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -59,3 +59,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DATE(c6).name == "DATE(local_date_time)") assert(DATE(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "DATE('2021-01-01T00:00')") } + + it should "Statement generated using the DATE_FORMAT function matches the specified string." in { + assert(DATE_FORMAT(c5, "%Y-%m-%d").name == "DATE_FORMAT(local_date_time, '%Y-%m-%d')") + assert(DATE_FORMAT(c6, "%Y-%m-%d").name == "DATE_FORMAT(local_date_time, '%Y-%m-%d')") + assert(DATE_FORMAT(LocalDateTime.of(2021, 1, 1, 0, 0), "%Y-%m-%d").name == "DATE_FORMAT('2021-01-01T00:00', '%Y-%m-%d')") + } From e71adec8cae5004f845efabc3486b0f750b53f76 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:54:30 +0900 Subject: [PATCH 16/74] Added DATE_SUB functions --- .../ldbc/statement/functions/DateTime.scala | 48 +++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c13242f26..c692971c6 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -22,8 +22,8 @@ trait DateTime: * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[DateTime].select(p => ADDDATE(p.birthDate, DateTime.Interval.YEAR(1))) - * // SELECT ADDDATE(birth_date, INTERVAL 1 YEAR) FROM date_time + * TableQuery[DateTime].select(p => DATE_ADD(p.birthDate, DateTime.Interval.YEAR(1))) + * // SELECT DATE_ADD(birth_date, INTERVAL 1 YEAR) FROM date_time * }}} * * @param column @@ -31,15 +31,15 @@ trait DateTime: * @param interval * The interval to be added to the column. */ - def ADDDATE[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = - Column(s"ADDDATE(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) + def DATE_ADD[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = + Column(s"DATE_ADD(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) /** * Function to perform addition on a specified date type column. * * {{{ - * TableQuery[DateTime].select(p => ADDDATE(LocalDate.now, DateTime.Interval.YEAR(1))) - * // SELECT ADDDATE('2008-02-02', INTERVAL 1 YEAR) FROM date_time + * TableQuery[DateTime].select(p => DATE_ADD(LocalDate.now, DateTime.Interval.YEAR(1))) + * // SELECT DATE_ADD('2008-02-02', INTERVAL 1 YEAR) FROM date_time * }}} * * @param date @@ -47,8 +47,40 @@ trait DateTime: * @param interval * The interval to be added to the date. */ - def ADDDATE(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = - Column(s"ADDDATE('${date.toString}', ${interval.statement})") + def DATE_ADD(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"DATE_ADD('${date.toString}', ${interval.statement})") + + /** + * Function to perform subtraction on a given date type column. + * + * {{{ + * TableQuery[DateTime].select(p => DATE_SUB(p.birthDate, DateTime.Interval.YEAR(1))) + * // SELECT DATE_SUB(birth_date, INTERVAL 1 YEAR) FROM date_time + * }}} + * + * @param column + * The column to which the subtraction is to be performed. + * @param interval + * The interval to be subtraction to the column. + */ + def DATE_SUB[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = + Column(s"DATE_SUB(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) + + /** + * Function to perform subtraction on a given date. + * + * {{{ + * TableQuery[DateTime].select(p => DATE_SUB(LocalDate.now, DateTime.Interval.YEAR(1))) + * // SELECT DATE_SUB('2008-02-02', INTERVAL 1 YEAR) FROM date_time + * }}} + * + * @param date + * The date to which the subtraction is to be performed. + * @param interval + * The interval to be subtraction to the date. + */ + def DATE_SUB(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"DATE_SUB('${date.toString}', ${interval.statement})") /** * Function to perform addition on a specified date type column. From 2629795c37c7797270f201e753861ca3b8555204 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Sun, 19 Jan 2025 18:54:37 +0900 Subject: [PATCH 17/74] Create DateTime DATE_SUB Test --- .../statement/functions/DateTimeTest.scala | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index ce24399e8..23910057f 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -22,18 +22,31 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c5 = Column.Impl[LocalDateTime]("local_date_time") private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") - it should "Statement generated using the ADDDATE function matches the specified string." in { - assert(ADDDATE(c1, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") - assert(ADDDATE(c1, Interval.MONTH(1)).name == "ADDDATE(local_date, INTERVAL 1 MONTH)") - assert(ADDDATE(c1, Interval.YEAR(1)).name == "ADDDATE(local_date, INTERVAL 1 YEAR)") - assert(ADDDATE(c2, Interval.DAY(1)).name == "ADDDATE(local_date, INTERVAL 1 DAY)") - assert(ADDDATE(c2, Interval.MONTH(1)).name == "ADDDATE(local_date, INTERVAL 1 MONTH)") - assert(ADDDATE(c2, Interval.YEAR(1)).name == "ADDDATE(local_date, INTERVAL 1 YEAR)") - assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.DAY(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 DAY)") - assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.MONTH(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 MONTH)") - assert(ADDDATE(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "ADDDATE('2021-01-01', INTERVAL 1 YEAR)") + it should "Statement generated using the DATE_ADD function matches the specified string." in { + assert(DATE_ADD(c1, Interval.DAY(1)).name == "DATE_ADD(local_date, INTERVAL 1 DAY)") + assert(DATE_ADD(c1, Interval.MONTH(1)).name == "DATE_ADD(local_date, INTERVAL 1 MONTH)") + assert(DATE_ADD(c1, Interval.YEAR(1)).name == "DATE_ADD(local_date, INTERVAL 1 YEAR)") + assert(DATE_ADD(c2, Interval.DAY(1)).name == "DATE_ADD(local_date, INTERVAL 1 DAY)") + assert(DATE_ADD(c2, Interval.MONTH(1)).name == "DATE_ADD(local_date, INTERVAL 1 MONTH)") + assert(DATE_ADD(c2, Interval.YEAR(1)).name == "DATE_ADD(local_date, INTERVAL 1 YEAR)") + assert(DATE_ADD(LocalDate.of(2021, 1, 1), Interval.DAY(1)).name == "DATE_ADD('2021-01-01', INTERVAL 1 DAY)") + assert(DATE_ADD(LocalDate.of(2021, 1, 1), Interval.MONTH(1)).name == "DATE_ADD('2021-01-01', INTERVAL 1 MONTH)") + assert(DATE_ADD(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "DATE_ADD('2021-01-01', INTERVAL 1 YEAR)") } + it should "Statement generated using the DATE_SUB function matches the specified string." in { + assert(DATE_SUB(c1, Interval.DAY(1)).name == "DATE_SUB(local_date, INTERVAL 1 DAY)") + assert(DATE_SUB(c1, Interval.MONTH(1)).name == "DATE_SUB(local_date, INTERVAL 1 MONTH)") + assert(DATE_SUB(c1, Interval.YEAR(1)).name == "DATE_SUB(local_date, INTERVAL 1 YEAR)") + assert(DATE_SUB(c2, Interval.DAY(1)).name == "DATE_SUB(local_date, INTERVAL 1 DAY)") + assert(DATE_SUB(c2, Interval.MONTH(1)).name == "DATE_SUB(local_date, INTERVAL 1 MONTH)") + assert(DATE_SUB(c2, Interval.YEAR(1)).name == "DATE_SUB(local_date, INTERVAL 1 YEAR)") + assert(DATE_SUB(LocalDate.of(2021, 1, 1), Interval.DAY(1)).name == "DATE_SUB('2021-01-01', INTERVAL 1 DAY)") + assert(DATE_SUB(LocalDate.of(2021, 1, 1), Interval.MONTH(1)).name == "DATE_SUB('2021-01-01', INTERVAL 1 MONTH)") + assert(DATE_SUB(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "DATE_SUB('2021-01-01', INTERVAL 1 YEAR)") + } + + it should "Statement generated using the ADDTIME function matches the specified string." in { assert(ADDTIME(c3, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") assert(ADDTIME(c4, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") From ebab5242f397a5bd52e628c86fca24dbf236b419 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:29:52 +0900 Subject: [PATCH 18/74] Added DATEDIFF functions --- .../ldbc/statement/functions/DateTime.scala | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c692971c6..96f536b93 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -240,6 +240,63 @@ trait DateTime: def DATE_FORMAT(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, format: String): Column[String] = Column(s"DATE_FORMAT('${date.toString}', '$format')") + /** + * Function to calculate the value of the number of days from one date to another. + * + * {{{ + * TableQuery[DateTime].select(p => DATEDIFF(p.birthDate, p.deathDate)) + * // SELECT DATEDIFF(birth_date, death_date) FROM date_time + * }}} + * + * @param from + * The starting date. + * @param to + * The ending date. + */ + def DATEDIFF[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime], B <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + from: Column[A], + to: Column[B] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DATEDIFF(${from.name}, ${to.name})") + + /** + * Function to calculate the value of the number of days from one date to another. + * + * {{{ + * TableQuery[DateTime].select(p => DATEDIFF(p.birthDate, LocalDate.of(2021, 1, 1))) + * // SELECT DATEDIFF(birth_date, '2021-01-01') FROM date_time + * }}} + * + * @param from + * The starting date. + * @param to + * The ending date. + */ + def DATEDIFF[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + from: Column[A], + to: LocalDate + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DATEDIFF(${from.name}, '${to.toString}')") + + /** + * Function to calculate the value of the number of days from one date to another. + * + * {{{ + * TableQuery[DateTime].select(p => DATEDIFF(p.birthDate, LocalDate.of(2021, 1, 1))) + * // SELECT DATEDIFF(birth_date, '2021-01-01') FROM date_time + * }}} + * + * @param from + * The starting date. + * @param to + * The ending date. + */ + def DATEDIFF( + from: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, + to: LocalDate + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DATEDIFF('${from.toString}', '${to.toString}')") + object DateTime: /** From dfc26d91663026b0c727adf554aaf8d6d7821996 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:29:59 +0900 Subject: [PATCH 19/74] Create DateTime DATEDIFF Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 23910057f..7e8d076e8 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -78,3 +78,11 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DATE_FORMAT(c6, "%Y-%m-%d").name == "DATE_FORMAT(local_date_time, '%Y-%m-%d')") assert(DATE_FORMAT(LocalDateTime.of(2021, 1, 1, 0, 0), "%Y-%m-%d").name == "DATE_FORMAT('2021-01-01T00:00', '%Y-%m-%d')") } + + it should "Statement generated using the DATEDIFF function matches the specified string." in { + assert(DATEDIFF(c5, c1).name == "DATEDIFF(local_date_time, local_date)") + assert(DATEDIFF(c6, c2).name == "DATEDIFF(local_date_time, local_date)") + assert(DATEDIFF(c5, LocalDate.of(2025, 1, 1)).name == "DATEDIFF(local_date_time, '2025-01-01')") + assert(DATEDIFF(c6, LocalDate.of(2025, 1, 1)).name == "DATEDIFF(local_date_time, '2025-01-01')") + assert(DATEDIFF(LocalDate.of(2024, 1, 1), LocalDate.of(2025, 1, 1)).name == "DATEDIFF('2024-01-01', '2025-01-01')") + } From e8b4122c2a03aa1e4dfd695381d978b6d1d7e651 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:31:04 +0900 Subject: [PATCH 20/74] Action sbt scalafmtAll --- .../ldbc/statement/functions/DateTime.scala | 147 +++++++++++------- .../statement/functions/DateTimeTest.scala | 19 ++- 2 files changed, 105 insertions(+), 61 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 96f536b93..260626d9e 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -9,6 +9,7 @@ package ldbc.statement.functions import java.time.* import ldbc.dsl.codec.* + import ldbc.statement.Column /** @@ -32,7 +33,7 @@ trait DateTime: * The interval to be added to the column. */ def DATE_ADD[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = - Column(s"DATE_ADD(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) + Column(s"DATE_ADD(${ column.name }, ${ interval.statement })")(using column.decoder, column.encoder) /** * Function to perform addition on a specified date type column. @@ -47,8 +48,11 @@ trait DateTime: * @param interval * The interval to be added to the date. */ - def DATE_ADD(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = - Column(s"DATE_ADD('${date.toString}', ${interval.statement})") + def DATE_ADD(date: LocalDate, interval: DateTime.Interval[Int])(using + Decoder[LocalDate], + Encoder[LocalDate] + ): Column[LocalDate] = + Column(s"DATE_ADD('${ date.toString }', ${ interval.statement })") /** * Function to perform subtraction on a given date type column. @@ -64,7 +68,7 @@ trait DateTime: * The interval to be subtraction to the column. */ def DATE_SUB[A <: LocalDate | Option[LocalDate]](column: Column[A], interval: DateTime.Interval[Int]): Column[A] = - Column(s"DATE_SUB(${column.name}, ${interval.statement})")(using column.decoder, column.encoder) + Column(s"DATE_SUB(${ column.name }, ${ interval.statement })")(using column.decoder, column.encoder) /** * Function to perform subtraction on a given date. @@ -79,8 +83,11 @@ trait DateTime: * @param interval * The interval to be subtraction to the date. */ - def DATE_SUB(date: LocalDate, interval: DateTime.Interval[Int])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = - Column(s"DATE_SUB('${date.toString}', ${interval.statement})") + def DATE_SUB(date: LocalDate, interval: DateTime.Interval[Int])(using + Decoder[LocalDate], + Encoder[LocalDate] + ): Column[LocalDate] = + Column(s"DATE_SUB('${ date.toString }', ${ interval.statement })") /** * Function to perform addition on a specified date type column. @@ -95,11 +102,14 @@ trait DateTime: * @param time * The time to be added to the column. */ - def ADDTIME[A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + def ADDTIME[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( column: Column[A], - time: LocalTime + time: LocalTime ): Column[A] = - Column(s"ADDTIME(${column.name}, '${time.toString}')")(using column.decoder, column.encoder) + Column(s"ADDTIME(${ column.name }, '${ time.toString }')")(using column.decoder, column.encoder) /** * Function to perform addition on a specified date type column. @@ -114,8 +124,11 @@ trait DateTime: * @param time * The time to be added to the date time. */ - def ADDTIME(dateTime: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, time: LocalTime): Column[LocalTime] = - Column(s"ADDTIME('${dateTime.toString}', '${time.toString}')") + def ADDTIME( + dateTime: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, + time: LocalTime + ): Column[LocalTime] = + Column(s"ADDTIME('${ dateTime.toString }', '${ time.toString }')") /** * Function to convert a date-time value dt from the time zone specified by from_tz to the time zone specified by to_tz. @@ -132,12 +145,16 @@ trait DateTime: * @param to * The time zone to which the conversion is to be performed. */ - def CONVERT_TZ[A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime]]( + def CONVERT_TZ[ + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( column: Column[A], - from: LocalTime, - to: LocalTime + from: LocalTime, + to: LocalTime ): Column[A] = - Column(s"CONVERT_TZ(${column.name}, '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')")(using column.decoder, column.encoder) + Column( + s"CONVERT_TZ(${ column.name }, '+${ from.getHour }:${ from.getMinute }', '+${ to.getHour }:${ to.getMinute }')" + )(using column.decoder, column.encoder) /** * Function to convert a date-time value dt from the time zone specified by from_tz to the time zone specified by to_tz. @@ -154,8 +171,14 @@ trait DateTime: * @param to * The time zone to which the conversion is to be performed. */ - def CONVERT_TZ(dateTime: LocalDateTime | OffsetDateTime | ZonedDateTime, from: LocalTime, to: LocalTime): Column[LocalDateTime] = - Column(s"CONVERT_TZ('${dateTime.toString}', '+${from.getHour}:${from.getMinute}', '+${to.getHour}:${to.getMinute}')") + def CONVERT_TZ( + dateTime: LocalDateTime | OffsetDateTime | ZonedDateTime, + from: LocalTime, + to: LocalTime + ): Column[LocalDateTime] = + Column( + s"CONVERT_TZ('${ dateTime.toString }', '+${ from.getHour }:${ from.getMinute }', '+${ to.getHour }:${ to.getMinute }')" + ) /** * Function to return the current date as 'YYYY-MM-DD' format. @@ -176,7 +199,7 @@ trait DateTime: * }}} */ def CURTIME(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column("CURTIME()") - + /** * Function to extract the date portion of a date or date-time expression. * @@ -188,8 +211,11 @@ trait DateTime: * @param column * Date or date/time column from which to extract the date portion */ - def DATE[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = - Column(s"DATE(${column.name})") + def DATE[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"DATE(${ column.name })") /** * Function to extract the date portion of a date or date-time expression. @@ -202,7 +228,7 @@ trait DateTime: * The date or date-time expression from which the date portion is to be extracted. */ def DATE(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime): Column[LocalDate] = - Column(s"DATE('${date.toString}')") + Column(s"DATE('${ date.toString }')") /** * Function to format a date value according to the format string. @@ -218,11 +244,14 @@ trait DateTime: * @param format * The format string. */ - def DATE_FORMAT[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + def DATE_FORMAT[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( column: Column[A], format: String )(using Decoder[String], Encoder[String]): Column[String] = - Column(s"DATE_FORMAT(${column.name}, '$format')") + Column(s"DATE_FORMAT(${ column.name }, '$format')") /** * Function to format a date value according to the format string. @@ -238,7 +267,7 @@ trait DateTime: * The format string. */ def DATE_FORMAT(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, format: String): Column[String] = - Column(s"DATE_FORMAT('${date.toString}', '$format')") + Column(s"DATE_FORMAT('${ date.toString }', '$format')") /** * Function to calculate the value of the number of days from one date to another. @@ -253,11 +282,16 @@ trait DateTime: * @param to * The ending date. */ - def DATEDIFF[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime], B <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + def DATEDIFF[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime], + B <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( from: Column[A], - to: Column[B] + to: Column[B] )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DATEDIFF(${from.name}, ${to.name})") + Column(s"DATEDIFF(${ from.name }, ${ to.name })") /** * Function to calculate the value of the number of days from one date to another. @@ -272,11 +306,14 @@ trait DateTime: * @param to * The ending date. */ - def DATEDIFF[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( - from: Column[A], - to: LocalDate - )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DATEDIFF(${from.name}, '${to.toString}')") + def DATEDIFF[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + from: Column[A], + to: LocalDate + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DATEDIFF(${ from.name }, '${ to.toString }')") /** * Function to calculate the value of the number of days from one date to another. @@ -292,11 +329,11 @@ trait DateTime: * The ending date. */ def DATEDIFF( - from: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, - to: LocalDate - )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DATEDIFF('${from.toString}', '${to.toString}')") - + from: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, + to: LocalDate + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DATEDIFF('${ from.toString }', '${ to.toString }')") + object DateTime: /** @@ -310,23 +347,23 @@ object DateTime: */ enum Interval[A](expr: A, val unit: String): def statement: String = s"INTERVAL $expr $unit" - case MICROSECOND(expr: Int) extends Interval(expr, "MICROSECOND") - case SECOND(expr: Int) extends Interval(expr, "SECOND") - case MINUTE(expr: Int) extends Interval(expr, "MINUTE") - case HOUR(expr: Int) extends Interval(expr, "HOUR") - case DAY(expr: Int) extends Interval(expr, "DAY") - case WEEK(expr: Int) extends Interval(expr, "WEEK") - case MONTH(expr: Int) extends Interval(expr, "MONTH") - case QUARTER(expr: Int) extends Interval(expr, "QUARTER") - case YEAR(expr: Int) extends Interval(expr, "YEAR") + case MICROSECOND(expr: Int) extends Interval(expr, "MICROSECOND") + case SECOND(expr: Int) extends Interval(expr, "SECOND") + case MINUTE(expr: Int) extends Interval(expr, "MINUTE") + case HOUR(expr: Int) extends Interval(expr, "HOUR") + case DAY(expr: Int) extends Interval(expr, "DAY") + case WEEK(expr: Int) extends Interval(expr, "WEEK") + case MONTH(expr: Int) extends Interval(expr, "MONTH") + case QUARTER(expr: Int) extends Interval(expr, "QUARTER") + case YEAR(expr: Int) extends Interval(expr, "YEAR") case SECOND_MICROSECOND(expr: String) extends Interval(expr, "SECOND_MICROSECOND") case MINUTE_MICROSECOND(expr: String) extends Interval(expr, "MINUTE_MICROSECOND") - case MINUTE_SECOND(expr: String) extends Interval(expr, "MINUTE_SECOND") - case HOUR_MICROSECOND(expr: String) extends Interval(expr, "HOUR_MICROSECOND") - case HOUR_SECOND(expr: String) extends Interval(expr, "HOUR_SECOND") - case HOUR_MINUTE(expr: String) extends Interval(expr, "HOUR_MINUTE") - case DAY_MICROSECOND(expr: String) extends Interval(expr, "DAY_MICROSECOND") - case DAY_SECOND(expr: String) extends Interval(expr, "DAY_SECOND") - case DAY_MINUTE(expr: String) extends Interval(expr, "DAY_MINUTE") - case DAY_HOUR(expr: String) extends Interval(expr, "DAY_HOUR") - case YEAR_MONTH(expr: YearMonth) extends Interval(expr, "YEAR_MONTH") + case MINUTE_SECOND(expr: String) extends Interval(expr, "MINUTE_SECOND") + case HOUR_MICROSECOND(expr: String) extends Interval(expr, "HOUR_MICROSECOND") + case HOUR_SECOND(expr: String) extends Interval(expr, "HOUR_SECOND") + case HOUR_MINUTE(expr: String) extends Interval(expr, "HOUR_MINUTE") + case DAY_MICROSECOND(expr: String) extends Interval(expr, "DAY_MICROSECOND") + case DAY_SECOND(expr: String) extends Interval(expr, "DAY_SECOND") + case DAY_MINUTE(expr: String) extends Interval(expr, "DAY_MINUTE") + case DAY_HOUR(expr: String) extends Interval(expr, "DAY_HOUR") + case YEAR_MONTH(expr: YearMonth) extends Interval(expr, "YEAR_MONTH") diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 7e8d076e8..f39c02afa 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -8,11 +8,11 @@ package ldbc.statement.functions import java.time.* -import ldbc.statement.Column -import ldbc.statement.functions.DateTime.* - import org.scalatest.flatspec.AnyFlatSpec +import ldbc.statement.functions.DateTime.* +import ldbc.statement.Column + class DateTimeTest extends AnyFlatSpec, DateTime: private val c1 = Column.Impl[LocalDate]("local_date") @@ -46,7 +46,6 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DATE_SUB(LocalDate.of(2021, 1, 1), Interval.YEAR(1)).name == "DATE_SUB('2021-01-01', INTERVAL 1 YEAR)") } - it should "Statement generated using the ADDTIME function matches the specified string." in { assert(ADDTIME(c3, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") assert(ADDTIME(c4, LocalTime.of(1, 1, 1, 1)).name == "ADDTIME(local_time, '01:01:01.000000001')") @@ -56,7 +55,13 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the CONVERT_TZ function matches the specified string." in { assert(CONVERT_TZ(c5, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") assert(CONVERT_TZ(c6, LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ(local_date_time, '+0:0', '+9:0')") - assert(CONVERT_TZ(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(0, 0), LocalTime.of(9, 0)).name == "CONVERT_TZ('2021-01-01T00:00', '+0:0', '+9:0')") + assert( + CONVERT_TZ( + LocalDateTime.of(2021, 1, 1, 0, 0), + LocalTime.of(0, 0), + LocalTime.of(9, 0) + ).name == "CONVERT_TZ('2021-01-01T00:00', '+0:0', '+9:0')" + ) } it should "Statement generated using the CURDATE function matches the specified string." in { @@ -76,7 +81,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the DATE_FORMAT function matches the specified string." in { assert(DATE_FORMAT(c5, "%Y-%m-%d").name == "DATE_FORMAT(local_date_time, '%Y-%m-%d')") assert(DATE_FORMAT(c6, "%Y-%m-%d").name == "DATE_FORMAT(local_date_time, '%Y-%m-%d')") - assert(DATE_FORMAT(LocalDateTime.of(2021, 1, 1, 0, 0), "%Y-%m-%d").name == "DATE_FORMAT('2021-01-01T00:00', '%Y-%m-%d')") + assert( + DATE_FORMAT(LocalDateTime.of(2021, 1, 1, 0, 0), "%Y-%m-%d").name == "DATE_FORMAT('2021-01-01T00:00', '%Y-%m-%d')" + ) } it should "Statement generated using the DATEDIFF function matches the specified string." in { From aa4e7a6ac19debda7f509456f4031c8d4d2b3a0e Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:38:03 +0900 Subject: [PATCH 21/74] Added DAYNAME functions --- .../ldbc/statement/functions/DateTime.scala | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 260626d9e..5dafdc9e9 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -334,6 +334,44 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"DATEDIFF('${ from.toString }', '${ to.toString }')") + /** + * A function that returns the name of the day of the week corresponding to date. + * The language used for the names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). + * @see https://dev.mysql.com/doc/refman/8.0/ja/locale-support.html + * + * {{{ + * TableQuery[DateTime].select(p => DAYNAME(p.birthDate)) + * // SELECT DAYNAME(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the day of the week. + */ + def DAYNAME[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[String], Encoder[String]): Column[String] = + Column(s"DAYNAME(${ column.name })") + + /** + * A function that returns the name of the day of the week corresponding to date. + * The language used for the names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). + * + * @see https://dev.mysql.com/doc/refman/8.0/ja/locale-support.html + * + * {{{ + * TableQuery[DateTime].select(_ => DAYNAME(LocalDate.of(2021, 1, 1))) + * // SELECT DAYNAME('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the day of the week. + */ + def DAYNAME(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[String], Encoder[String]): Column[String] = + Column(s"DAYNAME('${ date.toString }')") + object DateTime: /** From 3676a602bcad29bfdb032df6071280ab5e925ece Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:38:10 +0900 Subject: [PATCH 22/74] Create DateTime DAYNAME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index f39c02afa..98438402f 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -93,3 +93,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DATEDIFF(c6, LocalDate.of(2025, 1, 1)).name == "DATEDIFF(local_date_time, '2025-01-01')") assert(DATEDIFF(LocalDate.of(2024, 1, 1), LocalDate.of(2025, 1, 1)).name == "DATEDIFF('2024-01-01', '2025-01-01')") } + + it should "Statement generated using the DAYNAME function matches the specified string." in { + assert(DAYNAME(c5).name == "DAYNAME(local_date_time)") + assert(DAYNAME(c6).name == "DAYNAME(local_date_time)") + assert(DAYNAME(LocalDate.of(2025, 1, 1)).name == "DAYNAME('2025-01-01')") + } From 72dfd818d50ee28cb6d8c4e4653edc5a97cf8927 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:42:03 +0900 Subject: [PATCH 23/74] Added DAYOFMONTH functions --- .../ldbc/statement/functions/DateTime.scala | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 5dafdc9e9..090333514 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -372,6 +372,39 @@ trait DateTime: def DAYNAME(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[String], Encoder[String]): Column[String] = Column(s"DAYNAME('${ date.toString }')") + /** + * A function that returns the day of the month for date, in the range 1 to 31, or 0 for dates such as '0000-00-00' or '2008-00-00' that have a zero day part. + * + * {{{ + * TableQuery[DateTime].select(p => DAYOFMONTH(p.birthDate)) + * // SELECT DAYOFMONTH(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the day of the month. + */ + def DAYOFMONTH[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFMONTH(${ column.name })") + + /** + * A function that returns the day of the month for date, in the range 1 to 31, or 0 for dates such as '0000-00-00' or '2008-00-00' that have a zero day part. + * + * {{{ + * TableQuery[DateTime].select(_ => DAYOFMONTH(LocalDate.of(2021, 1, 1))) + * // SELECT DAYOFMONTH('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the day of the month. + */ + def DAYOFMONTH(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFMONTH('${ date.toString }')") + object DateTime: /** From da10ec182b09e0265effaa007736827bae87b90f Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:42:09 +0900 Subject: [PATCH 24/74] Create DateTime DAYOFMONTH Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 98438402f..7b2655772 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -99,3 +99,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DAYNAME(c6).name == "DAYNAME(local_date_time)") assert(DAYNAME(LocalDate.of(2025, 1, 1)).name == "DAYNAME('2025-01-01')") } + + it should "Statement generated using the DAYOFMONTH function matches the specified string." in { + assert(DAYOFMONTH(c5).name == "DAYOFMONTH(local_date_time)") + assert(DAYOFMONTH(c6).name == "DAYOFMONTH(local_date_time)") + assert(DAYOFMONTH(LocalDate.of(2025, 1, 1)).name == "DAYOFMONTH('2025-01-01')") + } From 21306ed088f1335ae2bb7a4be4046b9466b2f556 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:46:36 +0900 Subject: [PATCH 25/74] Added DAYOFWEEK functions --- .../ldbc/statement/functions/DateTime.scala | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 090333514..c641da0ec 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -343,7 +343,7 @@ trait DateTime: * TableQuery[DateTime].select(p => DAYNAME(p.birthDate)) * // SELECT DAYNAME(birth_date) FROM date_time * }}} - * + * * @param column * The date or date-time column from which to extract the day of the week. */ @@ -365,7 +365,7 @@ trait DateTime: * TableQuery[DateTime].select(_ => DAYNAME(LocalDate.of(2021, 1, 1))) * // SELECT DAYNAME('2021-01-01') FROM date_time * }}} - * + * * @param date * The date or date-time expression from which to extract the day of the week. */ @@ -374,12 +374,12 @@ trait DateTime: /** * A function that returns the day of the month for date, in the range 1 to 31, or 0 for dates such as '0000-00-00' or '2008-00-00' that have a zero day part. - * + * * {{{ * TableQuery[DateTime].select(p => DAYOFMONTH(p.birthDate)) * // SELECT DAYOFMONTH(birth_date) FROM date_time * }}} - * + * * @param column * The date or date-time column from which to extract the day of the month. */ @@ -393,18 +393,53 @@ trait DateTime: /** * A function that returns the day of the month for date, in the range 1 to 31, or 0 for dates such as '0000-00-00' or '2008-00-00' that have a zero day part. - * + * * {{{ * TableQuery[DateTime].select(_ => DAYOFMONTH(LocalDate.of(2021, 1, 1))) * // SELECT DAYOFMONTH('2021-01-01') FROM date_time * }}} - * + * * @param date * The date or date-time expression from which to extract the day of the month. */ def DAYOFMONTH(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"DAYOFMONTH('${ date.toString }')") + /** + * A function that returns the day of the week for date, in the range 1 to 7, where 1 represents Sunday. + * Day of the week index (1 = Sunday, 2 = Monday, ..., 7 = Saturday) for date. + * + * {{{ + * TableQuery[DateTime].select(p => DAYOFWEEK(p.birthDate)) + * // SELECT DAYOFWEEK(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the day of the week. + */ + def DAYOFWEEK[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFWEEK(${column.name})") + + /** + * A function that returns the day of the week for date, in the range 1 to 7, where 1 represents Sunday. + * Day of the week index (1 = Sunday, 2 = Monday, ..., 7 = Saturday) for date. + * + * {{{ + * TableQuery[DateTime].select(_ => DAYOFWEEK(LocalDate.of(2021, 1, 1))) + * // SELECT DAYOFWEEK('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the day of the week. + */ + def DAYOFWEEK(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFWEEK('${date.toString}')") + object DateTime: /** From 9648191ade1d3467924e3af46e6d927c72de37c6 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:46:42 +0900 Subject: [PATCH 26/74] Create DateTime DAYOFWEEK Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 7b2655772..17902aad7 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -105,3 +105,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DAYOFMONTH(c6).name == "DAYOFMONTH(local_date_time)") assert(DAYOFMONTH(LocalDate.of(2025, 1, 1)).name == "DAYOFMONTH('2025-01-01')") } + + it should "Statement generated using the DAYOFWEEK function matches the specified string." in { + assert(DAYOFWEEK(c5).name == "DAYOFWEEK(local_date_time)") + assert(DAYOFWEEK(c6).name == "DAYOFWEEK(local_date_time)") + assert(DAYOFWEEK(LocalDate.of(2025, 1, 1)).name == "DAYOFWEEK('2025-01-01')") + } From 41919917944664819537a55bab3b913b70aca144 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:49:04 +0900 Subject: [PATCH 27/74] Added DAYOFYEAR functions --- .../ldbc/statement/functions/DateTime.scala | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c641da0ec..f30fc56c7 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -408,12 +408,12 @@ trait DateTime: /** * A function that returns the day of the week for date, in the range 1 to 7, where 1 represents Sunday. * Day of the week index (1 = Sunday, 2 = Monday, ..., 7 = Saturday) for date. - * + * * {{{ * TableQuery[DateTime].select(p => DAYOFWEEK(p.birthDate)) * // SELECT DAYOFWEEK(birth_date) FROM date_time * }}} - * + * * @param column * The date or date-time column from which to extract the day of the week. */ @@ -428,18 +428,53 @@ trait DateTime: /** * A function that returns the day of the week for date, in the range 1 to 7, where 1 represents Sunday. * Day of the week index (1 = Sunday, 2 = Monday, ..., 7 = Saturday) for date. - * + * * {{{ * TableQuery[DateTime].select(_ => DAYOFWEEK(LocalDate.of(2021, 1, 1))) * // SELECT DAYOFWEEK('2021-01-01') FROM date_time * }}} - * + * * @param date * The date or date-time expression from which to extract the day of the week. */ def DAYOFWEEK(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"DAYOFWEEK('${date.toString}')") + /** + * A function that returns the day of the year for date, in the range 1 to 366. + * The range of DAYOFYEAR() is 1 to 366 because MySQL supports leap year. + * + * {{{ + * TableQuery[DateTime].select(p => DAYOFYEAR(p.birthDate)) + * // SELECT DAYOFYEAR(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the day of the year. + */ + def DAYOFYEAR[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFYEAR(${column.name})") + + /** + * A function that returns the day of the year for date, in the range 1 to 366. + * The range of DAYOFYEAR() is 1 to 366 because MySQL supports leap year. + * + * {{{ + * TableQuery[DateTime].select(_ => DAYOFYEAR(LocalDate.of(2021, 1, 1))) + * // SELECT DAYOFYEAR('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the day of the year. + */ + def DAYOFYEAR(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFYEAR('${date.toString}')") + object DateTime: /** From 3ec89f6710a33f5e231f6a2a16d76c827edc8aa6 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:49:16 +0900 Subject: [PATCH 28/74] Create DateTime DAYOFYEAR Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 17902aad7..ca8ba1d93 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -111,3 +111,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DAYOFWEEK(c6).name == "DAYOFWEEK(local_date_time)") assert(DAYOFWEEK(LocalDate.of(2025, 1, 1)).name == "DAYOFWEEK('2025-01-01')") } + + it should "Statement generated using the DAYOFYEAR function matches the specified string." in { + assert(DAYOFYEAR(c5).name == "DAYOFYEAR(local_date_time)") + assert(DAYOFYEAR(c6).name == "DAYOFYEAR(local_date_time)") + assert(DAYOFYEAR(LocalDate.of(2025, 1, 1)).name == "DAYOFYEAR('2025-01-01')") + } From 439f40344366d1cc2e727605f4a0dfb08c08ffa2 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:58:46 +0900 Subject: [PATCH 29/74] Added EXTRACT functions --- .../ldbc/statement/functions/DateTime.scala | 48 +++++++++++++++++-- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index f30fc56c7..e8945dde3 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -448,7 +448,7 @@ trait DateTime: * TableQuery[DateTime].select(p => DAYOFYEAR(p.birthDate)) * // SELECT DAYOFYEAR(birth_date) FROM date_time * }}} - * + * * @param column * The date or date-time column from which to extract the day of the year. */ @@ -463,18 +463,54 @@ trait DateTime: /** * A function that returns the day of the year for date, in the range 1 to 366. * The range of DAYOFYEAR() is 1 to 366 because MySQL supports leap year. - * + * * {{{ * TableQuery[DateTime].select(_ => DAYOFYEAR(LocalDate.of(2021, 1, 1))) * // SELECT DAYOFYEAR('2021-01-01') FROM date_time * }}} - * + * * @param date * The date or date-time expression from which to extract the day of the year. */ def DAYOFYEAR(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"DAYOFYEAR('${date.toString}')") + /** + * A function that returns the time part of the expression expr as a time value. + * + * {{{ + * TableQuery[DateTime].select(p => EXTRACT(p.timestamp, DateTime.TimeUnit.HOUR)) + * // SELECT EXTRACT(HOUR FROM timestamp) FROM date_time + * }}} + * @param column + * The column from which to extract the time part. + * @param timeUnit + * The time unit to be extracted. + */ + def EXTRACT[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( + column: Column[A], + timeUnit: DateTime.TimeUnit + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"EXTRACT(${timeUnit.toString} FROM ${column.name})") + + /** + * A function that returns the time part of the expression expr as a time value. + * + * {{{ + * TableQuery[DateTime].select(_ => EXTRACT(LocalDateTime.of(2021, 1, 1, 0, 0), DateTime.TimeUnit.HOUR)) + * // SELECT EXTRACT(HOUR FROM '2021-01-01T00:00') FROM date_time + * }}} + * @param date + * The date or date-time expression from which to extract the time part. + * @param timeUnit + * The time unit to be extracted. + */ + def EXTRACT( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, + timeUnit: DateTime.TimeUnit + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"EXTRACT(${timeUnit.toString} FROM '${date.toString.replaceAll("T", " ")}')") + object DateTime: /** @@ -508,3 +544,9 @@ object DateTime: case DAY_MINUTE(expr: String) extends Interval(expr, "DAY_MINUTE") case DAY_HOUR(expr: String) extends Interval(expr, "DAY_HOUR") case YEAR_MONTH(expr: YearMonth) extends Interval(expr, "YEAR_MONTH") + + /** + * Time unit for the INTERVAL expression. + */ + enum TimeUnit: + case MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR, SECOND_MICROSECOND, MINUTE_MICROSECOND, MINUTE_SECOND, HOUR_MICROSECOND, HOUR_SECOND, HOUR_MINUTE, DAY_MICROSECOND, DAY_SECOND, DAY_MINUTE, DAY_HOUR, YEAR_MONTH From a14d78858eb9e1d15c94e17900766821a5542ad5 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 00:58:54 +0900 Subject: [PATCH 30/74] Create DateTime EXTRACT Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index ca8ba1d93..5461b37b3 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -117,3 +117,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(DAYOFYEAR(c6).name == "DAYOFYEAR(local_date_time)") assert(DAYOFYEAR(LocalDate.of(2025, 1, 1)).name == "DAYOFYEAR('2025-01-01')") } + + it should "Statement generated using the EXTRACT function matches the specified string." in { + assert(EXTRACT(c5, TimeUnit.YEAR).name == "EXTRACT(YEAR FROM local_date_time)") + assert(EXTRACT(c6, TimeUnit.MONTH).name == "EXTRACT(MONTH FROM local_date_time)") + assert(EXTRACT(LocalDate.of(2025, 1, 1), TimeUnit.HOUR).name == "EXTRACT(HOUR FROM '2025-01-01')") + } From 7b3f74474158669e602078c0418b0cf1271935f2 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 01:05:17 +0900 Subject: [PATCH 31/74] Added FROM_DAYS functions --- .../ldbc/statement/functions/DateTime.scala | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index e8945dde3..c2fc4919e 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -511,6 +511,42 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"EXTRACT(${timeUnit.toString} FROM '${date.toString.replaceAll("T", " ")}')") + /** + * Function to convert a day value to a date. + * + * Use FROM_DAYS() carefully with older dates. It is not designed to be used with values prior to the advent of the Gregorian calendar (1582). + * + * @see https://dev.mysql.com/doc/refman/8.0/ja/mysql-calendar.html + * + * {{{ + * TableQuery[DateTime].select(p => FROM_DAYS(p.birthDate)) + * // SELECT FROM_DAYS(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the date. + */ + def FROM_DAYS[A <: Int | Long | Option[Int | Long]](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"FROM_DAYS(${column.name})") + + /** + * Function to convert a day value to a date. + * + * Use FROM_DAYS() carefully with older dates. It is not designed to be used with values prior to the advent of the Gregorian calendar (1582). + * + * @see https://dev.mysql.com/doc/refman/8.0/ja/mysql-calendar.html + * + * {{{ + * TableQuery[DateTime].select(_ => FROM_DAYS(730669)) + * // SELECT FROM_DAYS(730669) FROM date_time + * }}} + * + * @param days + * The number of days from which to extract the date. + */ + def FROM_DAYS[A <: Int | Long | Option[Int | Long]](days: A)(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"FROM_DAYS($days)") + object DateTime: /** From 0a5c8485b57e3c21cc1e70851106c92d54e31be9 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 01:05:27 +0900 Subject: [PATCH 32/74] Create DateTime FROM_DAYS Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 5461b37b3..4d86155db 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -21,6 +21,8 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c4 = Column.Impl[Option[LocalTime]]("local_time") private val c5 = Column.Impl[LocalDateTime]("local_date_time") private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") + private val c7 = Column.Impl[Int]("days") + private val c8 = Column.Impl[Option[Int]]("days") it should "Statement generated using the DATE_ADD function matches the specified string." in { assert(DATE_ADD(c1, Interval.DAY(1)).name == "DATE_ADD(local_date, INTERVAL 1 DAY)") @@ -123,3 +125,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(EXTRACT(c6, TimeUnit.MONTH).name == "EXTRACT(MONTH FROM local_date_time)") assert(EXTRACT(LocalDate.of(2025, 1, 1), TimeUnit.HOUR).name == "EXTRACT(HOUR FROM '2025-01-01')") } + + it should "Statement generated using the FROM_DAYS function matches the specified string." in { + assert(FROM_DAYS(c7).name == "FROM_DAYS(days)") + assert(FROM_DAYS(c8).name == "FROM_DAYS(days)") + assert(FROM_DAYS(730669).name == "FROM_DAYS(730669)") + } From ad9e9616045d10eaf62133254d1c973f343f8148 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 01:05:59 +0900 Subject: [PATCH 33/74] Action sbt scalafmtAll --- .../ldbc/statement/functions/DateTime.scala | 63 ++++++++++++------- 1 file changed, 40 insertions(+), 23 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c2fc4919e..3aefc6a83 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -369,7 +369,9 @@ trait DateTime: * @param date * The date or date-time expression from which to extract the day of the week. */ - def DAYNAME(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[String], Encoder[String]): Column[String] = + def DAYNAME( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[String], Encoder[String]): Column[String] = Column(s"DAYNAME('${ date.toString }')") /** @@ -402,7 +404,9 @@ trait DateTime: * @param date * The date or date-time expression from which to extract the day of the month. */ - def DAYOFMONTH(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = + def DAYOFMONTH( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"DAYOFMONTH('${ date.toString }')") /** @@ -421,9 +425,9 @@ trait DateTime: A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] ]( - column: Column[A] - )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DAYOFWEEK(${column.name})") + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFWEEK(${ column.name })") /** * A function that returns the day of the week for date, in the range 1 to 7, where 1 represents Sunday. @@ -437,8 +441,10 @@ trait DateTime: * @param date * The date or date-time expression from which to extract the day of the week. */ - def DAYOFWEEK(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DAYOFWEEK('${date.toString}')") + def DAYOFWEEK( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFWEEK('${ date.toString }')") /** * A function that returns the day of the year for date, in the range 1 to 366. @@ -456,9 +462,9 @@ trait DateTime: A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] ]( - column: Column[A] - )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DAYOFYEAR(${column.name})") + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFYEAR(${ column.name })") /** * A function that returns the day of the year for date, in the range 1 to 366. @@ -472,8 +478,10 @@ trait DateTime: * @param date * The date or date-time expression from which to extract the day of the year. */ - def DAYOFYEAR(date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"DAYOFYEAR('${date.toString}')") + def DAYOFYEAR( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"DAYOFYEAR('${ date.toString }')") /** * A function that returns the time part of the expression expr as a time value. @@ -487,11 +495,14 @@ trait DateTime: * @param timeUnit * The time unit to be extracted. */ - def EXTRACT[A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime]]( - column: Column[A], - timeUnit: DateTime.TimeUnit + def EXTRACT[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A], + timeUnit: DateTime.TimeUnit )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"EXTRACT(${timeUnit.toString} FROM ${column.name})") + Column(s"EXTRACT(${ timeUnit.toString } FROM ${ column.name })") /** * A function that returns the time part of the expression expr as a time value. @@ -506,10 +517,10 @@ trait DateTime: * The time unit to be extracted. */ def EXTRACT( - date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, - timeUnit: DateTime.TimeUnit + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime, + timeUnit: DateTime.TimeUnit )(using Decoder[Int], Encoder[Int]): Column[Int] = - Column(s"EXTRACT(${timeUnit.toString} FROM '${date.toString.replaceAll("T", " ")}')") + Column(s"EXTRACT(${ timeUnit.toString } FROM '${ date.toString.replaceAll("T", " ") }')") /** * Function to convert a day value to a date. @@ -526,8 +537,10 @@ trait DateTime: * @param column * The column from which to extract the date. */ - def FROM_DAYS[A <: Int | Long | Option[Int | Long]](column: Column[A])(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = - Column(s"FROM_DAYS(${column.name})") + def FROM_DAYS[A <: Int | Long | Option[Int | Long]]( + column: Column[A] + )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"FROM_DAYS(${ column.name })") /** * Function to convert a day value to a date. @@ -544,7 +557,9 @@ trait DateTime: * @param days * The number of days from which to extract the date. */ - def FROM_DAYS[A <: Int | Long | Option[Int | Long]](days: A)(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + def FROM_DAYS[A <: Int | Long | Option[Int | Long]]( + days: A + )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"FROM_DAYS($days)") object DateTime: @@ -585,4 +600,6 @@ object DateTime: * Time unit for the INTERVAL expression. */ enum TimeUnit: - case MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR, SECOND_MICROSECOND, MINUTE_MICROSECOND, MINUTE_SECOND, HOUR_MICROSECOND, HOUR_SECOND, HOUR_MINUTE, DAY_MICROSECOND, DAY_SECOND, DAY_MINUTE, DAY_HOUR, YEAR_MONTH + case MICROSECOND, SECOND, MINUTE, HOUR, DAY, WEEK, MONTH, QUARTER, YEAR, SECOND_MICROSECOND, MINUTE_MICROSECOND, + MINUTE_SECOND, HOUR_MICROSECOND, HOUR_SECOND, HOUR_MINUTE, DAY_MICROSECOND, DAY_SECOND, DAY_MINUTE, DAY_HOUR, + YEAR_MONTH From 5a725d5eb7ee3379adc8107b5ea2de0cfba83ba8 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 20:44:18 +0900 Subject: [PATCH 34/74] Added FROM_UNIXTIME functions --- .../ldbc/statement/functions/DateTime.scala | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 3aefc6a83..5e6d483bb 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -562,6 +562,36 @@ trait DateTime: )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"FROM_DAYS($days)") + /** + * Function to generate a UTC date in YYYYY-MM-DD hh:mm:ss format from a number. + * + * {{{ + * TableQuery[DateTime].select(p => FROM_UNIXTIME(p.birthDate)) + * // SELECT FROM_UNIXTIME(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the date. + */ + def FROM_UNIXTIME[A <: Int | Long | Option[Int | Long]]( + column: Column[A] + )(using Decoder[LocalDateTime], Encoder[LocalDateTime]): Column[LocalDateTime] = + Column(s"FROM_UNIXTIME(${ column.name })") + + /** + * Function to generate a UTC date in YYYYY-MM-DD hh:mm:ss format from a number. + * + * {{{ + * TableQuery[DateTime].select(_ => FROM_UNIXTIME(1612137600)) + * // SELECT FROM_UNIXTIME(1612137600) FROM date_time + * }}} + * + * @param timestamp + * The number from which to extract the date. + */ + def FROM_UNIXTIME(timestamp: Int | Long)(using Decoder[String], Encoder[String]): Column[String] = + Column(s"FROM_UNIXTIME($timestamp)") + object DateTime: /** From ec907ab0ff911b3fe22615066e272e016f795d86 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 20:44:24 +0900 Subject: [PATCH 35/74] Create DateTime FROM_UNIXTIME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 4d86155db..899146f1a 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -131,3 +131,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(FROM_DAYS(c8).name == "FROM_DAYS(days)") assert(FROM_DAYS(730669).name == "FROM_DAYS(730669)") } + + it should "Statement generated using the FROM_UNIXTIME function matches the specified string." in { + assert(FROM_UNIXTIME(c7).name == "FROM_UNIXTIME(days)") + assert(FROM_UNIXTIME(c8).name == "FROM_UNIXTIME(days)") + assert(FROM_UNIXTIME(730669).name == "FROM_UNIXTIME(730669)") + } From 574983da9f6531373a076a7f25ed2fec29e63844 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:00:46 +0900 Subject: [PATCH 36/74] Added HOUR functions --- .../ldbc/statement/functions/DateTime.scala | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 5e6d483bb..be4619d54 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -592,6 +592,42 @@ trait DateTime: def FROM_UNIXTIME(timestamp: Int | Long)(using Decoder[String], Encoder[String]): Column[String] = Column(s"FROM_UNIXTIME($timestamp)") + /** + * Function for extracting time-only values from date types. + * The range of returned values is from 0 to 23 for date-time values. However, since the range of TIME values is actually much larger, HOUR can return values greater than 23. + * + * {{{ + * TableQuery[DateTime].select(p => HOUR(p.birthDate)) + * // SELECT HOUR(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the hour. + */ + def HOUR[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"HOUR(${ column.name })") + + /** + * Function for extracting time-only values from date types. + * The range of returned values is from 0 to 23 for date-time values. However, since the range of TIME values is actually much larger, HOUR can return values greater than 23. + * + * {{{ + * TableQuery[DateTime].select(_ => HOUR(LocalTime.of(1, 1, 1, 1))) + * // SELECT HOUR('01:01:01.000000001') FROM date_time + * }}} + * @param date + * The date or date-time expression from which to extract the hour. + */ + def HOUR( + date: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"HOUR('${ date.toString.replaceAll("T", " ") }')") + object DateTime: /** From e0180280d0724cb63de24e9b53a6e9491ffcdbf0 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:00:54 +0900 Subject: [PATCH 37/74] Create DateTime HOUR Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 899146f1a..7d077a769 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -137,3 +137,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(FROM_UNIXTIME(c8).name == "FROM_UNIXTIME(days)") assert(FROM_UNIXTIME(730669).name == "FROM_UNIXTIME(730669)") } + + it should "Statement generated using the HOUR function matches the specified string." in { + assert(HOUR(c5).name == "HOUR(local_date_time)") + assert(HOUR(c6).name == "HOUR(local_date_time)") + assert(HOUR(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "HOUR('2021-01-01 00:00')") + } From 142cc9625d6630075f4d1b11ae3944ec1f6c4fd8 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:05:14 +0900 Subject: [PATCH 38/74] Added LAST_DAY functions --- .../ldbc/statement/functions/DateTime.scala | 41 +++++++++++++++++-- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index be4619d54..7cb13d691 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -595,12 +595,12 @@ trait DateTime: /** * Function for extracting time-only values from date types. * The range of returned values is from 0 to 23 for date-time values. However, since the range of TIME values is actually much larger, HOUR can return values greater than 23. - * + * * {{{ * TableQuery[DateTime].select(p => HOUR(p.birthDate)) * // SELECT HOUR(birth_date) FROM date_time * }}} - * + * * @param column * The column from which to extract the hour. */ @@ -615,7 +615,7 @@ trait DateTime: /** * Function for extracting time-only values from date types. * The range of returned values is from 0 to 23 for date-time values. However, since the range of TIME values is actually much larger, HOUR can return values greater than 23. - * + * * {{{ * TableQuery[DateTime].select(_ => HOUR(LocalTime.of(1, 1, 1, 1))) * // SELECT HOUR('01:01:01.000000001') FROM date_time @@ -628,6 +628,41 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"HOUR('${ date.toString.replaceAll("T", " ") }')") + /** + * Function that returns the value corresponding to the last day of the month from a date or date-time value. + * + * {{{ + * TableQuery[DateTime].select(p => LAST_DAY(p.birthDate)) + * // SELECT LAST_DAY(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the last day of the month. + */ + def LAST_DAY[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"LAST_DAY(${ column.name })") + + /** + * Function that returns the value corresponding to the last day of the month from a date or date-time value. + * + * {{{ + * TableQuery[DateTime].select(_ => LAST_DAY(LocalDate.of(2021, 1, 1))) + * // SELECT LAST_DAY('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the last day of the month. + */ + def LAST_DAY( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + Column(s"LAST_DAY('${ date.toString }')") + object DateTime: /** From d41ee610b5010e7f9c8bbdcda4c07263e31e4189 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:05:22 +0900 Subject: [PATCH 39/74] Create DateTime LAST_DAY Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 7d077a769..37028295f 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -143,3 +143,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(HOUR(c6).name == "HOUR(local_date_time)") assert(HOUR(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "HOUR('2021-01-01 00:00')") } + + it should "Statement generated using the LAST_DAY function matches the specified string." in { + assert(LAST_DAY(c5).name == "LAST_DAY(local_date_time)") + assert(LAST_DAY(c6).name == "LAST_DAY(local_date_time)") + assert(LAST_DAY(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "LAST_DAY('2021-01-01T00:00')") + } From b1d3f061bd19b568d570bddf8ecbf8651172743f Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:16:00 +0900 Subject: [PATCH 40/74] Added MAKEDATE functions --- .../ldbc/statement/functions/DateTime.scala | 41 ++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 7cb13d691..e62c3e3ec 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -654,7 +654,7 @@ trait DateTime: * TableQuery[DateTime].select(_ => LAST_DAY(LocalDate.of(2021, 1, 1))) * // SELECT LAST_DAY('2021-01-01') FROM date_time * }}} - * + * * @param date * The date or date-time expression from which to extract the last day of the month. */ @@ -663,6 +663,45 @@ trait DateTime: )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = Column(s"LAST_DAY('${ date.toString }')") + /** + * Function to return a date calculated from a given year and annual total. + * + * {{{ + * TableQuery[DateTime].select(p => MAKEDATE(p.birthDate, 1)) + * // SELECT MAKEDATE(birth_date, 1) FROM date_time + * }}} + * + * @param column + * The column from which to calculate the date. + * @param day + * The annual total from which to calculate the date. + * The annual total must be greater than 0. + */ + def MAKEDATE[A <: Year | Option[Year]]( + column: Column[A], + day: Int + )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + require(day > 0, "The annual total must be greater than 0.") + Column(s"MAKEDATE(${ column.name }, $day)") + + /** + * Function to return a date calculated from a given year and annual total. + * + * {{{ + * TableQuery[DateTime].select(p => MAKEDATE(2021, 1)) + * // SELECT MAKEDATE(2021, 1) FROM date_time + * }}} + * + * @param year + * The year from which to calculate the date. + * @param day + * The annual total from which to calculate the date. + * The annual total must be greater than 0. + */ + def MAKEDATE(year: Int | Year, day: Int)(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = + require(day > 0, "The annual total must be greater than 0.") + Column(s"MAKEDATE($year, $day)") + object DateTime: /** From d2960c565dee3ec395edaa815bcfe8cccb346b2e Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:16:06 +0900 Subject: [PATCH 41/74] Create DateTime MAKEDATE Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 37028295f..866bbedf4 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -23,6 +23,8 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") private val c7 = Column.Impl[Int]("days") private val c8 = Column.Impl[Option[Int]]("days") + private val c9 = Column.Impl[Year]("year") + private val c10 = Column.Impl[Option[Year]]("year") it should "Statement generated using the DATE_ADD function matches the specified string." in { assert(DATE_ADD(c1, Interval.DAY(1)).name == "DATE_ADD(local_date, INTERVAL 1 DAY)") @@ -149,3 +151,10 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(LAST_DAY(c6).name == "LAST_DAY(local_date_time)") assert(LAST_DAY(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "LAST_DAY('2021-01-01T00:00')") } + + it should "Statement generated using the MAKEDATE function matches the specified string." in { + assert(MAKEDATE(c9, 31).name == "MAKEDATE(year, 31)") + assert(MAKEDATE(c10, 64).name == "MAKEDATE(year, 64)") + assert(MAKEDATE(2025, 103).name == "MAKEDATE(2025, 103)") + assert(MAKEDATE(Year.of(2025), 103).name == "MAKEDATE(2025, 103)") + } From 5ddccc49c453eaece75865071e7f6621866127aa Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:28:38 +0900 Subject: [PATCH 42/74] Added MAKETIME functions --- .../ldbc/statement/functions/DateTime.scala | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index e62c3e3ec..dac7cfa1b 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -702,6 +702,56 @@ trait DateTime: require(day > 0, "The annual total must be greater than 0.") Column(s"MAKEDATE($year, $day)") + /** + * Function to return a time value calculated from the given hour, minute, and second. + * The range of the hour is 0 to 23, the range of the minute is 0 to 59, and the range of the second is 0 to 59. + * + * {{{ + * TableQuery[DateTime].select(p => MAKETIME(p.hour, p.minute, p.second)) + * // SELECT MAKETIME(hour, minute, second) FROM date_time + * }}} + * + * @param hour + * The hour from which to calculate the time. + * @param minute + * The minute from which to calculate the time. + * @param second + * The second from which to calculate the time. + */ + def MAKETIME[ + A <: Int | Long | Option[Int | Long], + B <: Int | Long | Option[Int | Long], + C <: Int | Long | Option[Int | Long] + ]( + hour: Column[A], + minute: Column[B], + second: Column[C] + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"MAKETIME(${hour.name}, ${minute.name}, ${second.name})") + + /** + * Function to return a time value calculated from the given hour, minute, and second. + * The range of the hour is 0 to 23, the range of the minute is 0 to 59, and the range of the second is 0 to 59. + * + * {{{ + * TableQuery[DateTime].select(_ => MAKETIME(1, 1, 1)) + * // SELECT MAKETIME(1, 1, 1) FROM date_time + * }}} + * + * @param hour + * The hour from which to calculate the time. + * @param minute + * The minute from which to calculate the time. + * @param second + * The second from which to calculate the time. + */ + def MAKETIME( + hour: Int | Long, + minute: Int | Long, + second: Int | Long + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"MAKETIME($hour, $minute, $second)") + object DateTime: /** From 2d06f50d080e7eb306ad2019e7fc57193c3ce3df Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:28:45 +0900 Subject: [PATCH 43/74] Create DateTime MAKETIME Test --- .../ldbc/statement/functions/DateTimeTest.scala | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 866bbedf4..2c3d4e39f 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -25,6 +25,12 @@ class DateTimeTest extends AnyFlatSpec, DateTime: private val c8 = Column.Impl[Option[Int]]("days") private val c9 = Column.Impl[Year]("year") private val c10 = Column.Impl[Option[Year]]("year") + private val c11 = Column.Impl[Int]("hour") + private val c12 = Column.Impl[Option[Int]]("hour") + private val c13 = Column.Impl[Int]("minute") + private val c14 = Column.Impl[Option[Int]]("minute") + private val c15 = Column.Impl[Int]("second") + private val c16 = Column.Impl[Option[Int]]("second") it should "Statement generated using the DATE_ADD function matches the specified string." in { assert(DATE_ADD(c1, Interval.DAY(1)).name == "DATE_ADD(local_date, INTERVAL 1 DAY)") @@ -158,3 +164,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MAKEDATE(2025, 103).name == "MAKEDATE(2025, 103)") assert(MAKEDATE(Year.of(2025), 103).name == "MAKEDATE(2025, 103)") } + + it should "Statement generated using the MAKETIME function matches the specified string." in { + assert(MAKETIME(c11, c13, c15).name == "MAKETIME(hour, minute, second)") + assert(MAKETIME(c12, c14, c16).name == "MAKETIME(hour, minute, second)") + assert(MAKETIME(24, 59, 59).name == "MAKETIME(24, 59, 59)") + } From 368830046ef95c4019223506c18146f7f123339f Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:34:00 +0900 Subject: [PATCH 44/74] Added MICROSECOND functions --- .../ldbc/statement/functions/DateTime.scala | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index dac7cfa1b..c3395b00f 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -752,6 +752,41 @@ trait DateTime: )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"MAKETIME($hour, $minute, $second)") + /** + * Function that returns microseconds from a time or date-time expression as a number in the range 0 to 999999. + * + * {{{ + * TableQuery[DateTime].select(p => MICROSECOND(p.birthDate)) + * // SELECT MICROSECOND(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the microseconds. + */ + def MICROSECOND[ + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MICROSECOND(${ column.name })") + + /** + * Function that returns microseconds from a time or date-time expression as a number in the range 0 to 999999. + * + * {{{ + * TableQuery[DateTime].select(_ => MICROSECOND(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT MICROSECOND('2021-01-01 00:00') FROM date_time + * }}} + * + * @param datetime + * The date or date-time expression from which to extract the microseconds. + */ + def MICROSECOND( + datetime: LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MICROSECOND('${ datetime.toString.replaceAll("T", " ") }')") + object DateTime: /** From b3d7a8e70785283ef316f106b766af705cf44039 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:34:06 +0900 Subject: [PATCH 45/74] Create DateTime MICROSECOND Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 2c3d4e39f..1ac7060ed 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -170,3 +170,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MAKETIME(c12, c14, c16).name == "MAKETIME(hour, minute, second)") assert(MAKETIME(24, 59, 59).name == "MAKETIME(24, 59, 59)") } + + it should "Statement generated using the MICROSECOND function matches the specified string." in { + assert(MICROSECOND(c5).name == "MICROSECOND(local_date_time)") + assert(MICROSECOND(c6).name == "MICROSECOND(local_date_time)") + assert(MICROSECOND(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MICROSECOND('2021-01-01 00:00')") + } From a5431b6d2c955b5713c284b5623e224637269904 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:39:59 +0900 Subject: [PATCH 46/74] Added MINUTE functions --- .../ldbc/statement/functions/DateTime.scala | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index c3395b00f..f2f32961d 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -787,6 +787,43 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"MICROSECOND('${ datetime.toString.replaceAll("T", " ") }')") + /** + * Function that returns the minute part of a date or date-time expression. + * The range of the minute is 0 to 59. + * + * {{{ + * TableQuery[DateTime].select(p => MINUTE(p.birthDate)) + * // SELECT MINUTE(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the minute. + */ + def MINUTE[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MINUTE(${ column.name })") + + /** + * Function that returns the minute part of a date or date-time expression. + * The range of the minute is 0 to 59. + * + * {{{ + * TableQuery[DateTime].select(_ => MINUTE(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT MINUTE('2021-01-01 00:00') FROM date_time + * }}} + * + * @param time + * The date or date-time expression from which to extract the minute. + */ + def MINUTE( + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MINUTE('${ time.toString.replaceAll("T", " ") }')") + object DateTime: /** From 3e26b77dbba26e89df2e723b010dd558f433e806 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 21:40:06 +0900 Subject: [PATCH 47/74] Create DateTime MINUTE Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 1ac7060ed..f670e94ef 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -176,3 +176,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MICROSECOND(c6).name == "MICROSECOND(local_date_time)") assert(MICROSECOND(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MICROSECOND('2021-01-01 00:00')") } + + it should "Statement generated using the MINUTE function matches the specified string." in { + assert(MINUTE(c5).name == "MINUTE(local_date_time)") + assert(MINUTE(c6).name == "MINUTE(local_date_time)") + assert(MINUTE(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MINUTE('2021-01-01 00:00')") + } From 73353efc7de66eccb2c1aeac024c400cce1b9505 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 23:00:56 +0900 Subject: [PATCH 48/74] Added MONTH functions --- .../ldbc/statement/functions/DateTime.scala | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index f2f32961d..e41d74dc8 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -824,6 +824,43 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"MINUTE('${ time.toString.replaceAll("T", " ") }')") + /** + * Function that returns the month part of a date or date-time expression. + * The range of the month is 1 to 12. + * + * {{{ + * TableQuery[DateTime].select(p => MONTH(p.birthDate)) + * // SELECT MONTH(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the month. + */ + def MONTH[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MONTH(${ column.name })") + + /** + * Function that returns the month part of a date or date-time expression. + * The range of the month is 1 to 12. + * + * {{{ + * TableQuery[DateTime].select(_ => MONTH(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT MONTH('2021-01-01 00:00') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the month. + */ + def MONTH( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"MONTH('${ date.toString.replaceAll("T", " ") }')") + object DateTime: /** From e74da607326c56aa071e41c514c62294ed9cb002 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Mon, 20 Jan 2025 23:01:03 +0900 Subject: [PATCH 49/74] Create DateTime MONTH Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index f670e94ef..1d6d35d7d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -182,3 +182,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MINUTE(c6).name == "MINUTE(local_date_time)") assert(MINUTE(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MINUTE('2021-01-01 00:00')") } + + it should "Statement generated using the MONTH function matches the specified string." in { + assert(MONTH(c5).name == "MONTH(local_date_time)") + assert(MONTH(c6).name == "MONTH(local_date_time)") + assert(MONTH(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MONTH('2021-01-01 00:00')") + } From a995c26be984b407a3035a3aa86782bb3c1cee0f Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 17:33:13 +0900 Subject: [PATCH 50/74] Added MONTHNAME functions --- .../ldbc/statement/functions/DateTime.scala | 53 ++++++++++++++++--- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index e41d74dc8..7b20095e0 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -232,7 +232,7 @@ trait DateTime: /** * Function to format a date value according to the format string. - * @see https://dev.mysql.com/doc/refman/8.0/ja/date-and-time-functions.html#function_date-format + * @see https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_date-format * * {{{ * TableQuery[DateTime].select(p => DATE_FORMAT(p.timestamp, "%Y-%m-%d")) @@ -337,7 +337,7 @@ trait DateTime: /** * A function that returns the name of the day of the week corresponding to date. * The language used for the names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). - * @see https://dev.mysql.com/doc/refman/8.0/ja/locale-support.html + * @see https://dev.mysql.com/doc/refman/8.0/en/locale-support.html * * {{{ * TableQuery[DateTime].select(p => DAYNAME(p.birthDate)) @@ -359,7 +359,7 @@ trait DateTime: * A function that returns the name of the day of the week corresponding to date. * The language used for the names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). * - * @see https://dev.mysql.com/doc/refman/8.0/ja/locale-support.html + * @see https://dev.mysql.com/doc/refman/8.0/en/locale-support.html * * {{{ * TableQuery[DateTime].select(_ => DAYNAME(LocalDate.of(2021, 1, 1))) @@ -527,7 +527,7 @@ trait DateTime: * * Use FROM_DAYS() carefully with older dates. It is not designed to be used with values prior to the advent of the Gregorian calendar (1582). * - * @see https://dev.mysql.com/doc/refman/8.0/ja/mysql-calendar.html + * @see https://dev.mysql.com/doc/refman/8.0/en/mysql-calendar.html * * {{{ * TableQuery[DateTime].select(p => FROM_DAYS(p.birthDate)) @@ -547,7 +547,7 @@ trait DateTime: * * Use FROM_DAYS() carefully with older dates. It is not designed to be used with values prior to the advent of the Gregorian calendar (1582). * - * @see https://dev.mysql.com/doc/refman/8.0/ja/mysql-calendar.html + * @see https://dev.mysql.com/doc/refman/8.0/en/mysql-calendar.html * * {{{ * TableQuery[DateTime].select(_ => FROM_DAYS(730669)) @@ -861,12 +861,53 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"MONTH('${ date.toString.replaceAll("T", " ") }')") + /** + * Function to return the full name of the month corresponding to a value of type Date. + * The language used for names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). + * + * @see https://dev.mysql.com/doc/refman/8.0/en/locale-support.html + * + * {{{ + * TableQuery[DateTime].select(p => MONTHNAME(p.birthDate)) + * // SELECT MONTHNAME(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the month name. + */ + def MONTHNAME[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[String], Encoder[String]): Column[String] = + Column(s"MONTHNAME(${ column.name })") + + /** + * Function to return the full name of the month corresponding to a value of type Date. + * The language used for names is controlled by the value of the lc_time_names system variable (Section 10.16, “Locale Support in MySQL Server”). + * + * @see https://dev.mysql.com/doc/refman/8.0/en/locale-support.html + * + * {{{ + * TableQuery[DateTime].select(_ => MONTHNAME(LocalDate.of(2021, 1, 1))) + * // SELECT MONTHNAME('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the month name. + */ + def MONTHNAME( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[String], Encoder[String]): Column[String] = + Column(s"MONTHNAME('${ date.toString }')") + object DateTime: /** * Extracts the date part of a date or datetime expression. * - * @see https://dev.mysql.com/doc/refman/8.0/ja/expressions.html#temporal-intervals + * @see https://dev.mysql.com/doc/refman/8.0/en/expressions.html#temporal-intervals * * {{{ * INTERVAL expr unit From 1ecec033ae35b0402177df05f8e6b0393b40f2c6 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 17:33:22 +0900 Subject: [PATCH 51/74] Create DateTime MONTHNAME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 1d6d35d7d..fe0e330af 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -188,3 +188,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MONTH(c6).name == "MONTH(local_date_time)") assert(MONTH(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MONTH('2021-01-01 00:00')") } + + it should "Statement generated using the MONTHNAME function matches the specified string." in { + assert(MONTHNAME(c5).name == "MONTHNAME(local_date_time)") + assert(MONTHNAME(c6).name == "MONTHNAME(local_date_time)") + assert(MONTHNAME(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MONTHNAME('2021-01-01T00:00')") + } From 82d569058c933819007c07349e39fdb0253e99d9 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 17:51:51 +0900 Subject: [PATCH 52/74] Added NOW functions --- .../main/scala/ldbc/statement/functions/DateTime.scala | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 7b20095e0..0a328b24f 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -902,6 +902,16 @@ trait DateTime: )(using Decoder[String], Encoder[String]): Column[String] = Column(s"MONTHNAME('${ date.toString }')") + /** + * Function to return the current date and time in 'YYYY-MM-DD hh:mm:ss' format. + * + * {{{ + * TableQuery[DateTime].select(_ => NOW) + * // SELECT NOW() FROM date_time + * }}} + */ + def NOW()(using Decoder[LocalDateTime], Encoder[LocalDateTime]): Column[LocalDateTime] = Column("NOW()") + object DateTime: /** From 4a99e929864a2f5f55b08a5b50f4283d34768972 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 17:51:57 +0900 Subject: [PATCH 53/74] Create DateTime NOW Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index fe0e330af..1c37ceb6d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -194,3 +194,7 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(MONTHNAME(c6).name == "MONTHNAME(local_date_time)") assert(MONTHNAME(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "MONTHNAME('2021-01-01T00:00')") } + + it should "Statement generated using the NOW function matches the specified string." in { + assert(NOW().name == "NOW()") + } From f452410b6e5d5dfc75f7d60a6e3f0f7a6f510ed8 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:41:00 +0900 Subject: [PATCH 54/74] Added PERIOD_ADD functions --- .../ldbc/statement/functions/DateTime.scala | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 0a328b24f..96634f53b 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -7,6 +7,7 @@ package ldbc.statement.functions import java.time.* +import java.time.format.DateTimeFormatter import ldbc.dsl.codec.* @@ -912,6 +913,23 @@ trait DateTime: */ def NOW()(using Decoder[LocalDateTime], Encoder[LocalDateTime]): Column[LocalDateTime] = Column("NOW()") + /** + * Function to add the specified month to the yyyyMM value. + * + * @param period + * The period in yyyyMM format. + * @param months + * The number of months to add. + */ + def PERIOD_ADD(period: YearMonth, months: Int): Column[YearMonth] = + val formatter = DateTimeFormatter.ofPattern("yyyyMM") + given Codec[YearMonth] = Codec[String].imap { str => + YearMonth.parse(str, formatter) + } { yearMonth => + yearMonth.format(formatter) + } + Column(s"PERIOD_ADD(${period.format(formatter)}, $months)") + object DateTime: /** From dcdf14a7e4bfdd01a44e77d6ac8c3c52eee8008a Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:41:06 +0900 Subject: [PATCH 55/74] Create DateTime PERIOD_ADD Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 1c37ceb6d..10a65b10e 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -198,3 +198,7 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the NOW function matches the specified string." in { assert(NOW().name == "NOW()") } + + it should "Statement generated using the PERIOD_ADD function matches the specified string." in { + assert(PERIOD_ADD(YearMonth.of(2025, 1), 1).name == "PERIOD_ADD(202501, 1)") + } From 70a83c1d8d76e78bdb5a3d27357bf248d9cfe7aa Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:45:36 +0900 Subject: [PATCH 56/74] Added QUARTER functions --- .../ldbc/statement/functions/DateTime.scala | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 96634f53b..4cbd56c6b 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -930,6 +930,41 @@ trait DateTime: } Column(s"PERIOD_ADD(${period.format(formatter)}, $months)") + /** + * Function to return the quarter corresponding to date in the range 1 to 4. + * + * {{{ + * TableQuery[DateTime].select(p => QUARTER(p.birthDate)) + * // SELECT QUARTER(birth_date) FROM date_time + * }}} + * + * @param column + * The date or date-time column from which to extract the quarter. + */ + def QUARTER[ + A <: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"QUARTER(${ column.name })") + + /** + * Function to return the quarter corresponding to date in the range 1 to 4. + * + * {{{ + * TableQuery[DateTime].select(_ => QUARTER(LocalDate.of(2021, 1, 1))) + * // SELECT QUARTER('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the quarter. + */ + def QUARTER( + date: LocalDate | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"QUARTER('${ date.toString }')") + object DateTime: /** From e06c0679ad1f9d3d1fa3908474e950af45f4c3d0 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:45:44 +0900 Subject: [PATCH 57/74] Create DateTime QUARTER Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 10a65b10e..fed74dff6 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -202,3 +202,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the PERIOD_ADD function matches the specified string." in { assert(PERIOD_ADD(YearMonth.of(2025, 1), 1).name == "PERIOD_ADD(202501, 1)") } + + it should "Statement generated using the QUARTER function matches the specified string." in { + assert(QUARTER(c5).name == "QUARTER(local_date_time)") + assert(QUARTER(c6).name == "QUARTER(local_date_time)") + assert(QUARTER(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "QUARTER('2021-01-01T00:00')") + } From 6f8cd87f4d412147da9958469f809469fc9b3bcd Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:56:33 +0900 Subject: [PATCH 58/74] Added SEC_TO_TIME functions --- .../ldbc/statement/functions/DateTime.scala | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 4cbd56c6b..2a9424b49 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -965,6 +965,35 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"QUARTER('${ date.toString }')") + /** + * Function to convert TIME values to hh:mm:ss format. + * + * {{{ + * TableQuery[DateTime].select(p => SEC_TO_TIME(p.seconds)) + * // SELECT SEC_TO_TIME(seconds) FROM date_time + * }}} + * + * @param column + * The column to be converted. + */ + def SEC_TO_TIME[A <: Long | Int | Option[Long | Int]](column: Column[A]): Column[LocalTime] = + given Codec[LocalTime] = Codec[Int].imap(LocalTime.ofSecondOfDay(_))(_.toSecondOfDay) + Column(s"SEC_TO_TIME(${column.name})") + + /** + * Function to convert TIME values to hh:mm:ss format. + * + * {{{ + * TableQuery[DateTime].select(_ => SEC_TO_TIME(3600)) + * // SELECT SEC_TO_TIME(3600) FROM date_time + * }}} + * @param seconds + * The number of seconds to be converted. + */ + def SEC_TO_TIME(seconds: Long): Column[LocalTime] = + given Codec[LocalTime] = Codec[Int].imap(LocalTime.ofSecondOfDay(_))(_.toSecondOfDay) + Column(s"SEC_TO_TIME($seconds)") + object DateTime: /** From 7691d2644776ace9ffcdfff678a925e448fa6213 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 18:56:39 +0900 Subject: [PATCH 59/74] Create DateTime SEC_TO_TIME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index fed74dff6..538a9d8e9 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -208,3 +208,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(QUARTER(c6).name == "QUARTER(local_date_time)") assert(QUARTER(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "QUARTER('2021-01-01T00:00')") } + + it should "Statement generated using the SEC_TO_TIME function matches the specified string." in { + assert(SEC_TO_TIME(c15).name == "SEC_TO_TIME(second)") + assert(SEC_TO_TIME(c16).name == "SEC_TO_TIME(second)") + assert(SEC_TO_TIME(2378).name == "SEC_TO_TIME(2378)") + } From 5cf3b68fd37c11df5a2c4edc9187b08477929b12 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 19:01:22 +0900 Subject: [PATCH 60/74] Added SECOND functions --- .../ldbc/statement/functions/DateTime.scala | 35 +++++++++++++++++++ .../statement/functions/DateTimeTest.scala | 6 ++++ 2 files changed, 41 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 2a9424b49..95f050312 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -994,6 +994,41 @@ trait DateTime: given Codec[LocalTime] = Codec[Int].imap(LocalTime.ofSecondOfDay(_))(_.toSecondOfDay) Column(s"SEC_TO_TIME($seconds)") + /** + * Function to return the second part of a date or date-time expression. + * + * {{{ + * TableQuery[DateTime].select(p => SECOND(p.birthDate)) + * // SELECT SECOND(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the second. + */ + def SECOND[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + column: Column[A] + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"SECOND(${ column.name })") + + /** + * Function to return the second part of a date or date-time expression. + * + * {{{ + * TableQuery[DateTime].select(_ => SECOND(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT SECOND('2021-01-01 00:00') FROM date_time + * }}} + * + * @param time + * The date or date-time expression from which to extract the second. + */ + def SECOND( + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Int], Encoder[Int]): Column[Int] = + Column(s"SECOND('${ time.toString.replaceAll("T", " ") }')") + object DateTime: /** diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 538a9d8e9..dd16050cc 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -214,3 +214,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(SEC_TO_TIME(c16).name == "SEC_TO_TIME(second)") assert(SEC_TO_TIME(2378).name == "SEC_TO_TIME(2378)") } + + it should "Statement generated using the SECOND function matches the specified string." in { + assert(SECOND(c5).name == "SECOND(local_date_time)") + assert(SECOND(c6).name == "SECOND(local_date_time)") + assert(SECOND(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "SECOND('2021-01-01 00:00')") + } From d0baea4ba726530d6cc15cc76a07d70dcae87e3e Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 19:09:52 +0900 Subject: [PATCH 61/74] Added SUBTIME functions --- .../ldbc/statement/functions/DateTime.scala | 50 +++++++++++++++++-- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 95f050312..367c2b090 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -996,12 +996,12 @@ trait DateTime: /** * Function to return the second part of a date or date-time expression. - * + * * {{{ * TableQuery[DateTime].select(p => SECOND(p.birthDate)) * // SELECT SECOND(birth_date) FROM date_time * }}} - * + * * @param column * The column from which to extract the second. */ @@ -1015,12 +1015,12 @@ trait DateTime: /** * Function to return the second part of a date or date-time expression. - * + * * {{{ * TableQuery[DateTime].select(_ => SECOND(LocalDateTime.of(2021, 1, 1, 0, 0))) * // SELECT SECOND('2021-01-01 00:00') FROM date_time * }}} - * + * * @param time * The date or date-time expression from which to extract the second. */ @@ -1029,6 +1029,48 @@ trait DateTime: )(using Decoder[Int], Encoder[Int]): Column[Int] = Column(s"SECOND('${ time.toString.replaceAll("T", " ") }')") + /** + * Function to calculate the difference time from a date/time or time type value. + * + * {{{ + * TableQuery[DateTime].select(p => SEC_TO_TIME(p.start, p.end)) + * // SELECT SEC_TO_TIME(start, end) FROM date_time + * }}} + * + * @param time + * The start time. + * @param interval + * The end time. + */ + def SUBTIME[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime], + B <: LocalTime | Option[LocalTime] + ]( + time: Column[A], + interval: Column[B] + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"SUBTIME(${time.name}, ${interval.name})") + + /** + * Function to calculate the difference time from a date/time or time type value. + * + * {{{ + * TableQuery[DateTime].select(_ => SUBTIME(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT SUBTIME('2021-01-01 00:00', '2021-01-01 00:00') FROM date_time + * }}} + * + * @param time + * The start time. + * @param interval + * The end time. + */ + def SUBTIME( + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, + interval: LocalTime + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"SUBTIME('${time.toString.replaceAll("T", " ")}', '${interval.toString}')") + object DateTime: /** From 8f666edb385151a8746e98ba7432f722b9bb8edc Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 19:10:07 +0900 Subject: [PATCH 62/74] Create DateTime SUBTIME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index dd16050cc..9761b8a46 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -220,3 +220,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(SECOND(c6).name == "SECOND(local_date_time)") assert(SECOND(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "SECOND('2021-01-01 00:00')") } + + it should "Statement generated using the SUBTIME function matches the specified string." in { + assert(SUBTIME(c5, c3).name == "SUBTIME(local_date_time, local_time)") + assert(SUBTIME(c6, c4).name == "SUBTIME(local_date_time, local_time)") + assert(SUBTIME(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(1, 1, 1, 1)).name == "SUBTIME('2021-01-01 00:00', '01:01:01.000000001')") + } From 914de6754561d15ca70c9509df06345eaa34e038 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 19:12:49 +0900 Subject: [PATCH 63/74] Added SYSDATE functions --- .../ldbc/statement/functions/DateTime.scala | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 367c2b090..e489e788f 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1031,12 +1031,12 @@ trait DateTime: /** * Function to calculate the difference time from a date/time or time type value. - * + * * {{{ * TableQuery[DateTime].select(p => SEC_TO_TIME(p.start, p.end)) * // SELECT SEC_TO_TIME(start, end) FROM date_time * }}} - * + * * @param time * The start time. * @param interval @@ -1054,12 +1054,12 @@ trait DateTime: /** * Function to calculate the difference time from a date/time or time type value. - * + * * {{{ * TableQuery[DateTime].select(_ => SUBTIME(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2021, 1, 1, 0, 0))) * // SELECT SUBTIME('2021-01-01 00:00', '2021-01-01 00:00') FROM date_time * }}} - * + * * @param time * The start time. * @param interval @@ -1071,6 +1071,16 @@ trait DateTime: )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"SUBTIME('${time.toString.replaceAll("T", " ")}', '${interval.toString}')") + /** + * Function to return the current date and time in 'YYYY-MM-DD hh:mm:ss' format. + * + * {{{ + * TableQuery[DateTime].select(_ => SYSDATE) + * // SELECT SYSDATE() FROM date_time + * }}} + */ + def SYSDATE()(using Decoder[LocalDateTime], Encoder[LocalDateTime]): Column[LocalDateTime] = Column("SYSDATE()") + object DateTime: /** From 212056de466725101e73e00190203ff10e093552 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Wed, 22 Jan 2025 19:12:55 +0900 Subject: [PATCH 64/74] Create DateTime SYSDATE Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 9761b8a46..395d5276a 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -226,3 +226,7 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(SUBTIME(c6, c4).name == "SUBTIME(local_date_time, local_time)") assert(SUBTIME(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(1, 1, 1, 1)).name == "SUBTIME('2021-01-01 00:00', '01:01:01.000000001')") } + + it should "Statement generated using the SYSDATE function matches the specified string." in { + assert(SYSDATE().name == "SYSDATE()") + } From 47f2ad5b47330ad200db927a34de2d96c0f9e87c Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 19:57:42 +0900 Subject: [PATCH 65/74] Added TIME functions --- .../ldbc/statement/functions/DateTime.scala | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index e489e788f..93ca2c9c9 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1081,6 +1081,34 @@ trait DateTime: */ def SYSDATE()(using Decoder[LocalDateTime], Encoder[LocalDateTime]): Column[LocalDateTime] = Column("SYSDATE()") + /** + * Function to extract only the time portion from a time or date-time expression value. + * + * {{{ + * TableQuery[DateTime].select(p => TIME(p.birthDate)) + * // SELECT TIME(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the time. + */ + def TIME[ A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]](column: Column[A])(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIME(${column.name})") + + /** + * Function to extract only the time portion from a time or date-time expression value. + * + * {{{ + * TableQuery[DateTime].select(_ => TIME(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT TIME('2021-01-01 00:00') FROM date_time + * }}} + * @param time + * The time or date-time expression from which to extract the time. + */ + def TIME(time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIME('${time.toString.replaceAll("T", " ")}')") + object DateTime: /** From 05b72fdf2097ca12e04f34c28faa7520eba07fee Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 19:57:49 +0900 Subject: [PATCH 66/74] Create DateTime TIME Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 395d5276a..5eb0892d9 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -230,3 +230,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the SYSDATE function matches the specified string." in { assert(SYSDATE().name == "SYSDATE()") } + + it should "Statement generated using the TIME function matches the specified string." in { + assert(TIME(c5).name == "TIME(local_date_time)") + assert(TIME(c6).name == "TIME(local_date_time)") + assert(TIME(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "TIME('2021-01-01 00:00')") + } From 572cb1ae0f8a2c7733a4b5f1e36e8af9c5ded0b9 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 19:58:18 +0900 Subject: [PATCH 67/74] Action sbt scalafmtAll --- .../ldbc/statement/functions/DateTime.scala | 37 ++++++++++--------- .../statement/functions/DateTimeTest.scala | 25 ++++++++----- 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 93ca2c9c9..6d96de407 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -680,7 +680,7 @@ trait DateTime: */ def MAKEDATE[A <: Year | Option[Year]]( column: Column[A], - day: Int + day: Int )(using Decoder[LocalDate], Encoder[LocalDate]): Column[LocalDate] = require(day > 0, "The annual total must be greater than 0.") Column(s"MAKEDATE(${ column.name }, $day)") @@ -724,11 +724,11 @@ trait DateTime: B <: Int | Long | Option[Int | Long], C <: Int | Long | Option[Int | Long] ]( - hour: Column[A], + hour: Column[A], minute: Column[B], second: Column[C] )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = - Column(s"MAKETIME(${hour.name}, ${minute.name}, ${second.name})") + Column(s"MAKETIME(${ hour.name }, ${ minute.name }, ${ second.name })") /** * Function to return a time value calculated from the given hour, minute, and second. @@ -747,7 +747,7 @@ trait DateTime: * The second from which to calculate the time. */ def MAKETIME( - hour: Int | Long, + hour: Int | Long, minute: Int | Long, second: Int | Long )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = @@ -765,8 +765,7 @@ trait DateTime: * The column from which to extract the microseconds. */ def MICROSECOND[ - A <: LocalDateTime | OffsetDateTime | ZonedDateTime | - Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime] ]( column: Column[A] )(using Decoder[Int], Encoder[Int]): Column[Int] = @@ -928,7 +927,7 @@ trait DateTime: } { yearMonth => yearMonth.format(formatter) } - Column(s"PERIOD_ADD(${period.format(formatter)}, $months)") + Column(s"PERIOD_ADD(${ period.format(formatter) }, $months)") /** * Function to return the quarter corresponding to date in the range 1 to 4. @@ -978,7 +977,7 @@ trait DateTime: */ def SEC_TO_TIME[A <: Long | Int | Option[Long | Int]](column: Column[A]): Column[LocalTime] = given Codec[LocalTime] = Codec[Int].imap(LocalTime.ofSecondOfDay(_))(_.toSecondOfDay) - Column(s"SEC_TO_TIME(${column.name})") + Column(s"SEC_TO_TIME(${ column.name })") /** * Function to convert TIME values to hh:mm:ss format. @@ -1047,10 +1046,10 @@ trait DateTime: Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime], B <: LocalTime | Option[LocalTime] ]( - time: Column[A], + time: Column[A], interval: Column[B] )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = - Column(s"SUBTIME(${time.name}, ${interval.name})") + Column(s"SUBTIME(${ time.name }, ${ interval.name })") /** * Function to calculate the difference time from a date/time or time type value. @@ -1066,10 +1065,10 @@ trait DateTime: * The end time. */ def SUBTIME( - time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime, interval: LocalTime )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = - Column(s"SUBTIME('${time.toString.replaceAll("T", " ")}', '${interval.toString}')") + Column(s"SUBTIME('${ time.toString.replaceAll("T", " ") }', '${ interval.toString }')") /** * Function to return the current date and time in 'YYYY-MM-DD hh:mm:ss' format. @@ -1092,9 +1091,11 @@ trait DateTime: * @param column * The column from which to extract the time. */ - def TIME[ A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | - Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime]](column: Column[A])(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = - Column(s"TIME(${column.name})") + def TIME[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ](column: Column[A])(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIME(${ column.name })") /** * Function to extract only the time portion from a time or date-time expression value. @@ -1106,8 +1107,10 @@ trait DateTime: * @param time * The time or date-time expression from which to extract the time. */ - def TIME(time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime)(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = - Column(s"TIME('${time.toString.replaceAll("T", " ")}')") + def TIME( + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIME('${ time.toString.replaceAll("T", " ") }')") object DateTime: diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 5eb0892d9..4aaf4300d 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -15,15 +15,15 @@ import ldbc.statement.Column class DateTimeTest extends AnyFlatSpec, DateTime: - private val c1 = Column.Impl[LocalDate]("local_date") - private val c2 = Column.Impl[Option[LocalDate]]("local_date") - private val c3 = Column.Impl[LocalTime]("local_time") - private val c4 = Column.Impl[Option[LocalTime]]("local_time") - private val c5 = Column.Impl[LocalDateTime]("local_date_time") - private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") - private val c7 = Column.Impl[Int]("days") - private val c8 = Column.Impl[Option[Int]]("days") - private val c9 = Column.Impl[Year]("year") + private val c1 = Column.Impl[LocalDate]("local_date") + private val c2 = Column.Impl[Option[LocalDate]]("local_date") + private val c3 = Column.Impl[LocalTime]("local_time") + private val c4 = Column.Impl[Option[LocalTime]]("local_time") + private val c5 = Column.Impl[LocalDateTime]("local_date_time") + private val c6 = Column.Impl[Option[LocalDateTime]]("local_date_time") + private val c7 = Column.Impl[Int]("days") + private val c8 = Column.Impl[Option[Int]]("days") + private val c9 = Column.Impl[Year]("year") private val c10 = Column.Impl[Option[Year]]("year") private val c11 = Column.Impl[Int]("hour") private val c12 = Column.Impl[Option[Int]]("hour") @@ -224,7 +224,12 @@ class DateTimeTest extends AnyFlatSpec, DateTime: it should "Statement generated using the SUBTIME function matches the specified string." in { assert(SUBTIME(c5, c3).name == "SUBTIME(local_date_time, local_time)") assert(SUBTIME(c6, c4).name == "SUBTIME(local_date_time, local_time)") - assert(SUBTIME(LocalDateTime.of(2021, 1, 1, 0, 0), LocalTime.of(1, 1, 1, 1)).name == "SUBTIME('2021-01-01 00:00', '01:01:01.000000001')") + assert( + SUBTIME( + LocalDateTime.of(2021, 1, 1, 0, 0), + LocalTime.of(1, 1, 1, 1) + ).name == "SUBTIME('2021-01-01 00:00', '01:01:01.000000001')" + ) } it should "Statement generated using the SYSDATE function matches the specified string." in { From fd9c68182714997781d7dca607f7f9883872c66a Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:05:19 +0900 Subject: [PATCH 68/74] Added TIME_TO_SEC functions --- .../ldbc/statement/functions/DateTime.scala | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 6d96de407..7ecd67a42 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1112,6 +1112,39 @@ trait DateTime: )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"TIME('${ time.toString.replaceAll("T", " ") }')") + /** + * Function to convert the time portion from a date type value to seconds. + * + * {{{ + * TableQuery[DateTime].select(p => TIME_TO_SEC(p.birthDate)) + * // SELECT TIME_TO_SEC(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the time. + */ + def TIME_TO_SEC[ + A <: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime] + ](column: Column[A])(using Decoder[Long], Encoder[Long]): Column[Long] = + Column(s"TIME_TO_SEC(${ column.name })") + + /** + * Function to convert the time portion from a date type value to seconds. + * + * {{{ + * TableQuery[DateTime].select(_ => TIME_TO_SEC(LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT TIME_TO_SEC('2021-01-01 00:00') FROM date_time + * }}} + * + * @param time + * The time or date-time expression from which to extract the time. + */ + def TIME_TO_SEC( + time: LocalTime | LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[Long], Encoder[Long]): Column[Long] = + Column(s"TIME_TO_SEC('${ time.toString.replaceAll("T", " ") }')") + object DateTime: /** From 599d7bc4a11afc8272e4809f70d0c871f0a2e3f3 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:05:27 +0900 Subject: [PATCH 69/74] Create DateTime TIME_TO_SEC Test --- .../test/scala/ldbc/statement/functions/DateTimeTest.scala | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 4aaf4300d..71730ad05 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -241,3 +241,9 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(TIME(c6).name == "TIME(local_date_time)") assert(TIME(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "TIME('2021-01-01 00:00')") } + + it should "Statement generated using the TIME_TO_SEC function matches the specified string." in { + assert(TIME_TO_SEC(c5).name == "TIME_TO_SEC(local_date_time)") + assert(TIME_TO_SEC(c6).name == "TIME_TO_SEC(local_date_time)") + assert(TIME_TO_SEC(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "TIME_TO_SEC('2021-01-01 00:00')") + } From 9aa7f5668209b3242c595f1ba1c48fd8f7ae0daa Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:14:38 +0900 Subject: [PATCH 70/74] Added TIMEDIFF functions --- .../ldbc/statement/functions/DateTime.scala | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 7ecd67a42..712d0fe98 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1145,6 +1145,70 @@ trait DateTime: )(using Decoder[Long], Encoder[Long]): Column[Long] = Column(s"TIME_TO_SEC('${ time.toString.replaceAll("T", " ") }')") + /** + * A function that calculates the difference of the time portion from a date/time type value and returns the result as a time type. + * + * {{{ + * TableQuery[DateTime].select(p => TIMEDIFF(p.start, p.end)) + * // SELECT TIMEDIFF(start, end) FROM date_time + * }}} + * + * @param start + * The start time. + * @param end + * The end time. + */ + def TIMEDIFF[ + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + start: Column[A], + end: Column[A] + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIMEDIFF(${ start.name }, ${ end.name })") + + + /** + * A function that calculates the difference of the time portion from a date/time type value and returns the result as a time type. + * + * {{{ + * TableQuery[DateTime].select(p => TIMEDIFF(p.start, LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT TIMEDIFF(start, '2021-01-01 00:00') FROM date_time + * }}} + * + * @param start + * The start time. + * @param end + * The end time. + */ + def TIMEDIFF[ + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | + Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + ]( + start: Column[A], + end: LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIMEDIFF(${ start.name }, '${ end.toString.replaceAll("T", " ") }')") + + /** + * A function that calculates the difference of the time portion from a date/time type value and returns the result as a time type. + * + * {{{ + * TableQuery[DateTime].select(_ => TIMEDIFF(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2021, 1, 1, 0, 0))) + * // SELECT TIMEDIFF('2021-01-01 00:00', '2021-01-01 00:00') FROM date_time + * }}} + * + * @param start + * The start time. + * @param end + * The end time. + */ + def TIMEDIFF[A <: LocalDateTime | OffsetDateTime | ZonedDateTime]( + start: A, + end: A + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + Column(s"TIMEDIFF('${ start.toString.replaceAll("T", " ") }', '${ end.toString.replaceAll("T", " ") }')") + object DateTime: /** From 7267b7ff7b714d2d78ea465851c20863c18d7d90 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:14:44 +0900 Subject: [PATCH 71/74] Create DateTime TIMEDIFF Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index 71730ad05..d63b4ad11 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -247,3 +247,11 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(TIME_TO_SEC(c6).name == "TIME_TO_SEC(local_date_time)") assert(TIME_TO_SEC(LocalDateTime.of(2021, 1, 1, 0, 0)).name == "TIME_TO_SEC('2021-01-01 00:00')") } + + it should "Statement generated using the TIMEDIFF function matches the specified string." in { + assert(TIMEDIFF(c5, c5).name == "TIMEDIFF(local_date_time, local_date_time)") + assert(TIMEDIFF(c6, c6).name == "TIMEDIFF(local_date_time, local_date_time)") + assert(TIMEDIFF(c5, LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF(local_date_time, '2025-01-01 01:01')") + assert(TIMEDIFF(c6, LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF(local_date_time, '2025-01-01 01:01')") + assert(TIMEDIFF(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF('2021-01-01 00:00', '2025-01-01 01:01')") + } From e5317200cbfa5c2360859ac77e68a32668d4cecd Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:27:07 +0900 Subject: [PATCH 72/74] Added TIMESTAMP functions --- .../ldbc/statement/functions/DateTime.scala | 51 +++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 712d0fe98..6e2678122 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1209,6 +1209,57 @@ trait DateTime: )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"TIMEDIFF('${ start.toString.replaceAll("T", " ") }', '${ end.toString.replaceAll("T", " ") }')") + /** + * Function to return a date or date-time format value as a date-time value. + * + * {{{ + * TableQuery[DateTime].select(p => TIMESTAMP(p.birthDate)) + * // SELECT TIMESTAMP(birth_date) FROM date_time + * }}} + * + * @param column + * The column from which to extract the date-time value. + */ + def TIMESTAMP[A <: LocalDate | Option[LocalDate]]( + column: Column[A] + )(using Decoder[Option[LocalDateTime]], Encoder[Option[LocalDateTime]]): Column[Option[LocalDateTime]] = + Column(s"TIMESTAMP(${ column.name })") + + /** + * Function to return a date or date-time format value as a date-time value. + * + * {{{ + * TableQuery[DateTime].select(_ => TIMESTAMP(LocalDate.of(2021, 1, 1))) + * // SELECT TIMESTAMP('2021-01-01') FROM date_time + * }}} + * + * @param date + * The date or date-time expression from which to extract the date-time value. + */ + def TIMESTAMP[A <: LocalDate]( + date: A + )(using Decoder[Option[LocalDateTime]], Encoder[Option[LocalDateTime]]): Column[Option[LocalDateTime]] = + Column(s"TIMESTAMP('${ date.toString }')") + + /** + * Function that adds the value of a time expression to the value of a date or date-time expression and returns the result as a date-time value. + * + * {{{ + * TableQuery[DateTime].select(p => TIMESTAMP(p.birthDate, p.birthTime)) + * // SELECT TIMESTAMP(birth_date, birth_time) FROM date_time + * }}} + * + * @param column1 + * The date or date-time expression. + * @param column2 + * The time expression. + */ + def TIMESTAMP[A <: LocalDateTime | Option[LocalDateTime], B <: LocalTime | Option[LocalTime]]( + column1: Column[A], + column2: Column[B], + )(using Decoder[Option[LocalDateTime]], Encoder[Option[LocalDateTime]]): Column[Option[LocalDateTime]] = + Column(s"TIMESTAMP(${column1.name}, ${column2.name})") + object DateTime: /** From e6b5a0fbbee0c866efbb10a0f176e97b7a1f5ea4 Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:27:13 +0900 Subject: [PATCH 73/74] Create DateTime TIMESTAMP Test --- .../scala/ldbc/statement/functions/DateTimeTest.scala | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index d63b4ad11..c576ff1dc 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -255,3 +255,11 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(TIMEDIFF(c6, LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF(local_date_time, '2025-01-01 01:01')") assert(TIMEDIFF(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF('2021-01-01 00:00', '2025-01-01 01:01')") } + + it should "Statement generated using the TIMESTAMP function matches the specified string." in { + assert(TIMESTAMP(c1).name == "TIMESTAMP(local_date)") + assert(TIMESTAMP(c2).name == "TIMESTAMP(local_date)") + assert(TIMESTAMP(c5, c3).name == "TIMESTAMP(local_date_time, local_time)") + assert(TIMESTAMP(c6, c4).name == "TIMESTAMP(local_date_time, local_time)") + assert(TIMESTAMP(LocalDate.of(2021, 1, 1)).name == "TIMESTAMP('2021-01-01')") + } From 64a6ddd6953aefd920fc5411ee090190db21a4ff Mon Sep 17 00:00:00 2001 From: takapi327 Date: Thu, 23 Jan 2025 20:28:59 +0900 Subject: [PATCH 74/74] Action sbt scalafmtAll --- .../ldbc/statement/functions/DateTime.scala | 25 ++++++++----------- .../statement/functions/DateTimeTest.scala | 7 +++++- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala index 6e2678122..238edb19b 100644 --- a/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala +++ b/module/ldbc-statement/src/main/scala/ldbc/statement/functions/DateTime.scala @@ -1159,15 +1159,13 @@ trait DateTime: * The end time. */ def TIMEDIFF[ - A <: LocalDateTime | OffsetDateTime | ZonedDateTime | - Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime] ]( start: Column[A], - end: Column[A] + end: Column[A] )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"TIMEDIFF(${ start.name }, ${ end.name })") - /** * A function that calculates the difference of the time portion from a date/time type value and returns the result as a time type. * @@ -1182,12 +1180,11 @@ trait DateTime: * The end time. */ def TIMEDIFF[ - A <: LocalDateTime | OffsetDateTime | ZonedDateTime | - Option[LocalDateTime | OffsetDateTime | ZonedDateTime] + A <: LocalDateTime | OffsetDateTime | ZonedDateTime | Option[LocalDateTime | OffsetDateTime | ZonedDateTime] ]( - start: Column[A], - end: LocalDateTime | OffsetDateTime | ZonedDateTime - )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = + start: Column[A], + end: LocalDateTime | OffsetDateTime | ZonedDateTime + )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"TIMEDIFF(${ start.name }, '${ end.toString.replaceAll("T", " ") }')") /** @@ -1205,7 +1202,7 @@ trait DateTime: */ def TIMEDIFF[A <: LocalDateTime | OffsetDateTime | ZonedDateTime]( start: A, - end: A + end: A )(using Decoder[LocalTime], Encoder[LocalTime]): Column[LocalTime] = Column(s"TIMEDIFF('${ start.toString.replaceAll("T", " ") }', '${ end.toString.replaceAll("T", " ") }')") @@ -1255,10 +1252,10 @@ trait DateTime: * The time expression. */ def TIMESTAMP[A <: LocalDateTime | Option[LocalDateTime], B <: LocalTime | Option[LocalTime]]( - column1: Column[A], - column2: Column[B], - )(using Decoder[Option[LocalDateTime]], Encoder[Option[LocalDateTime]]): Column[Option[LocalDateTime]] = - Column(s"TIMESTAMP(${column1.name}, ${column2.name})") + column1: Column[A], + column2: Column[B] + )(using Decoder[Option[LocalDateTime]], Encoder[Option[LocalDateTime]]): Column[Option[LocalDateTime]] = + Column(s"TIMESTAMP(${ column1.name }, ${ column2.name })") object DateTime: diff --git a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala index c576ff1dc..4fd6227ce 100644 --- a/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala +++ b/module/ldbc-statement/src/test/scala/ldbc/statement/functions/DateTimeTest.scala @@ -253,7 +253,12 @@ class DateTimeTest extends AnyFlatSpec, DateTime: assert(TIMEDIFF(c6, c6).name == "TIMEDIFF(local_date_time, local_date_time)") assert(TIMEDIFF(c5, LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF(local_date_time, '2025-01-01 01:01')") assert(TIMEDIFF(c6, LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF(local_date_time, '2025-01-01 01:01')") - assert(TIMEDIFF(LocalDateTime.of(2021, 1, 1, 0, 0), LocalDateTime.of(2025, 1, 1, 1, 1)).name == "TIMEDIFF('2021-01-01 00:00', '2025-01-01 01:01')") + assert( + TIMEDIFF( + LocalDateTime.of(2021, 1, 1, 0, 0), + LocalDateTime.of(2025, 1, 1, 1, 1) + ).name == "TIMEDIFF('2021-01-01 00:00', '2025-01-01 01:01')" + ) } it should "Statement generated using the TIMESTAMP function matches the specified string." in {