vapor-community / postgresql

Robust PostgreSQL interface for Swift
MIT License
131 stars 33 forks source link

Error encoding array of enums as jsonb #78

Open mcritz opened 5 years ago

mcritz commented 5 years ago

I’d like to encode an array of enums, but get the following error during migration:

Fatal error: Error raised at top level: ⚠️ PostgreSQL Error: column "priviliges" is of type jsonb[] but expression is of type smallint[] - id: PostgreSQLError.server.error.transformAssignedExpr

Any help would be appreciated, thank you.

reproduce with:

import Foundation
import Foundation
import Authentication
import FluentPostgreSQL
import Crypto
enum Privilege: UInt8, Codable {
    case createPost,
    updateOtherUserPost,
    createTopic,
    adminUsers

    static var allPriviliges: [Privilege] {
        get {
            return [
            .createPost,
            .updateOtherUserPost,
            .createTopic,
            .adminUsers
            ]
        }
    }
}

You’ll need a basic User with id, email, username, password, and privs: [Privilege].

struct AdminUser: Migration {
    typealias Database = PostgreSQLDatabase

    static func prepare(on conn: PostgreSQLConnection) -> EventLoopFuture<Void> {
        let adminUsername = Environment.get("ADMIN_USER")
        let adminEmail = Environment.get("ADMIN_EMAIL")
        let envPassword = Environment.get("ADMIN_PASSWORD")
        guard let password = envPassword, password.count > 7,
            let username = adminUsername,
            let email = adminEmail
            else {
                fatalError("Required Admin values not set in environment")
        }
        let maybeEncryptedPassword = try? BCrypt.hash(password)
        guard let encryptedPassword = maybeEncryptedPassword else {
            fatalError("Admin password could not be encrypted")
        }
        let admin = User(id: nil,
                         email: email,
                         username: username,
                         password: encryptedPassword,
                         privs: Privilege.allPriviliges)
        return admin.save(on: conn).transform(to: ())
    }
    static func revert(on conn: PostgreSQLConnection) -> EventLoopFuture<Void> {
        return .done(on: conn)
    }
}

Things attempted: change enum type to String, Codable, Uint, Codable. Using just privs: [. adminUsers] in User().

baldoph commented 4 years ago

Fighting with this as I speak