diff --git a/all/src/test/scala/spec/AirportSpec.scala b/all/src/test/scala/spec/AirportSpec.scala index 4695c0b6..b57c2337 100644 --- a/all/src/test/scala/spec/AirportSpec.scala +++ b/all/src/test/scala/spec/AirportSpec.scala @@ -8,10 +8,10 @@ import lightdb.lucene.LuceneStore import lightdb.store.StoreManager import lightdb.store.split.SplitStoreManager import lightdb.upgrade.DatabaseUpgrade -import lightdb.{Id, LightDB, Unique} +import lightdb.{Id, LightDB} import org.scalatest.matchers.should.Matchers import org.scalatest.wordspec.AsyncWordSpec -import rapid.{AsyncTaskSpec, Task} +import rapid.{AsyncTaskSpec, Task, Unique} import scribe.{rapid => logger} import java.nio.file.Path @@ -146,7 +146,7 @@ class AirportSpec extends AsyncWordSpec with AsyncTaskSpec with Matchers { val vip: I[Boolean] = field.index("vip", _.vip) // val vipKeys: ValueStore[String, Airport] = ValueStore[String, Airport]("vipKeys", doc => if (doc.vip) List(doc._id.value) else Nil, this, persistence = Persistence.Cached) - override def id(value: String = Unique()): Id[Airport] = { + override def id(value: String = Unique().sync()): Id[Airport] = { val index = value.indexOf('/') val v = if (index != -1) { value.substring(index + 1) diff --git a/build.sbt b/build.sbt index a21c098a..5ea24872 100644 --- a/build.sbt +++ b/build.sbt @@ -15,7 +15,7 @@ val developerURL: String = "https://matthicks.com" name := projectName ThisBuild / organization := org -ThisBuild / version := "2.0.1" +ThisBuild / version := "2.1.0-SNAPSHOT" ThisBuild / scalaVersion := scala213 ThisBuild / crossScalaVersions := allScalaVersions ThisBuild / scalacOptions ++= Seq("-unchecked", "-deprecation") diff --git a/core/src/main/scala/lightdb/Id.scala b/core/src/main/scala/lightdb/Id.scala index 20d14622..d55bcb1c 100644 --- a/core/src/main/scala/lightdb/Id.scala +++ b/core/src/main/scala/lightdb/Id.scala @@ -1,6 +1,7 @@ package lightdb import fabric.rw._ +import rapid.Unique case class Id[Doc](value: String) extends AnyVal { def bytes: Array[Byte] = { @@ -17,7 +18,7 @@ object Id { implicit def rw[T]: RW[Id[T]] = _rw.asInstanceOf[RW[Id[T]]] - def apply[T](value: String = Unique()): Id[T] = new Id[T](value) + def apply[T](value: String = Unique().sync()): Id[T] = new Id[T](value) def toString[T](id: Id[T]): String = id.value } \ No newline at end of file diff --git a/core/src/main/scala/lightdb/Unique.scala b/core/src/main/scala/lightdb/Unique.scala deleted file mode 100644 index 48e0e9d4..00000000 --- a/core/src/main/scala/lightdb/Unique.scala +++ /dev/null @@ -1,75 +0,0 @@ -package lightdb - -import java.util.concurrent.ThreadLocalRandom - -/** - * Unique String generator - */ -object Unique { - lazy val LettersLower = "abcdefghijklmnopqrstuvwxyz" - lazy val LettersUpper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - lazy val Numbers = "0123456789" - lazy val Readable = "ABCDEFGHJKLMNPQRSTWXYZ23456789" - lazy val Hexadecimal = s"${Numbers}abcdef" - lazy val LettersAndNumbers = s"$LettersLower$Numbers" - lazy val AllLetters = s"$LettersLower$LettersUpper" - lazy val AllLettersAndNumbers = s"$LettersLower$LettersUpper$Numbers" - - /** - * Random number generator used to generate unique values. Defaults to `threadLocalRandom`. - */ - var random: Int => Int = threadLocalRandom - - /** - * The default length to use for generating unique values. Defaults to 32. - */ - var defaultLength: Int = 32 - - /** - * The default characters to use for generating unique values. Defaults to AllLettersAndNumbers. - */ - var defaultCharacters: String = AllLettersAndNumbers - - /** - * Uses java.util.concurrent.ThreadLocalRandom to generate random numbers. - * - * @param max the maximum value to include - * @return random number between 0 and max - */ - final def threadLocalRandom(max: Int): Int = ThreadLocalRandom.current().nextInt(max) - - /** - * Generates a unique String using the characters supplied at the length defined. - * - * @param length the length of the resulting String. Defaults to Unique.defaultLength. - * @param characters the characters for use in the String. Defaults to Unique.defaultCharacters. - * @return a unique String - */ - def apply(length: Int = defaultLength, characters: String = defaultCharacters): String = { - val charMax = characters.length - val r = random - (0 until length).map(_ => characters.charAt(r(charMax))).mkString - } - - /** - * Convenience functionality to generate a UUID (https://en.wikipedia.org/wiki/Universally_unique_identifier) - * - * 32 characters of unique hexadecimal values with dashes representing 36 total characters - */ - def uuid: String = { - val a = apply(8, Hexadecimal) - val b = apply(4, Hexadecimal) - val c = apply(3, Hexadecimal) - val d = apply(1, "89ab") - val e = apply(3, Hexadecimal) - val f = apply(12, Hexadecimal) - s"$a-$b-4$c-$d$e-$f" - } - - /** - * Returns the number of possible values for a specific length and characters. - */ - def poolSize(length: Int = 32, characters: String = AllLettersAndNumbers): Long = { - math.pow(characters.length, length).toLong - } -} \ No newline at end of file diff --git a/core/src/main/scala/lightdb/doc/DocumentModel.scala b/core/src/main/scala/lightdb/doc/DocumentModel.scala index eb9792fe..a4b15899 100644 --- a/core/src/main/scala/lightdb/doc/DocumentModel.scala +++ b/core/src/main/scala/lightdb/doc/DocumentModel.scala @@ -7,7 +7,7 @@ import lightdb.facet.{FacetConfig, FacetValue} import lightdb.field.Field._ import lightdb.field.{Field, FieldGetter} import lightdb.filter.FilterBuilder -import rapid.Task +import rapid.{Task, Unique} import scala.language.implicitConversions @@ -18,7 +18,7 @@ trait DocumentModel[Doc <: Document[Doc]] { val _id: UniqueIndex[Doc, Id[Doc]] = field.unique("_id", (doc: Doc) => doc._id) - def id(value: String = Unique()): Id[Doc] = Id(value) + def id(value: String = Unique().sync()): Id[Doc] = Id(value) def init[Model <: DocumentModel[Doc]](collection: Collection[Doc, Model]): Task[Unit] = Task.unit diff --git a/h2/src/main/scala/lightdb/h2/H2Store.scala b/h2/src/main/scala/lightdb/h2/H2Store.scala index 70bf46dd..d41e60a5 100644 --- a/h2/src/main/scala/lightdb/h2/H2Store.scala +++ b/h2/src/main/scala/lightdb/h2/H2Store.scala @@ -4,7 +4,8 @@ import lightdb.doc.{Document, DocumentModel} import lightdb.sql.connect.{ConnectionManager, SQLConfig, SingleConnectionManager} import lightdb.sql.{SQLDatabase, SQLStore} import lightdb.store.{Store, StoreManager, StoreMode} -import lightdb.{LightDB, Unique} +import lightdb.LightDB +import rapid.Unique import java.nio.file.Path import java.sql.Connection @@ -38,7 +39,7 @@ class H2Store[Doc <: Document[Doc], Model <: DocumentModel[Doc]](name: String, object H2Store extends StoreManager { def config(file: Option[Path]): SQLConfig = SQLConfig( - jdbcUrl = s"jdbc:h2:${file.map(_.toFile.getCanonicalPath).map(p => s"file:$p").getOrElse(s"test:${Unique()}")};NON_KEYWORDS=VALUE,USER,SEARCH" + jdbcUrl = s"jdbc:h2:${file.map(_.toFile.getCanonicalPath).map(p => s"file:$p").getOrElse(s"test:${Unique().sync()}")};NON_KEYWORDS=VALUE,USER,SEARCH" ) def apply[Doc <: Document[Doc], Model <: DocumentModel[Doc]](name: String,