Skip to content

Commit

Permalink
Drop some optional arrays in the fetchspec
Browse files Browse the repository at this point in the history
The empty array has no relevant overhead in Swift,
just use that and make code simpler.
Affects:
- `fetchAttributeNames`
- `sortOrderings`
- `prefetchingRelationshipKeyPathes`
  • Loading branch information
helje5 committed Dec 5, 2024
1 parent 251e93d commit 6e83e77
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 136 deletions.
6 changes: 3 additions & 3 deletions Sources/ZeeQL/Access/AccessDataSourceFinders.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ZeeQL
//
// Created by Helge Heß on 22.08.19.
// Copyright © 2019 ZeeZide GmbH. All rights reserved.
// Copyright © 2019-2024 ZeeZide GmbH. All rights reserved.
//

public extension AccessDataSource {
Expand Down Expand Up @@ -206,8 +206,8 @@ public extension AccessDataSource { // Finders

var fs = try fetchSpecificationForFetch()
fs.qualifier = and(q, auxiliaryQualifier)
fs.sortOrderings = nil /* no sorting, makes DB faster */
fs.fetchLimit = 1 /* we just want to find one record */
fs.sortOrderings = [] /* no sorting, makes DB faster */
fs.fetchLimit = 1 /* we just want to find one record */
return fs
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/ZeeQL/Access/ActiveDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ open class ActiveDataSource<Object: ActiveRecordType>: AccessDataSource<Object>,
var cfs = fs
cfs.fetchesReadOnly = true
cfs.fetchAttributeNames = pkeys
cfs.prefetchingRelationshipKeyPathes = nil
cfs.prefetchingRelationshipKeyPathes = []

let pkeyAttrs = pkeys.compactMap { entity[attribute: $0] }
assert(pkeyAttrs.count == pkeys.count, "could not lookup all pkeys!")
Expand Down Expand Up @@ -177,7 +177,7 @@ open class ActiveDataSource<Object: ActiveRecordType>: AccessDataSource<Object>,
// The idea is that this preserves the WHERE part of the query, including
// relationships.
var cfs = fs
cfs.sortOrderings = nil // no need to sort
cfs.sortOrderings = [] // no need to sort

// hm, well, OK.
cfs.fetchLimit = 1 // TBD: could use '2' to detect query issues
Expand Down
4 changes: 2 additions & 2 deletions Sources/ZeeQL/Access/AdaptorChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,8 @@ public extension AdaptorChannel { // MARK: - Operations
attributes = attrs
}
else if let entity = e {
if let fs = fs, let an = fs.fetchAttributeNames {
attributes = entity.attributesWithNames(an)
if let fs = fs, !fs.fetchAttributeNames.isEmpty {
attributes = entity.attributesWithNames(fs.fetchAttributeNames)
}
else {
attributes = entity.attributes
Expand Down
14 changes: 6 additions & 8 deletions Sources/ZeeQL/Access/DatabaseChannel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1186,9 +1186,7 @@ open class TypedDatabaseChannel<ObjectType> : DatabaseChannelBase,
_ ec: ObjectTrackingContext? = nil
) throws
{
guard let prefetchRelPathes = fs.prefetchingRelationshipKeyPathes,
!prefetchRelPathes.isEmpty else
{
guard !fs.prefetchingRelationshipKeyPathes.isEmpty else {
/* simple case, no prefetches */
return try primarySelectObjectsWithFetchSpecification(fs, ec)
}
Expand Down Expand Up @@ -1273,7 +1271,8 @@ open class TypedDatabaseChannel<ObjectType> : DatabaseChannelBase,

do {
try fetchRelationships(fs.entity, entityName,
prefetchRelPathes, baseObjects, ec)
fs.prefetchingRelationshipKeyPathes,
baseObjects, ec)
}
catch {
cancelFetch()
Expand Down Expand Up @@ -1347,9 +1346,7 @@ open class DatabaseChannel : DatabaseChannelBase, IteratorProtocol {
= nil)
throws
{
guard let prefetchRelPathes = fs.prefetchingRelationshipKeyPathes,
!prefetchRelPathes.isEmpty
else {
guard !fs.prefetchingRelationshipKeyPathes.isEmpty else {
/* simple case, no prefetches */
return try primarySelectObjectsWithFetchSpecification(fs, ec)
}
Expand Down Expand Up @@ -1425,7 +1422,8 @@ open class DatabaseChannel : DatabaseChannelBase, IteratorProtocol {

do {
try fetchRelationships(fs.entity, entityName,
prefetchRelPathes, baseObjects, ec)
fs.prefetchingRelationshipKeyPathes,
baseObjects, ec)
}
catch {
cancelFetch()
Expand Down
20 changes: 4 additions & 16 deletions Sources/ZeeQL/Access/ModelLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,8 @@ open class CoreDataModelLoader : ModelLoader {
}
else { limit = nil }

let sos : [ SortOrdering ]? = nil
var fs = ModelFetchSpecification(entity: entity, qualifier: q,
sortOrderings: sos, limit: limit)
sortOrderings: [], limit: limit)

fs.usesDistinct = boolValue(attrs["returnDistinctResults"])

Expand Down Expand Up @@ -356,30 +355,19 @@ open class CoreDataModelLoader : ModelLoader {
for xml in xml.childElementsWithName("ordering") {
// `<ordering key="name" />` (multiple are possible!)
guard let ordering = loadSortOrdering(from: xml) else { continue }
if fs.sortOrderings == nil { fs.sortOrderings = [] }
fs.sortOrderings?.append(ordering)
fs.sortOrderings.append(ordering)
}

if let v = attrs["attributes"]?.split(separator: ","), !v.isEmpty {
if fs.fetchAttributeNames == nil {
fs.fetchAttributeNames = v.map(String.init)
}
else {
fs.fetchAttributeNames?.append(contentsOf: v.map(String.init))
}
fs.fetchAttributeNames.append(contentsOf: v.map(String.init))
}
for xml in xml.childElementsWithName("attributes") {
// <attributes>objectId,permissions</attributes>
guard let v = xml.textContent?.split(separator: ","), !v.isEmpty else {
assertionFailure("<attributes> tag w/o content?")
continue
}
if fs.fetchAttributeNames == nil {
fs.fetchAttributeNames = v.map(String.init)
}
else {
fs.fetchAttributeNames?.append(contentsOf: v.map(String.init))
}
fs.fetchAttributeNames.append(contentsOf: v.map(String.init))
}
if let xml = xml.firstChildElementWithName("qualifier") {
// <qualifier>(principalId IN $authIds) AND (objectId IN $ids)</qualifier>
Expand Down
30 changes: 15 additions & 15 deletions Sources/ZeeQL/Access/TypedFetchSpecification.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ public struct TypedFetchSpecification<Object: DatabaseObject>
return nil
}

public var fetchAttributeNames : [ String ]?
public var fetchAttributeNames = [ String ]()
public var qualifier : Qualifier?
public var sortOrderings : [ SortOrdering ]?
public var sortOrderings = [ SortOrdering ]()
public var fetchLimit : Int?
public var fetchOffset : Int?
public var hints = [ String : Any ]()
Expand All @@ -55,14 +55,14 @@ public struct TypedFetchSpecification<Object: DatabaseObject>
public var fetchesRawRows = false
public var fetchesReadOnly = false
public var requiresAllQualifierBindingVariables = false
public var prefetchingRelationshipKeyPathes : [ String ]?
public var prefetchingRelationshipKeyPathes = [ String ]()

@inlinable
public init(entityName : String? = nil,
qualifier : Qualifier? = nil,
sortOrderings : [ SortOrdering ]? = nil,
limit : Int? = nil,
prefetch : [ String ]? = nil,
public init(entityName : String? = nil,
qualifier : Qualifier? = nil,
sortOrderings : [ SortOrdering ] = [],
limit : Int? = nil,
prefetch : [ String ] = [],
requiresAllQualifierBindingVariables: Bool = false)
{
self._entityName = entityName
Expand All @@ -76,10 +76,10 @@ public struct TypedFetchSpecification<Object: DatabaseObject>

@inlinable
public init(entity : Entity,
qualifier : Qualifier? = nil,
sortOrderings : [ SortOrdering ]? = nil,
limit : Int? = nil,
prefetch : [ String ]? = nil,
qualifier : Qualifier? = nil,
sortOrderings : [ SortOrdering ] = [],
limit : Int? = nil,
prefetch : [ String ] = [],
requiresAllQualifierBindingVariables: Bool = false)
{
self._entity = entity
Expand All @@ -94,9 +94,9 @@ public struct TypedFetchSpecification<Object: DatabaseObject>
/// Initialize w/ a qualifier string.
public init(entity : Entity,
_ q : String,
sortOrderings : [ SortOrdering ]? = nil,
limit : Int? = nil,
prefetch : [ String ]? = nil)
sortOrderings : [ SortOrdering ] = [],
limit : Int? = nil,
prefetch : [ String ] = [])
{
self._entity = entity
self.qualifier = qualifierWith(format: q)
Expand Down
4 changes: 2 additions & 2 deletions Sources/ZeeQL/Control/ArrayDataSource.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,9 @@ open class ArrayDataSource<Object: SwiftObject> : DataSource<Object>,
}


if let sos = fs.sortOrderings, !sos.isEmpty {
if !fs.sortOrderings.isEmpty {
// TODO: sort
log.warn("not applying sort orderings", self, sos)
log.warn("not applying sort orderings", self, fs.sortOrderings)
}

let count = filtered.count
Expand Down
8 changes: 3 additions & 5 deletions Sources/ZeeQL/Control/EntityType+Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ public extension EntityType {
// TBD: maybe rename, 'select' should run the actual select, right?

@inlinable
static func select(_ attributes: String...)
-> FetchSpecification
{
static func select(_ attributes: String...) -> FetchSpecification {
var fs = ModelFetchSpecification(entity: Self.entity)
fs.fetchAttributeNames = attributes.isEmpty ? nil : attributes
fs.fetchAttributeNames = attributes
return fs
}

Expand Down Expand Up @@ -57,7 +55,7 @@ public extension TypedEntityType where Self: DatabaseObject {
-> TypedFetchSpecification<Self>
{
var fs = TypedFetchSpecification<Self>(entity: Self.entity)
fs.fetchAttributeNames = attributes.isEmpty ? nil : attributes
fs.fetchAttributeNames = attributes
return fs
}

Expand Down
65 changes: 24 additions & 41 deletions Sources/ZeeQL/Control/FetchSpecification+Builder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,8 @@ public extension FetchSpecification {
{
transform {
if clear { $0.prefetchingRelationshipKeyPathes = [] }
if $0.prefetchingRelationshipKeyPathes == nil {
$0.prefetchingRelationshipKeyPathes = [ path ]
}
else {
$0.prefetchingRelationshipKeyPathes?.append(path)
$0.prefetchingRelationshipKeyPathes?.append(contentsOf: more)
}
$0.prefetchingRelationshipKeyPathes.append(path)
$0.prefetchingRelationshipKeyPathes.append(contentsOf: more)
}
}
@inlinable
Expand All @@ -114,14 +109,8 @@ public extension FetchSpecification {
// `fs.prefetch(Person.e.company.addresses)`
transform {
if clear { $0.prefetchingRelationshipKeyPathes = [] }
if $0.prefetchingRelationshipKeyPathes == nil {
$0.prefetchingRelationshipKeyPathes = [ path.name ]
}
else {
$0.prefetchingRelationshipKeyPathes?.append(path.name)
$0.prefetchingRelationshipKeyPathes?
.append(contentsOf: more.map(\.name))
}
$0.prefetchingRelationshipKeyPathes.append(path.name)
$0.prefetchingRelationshipKeyPathes.append(contentsOf: more.map(\.name))
}
}

Expand All @@ -131,22 +120,22 @@ public extension FetchSpecification {
@inlinable
func order(by: SortOrdering, _ e: SortOrdering...) -> Self {
transform {
if let old = $0.sortOrderings { $0.sortOrderings = old + [ by ] + e }
else { $0.sortOrderings = [ by ] + e }
$0.sortOrderings.append(by)
$0.sortOrderings.append(contentsOf: e)
}
}

@inlinable
func order(by: String, _ e: String...) -> Self {
transform {
var ops = [ SortOrdering ]()
if let p = SortOrdering.parse(by) { ops += p }
if let p = SortOrdering.parse(by) { $0.sortOrderings += p }
else { assertionFailure("Could not parse order string")}
for by in e {
if let p = SortOrdering.parse(by) { ops += p }
if let p = SortOrdering.parse(by) {
$0.sortOrderings.append(contentsOf: p)
}
else { assertionFailure("Could not parse order string")}
}

if let old = $0.sortOrderings { $0.sortOrderings = old + ops }
else { $0.sortOrderings = ops }
}
}
}
Expand Down Expand Up @@ -188,8 +177,7 @@ public extension DatabaseFetchSpecification
for key in repeat each key {
let attribute = Object.e[keyPath: key]
let so = SortOrdering(key: AttributeKey(attribute), selector: selector)
if $0.sortOrderings == nil { $0.sortOrderings = [ so ] }
else { $0.sortOrderings?.append(so) }
$0.sortOrderings.append(so)
}
}
}
Expand Down Expand Up @@ -219,7 +207,7 @@ public extension DatabaseFetchSpecification
if clear { $0.prefetchingRelationshipKeyPathes = [] }
for relationship in repeat each relationship {
let relationship = Object.e[keyPath: relationship]
$0.prefetchingRelationshipKeyPathes?.append(relationship.name)
$0.prefetchingRelationshipKeyPathes.append(relationship.name)
}
}
}
Expand All @@ -233,7 +221,7 @@ public extension DatabaseFetchSpecification
if clear { $0.prefetchingRelationshipKeyPathes = [] }
for relationship in repeat each relationship {
let relationship = Object.e[keyPath: relationship]
$0.prefetchingRelationshipKeyPathes?.append(relationship.name)
$0.prefetchingRelationshipKeyPathes.append(relationship.name)
}
}
}
Expand All @@ -247,7 +235,7 @@ public extension DatabaseFetchSpecification
if clear { $0.prefetchingRelationshipKeyPathes = [] }
for relationship in repeat each relationship {
let relationship = Object.e[keyPath: relationship]
$0.prefetchingRelationshipKeyPathes?.append(relationship.name)
$0.prefetchingRelationshipKeyPathes.append(relationship.name)
}
}
}
Expand All @@ -257,17 +245,19 @@ public extension DatabaseFetchSpecification

public extension FetchSpecification {

@inlinable
static func select<T: EntityType>(_ attributes: String..., from: T.Type)
-> FetchSpecification
{
var fs = ModelFetchSpecification(entity: from.entity)
fs.fetchAttributeNames = attributes.isEmpty ? nil : attributes
fs.fetchAttributeNames = attributes
return fs
}


// MARK: - Ordering

@inlinable
func order(by : Attribute...,
asc : Attribute? = nil,
desc : Attribute? = nil,
Expand All @@ -277,35 +267,28 @@ public extension FetchSpecification {
{
var fs = self

var ops = [ SortOrdering ]()

for by in by {
let so = SortOrdering(key: AttributeKey(by), selector: .CompareAscending)
ops.append(so)
fs.sortOrderings.append(so)
}
if let by = asc {
let so = SortOrdering(key: AttributeKey(by), selector: .CompareAscending)
ops.append(so)
fs.sortOrderings.append(so)
}
if let by = desc {
let so = SortOrdering(key: AttributeKey(by), selector: .CompareDescending)
ops.append(so)
fs.sortOrderings.append(so)
}
if let by = iasc {
let so = SortOrdering(key: AttributeKey(by),
selector: .CompareCaseInsensitiveAscending)
ops.append(so)
fs.sortOrderings.append(so)
}
if let by = idesc {
let so = SortOrdering(key: AttributeKey(by),
selector: .CompareCaseInsensitiveDescending)
ops.append(so)
fs.sortOrderings.append(so)
}

guard !ops.isEmpty else { return self }

if let old = fs.sortOrderings { fs.sortOrderings = old + ops }
else { fs.sortOrderings = ops }
return fs
}
}
Loading

0 comments on commit 6e83e77

Please sign in to comment.