Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
helje5 committed Nov 8, 2024
2 parents e550adc + 7542c02 commit 520cdbd
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 97 deletions.
93 changes: 63 additions & 30 deletions Sources/ZeeQL/Access/Attribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// ZeeQL
//
// Created by Helge Hess on 18/02/2017.
// Copyright © 2017-2019 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

/**
Expand Down Expand Up @@ -148,7 +148,7 @@ extension Attribute {


/**
* An Attribute description which stores the info as regular variables.
* An ``Attribute`` description which stores the info as regular variables.
*
* Suitable for use with models loaded from XML, or models fetched from a
* database.
Expand All @@ -175,8 +175,15 @@ open class ModelAttribute : Attribute, Equatable {
public final var readFormat : String?
public final var writeFormat : String?

// patterns
public final var isColumnNamePattern = false
/// Pattern types.
public enum PatternType: String, Sendable {
case none = ""
/// The columnName is a pattern
case columnName = "columnName"
/// The attribute should be skipped in the entity.
case skip = "skip"
}
public final var patternType : PatternType = .none

public final var userData = [ String : Any ]()

Expand Down Expand Up @@ -211,14 +218,14 @@ open class ModelAttribute : Attribute, Equatable {
self.valueType = attr.valueType

if let ma = attr as? ModelAttribute {
self.defaultValue = ma.defaultValue
self.comment = ma.comment
self.collation = ma.collation
self.privileges = ma.privileges
self.isColumnNamePattern = ma.isColumnNamePattern
self.defaultValue = ma.defaultValue
self.comment = ma.comment
self.collation = ma.collation
self.privileges = ma.privileges
self.patternType = ma.patternType

self.userData = ma.userData
self.elementID = ma.elementID
self.userData = ma.userData
self.elementID = ma.elementID
}
}

Expand All @@ -233,13 +240,14 @@ open class ModelAttribute : Attribute, Equatable {
// MARK: - Pattern Models

public var isPattern : Bool {
if isColumnNamePattern { return true }
if externalType == nil { return true }
if patternType != .none { return true }
if externalType == nil { return true }
if allowsNull == nil { return true }
return false
}

public func doesColumnNameMatchPattern(_ columnName: String) -> Bool {
if !isColumnNamePattern { return columnName == self.columnName }
if patternType != .columnName { return columnName == self.columnName }
if self.columnName == "*" { return true } // match all

// TODO: fix pattern handling, properly process '*' etc
Expand All @@ -252,27 +260,50 @@ open class ModelAttribute : Attribute, Equatable {
/* derive info */

let rAttr = ModelAttribute(attribute: self)
if let v = attr.externalType { rAttr.externalType = v }
if let v = attr.isAutoIncrement { rAttr.isAutoIncrement = v }
if let v = attr.allowsNull { rAttr.allowsNull = v }
if let v = attr.width { rAttr.width = v }
if let v = attr.readFormat { rAttr.readFormat = v }
if let v = attr.writeFormat { rAttr.writeFormat = v }
if let v = attr.defaultValue { rAttr.defaultValue = v }
if let v = attr.comment { rAttr.comment = v }
if let v = attr.collation { rAttr.collation = v }
if let v = attr.privileges { rAttr.privileges = v }
// The pattern *overrides* the external spec! If you want the information
// schema to win, leave out the value in the pattern.
if rAttr.externalType == nil, let v = attr.externalType {
rAttr.externalType = v
}
if rAttr.isAutoIncrement == nil, let v = attr.isAutoIncrement {
rAttr.isAutoIncrement = v
}
if rAttr.allowsNull == nil, let v = attr.allowsNull {
rAttr.allowsNull = v
}
if rAttr.width == nil, let v = attr.width {
rAttr.width = v
}
if rAttr.readFormat == nil, let v = attr.readFormat {
rAttr.readFormat = v
}
if rAttr.writeFormat == nil, let v = attr.writeFormat {
rAttr.writeFormat = v
}
if rAttr.defaultValue == nil, let v = attr.defaultValue {
rAttr.defaultValue = v
}
if rAttr.comment == nil, let v = attr.comment {
rAttr.comment = v
}
if rAttr.collation == nil, let v = attr.collation {
rAttr.collation = v
}
if rAttr.privileges == nil, let v = attr.privileges {
rAttr.privileges = v
}

/* construct */
rAttr.isColumnNamePattern = false // TBD: do we need to fix the colName?
rAttr.patternType = .none // TBD: do we need to fix the colName?
return rAttr
}

public func addAttributesMatchingAttributes(to list: inout [ Attribute ],
attributes: [ Attribute ],
entity: Entity? = nil) -> Bool
{
if !isColumnNamePattern {
if patternType == .skip { return false }
if patternType != .columnName {
/* check whether we are contained */
// TODO: is this correct, could be more than 1 attribute with the same
// column?
Expand Down Expand Up @@ -307,9 +338,9 @@ open class ModelAttribute : Attribute, Equatable {
/* clone and add */

let attrCopy = ModelAttribute(attribute: self)
attrCopy.name = attr.name
attrCopy.columnName = attr.columnName
attrCopy.isColumnNamePattern = false
attrCopy.name = attr.name
attrCopy.columnName = attr.columnName
attrCopy.patternType = .none
list.append(attrCopy)
}
return true
Expand Down Expand Up @@ -343,10 +374,12 @@ open class ModelAttribute : Attribute, Equatable {
if let cn = columnName {
ms += "["
ms += cn
if isColumnNamePattern { ms += "*" }
if patternType == .columnName { ms += "*" }
ms += "]"
}

if patternType == .skip { ms += " SKIP" }

// TODO: precision
let ws : String
if let w = width { ws = "(\(w))" }
Expand Down
11 changes: 9 additions & 2 deletions Sources/ZeeQL/Access/AttributeKey.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,30 @@
// ZeeQL
//
// Created by Helge Hess on 02/03/17.
// Copyright © 2017 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

/**
* A ``Key`` that has access to an ``Attribute`` (an potentially the associated
* ``Entity``).
*
* The ``Key/key`` is the ``Attribute/name``.
*/
public struct AttributeKey : Key, Equatable {

public var key : String { return attribute.name }

public let entity : Entity?
public let attribute : Attribute

@inlinable
public init(_ attribute: Attribute, entity: Entity? = nil) {
self.attribute = attribute
self.entity = entity
}

@inlinable
public static func ==(lhs: AttributeKey, rhs: AttributeKey) -> Bool {
return lhs.key == rhs.key
}

}
11 changes: 10 additions & 1 deletion Sources/ZeeQL/Access/CodeEntity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,26 @@
// ZeeQL
//
// Created by Helge Hess on 28/02/2017.
// Copyright © 2017 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

#if canImport(Foundation)
import Foundation
#endif

open class CodeEntityBase : Entity {
// Those are available in subclasses, which makes it convenient
// (can't do this in Generic classes, hence this intermediate)
public enum Attribute {
public typealias Int = CodeAttribute<Swift.Int>
public typealias OptInt = CodeAttribute<Swift.Int?>
public typealias String = CodeAttribute<Swift.String>
public typealias NullableString = CodeAttribute<Swift.String?>
public typealias OptString = CodeAttribute<Swift.String?>
#if canImport(Foundation)
public typealias Date = CodeAttribute<Foundation.Date>
public typealias OptDate = CodeAttribute<Foundation.Date?>
#endif
}
public typealias Info = Attribute

Expand Down
42 changes: 40 additions & 2 deletions Sources/ZeeQL/Access/CodeValueAttribute.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
// ZeeQL
//
// Created by Helge Hess on 06/03/17.
// Copyright © 2017 ZeeZide GmbH. All rights reserved.
// Copyright © 2017-2024 ZeeZide GmbH. All rights reserved.
//

#if canImport(Foundation)
import Foundation
#endif

/**
* CodeValueAttribute objects are used to describe properties of Entity objects
* (which then become columns in the database) from within Swift source code
Expand Down Expand Up @@ -96,7 +100,16 @@ public extension ActiveRecord {
return box(name: name, column: column, externalType: externalType,
value: value)
}

public static func OptInt(name : Swift.String? = nil,
column : Swift.String? = nil,
externalType : Swift.String? = nil,
_ value : Swift.Int? = nil)
-> CodeValueAttribute<Swift.Int?>
{
return box(name: name, column: column, externalType: externalType,
value: value)
}

public static func String(name : Swift.String? = nil,
column : Swift.String? = nil,
externalType : Swift.String? = nil,
Expand All @@ -120,6 +133,31 @@ public extension ActiveRecord {
externalType: externalType, width: width,
value: value)
}

#if canImport(Foundation)
public static func Date(name : Swift.String? = nil,
column : Swift.String? = nil,
externalType : Swift.String? = nil,
_ value : Foundation.Date = Foundation.Date())
-> CodeValueAttribute<Foundation.Date>
{
return box(name: name, column: column,
externalType: externalType,
value: value)
}

public static func OptDate(name : Swift.String? = nil,
column : Swift.String? = nil,
externalType : Swift.String? = nil,
width : Swift.Int? = nil,
_ value : Foundation.Date? = nil)
-> CodeValueAttribute<Foundation.Date?>
{
return box(name: name, column: column,
externalType: externalType, width: width,
value: value)
}
#endif // canImport(Foundation)
}
}

Expand Down
14 changes: 14 additions & 0 deletions Sources/ZeeQL/Access/Entity.swift
Original file line number Diff line number Diff line change
Expand Up @@ -226,19 +226,33 @@ public extension Entity { // default imp
return AttributeKey(attr, entity: self)
}

/**
* Iterates over the relationships and calls
* ``Relationship/connectRelationships(in:entity:)`` on them.
*
* - Parameters:
* - model: The model to resolve the entities.
*/
@inlinable
func connectRelationships(in model : Model) {
for relship in relationships {
relship.connectRelationships(in: model, entity: self)
}
}
/**
* Iterates over the relationships and calls
* ``Relationship/disconnectRelationships()`` on them.
*/
@inlinable
func disconnectRelationships() {
for relship in relationships {
relship.disconnectRelationships()
}
}

/**
* Returns the names of the attributes and relationships of the entity.
*/
@inlinable
var classPropertyNames : [ String ]? {
if attributes.isEmpty && relationships.isEmpty { return nil }
Expand Down
Loading

0 comments on commit 520cdbd

Please sign in to comment.