Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

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
99 changes: 49 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,67 @@ 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)))
}
if let primary = mirrorData.primary {
c.append((primary.label,primary.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 +100,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
}