diff --git a/core/jvm/src/main/scala/zio/sql/expr/Expr.scala b/core/jvm/src/main/scala/zio/sql/expr/Expr.scala index 178e58b20..c852bcf23 100644 --- a/core/jvm/src/main/scala/zio/sql/expr/Expr.scala +++ b/core/jvm/src/main/scala/zio/sql/expr/Expr.scala @@ -37,6 +37,11 @@ sealed trait Expr[-F, -A, +B] { self => )(implicit ev: B <:< Boolean): Expr[F with F2, A1, Boolean] = Expr.Binary(self.widen[Boolean], that, BinaryOp.OrBool) + def soundsLike[F2, A1 <: A, B1 >: B](that: Expr[F2, A1, String])(implicit + ev: B <:< String + ): Expr[F with F2, A1, String] = + Expr.Binary(self.widen[String], that, BinaryOp.MySqlExtensions.SoundsLike) + def ===[F2, A1 <: A, B1 >: B, B2](that: Expr[F2, A1, B2])(implicit ct: ComparableTypes[B1, B2] ): Expr[F with F2, A1, Boolean] = diff --git a/core/jvm/src/main/scala/zio/sql/ops/Operator.scala b/core/jvm/src/main/scala/zio/sql/ops/Operator.scala index 50cdd0031..f1e0d34dc 100644 --- a/core/jvm/src/main/scala/zio/sql/ops/Operator.scala +++ b/core/jvm/src/main/scala/zio/sql/ops/Operator.scala @@ -52,7 +52,12 @@ object Operator { final case class OrBit[A: IsIntegral]() extends BinaryOp[A] { def isIntegral: IsIntegral[A] = implicitly[IsIntegral[A]] override val symbol: String = "|" + } + object MySqlExtensions { + case object SoundsLike extends BinaryOp[String] { + override val symbol: String = "sounds like" + } } } diff --git a/mysql/src/test/resources/shop_schema.sql b/mysql/src/test/resources/shop_schema.sql index 1ad8c80c9..40a323f66 100644 --- a/mysql/src/test/resources/shop_schema.sql +++ b/mysql/src/test/resources/shop_schema.sql @@ -48,7 +48,8 @@ values ('f76c9ace-be07-4bf3-bd4c-4a9c62882e64', 'Terrence', 'Noel', true, '1999-11-02'), ('784426a5-b90a-4759-afbb-571b7a0ba35e', 'Mila', 'Paterso', true, '1990-11-16'), ('df8215a2-d5fd-4c6c-9984-801a1b3a2a0b', 'Alana', 'Murray', true, '1995-11-12'), - ('636ae137-5b1a-4c8c-b11f-c47c624d9cdc', 'Jose', 'Wiggins', false, '1987-03-23'); + ('636ae137-5b1a-4c8c-b11f-c47c624d9cdc', 'Jose', 'Wiggins', false, '1987-03-23'), + ('d4f6c156-20ac-4d27-8ced-535bf4315ebc', 'Robert', 'Rupert', false, '1998-06-11'); insert into products (id, name, description, image_url) diff --git a/mysql/src/test/scala/zio/sql/mysql/CustomFunctionDefSpec.scala b/mysql/src/test/scala/zio/sql/mysql/CustomFunctionDefSpec.scala index 34f512f73..224f4eec6 100644 --- a/mysql/src/test/scala/zio/sql/mysql/CustomFunctionDefSpec.scala +++ b/mysql/src/test/scala/zio/sql/mysql/CustomFunctionDefSpec.scala @@ -1,13 +1,15 @@ package zio.sql.mysql -import zio.test._ -import zio.test.Assertion._ +import zio.Chunk import zio.schema._ -import java.time.{ LocalDate, LocalTime, ZoneId } -import java.time.format.DateTimeFormatter import zio.sql.Jdbc -import java.util.UUID import zio.sql.table._ +import zio.test.Assertion._ +import zio.test._ + +import java.time.format.DateTimeFormatter +import java.time.{ LocalDate, LocalTime, ZoneId } +import java.util.UUID object CustomFunctionDefSpec extends MysqlRunnableSpec with Jdbc { @@ -119,6 +121,22 @@ object CustomFunctionDefSpec extends MysqlRunnableSpec with Jdbc { assertZIO(testResult.runHead.some)(equalTo(expected)) }, + test("sounds like") { + val query = select("Robert".soundsLike("Rupert")) + + val testResult = execute(query) + + assertZIO(testResult.runHead.some)(equalTo(true)) + }, + test("sounds like on column") { + val query = select(customerId).from(customers).where(fName.soundsLike(lName)) + + for { + result <- execute(query).runCollect + } yield assertTrue( + result == Chunk(UUID.fromString("d4f6c156-20ac-4d27-8ced-535bf4315ebc")) + ) + }, test("current_date") { val query = select(CurrentDate)