From dc0e385126a2e0c1ee652d19bd5048ae52a47b8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?TATSUNO=20=E2=80=9CTaz=E2=80=9D=20Yasuhiro?= Date: Sat, 9 Aug 2025 15:19:28 +0900 Subject: [PATCH] S3OutputLocation is optional when Workgroup is supplied --- src/main/scala/scalikejdbc/athena/Config.scala | 16 +++++++++++----- src/test/resources/application.conf | 18 +++++++++++++++++- .../scala/scalikejdbc/athena/ConfigSpec.scala | 16 +++++++++++++++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/src/main/scala/scalikejdbc/athena/Config.scala b/src/main/scala/scalikejdbc/athena/Config.scala index b783fda..981e356 100644 --- a/src/main/scala/scalikejdbc/athena/Config.scala +++ b/src/main/scala/scalikejdbc/athena/Config.scala @@ -8,6 +8,7 @@ import scala.collection.JavaConverters._ import scala.util.Try class Config(dbName: Any) { + import Config._ private[this] val prefix = "athena." + (dbName match { @@ -36,11 +37,16 @@ class Config(dbName: Any) { private[athena] lazy val options: Properties = { val p = new Properties() - (map.get(S3OutputLocation), map.get(S3OutputLocationPrefix)) match { - case (Some(d), Some(p)) => throw new ConfigException(s"duplicate settings: $prefix.$S3OutputLocation=$d, $prefix.$S3OutputLocationPrefix=$p") - case (Some(v), _) => p.setProperty(S3OutputLocation, v) - case (_, Some(v)) => p.setProperty(S3OutputLocation, s"$v/${UUID.randomUUID()}") - case _ => throw new ConfigException(s"no configuration setting: key=$prefix.$S3OutputLocation, $prefix.$S3OutputLocationPrefix") + // driver v3:WorkGroup, v2:Workgroup + // If workgroups is missing (fallback to primary workgroup), S3OutputLocation is mandatory. + // However, if any user-defined workgroup is specified, S3OutputLocation is optional. + if (!map.get("WorkGroup").orElse(map.get("Workgroup")).exists(_ != "primary")) { + (map.get(S3OutputLocation), map.get(S3OutputLocationPrefix)) match { + case (Some(d), Some(p)) => throw new ConfigException(s"duplicate settings: $prefix.$S3OutputLocation=$d, $prefix.$S3OutputLocationPrefix=$p") + case (Some(v), _) => p.setProperty(S3OutputLocation, v) + case (_, Some(v)) => p.setProperty(S3OutputLocation, s"$v/${UUID.randomUUID()}") + case _ => throw new ConfigException(s"no configuration setting: key=$prefix.$S3OutputLocation, $prefix.$S3OutputLocationPrefix") + } } map.foreach { entry => val (name, value) = entry diff --git a/src/test/resources/application.conf b/src/test/resources/application.conf index a3aa543..e8ab665 100644 --- a/src/test/resources/application.conf +++ b/src/test/resources/application.conf @@ -7,6 +7,22 @@ athena { S3OutputLocation="s3://query-results-bucket/folder/" LogPath="logs/application.log" } + workgroup-only { + driver="com.amazon.athena.jdbc.AthenaDriver" + url="jdbc:athena://AwsRegion=us-east-2" + readOnly="false" + AwsCredentialsProviderClass="DefaultChain" + LogPath="logs/application.log" + WorkGroup="my-own-workgroup" + } + workgroup-primary { + driver="com.amazon.athena.jdbc.AthenaDriver" + url="jdbc:athena://AwsRegion=us-east-2" + readOnly="false" + AwsCredentialsProviderClass="DefaultChain" + LogPath="logs/application.log" + WorkGroup="primary" + } athena { driver="com.amazon.athena.jdbc.AthenaDriver" url="jdbc:athena://AwsRegion=ap-southeast-1" @@ -44,7 +60,7 @@ athena { driver="com.simba.athena.jdbc.Driver" url="jdbc:awsathena://AwsRegion=us-east-2" readOnly="false" - S3OutputLocation="s3://query-results-bucket/folder/" + Workgroup="my-own-workgroup" AwsCredentialsProviderClass="com.simba.athena.amazonaws.auth.profile.ProfileCredentialsProvider" LogPath="logs/application.log" LogLevel=3 diff --git a/src/test/scala/scalikejdbc/athena/ConfigSpec.scala b/src/test/scala/scalikejdbc/athena/ConfigSpec.scala index f9e90d1..aa204c3 100644 --- a/src/test/scala/scalikejdbc/athena/ConfigSpec.scala +++ b/src/test/scala/scalikejdbc/athena/ConfigSpec.scala @@ -15,6 +15,19 @@ class ConfigSpec extends AnyFunSpec with OptionValues { assert(config.readOnly.value === false) assert(config.timeZone.isEmpty) } + it("workgropup") { + val config = new Config("workgroup-only") + assert(config.url === "jdbc:athena://AwsRegion=us-east-2") + assert(config.options.getProperty("S3OutputLocation") === null) + assert(config.options.getProperty("WorkGroup") === "my-own-workgroup") + assert(config.options.getProperty("LogPath") === "logs/application.log") + assert(config.getTmpStagingDir.isEmpty) + assert(config.readOnly.value === false) + assert(config.timeZone.isEmpty) + } + it("primary workgroupRequires S3OutputLocation") { + assertThrows[ConfigException](new Config("workgroup-primary").options) + } it("named db") { val config = new Config("athena") assert(config.url === "jdbc:athena://AwsRegion=ap-southeast-1") @@ -35,7 +48,8 @@ class ConfigSpec extends AnyFunSpec with OptionValues { it("v2") { val config = new Config("v2.default") assert(config.url === "jdbc:awsathena://AwsRegion=us-east-2") - assert(config.options.getProperty("S3OutputLocation") === "s3://query-results-bucket/folder/") + assert(config.options.getProperty("S3OutputLocation") === null) + assert(config.options.getProperty("Workgroup") === "my-own-workgroup") assert(config.options.getProperty("LogPath") === "logs/application.log") assert(config.getTmpStagingDir.isEmpty) assert(config.readOnly.value === false)