Kitura / Swift-Kuery-ORM

An ORM for Swift, built on Codable
Apache License 2.0
212 stars 30 forks source link

Select issue on Swift-Kuery-ORM: 0.4.x #92

Closed diuming closed 5 years ago

diuming commented 5 years ago

Swift-Kuery-ORM: 0.4.1 PostgreSQL: 10.6

Please! take a look getUsers(email: String) function in User Model. getUsers(query: query1) occurs an error

User Model

struct User: Codable {
    static var tableName =  "Users"
    var id: String =  UUID.init().uuidString
    var name: String
    var password: String
    var email: String
}

extension User: Model {

    static func getUsers(email: String) throws -> [User] {
        let table = try User.getTable()
        let column = try table.column(for: "email")
        let query1 = Select(column, from: table).where ( column == email )
        let query2 = Select(from: table).where ( column == email )
        return try getUsers(query: query1)
    }

    private static func getUsers(query: Query) throws -> [User] {
        let wait = DispatchSemaphore(value: 0)
        var reqError = RequestError.notFound
        var reqUsers: [User]?
        User.executeQuery(query: query, parameters: nil) { results, error in
            if let users = results {
                reqUsers = users
            } else if let e = error {
                reqError = e
            }
            wait.signal()
        }
        wait.wait()
        if let reqUsers = reqUsers, reqUsers.count > 0 {
            return reqUsers
        } else {
            throw reqError
        }
    }
}

extension Table

public extension Table {
    public func column(for name: String) throws -> Column {
        guard let column = self.columns.first(where: { $0.name == name }) else {
            throw RequestError.notFound
        }
        return column
    }
}
kilnerm commented 5 years ago

I will recreate the issue and do some investigation.

kilnerm commented 5 years ago

@diuming, The reason you get the error running query1 is that the rows returned by it do not contain the fields necessary for decoding into your User model (they only return the email field).

A query defined as let query3 = Select(fields: [idColumn, nameColumn, passwordColumn, emailColumn], from: [table]) is successful as all the columns are returned.

Let me know if you have any further questions.

diuming commented 5 years ago

@kilnerm thanks for replying

the query3 looks like the query2, right? SELECT * FROM Users WHERE email == "abc@cde.def";

I just want to select specific columns, example SELECT email FROM Users WHERE email == "abc@cde.def"

So, as you means I can only use query2 and query3 for Model, Right?

kilnerm commented 5 years ago

@diuming, the executeQuery API will return you an array of decoded models. Because your query1 does not include all the fields to allow the results to be decoded you see the error.

Your queries will need to retrieve all fields to be able to decode into Models. If you want to get a subset of data back from your tables you could use a connection to execute basic SwiftKuery operations.

diuming commented 5 years ago

@kilnerm Got it! thx