 //: The resulting code is not as streamlined as usual GRDB code, but we could
 //: already do what we needed without much effort.
 //:
+//: ## Custom Protocol: MyDatabaseDecoder
+//:
 //: In the rest of this playground, we will define a **new realm of requests**.
 //:
 //: GRDB ships with three build-in realms of requests: requests of raw rows,

//: few extensions that guarantee the most efficient use of GRDB, and have the
//: Base class adopt this protocol.
//:
//: But first, let's see how polymorphic decoding can be done as simply as
//: possible. After all, it is useless to design a full-fledged protocol unless
//: we need to use this protocol several times, or write code that is as
//: streamlined as possible. Keep it simple, stupid!
//:
//: Can we fetch Foo and Bar values from an SQL request? Sure:


    }
}

try dbQueue.read { db in
    print("> Fetch from request")
    let request = Base.all()
    let bases = try request.fetchAll(db)
    for base in bases {
        print(base.description)
    }
}

//: Types that adopt both FetchableRecord and TableRecord are able to fetch
//: right from the base type. Let's allow this as well for MyDatabaseDecoder:
//:
//:     try dbQueue.read { db in
//:         try Base.fetchCursor(db) // Cursor of Base
//:         try Base.fetchAll(db)    // [Base]
//:         try Base.fetchOne(db)    // Base?
//:     }
extension MyDatabaseDecoder where Self: TableRecord {
    static func fetchCursor(_ db: Database) throws -> MapCursor<RowCursor, DecodedType> {
        return try all().fetchCursor(db)
    }
    
    static func fetchAll(_ db: Database) throws -> [DecodedType] {
        return try all().fetchAll(db)
    }
    
    static func fetchOne(_ db: Database) throws -> DecodedType? {
        return try all().fetchOne(db)
    }
}

try dbQueue.read { db in
    print("> Fetch from base type")
    let bases = try Base.fetchAll(db)
    for base in bases {
        print(base.description)
    }
}

//: Finally, you don't have a true GRDB record unless it allows fetching from
//: raw SQL:
//:
//:     try dbQueue.read { db in
//:         try Base.fetchCursor(db, "SELECT ...") // Cursor of Base
//:         try Base.fetchAll(db, "SELECT ...")    // [Base]
//:         try Base.fetchOne(db, "SELECT ...")    // Base?
//:     }
extension MyDatabaseDecoder {
    static func fetchCursor(_ db: Database, _ sql: String, arguments: StatementArguments? = nil, adapter: RowAdapter? = nil) throws -> MapCursor<RowCursor, DecodedType> {
        return try fetchCursor(db, SQLRequest<Self>(sql, arguments: arguments, adapter: adapter))
    }
