Giter Club home page Giter Club logo

Comments (4)

groue avatar groue commented on June 9, 2024

Hello @Craz1k0ek,

Things would have been different if the library had been born after Swift 5.5. But the Row subscript was introduced far before, and I'm reluctant to change apis unless necessary.

And I'm not sure it is necessary. That throwing subscript is not missed. There is no user demand for try row["name"].

You actually describe the situation pretty well:

name = row["namee"] // <-- namee ≠ name, I know, programmer error, but still...

I agree, it is a programmer error. And a crash is a valid answer.

More seriously, the library has always assumed that it deals with trusted local database. Dealing with untrusted databases requires more work. See Advice for failable record initialisation for a longer discussion.

In the end: the topic is not closed, and I'm keen to ear good arguments for a throwing subscript. It just happens that turning programmer errors into runtime errors is not one of them :-)

from grdb.swift.

Craz1k0ek avatar Craz1k0ek commented on June 9, 2024

@groue thanks for your reply. I agree with your comment and I am aware of the fact that this could be a breaking change. We could opt in for additional syntax on the subscript i.e.:

@available(swift, introduced: 5.5)
@inlinable
public subscript<Value: DatabaseValueConvertible & StatementColumnConvertible>(column columnName: String) -> Value {
    get throws {
        try decode(Value.self, forKey: columnName)
    }
}

// Usage example

let name: String = try row[column: "name"]

This way, the existing API should be unaffected and the requested functionality still does become available.

Additionally, after further looking around, I also found the decode functions on the Row such as this one:

// Example from line 1025
func decode<Value: DatabaseValueConvertible>(
    _ type: Value.Type = Value.self,
    forKey columnName: String)
throws -> Value

Would it be an idea to open up this API by marking these functions (and alike functions) public. This should, as far as I can tell, not break the API. This has two nice to haves:

  1. The requested behaviour in the original question is answered, albeit through a different syntax, but it's there. I.e. one can use row.decode(String.self, forKey: "name").
  2. The syntax is very similar as to how the Codable protocol is implemented by Apple. This way, the usage of the Row object is easy to understand for any programmer, as most of us have been using Codable in some way or form for JSON. I guess that's also why the FetchableRecordDecoder has been made available publicly, as this suits the syntax very well.

EDIT:

And I'm not sure it is necessary. That throwing subscript is not missed. There is no user demand for try row["name"].

I am aware that this comment does not answer your comment. I would like to be able to manage the database remotely as well, by allowing migrations, table definitions and such to be downloadable. This would require the subscript of the tables to be done dynamically, but you can image there's room for error when doing things like that.

from grdb.swift.

groue avatar groue commented on June 9, 2024

I would like to be able to manage the database remotely as well, by allowing migrations, table definitions and such to be downloadable. This would require the subscript of the tables to be done dynamically, but you can image there's room for error when doing things like that.

This is a valid use case 👍

Additionally, after further looking around, I also found the decode functions on the Row such as this one:

func decode<Value: DatabaseValueConvertible>(
    _ type: Value.Type = Value.self,
    forKey columnName: String)
throws -> Value

Thanks for your suggestion. Yes, those methods are the ones you are looking for :-) They look similar to Codable api indeed, because I needed some inspiration ;-)

If public, your initial sample code would be turned into:

extension User: FetchableRecord {
    public init(row: Row) throws {
        id = try row.decode(forKey: "id")
        name = try row.decode(forKey: "name")
    }
}

It's not just a matter of making them public, though. The RowDecodingError type would become public as well, so that your app that manages a remote database can catch it and react accordingly.

This error type is currently a dump of everything needed to produce error messages that contain a maximum of information (down to the original SQL statement). It wasn't vetted for public consumption. Since you are interested, it would be helpful if you could tell what you expect from this type!

EDIT: it is also quite probable that users would like to create instances of RowDecodingError. So we also need to take care of that. To sum up, the only remaining difficulty before we can expose throwing row accessors is to make RowDecodingError a good public type that lets people work with it.

from grdb.swift.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.