Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import PackageDescription

let package = Package(
name: "StORM",
name: "StORM-R",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can't merge with this in place sorry.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is some of the problems I found using MySQL-StORM today. I didn't test it after Fork. Sorry, I made a mistake. I will continue to use the discovery of some existing problems

targets: [],
dependencies: [
.Package(url: "https://github.com/PerfectlySoft/PerfectLib.git", majorVersion: 2)
Expand Down
96 changes: 46 additions & 50 deletions Sources/StORM/StORM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@
/// When true, certain methods will generate a debug message under certain conditions.
public var StORMdebug = false

/// If you set the StORMIgnoreClassString field, you support the parent class property lookup until you find the set field class, or you only support sub class property lookups
public var StORMIgnoreClassString:String = ""
/// Set the suffix to the primary key and defaults to id
public var StORMPrimarykeySuffix:String = "id"

/// Base StORM superclass from which all Database-Connector StORM classes inherit.
/// Provides base functionality and rules.
Expand All @@ -24,80 +28,64 @@ open class StORM {

/// Contain last error message as string.
open var errorMsg = ""

/// Database primary key
private var primary:(String,Any)?

/// Base empty init function.
public init() {}

/// Provides structure introspection to client methods.
public func cols(_ offset: Int = 0) -> [(String, Any)] {
var c = [(String, Any)]()
var count = 0
let mirror = Mirror(reflecting: self)
for child in mirror.children {
guard let key = child.label else {
continue
}
if count >= offset && !key.hasPrefix("internal_") && !key.hasPrefix("_") {
c.append((key, type(of:child.value)))
//c[key] = type(of:child.value)
}
count += 1
}
let mirrorData = StORMMirrorData.mirror(mirror: mirror)
for child in mirrorData.childs {
c.append((child.label, type(of: child.value)))
}
return c
}



open func modifyValue(_ v: Any, forKey k: String) -> Any { return v }

/// Returns a [(String,Any)] object representation of the current object.
/// If any object property begins with an underscore, or with "internal_" it is omitted from the response.
public func asData(_ offset: Int = 0) -> [(String, Any)] {
var c = [(String, Any)]()
var count = 0
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
if value is [String:Any] {
c.append((label, modifyValue(try! (value as! [String:Any]).jsonEncodedString(), forKey: label)))
} else if value is [String] {
c.append((label, modifyValue((value as! [String]).joined(separator: ","), forKey: label)))
} else {
c.append((label, modifyValue(value, forKey: label)))
}
}
count += 1
}
let mirrorData = StORMMirrorData.mirror(mirror: mirror)
for child in mirrorData.childs {
if child.value is [String:Any] {
c.append((child.label, modifyValue(try! (child.value as! [String:Any]).jsonEncodedString(), forKey: child.label)))
} else if child.value is [String] {
c.append((child.label, modifyValue((child.value as! [String]).joined(separator: ","), forKey: child.label)))
} else {
c.append((child.label, modifyValue(child.value, forKey: child.label)))
}
}
return c
}

/// Returns a [String:Any] object representation of the current object.
/// If any object property begins with an underscore, or with "internal_" it is omitted from the response.
public func asDataDict(_ offset: Int = 0) -> [String: Any] {
var c = [String: Any]()
var count = 0
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
if count >= offset && !label.hasPrefix("internal_") && !label.hasPrefix("_") {
if value is [String:Any] {
c[label] = modifyValue(try! (value as! [String:Any]).jsonEncodedString(), forKey: label)
} else if value is [String] {
c[label] = modifyValue((value as! [String]).joined(separator: ","), forKey: label)
} else {
c[label] = modifyValue(value, forKey: label)
}
}
count += 1
}
for (label,value) in asData(offset) {
c[label] = value
}
return c
}

/// Returns a tuple of name & value of the object's key
/// The key is determined to be it's first property, which is assumed to be the object key.
public func firstAsKey() -> (String, Any) {
let mirror = Mirror(reflecting: self)
for case let (label?, value) in mirror.children {
return (label, modifyValue(value, forKey: label))
}
return ("id", "unknown")
guard let child = StORMMirrorData.mirror(mirror: mirror).primary else {
return ("id", "unknown")
}
return (child.label, modifyValue(child.value, forKey: child.label))
}

/// Returns a boolean that is true if the first property in the class contains a value.
Expand All @@ -109,20 +97,28 @@ open class StORM {
} else {
return false
}
} else {
if (val as! String).isEmpty {
return true
} else {
return false
}
}
} else if val is Int32 {
if val as! Int32 == 0 {
return true
} else {
return false
}
} else if val is String {
if (val as! String).isEmpty {
return true
} else {
return false
}
} else {
return false
}
}

/// The create method is designed to be overridden
/// If not set in the chile class it will return an error of the enum value .notImplemented
open func create() throws {
throw StORMError.notImplemented
}
}

71 changes: 71 additions & 0 deletions Sources/StORM/StORMMirrorData.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//
// StORMMirrorData.swift
// StORM
//
// Created by 张行 on 2017/8/14.
//
//

import Foundation

/// A field that supports the search for subclasses and the parent class matches the attribute seat database
public class StORMMirrorData {
public var childs:[StORMMirrorDataChild] = [] /// In addition to the primary key, the database field
public var primary:StORMMirrorDataChild? /// The primary key field may exist or does not exist

/// Resolve Mirror to find the criteria for the database field and the primary key
public static func mirror(mirror:Mirror) -> StORMMirrorData {
let mirrorData = StORMMirrorData()
for child in mirrorData.mirrorData(mirror: mirror) {
mirrorData.childs.append(StORMMirrorDataChild(label: child.0, value: child.1))
}
return mirrorData
}

public func mirrorData(mirror:Mirror) -> [(String,Any)] {
var c:[(String,Any)] = []
if "\(mirror.subjectType)" == StORMIgnoreClassString {
return c
}
var count:Int = 0
for case let (label?,value) in mirror.children {
if isFilterKey(key: label) {
continue
}
if count == 0 && isPrimaryKey(key: label) && (self.primary == nil){
self.primary = StORMMirrorDataChild(label: label, value: value)
} else {
c.append((label,value))
}
count += 1
}
if let superMirror = mirror.superclassMirror {
if StORMIgnoreClassString.characters.count > 0 {
c.append(contentsOf: mirrorData(mirror: superMirror))
}

}
return c
}

///Is the filter field, YES represents the filter field, and NO stands for the database table field
public func isFilterKey(key:String) -> Bool {
if key.hasPrefix("internal_") {
return true
}
if key.hasPrefix("_") {
return true
}
return false
}

/// Is it the primary key for the database? YES stands for the primary key, and NO stands for not a primary key
public func isPrimaryKey(key:String) -> Bool {
return key.hasSuffix(StORMPrimarykeySuffix)
}
}

public struct StORMMirrorDataChild {
public var label:String
public var value:Any
}