/ / Comment convertir un UUID en MongoDB oid - mongodb, scala, uuid, reactivemongo

Comment convertir un UUID en MongoDB oid - mongodb, scala, uuid, reactivemongo

Étant donné un java.util.UUID généré comme ça ...

import java.util.UUID

val uuid = UUID.randomUUID

... est-il possible de le convertir en MongoDB ObjectID et préserver l'unicité? Ou dois-je simplement définir _id à la valeur UUID?

Bien sûr, la meilleure solution serait d'utiliser BSONObjectID.generate... mais dans mon cas je reçois un Jeton Web JSON avec un UUID comme identifiant et je dois le suivre dans une collection MongoDB.

Tx.

Réponses:

1 pour la réponse № 1

Pourquoi ne pas simplement économiser _id = uuid ?

MongoDB s'en occupera simplement :)


1 pour la réponse № 2

Les objets implicites suivants permettent à reactivemongo de convertir l'UUID en BSONBinary.

  implicit val uuidBSONWriter: BSONWriter[UUID, BSONBinary] =
new BSONWriter[UUID, BSONBinary] {
override def write(uuid: UUID): BSONBinary = {
val ba: ByteArrayOutputStream = new ByteArrayOutputStream(16)
val da: DataOutputStream = new DataOutputStream(ba)
da.writeLong(uuid.getMostSignificantBits)
da.writeLong(uuid.getLeastSignificantBits)
BSONBinary(ba.toByteArray, Subtype.OldUuidSubtype)
}
}

implicit val uuidBSONReader: BSONReader[BSONBinary, UUID] =
new BSONReader[BSONBinary, UUID] {
override def read(bson: BSONBinary): UUID = {
val ba = bson.byteArray
new UUID(getLong(ba, 0), getLong(ba, 8))
}
}

def getLong(array:Array[Byte], offset:Int):Long = {
(array(offset).toLong & 0xff) << 56 |
(array(offset+1).toLong & 0xff) << 48 |
(array(offset+2).toLong & 0xff) << 40 |
(array(offset+3).toLong & 0xff) << 32 |
(array(offset+4).toLong & 0xff) << 24 |
(array(offset+5).toLong & 0xff) << 16 |
(array(offset+6).toLong & 0xff) << 8 |
(array(offset+7).toLong & 0xff)
}

Voici un exemple d'utilisation des objets écrivain et lecteur ci-dessus

abstract class EntityDao[E <: Entity](db: => DB, collectionName: String) {

val ATTR_ENTITY_UUID = "entityUuid"

val collection = db[BSONCollection](collectionName)

def ensureIndices(): Future[Boolean] = {
collection.indexesManager.ensure(
Index(Seq(ATTR_ENTITY_UUID -> IndexType.Ascending),unique = true)
)
}

def createEntity(entity: E) = {
val entityBSON = BSONDocument(ATTR_ENTITY_UUID -> entity.entityUuid)
collection.insert(entityBSON)
}

def findByUuid(uuid: UUID)(implicit reader: BSONDocumentReader[E]): Future[Option[E]] = {
val selector = BSONDocument(ATTR_ENTITY_UUID -> uuid)
collection.find(selector).one[E]
}
}

0 pour la réponse № 3

Voici une implémentation alternative du gestionnaire BSON pour UUID sans torsion manuelle des bits:

import reactivemongo.bson._
import java.nio.ByteBuffer
import java.util.UUID

implicit val uuidBSONHandler: BSONHandler[BSONBinary, UUID] = BSONHandler(
{ bson =>
val lb = ByteBuffer.wrap(bson.byteArray).asLongBuffer
new UUID(lb.get(0), lb.get(1))
},
{ uuid =>
val arr = Array.ofDim[Byte](16)
ByteBuffer.wrap(arr).asLongBuffer.put(uuid.getMostSignificantBits).put(uuid.getLeastSignificantBits)
BSONBinary(arr, Subtype.UuidSubtype)
})