Skip to content

Commit

Permalink
Type out the ctx.fetchObjects methods
Browse files Browse the repository at this point in the history
Bind them to a specific DatabaseObject type,
makes sense.
There is still some `Any` in the stack that
should be removed, but this is a better starting
point.
Also rename the now-outdated method name.
  • Loading branch information
helje5 committed Nov 27, 2024
1 parent 3724bdf commit 5d1d939
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 47 deletions.
21 changes: 11 additions & 10 deletions Sources/ZeeQL/Access/DatabaseChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ZeeQL
//
// Created by Helge Hess on 27/02/17.
// Copyright © 2017-2020 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

open class DatabaseChannelBase {
Expand Down Expand Up @@ -722,7 +722,7 @@ open class DatabaseChannelBase {
*
* - returns: null if there are no more objects, or the fetched object/record
*/
func fetchObject() -> DatabaseObject? {
public func fetchObject() -> DatabaseObject? {
/* use iterator if the objects are already fetched in total */
// TODO: make the function throws

Expand Down Expand Up @@ -1116,11 +1116,12 @@ open class DatabaseChannelBase {

// MARK: - Typed Concrete Class

open class TypedDatabaseChannel<ObjectType: DatabaseObject> : DatabaseChannelBase,
IteratorProtocol
open class TypedDatabaseChannel<ObjectType> : DatabaseChannelBase,
IteratorProtocol
where ObjectType: DatabaseObject
{

public var objects : IndexingIterator<[ObjectType]>?
public var objects : IndexingIterator<[ ObjectType ]>?

override var hasObjectIterator : Bool { return objects != nil }

Expand Down Expand Up @@ -1166,15 +1167,15 @@ open class TypedDatabaseChannel<ObjectType: DatabaseObject> : DatabaseChannelBas
* This is the primary method for fetches and has additional handling for
* prefetched relationships.
*
* - parameters:
* - Parameters:
* - fs: The FetchSpecification which outlines how objects are being
* fetched.
* - ec: TODO
*/
override func selectObjectsWithFetchSpecification(_ fs: FetchSpecification,
_ ec: ObjectTrackingContext?
= nil)
throws
override public func selectObjectsWithFetchSpecification(
_ fs: FetchSpecification,
_ ec: ObjectTrackingContext? = nil
) throws
{
guard let prefetchRelPathes = fs.prefetchingRelationshipKeyPathes,
!prefetchRelPathes.isEmpty
Expand Down
27 changes: 17 additions & 10 deletions Sources/ZeeQL/Access/DatabaseContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ZeeQL
//
// Created by Helge Hess on 03/03/2017.
// Copyright © 2017-2019 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

/**
Expand Down Expand Up @@ -50,21 +50,28 @@ public class DatabaseContext : ObjectStore, SmartDescription {
}
}

public func objectsWith(fetchSpecification fs : FetchSpecification,
in tc : ObjectTrackingContext,
_ cb : ( Any ) -> Void) throws
@inlinable
public func objectsWithFetchSpecification<O>(
_ fetchSpecification : FetchSpecification,
in trackingContext : ObjectTrackingContext,
_ yield : ( O ) throws -> Void
) throws
where O: DatabaseObject
{
if fs.requiresAllQualifierBindingVariables {
if let keys = fs.qualifier?.bindingKeys, !keys.isEmpty {
throw Error.FetchSpecificationHasUnresolvedBindings(fs)
if fetchSpecification.requiresAllQualifierBindingVariables {
if let keys = fetchSpecification.qualifier?.bindingKeys, !keys.isEmpty {
throw Error.FetchSpecificationHasUnresolvedBindings(fetchSpecification)
}
}

let ch = DatabaseChannel(database: database)
try ch.selectObjectsWithFetchSpecification(fs, tc)
let ch = TypedDatabaseChannel<O>(database: database)
try ch
.selectObjectsWithFetchSpecification(fetchSpecification, trackingContext)

while let o = ch.fetchObject() {
cb(o)
assert(o is O)
guard let typed = o as? O else { continue }
try yield(typed)
}
}

Expand Down
7 changes: 1 addition & 6 deletions Sources/ZeeQL/Access/DatabaseDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ open class DatabaseDataSource<Object: DatabaseObject>
yield: ( Object ) throws -> Void)
throws
{
let results = try objectContext.objectsWith(fetchSpecification: fs)
for result in results {
assert(result is Object)
guard let object = result as? Object else { continue }
try yield(object)
}
try objectContext.objectsWithFetchSpecification(fs, yield)
}
}
16 changes: 9 additions & 7 deletions Sources/ZeeQL/Control/ObjectStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ZeeQL
//
// Created by Helge Hess on 17/02/17.
// Copyright © 2017-2019 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

public protocol ObjectWithGlobalID {
Expand All @@ -15,14 +15,16 @@ public protocol ObjectWithGlobalID {
* A store which stores objects :-)
*
* Current subclasses:
* - `ObjectTrackingContext` (an object uniquer)
* - `DatabaseContext` (a store on top of `Database`)
* - ``ObjectTrackingContext`` (an object uniquer)
* - ``DatabaseContext`` (a store on top of `Database`)
*/
public protocol ObjectStore {

// TBD: add throws?
func objectsWith(fetchSpecification : FetchSpecification,
in tc : ObjectTrackingContext,
_ cb : ( Any ) -> Void) throws
func objectsWithFetchSpecification<O>(
_ fetchSpecification : FetchSpecification,
in trackingContext : ObjectTrackingContext,
_ yield : ( O ) throws -> Void
) throws
where O: DatabaseObject

}
47 changes: 33 additions & 14 deletions Sources/ZeeQL/Control/ObjectTrackingContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,47 @@ open class ObjectTrackingContext : ObjectStore {

/**
* Fetches the objects for the given specification. This works by calling
* `objectsWith(fetchSpecification:in:)` with the tracking context itself.
* ``objectsWithFetchSpecification(_:in:_:)`` with the tracking context
* itself.
*/
@inlinable
open func objectsWith(fetchSpecification fs: FetchSpecification) throws
-> [ Any ]
open func objectsWithFetchSpecification<O>(_ type: O.Type = O.self,
_ fs: FetchSpecification) throws
-> [ O ]
where O: DatabaseObject
{
var objects = [ Any ]()
try objectsWith(fetchSpecification: fs, in: self) {
objects.append($0)
}
var objects = [ O ]()
try objectsWithFetchSpecification(fs) { objects.append($0) }
return objects
}

/**
* This method asks the `rootObjectStore` to fetch the objects specified
* in the _fs.
* Objects will get registered in the given tracking context.
* Fetches the objects for the given specification. This works by calling
* ``objectsWithFetchSpecification(_:in:_:)`` with the tracking context
* itself.
*/
@inlinable
open func objectsWithFetchSpecification<O>(_ fs: FetchSpecification,
_ cb: ( O ) throws -> Void) throws
where O: DatabaseObject
{
return try objectsWithFetchSpecification(fs, in: self, cb)
}

/**
* This method asks the ``rootObjectStore`` to fetch the objects specified
* in the _fs (usually a ``DatabaseContext``).
*
* Objects will get registered in the given tracking context (usually `self`
* for ``ObjectTrackingContext``)
*
* This is the primitve method of ``ObjectStore``.
*/
@inlinable
open func objectsWith(fetchSpecification fs: FetchSpecification,
in tc: ObjectTrackingContext,
_ cb: ( Any ) -> Void) throws
open func objectsWithFetchSpecification<O>(_ fs: FetchSpecification,
in tc: ObjectTrackingContext,
_ cb: ( O ) throws -> Void) throws
where O: DatabaseObject
{
if fs.requiresAllQualifierBindingVariables {
if let q = fs.qualifier {
Expand All @@ -77,7 +96,7 @@ open class ObjectTrackingContext : ObjectStore {
}
}

return try rootObjectStore.objectsWith(fetchSpecification: fs, in: tc, cb)
return try rootObjectStore.objectsWithFetchSpecification(fs, in: tc, cb)
}


Expand Down

0 comments on commit 5d1d939

Please sign in to comment.