removed Median and StandardDeviation from supported aggregates as core data doesn't seem to support them either

This commit is contained in:
John Rommel Estropia
2015-06-06 17:44:04 +09:00
parent b0a637520e
commit c4171de86e
7 changed files with 70 additions and 83 deletions

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "CoreStore"
s.version = "0.1.1"
s.version = "0.1.2"
s.license = "MIT"
s.summary = "Simple, elegant, and smart Core Data programming with Swift"
s.homepage = "https://github.com/JohnEstropia/CoreStore"

View File

@@ -108,7 +108,8 @@ public enum SelectTerm: StringLiteralConvertible {
return ._Aggregate(
function: "average:",
keyPath,
As: alias ?? "average(\(keyPath))"
As: alias ?? "average(\(keyPath))",
nativeType: .DecimalAttributeType
)
}
@@ -129,7 +130,8 @@ public enum SelectTerm: StringLiteralConvertible {
return ._Aggregate(
function: "count:",
keyPath,
As: alias ?? "count(\(keyPath))"
As: alias ?? "count(\(keyPath))",
nativeType: .Integer64AttributeType
)
}
@@ -150,28 +152,8 @@ public enum SelectTerm: StringLiteralConvertible {
return ._Aggregate(
function: "max:",
keyPath,
As: alias ?? "max(\(keyPath))"
)
}
/**
Provides a `SelectTerm` to a `Select` clause for querying the median value for an attribute.
let medianAge = CoreStore.queryValue(
From(MyPersonEntity),
Select<Int>(.Median("age"))
)
:param: keyPath the attribute name
:param: alias the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "max(<attributeName>)" is used
:returns: a `SelectTerm` to a `Select` clause for querying the median value for an attribute
*/
public static func Median(keyPath: KeyPath, As alias: KeyPath? = nil) -> SelectTerm {
return ._Aggregate(
function: "median:",
keyPath, As:
alias ?? "median(\(keyPath))"
As: alias ?? "max(\(keyPath))",
nativeType: .UndefinedAttributeType
)
}
@@ -180,7 +162,7 @@ public enum SelectTerm: StringLiteralConvertible {
let minimumAge = CoreStore.queryValue(
From(MyPersonEntity),
Select<Int>(.Median("age"))
Select<Int>(.Minimum("age"))
)
:param: keyPath the attribute name
@@ -192,28 +174,8 @@ public enum SelectTerm: StringLiteralConvertible {
return ._Aggregate(
function: "min:",
keyPath,
As: alias ?? "min(\(keyPath))"
)
}
/**
Provides a `SelectTerm` to a `Select` clause for querying the standard deviation value for an attribute.
let stddevAge = CoreStore.queryValue(
From(MyPersonEntity),
Select<Int>(.StandardDeviation("age"))
)
:param: keyPath the attribute name
:param: alias the dictionary key to use to access the result. Ignored when the query return value is not an `NSDictionary`. If `nil`, the default key "stddev(<attributeName>)" is used
:returns: a `SelectTerm` to a `Select` clause for querying the standard deviation value for an attribute
*/
public static func StandardDeviation(keyPath: KeyPath, As alias: KeyPath? = nil) -> SelectTerm {
return ._Aggregate(
function: "stddev:",
keyPath,
As: alias ?? "stddev(\(keyPath))"
As: alias ?? "min(\(keyPath))",
nativeType: .UndefinedAttributeType
)
}
@@ -234,7 +196,8 @@ public enum SelectTerm: StringLiteralConvertible {
return ._Aggregate(
function: "sum:",
keyPath,
As: alias ?? "sum(\(keyPath))"
As: alias ?? "sum(\(keyPath))",
nativeType: .DecimalAttributeType
)
}
@@ -260,7 +223,7 @@ public enum SelectTerm: StringLiteralConvertible {
// MARK: Internal
case _Attribute(KeyPath)
case _Aggregate(function: String, KeyPath, As: String)
case _Aggregate(function: String, KeyPath, As: String, nativeType: NSAttributeType)
}
@@ -358,12 +321,19 @@ public struct Select<T: SelectResultType> {
CoreStore.log(.Warning, message: "The property \"\(keyPath)\" does not exist in entity <\(entityDescription.managedObjectClassName)> and will be ignored by \(typeName(self)) query clause.")
}
case ._Aggregate(let function, let keyPath, let alias):
case ._Aggregate(let function, let keyPath, let alias, let nativeType):
if let attributeDescription = attributesByName[keyPath] as? NSAttributeDescription {
let expressionDescription = NSExpressionDescription()
expressionDescription.name = alias
expressionDescription.expressionResultType = attributeDescription.attributeType
if nativeType == .UndefinedAttributeType {
expressionDescription.expressionResultType = attributeDescription.attributeType
}
else {
expressionDescription.expressionResultType = nativeType
}
expressionDescription.expression = NSExpression(
forFunction: function,
arguments: [NSExpression(forKeyPath: keyPath)]
@@ -388,7 +358,7 @@ public struct Select<T: SelectResultType> {
case ._Attribute(let keyPath):
return keyPath
case ._Aggregate(_, _, let alias):
case ._Aggregate(_, _, let alias, _):
return alias
}
}

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.1</string>
<string>0.1.2</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>

View File

@@ -32,7 +32,7 @@
</configuration>
<elements>
<element name="Palette" positionX="261" positionY="189" width="128" height="105"/>
<element name="UserAccount" positionX="261" positionY="216" width="128" height="90"/>
<element name="Place" positionX="261" positionY="225" width="128" height="105"/>
<element name="UserAccount" positionX="261" positionY="216" width="128" height="90"/>
</elements>
</model>

View File

@@ -22,13 +22,15 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
CoreStore.logger = DefaultLogger()
}
let dataStack = DataStack()
// MARK: UIViewController
override func viewDidLoad() {
super.viewDidLoad()
self.dataStack.addSQLiteStore("emptyStore.sqlite")
CoreStore.logger = self
}
@@ -52,7 +54,15 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
GCDQueue.Main.async { [weak self] in
self?.textView?.insertText("\(fileName.stringValue.lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log] \(message)\n\n")
let levelString: String
switch level {
case .Trace: levelString = "Trace"
case .Notice: levelString = "Notice"
case .Warning: levelString = "Warning"
case .Fatal: levelString = "Fatal"
}
self?.textView?.insertText("\(fileName.stringValue.lastPathComponent):\(lineNumber) \(functionName)\n ↪︎ [Log:\(levelString)] \(message)\n\n")
}
}
@@ -88,21 +98,23 @@ class CustomLoggerViewController: UIViewController, CoreStoreLogger {
switch self.segmentedControl?.selectedSegmentIndex {
case .Some(0):
CoreStore.beginAsynchronous { (transaction) -> Void in
self.dataStack.beginAsynchronous { (transaction) -> Void in
transaction.create(Into(UserAccount))
}
case .Some(1):
CoreStore.addSQLiteStore("dummy.sqlite", configuration: "test1")
CoreStore.addSQLiteStore("dummy.sqlite", configuration: "test2")
self.dataStack.addSQLiteStore("emptyStore.sqlite", configuration: "invalidStore")
case .Some(2):
CoreStore.beginAsynchronous { (transaction) -> Void in
self.dataStack.beginAsynchronous { (transaction) -> Void in
transaction.commit()
transaction.commit()
}
default: return
default:
return
}
}
}

View File

@@ -168,9 +168,16 @@ class StackSetupDemoViewController: UITableViewController {
switch section {
case 0: return "Facebook Accounts"
case 1: return "Twitter Accounts"
default: return nil
case 0:
let count = Static.facebookStack.fetchCount(From(UserAccount)) ?? 0
return "Facebook Accounts (\(count) users)"
case 1:
let count = Static.twitterStack.fetchCount(From(UserAccount)) ?? 0
return "Twitter Accounts (\(count) users)"
default:
return nil
}
}

View File

@@ -1,7 +1,7 @@
# CoreStore
[![Version](https://img.shields.io/cocoapods/v/CoreStore.svg?style=flat)](http://cocoadocs.org/docsets/CoreStore)
[![Platform](https://img.shields.io/cocoapods/p/CoreStore.svg?style=flat)](http://cocoadocs.org/docsets/CoreStore)
[![License](https://img.shields.io/github/license/JohnEstropia/CoreStore.svg?style=flat)](http://cocoadocs.org/docsets/CoreStore)
[![License](https://img.shields.io/cocoapods/l/CoreStore.svg?style=flat)](https://raw.githubusercontent.com/JohnEstropia/CoreStore/master/LICENSE)
Simple, elegant, and smart Core Data programming with Swift
(Swift, iOS 8+)
@@ -11,8 +11,8 @@ Simple, elegant, and smart Core Data programming with Swift
## What CoreStore does better:
- Heavily supports multiple persistent stores per data stack, just the way .xcdatamodeld files are designed to. CoreStore will also manage one data stack by default, but you can create and manage as many as you need.
- Ability to plug-in your own logging framework (or any of your favorite 3rd-party logger)
- Gets around a limitation with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the .xcdatamodeld file, so you are free to name them independently.
- Ability to plug-in your own logging framework
- Gets around a limitation with other Core Data wrappers where the entity name should be the same as the `NSManagedObject` subclass name. CoreStore loads entity-to-class mappings from the managed object model file, so you are free to name them independently.
- Provides type-safe, easy to configure observers to replace `NSFetchedResultsController` and KVO
- Exposes API not just for fetching, but also for querying aggregates and property values
- Makes it hard to fall into common concurrency mistakes. All `NSManagedObjectContext` tasks are encapsulated into safer, higher-level abstractions without sacrificing flexibility and customizability.
@@ -31,9 +31,9 @@ CoreStore.addSQLiteStore("MyStore.sqlite")
Simple transactions:
```swift
CoreStore.beginAsynchronous { (transaction) -> Void in
let object = transaction.create(Into(MyEntity))
object.entityID = 1
object.name = "test entity"
let person = transaction.create(Into(MyPersonEntity))
person.name = "John Smith"
person.age = 42
transaction.commit { (result) -> Void in
switch result {
@@ -46,24 +46,24 @@ CoreStore.beginAsynchronous { (transaction) -> Void in
Easy fetching:
```swift
let objects = CoreStore.fetchAll(From(MyEntity))
let people = CoreStore.fetchAll(From(MyPersonEntity))
```
```swift
let objects = CoreStore.fetchAll(
From(MyEntity),
Where("entityID", isEqualTo: 1),
OrderBy(.Ascending("entityID"), .Descending("name")),
let people = CoreStore.fetchAll(
From(MyPersonEntity),
Where("age > 30"),
OrderBy(.Ascending("name"), .Descending("age")),
Tweak { (fetchRequest) -> Void in
fetchRequest.includesPendingChanges = true
fetchRequest.includesPendingChanges = false
}
)
```
Simple queries:
```swift
let count = CoreStore.queryValue(
From(MyEntity),
Select<Int>(.Count("entityID"))
let maxAge = CoreStore.queryValue(
From(MyPersonEntity),
Select<Int>(.Maximum("age"))
)
```
@@ -497,9 +497,7 @@ If you only need a value for a particular attribute, you can just specify the ke
- `.Average(...)`
- `.Count(...)`
- `.Maximum(...)`
- `.Median(...)`
- `.Minimum(...)`
- `.StandardDeviation(...)`
- `.Sum(...)`
```swift
@@ -572,7 +570,7 @@ which now returns:
**`GroupBy` clause**
The `GroupBy` clause lets you group results by a specified attribute/aggregate. This is only useful only for `queryAttributes(...)` since `queryValue(...)` just returns the first value anyway.
The `GroupBy` clause lets you group results by a specified attribute/aggregate. This is useful only for `queryAttributes(...)` since `queryValue(...)` just returns the first value.
```swift
let personJSON = CoreStore.queryAttributes(
From(MyPersonEntity),