mirror of
https://github.com/pikami/cosmium.git
synced 2025-02-13 11:26:00 +00:00
96 lines
2.4 KiB
Go
96 lines
2.4 KiB
Go
package resourceid
|
|
|
|
import (
|
|
"encoding/base64"
|
|
"math/rand"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
)
|
|
|
|
type ResourceType int
|
|
|
|
const (
|
|
ResourceTypeDatabase ResourceType = iota
|
|
ResourceTypeCollection
|
|
ResourceTypeDocument
|
|
ResourceTypeStoredProcedure
|
|
ResourceTypeTrigger
|
|
ResourceTypeUserDefinedFunction
|
|
ResourceTypeConflict
|
|
ResourceTypePartitionKeyRange
|
|
ResourceTypeSchema
|
|
)
|
|
|
|
func New(resourceType ResourceType) string {
|
|
var idBytes []byte
|
|
switch resourceType {
|
|
case ResourceTypeDatabase:
|
|
idBytes = randomBytes(4)
|
|
case ResourceTypeCollection:
|
|
idBytes = randomBytes(4)
|
|
// first byte should be bigger than 0x80 for collection ids
|
|
// clients classify this id as "user" otherwise
|
|
if (idBytes[0] & 0x80) <= 0 {
|
|
idBytes[0] = byte(rand.Intn(0x80) + 0x80)
|
|
}
|
|
case ResourceTypeDocument:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) // Upper 4 bits = 0
|
|
case ResourceTypeStoredProcedure:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) | 0x08 // Upper 4 bits = 0x08
|
|
case ResourceTypeTrigger:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) | 0x07 // Upper 4 bits = 0x07
|
|
case ResourceTypeUserDefinedFunction:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) | 0x06 // Upper 4 bits = 0x06
|
|
case ResourceTypeConflict:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) | 0x04 // Upper 4 bits = 0x04
|
|
case ResourceTypePartitionKeyRange:
|
|
// we don't do partitions yet, so just use a fixed id
|
|
idBytes = []byte{0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x50}
|
|
case ResourceTypeSchema:
|
|
idBytes = randomBytes(8)
|
|
idBytes[7] = byte(rand.Intn(0x10)) | 0x09 // Upper 4 bits = 0x09
|
|
default:
|
|
idBytes = randomBytes(4)
|
|
}
|
|
|
|
encoded := base64.StdEncoding.EncodeToString(idBytes)
|
|
return strings.ReplaceAll(encoded, "/", "-")
|
|
}
|
|
|
|
func NewCombined(ids ...string) string {
|
|
combinedIdBytes := make([]byte, 0)
|
|
|
|
for _, id := range ids {
|
|
idBytes, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(id, "-", "/"))
|
|
combinedIdBytes = append(combinedIdBytes, idBytes...)
|
|
}
|
|
|
|
encoded := base64.StdEncoding.EncodeToString(combinedIdBytes)
|
|
return strings.ReplaceAll(encoded, "/", "-")
|
|
}
|
|
|
|
func uintToBytes(id uint32) []byte {
|
|
buf := make([]byte, 4)
|
|
for i := 0; i < 4; i++ {
|
|
buf[i] = byte(id >> (i * 8))
|
|
}
|
|
|
|
return buf
|
|
}
|
|
|
|
func randomBytes(count int) []byte {
|
|
buf := make([]byte, count)
|
|
for i := 0; i < count; i += 4 {
|
|
id := uuid.New().ID()
|
|
idBytes := uintToBytes(id)
|
|
copy(buf[i:], idBytes)
|
|
}
|
|
return buf
|
|
}
|