Skip to content

Commit

Permalink
Add a few more fetch convenience functions
Browse files Browse the repository at this point in the history
Incremental ones, and one that takes a
already fetch specification (e.g. from a code
model ...)
  • Loading branch information
helje5 committed Dec 4, 2024
1 parent 1c7a662 commit 2cf3bf7
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 18 deletions.
99 changes: 82 additions & 17 deletions Sources/ZeeQL/Access/AccessDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,19 +146,63 @@ open class AccessDataSource<Object: SwiftObject> : DataSource<Object>,

public extension AccessDataSourceType {

/**
* This method takes the name of a fetch specification. It looks up the fetch
* spec in the ``Entity`` associated with the datasource and then binds the
* spec with the given key/value pairs.
*
* Example:
* ```swift
* try ds.fetchObjects(myFetchSpec, ["contactId": 12345]) { contact in
* print("Contact:", contact)
* }
* ```
*
* This calls ``FetchSpecification/fetchSpecificiationWith(bindings:)-585ip``
* and passes in the given key/value pair (contactId=12345).
*
* Finally the fetch will be performed using
* ``_primaryFetchObjects``.
*
* - Parameters:
* - fetchSpecification: The ``FetchSpecification`` to use.
* - keysAndValues: The key/value pairs to apply as bindings.
*/
@inlinable
func fetchObjects(_ fetchSpecification: FetchSpecification,
_ binds: [ String : Any ] = [:],
yield: ( Object ) throws -> Void) throws
{
if !binds.isEmpty {
guard let fs = try fetchSpecification
.fetchSpecificiationWith(bindings: binds) else
{
throw AccessDataSourceError
.CouldNotResolveBindings(fetchSpecification: fetchSpecification,
bindings: binds)
}
try _primaryFetchObjects(fs) { try yield($0) }
}
else {
try _primaryFetchObjects(fetchSpecification) { try yield($0) }
}
}

/**
* This method takes the name of a fetch specification. It looks up the fetch
* spec in the `Entity` associated with the datasource and then binds the
* spec with the given key/value pairs.
*
* Example:
* ```swift
* let persons = try ds.fetchObjects("myContacts", ["contactId": 12345])
* try ds.fetchObjects("myContacts", ["contactId": 12345]) { contact in
* print("Contact:", contact)
* }
* ```
*
* This will lookup the `FetchSpecification` named "myContacts" in
* the `Entity` of the datasource. It then calls
* `fetchSpecificationWithQualifierBindings()`
* ``FetchSpecification/fetchSpecificiationWith(bindings:)-585ip``
* and passes in the given key/value pair (contactId=12345).
*
* Finally the fetch will be performed using
Expand All @@ -167,15 +211,16 @@ public extension AccessDataSourceType {
* - Parameters:
* - fetchSpecificationName: The name of the fetch specification to use.
* - keysAndValues: The key/value pairs to apply as bindings.
* - Returns: The fetched objects.
*/
@inlinable
func fetchObjects(_ fetchSpecificationName: String,
_ binds: [ String : Any ] = [:]) throws -> [ Object ]
_ binds: [ String : Any ] = [:],
yield: ( Object ) throws -> Void) throws
{
guard let findEntity = entity else {
// TBD: improve exception
log.error("did not find entity, cannot construct fetchspec");
log.error("did not find entity, cannot construct fetchspec:",
fetchSpecificationName)
throw AccessDataSourceError.MissingEntity
}

Expand All @@ -184,21 +229,41 @@ public extension AccessDataSourceType {
.DidNotFindFetchSpecification(name: fetchSpecificationName,
entity: findEntity)
}

return try fetchObjects(fs, binds, yield: yield)
}

/**
* This method takes the name of a fetch specification. It looks up the fetch
* spec in the `Entity` associated with the datasource and then binds the
* spec with the given key/value pairs.
*
* Example:
* ```swift
* let persons = try ds.fetchObjects("myContacts", ["contactId": 12345])
* ```
*
* This will lookup the `FetchSpecification` named "myContacts" in
* the `Entity` of the datasource. It then calls
* `fetchSpecificationWithQualifierBindings()`
* and passes in the given key/value pair (contactId=12345).
*
* Finally the fetch will be performed using
* ``_primaryFetchObjects``.
*
* - Parameters:
* - fetchSpecificationName: The name of the fetch specification to use.
* - keysAndValues: The key/value pairs to apply as bindings.
* - Returns: The fetched objects.
*/
@inlinable
func fetchObjects(_ fetchSpecificationName: String,
_ binds: [ String : Any ] = [:]) throws -> [ Object ]
{
var results = [ Object ]()
if !binds.isEmpty {
guard let fs = try fs.fetchSpecificiationWith(bindings: binds) else {
throw AccessDataSourceError
.CouldNotResolveBindings(fetchSpecification: fs, bindings: binds)
}
try _primaryFetchObjects(fs) { results.append($0) }
}
else {
try _primaryFetchObjects(fs) { results.append($0) }
}
try fetchObjects(fetchSpecificationName, binds) { results.append($0) }
return results
}

/**
* This method takes the name of a fetch specification. It looks up the fetch
* spec in the `Entity` associated with the datasource and then binds the
Expand Down
2 changes: 1 addition & 1 deletion Sources/ZeeQL/Access/AccessDataSourceError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,5 @@ public enum AccessDataSourceError: Swift.Error {

case DidNotFindFetchSpecification(name: String, entity: Entity)
case CouldNotResolveBindings(fetchSpecification: FetchSpecification,
bindings: [ String : Any])
bindings: Any)
}

0 comments on commit 2cf3bf7

Please sign in to comment.