Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Row scopes collection, breadth-first scope search #335

Merged
merged 10 commits into from
Apr 20, 2018
Merged

Conversation

groue
Copy link
Owner

@groue groue commented Apr 19, 2018

This PR enhances row scopes. The changes only impact hard-core users, GRDB internals, and pave the way to associations in GRDB3.

Row scopes are now accessed through a dedicated collection:

// Define a tree of nested scopes
let adapter = ScopeAdapter([
    "foo": RangeRowAdapter(0..<1),
    "bar": RangeRowAdapter(1..<2).addingScopes([
        "baz" : RangeRowAdapter(2..<3)])])

// Fetch
let sql = "SELECT 1 AS foo, 2 AS bar, 3 AS baz"
let row = try Row.fetchOne(db, sql, adapter: adapter)!

row               // [foo:1, bar:2, baz:3]

row.scopes.count  // 2
row.scopes.names  // ["foo", "bar"]

row.scopes["foo"] // [foo:1]
row.scopes["bar"] // [bar:2]
row.scopes["baz"] // nil

for (name, scopedRow) in row.scopes {
    print(name, scopedRow)
}

The tree of nested scopes has its own dedicated view as well, that performs a breadth-first search of scope names:

row.scopesTree.names  // ["foo", "bar", "baz"]

row.scopesTree["foo"] // [foo:1]
row.scopesTree["bar"] // [bar:2]
row.scopesTree["baz"] // [baz:3]

This breadth-first search in the tree of nested scopes is now used when extracting records from rows. This will be paramount for associations ergonomics, so that the user can decode flat records from hierarchical scopes:

// From this hierarchical request made from associations...
let request = Book
    .including(required: Book.author
        .including(optional: Author.country))
    .including(optional: Bool.coverImage)

// ... you will decode flat records like the one below:
struct BookInfo: FetchableRecord, Decodable {
    var book: Book
    var author: Author
    var country: Country?
    var coverImage: CoverImage?
}
let bookInfos = try BookInfo.fetchAll(db, request) // [BookInfo]

// ... or perform explicit row decoding:
let rows = try Row.fetchCursor(db, request)
while let row = try rows.next() {
    let book = Book(row: row)
    let author: Author = row["author"]
    let country: Country? = row["country"]
    let coverImage: CoverImage? = row["coverImage"]
}

@groue groue added this to the GRDB 3.0 milestone Apr 19, 2018
@groue groue mentioned this pull request Apr 19, 2018
29 tasks
@groue groue merged commit 1e7e011 into GRDB3 Apr 20, 2018
@groue groue deleted the GRDB3-RowLookup branch April 20, 2018 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant