Skip to content

Commit

Permalink
Fix too strict BQTableId
Browse files Browse the repository at this point in the history
- Add convenince functions to BQDataset
- Add another unsafe variant to BQTableId
  • Loading branch information
hamnis committed Aug 24, 2023
1 parent 39fa19b commit 97ca9b2
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 11 deletions.
5 changes: 4 additions & 1 deletion build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ lazy val core = crossProject(JVMPlatform)
)
}
},
mimaBinaryIssueFilters ++= Nil
mimaBinaryIssueFilters ++= List(
ProblemFilters.exclude[DirectMissingMethodProblem]("no.nrk.bigquery.BQDataset.of"),
ProblemFilters.exclude[DirectMissingMethodProblem]("no.nrk.bigquery.BQDataset.unsafeOf")
)
)
.disablePlugins(TypelevelCiSigningPlugin, Sonatype, SbtGpg)

Expand Down
11 changes: 7 additions & 4 deletions core/src/main/scala/no/nrk/bigquery/BQDataset.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,18 @@ final case class BQDataset private[bigquery] (
def underlying: DatasetId = DatasetId.of(project.value, id)

def withLocation(locationId: LocationId): BQDataset = copy(location = Some(locationId))
def withoutLocation: BQDataset = copy(location = None)
def withId(id: String): BQDataset = copy(id = id)
def withProject(project: ProjectId): BQDataset = copy(project = project)
}

object BQDataset {
private val regex: Pattern = "^[a-zA-Z0-9_]{1,1024}".r.pattern

def unsafeOf(project: ProjectId, dataset: String) =
of(project, dataset).fold(err => throw new IllegalArgumentException(err), identity)
def unsafeOf(project: ProjectId, dataset: String, location: Option[LocationId] = None) =
of(project, dataset, location).fold(err => throw new IllegalArgumentException(err), identity)

def of(project: ProjectId, dataset: String): Either[String, BQDataset] =
if (regex.matcher(dataset).matches()) Right(BQDataset(project, dataset, None))
def of(project: ProjectId, dataset: String, location: Option[LocationId] = None): Either[String, BQDataset] =
if (regex.matcher(dataset).matches()) Right(BQDataset(project, dataset, location))
else Left(s"invalid project ID '$dataset' - must match ${regex.pattern()}")
}
5 changes: 4 additions & 1 deletion core/src/main/scala/no/nrk/bigquery/BQTableId.scala
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ final case class BQTableId private[bigquery] (dataset: BQDataset, tableName: Str

object BQTableId {

private val regex: Pattern = "(?U)^\\w[\\w_ -]{1,1023}".r.pattern
private val regex: Pattern = "(?U)^\\w[\\w_ *$-]{1,1023}".r.pattern

def of(dataset: BQDataset, tableName: String): Either[String, BQTableId] =
if (regex.matcher(tableName).matches()) Right(BQTableId(dataset, tableName))
Expand All @@ -38,6 +38,9 @@ object BQTableId {
def unsafeOf(dataset: BQDataset, tableName: String): BQTableId =
of(dataset, tableName).fold(err => throw new IllegalArgumentException(err), identity)

def unsafeFrom(project: ProjectId, dataset: String, tableName: String): BQTableId =
unsafeFromString(s"${project.value}.${dataset}.${tableName}")

def unsafeFromGoogle(dataset: BQDataset, tableId: TableId): BQTableId = {
require(
tableId.getProject == dataset.project.value && dataset.id == tableId.getDataset,
Expand Down
9 changes: 9 additions & 0 deletions core/src/test/scala/no/nrk/bigquery/BQTableIdTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,13 @@ class BQTableIdTest extends munit.ScalaCheckSuite {
assertEquals(obtained, Right(BQTableId(BQDataset(ProjectId(project), dataset, None), table)))
}
}

test("examples must work") {
val ids = List("cloudaudit_googleapis_com_data_access_*", "service_daily_example_v01$20200801")

for (id <- ids) {
val obtained = BQTableId.of(dataset, id)
assertEquals(obtained, Right(BQTableId(dataset, id)))
}
}
}
10 changes: 5 additions & 5 deletions core/src/test/scala/no/nrk/bigquery/Generators.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ object Generators {

val validProjectIdGen = for {
firstchar <- Gen.stringOfN(1, Gen.alphaLowerChar)
maybedash <- Gen.oneOf("", "-")
maybeSymbol <- Gen.oneOf("", "-")
alphaNumLower = Gen.oneOf(Gen.alphaLowerChar, Gen.numChar)
afterdash <- Gen.stringOfN(6 - maybedash.length, alphaNumLower)
afterdash <- Gen.stringOfN(6 - maybeSymbol.length, alphaNumLower)
lastChars <- Generators
.shorterThan(29 - (1 + afterdash.length + maybedash.length), Gen.stringOf(alphaNumLower))
} yield firstchar + maybedash + afterdash + lastChars
.shorterThan(29 - (1 + afterdash.length + maybeSymbol.length), Gen.stringOf(alphaNumLower))
} yield firstchar + maybeSymbol + afterdash + lastChars

val validDatasetIdGen = for {
alpha <- Generators.shorterThanAlphaNum(1021).filterNot(_.isEmpty)
Expand All @@ -31,7 +31,7 @@ object Generators {
.stringOfN(1, unicodeIdentifierPart)
.map(_.replaceAll("(?U)\\W", ""))
.map(s => if (s.isEmpty) "a" else s)
choose <- Gen.oneOf("", " ", "-", "_")
choose <- Gen.oneOf("", " ", "-", "_", "$", "*")
next <- Generators.shorterThan(
1022,
Gen.stringOf(unicodeIdentifierPart).map(_.replaceAll("(?U)\\W", "")).filter(_.nonEmpty))
Expand Down

0 comments on commit 97ca9b2

Please sign in to comment.