Closed JetForMe closed 2 years ago
I managed to add it to my local project easy enough with:
extension UUID: Value {
public static var declaredDatatype: String {
Blob.declaredDatatype
}
// swiftlint:disable:next force_unwrapping
public static func fromDatatypeValue(_ dataValue: Blob) -> UUID { UUID(data: Data(dataValue.bytes))! }
// swiftlint:disable:next force_unwrapping
public var datatypeValue: Blob { data.withUnsafeBytes { Blob(bytes: $0.baseAddress!, length: data.count) } }
}
I can use it in an expression like any other type:
Expression
I think I have a few more extensions to make this work:
public extension UUID {
/// Construct a `UUID` from raw `Data`
init?(data: Data) {
guard data.count == 16 else {
return nil
}
self = UUID(uuid: BytesToUUID(data.bytes))
}
/// Returns a `Data` representation of the UUID
var data: Data {
var raw = uuid
return withUnsafeBytes(of: &raw) { Data($0) }
}
}
// swiftlint:disable:next identifier_name
private func BytesToUUID( _ u: [UInt8] ) -> uuid_t {
( u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7], u[8], u[9], u[10], u[11], u[12], u[13], u[14], u[15])
}
Should be fixed by #981. Tell me if there's something wrong.
Why are UUID values stored as Strings instead of Blobs? It seems it would be more efficient to store as blobs since they are fixed length binary data. Doesn't string comparison involve extra Unicode overhead?
In #981 it was decided to "Storing them as string for better readability in the database", i.e. it was optimized for human legibility.
Probably not a good call, given that you can always use hex(...)
to turn them back into a string.
Unfortunately the prevents me from storing it as a blob. I used to have a extension UUID: Value { }
to handle UUID natively as a Blob. When I updated to a newer version of SQLite.swift it was in conflict with the new built-in one.
Human readability isn't as important as performance, especially since you can just run
.mode quote
in sqlite3 and make blobs completely readable.
Update on my op: Vapor is storing them as SQLite native UUID type, and the sqlite3
CLI renders them as a human-readable string.
I agree that string storage is not a great default setting, it's really wasteful in terms of space. Ideally, the user of the library should be able to pick the correct serialization format required. Given the static nature of extensions in Swift, I'm not sure how feasible this is.
There is also the whole issue of
"BB585245-7338-4638-8DF5-BF20B9EDD589" != "bb585245-7338-4638-8df5-bf20b9edd589"
Which would go away if they were stored as blobs.
Build Information
General guidelines
Could we get support for
UUID
? I’m working on adding it, and it seemed that SQLite supported it natively, but I think Vapor just created my table with that as the type name. I'm trying to figure out what it really is underneath. Ah, it must be string. Pity, that's wasteful of space.