Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/Oyvindkg/swiftydb

πŸ’€Neither supported nor maintained for years. A type-safe, protocol-based, pure Swift database offering effortless persistence of any object
https://github.com/Oyvindkg/swiftydb

database protocol-oriented swift swiftydb

Last synced: about 2 months ago
JSON representation

πŸ’€Neither supported nor maintained for years. A type-safe, protocol-based, pure Swift database offering effortless persistence of any object

Awesome Lists containing this project

README

        

![Logo](http://i.imgur.com/uQhXJLJ.png)

There are many libraries out there that aims to help developers easily create and use SQLite databases.
Unfortunately developers still have to get bogged down in simple tasks such as writing table definitions
and SQL queries. SwiftyDB automatically handles everything you don't want to spend your time doing.

[![CI Status](https://img.shields.io/travis/Oyvindkg/swiftydb/master.svg?style=flat)](https://travis-ci.org/Oyvindkg/swiftydb)
[![Version](https://img.shields.io/cocoapods/v/SwiftyDB.svg?style=flat)](http://cocoapods.org/pods/SwiftyDB)
[![License](https://img.shields.io/cocoapods/l/SwiftyDB.svg?style=flat)](http://cocoapods.org/pods/SwiftyDB)
[![Platform](https://img.shields.io/cocoapods/p/SwiftyDB.svg?style=flat)](http://cocoapods.org/pods/SwiftyDB)
[![Swift](https://img.shields.io/badge/swift-2-brightgreen.svg?style=flat)](http://cocoapods.org/pods/SwiftyDB)

You can find the [documentation here](http://oyvindkg.github.io/swiftydb/docs/)

**Content**

[Features](#features)

[Usage](#usage)

  [Access the database](#accessTheDatabase)

   [Synchronous access](#syncAccess)

   [Aynchronous access](#asyncAccess)

  [Result format](#resultFormat)

  [Filter results](#filterResults)

  [Defining your classes](#definingYourClasses)

   [Primary keys](#primaryKeys)

   [Ignoring properties](#ignoringProperties)

  [How to retrieve objects](#howToRetrieveObjects)

[Installation](#installation)

[License](#license)

### Features
- [x] Creates and updates databases, tables, and records automatically
- [x] Supports optional types
- [x] Simple equality-based filtering
- [x] Thread safe database operations
- [x] Supports asynchronous database access
- [x] 100% documented
- [x] Complex filtering
- [x] Store collections
- [ ] Store nested objects
- [ ] Automated migration
- [ ] Custom indices

## Usage

Almost pure plug and play. All you have to do is create an instance of SwiftyDB, and everything will be handled automagically behind the scenes 🎩

### Access the database

Tell SwiftyDB what you want to call your database, and you are ready to go. If a database with the provided name does not exist, it will be created.

```Swift
let database = SwiftyDB(databaseName: "dogtopia")
```

#### Synchronous access

##### Add or update a record
```Swift
database.addObject(dog, update: true)
database.addObjects(dogs, update: true)
````

##### Retrieve data

Retrieve data with datatypes matching those of the type's properties
```Swift
/* Array of dictionaries representing `Dog` objects from the database */
database.dataForType(Dog.self)
database.dataForType(Dog.self, matchingFilters: ["id": 1])
````
Dog data example
```Swift
[
"id": 1, // As an Int
"name": "Ghost", // As a String
"owner": "John Snow", // As a String
"birth": August 6, 1996 // As an NSDate
]
```

##### Retrieve objects

Retrieve objects with data from the database
```Swift
database.objectsForType(Dog.self)
database.objectsForType(Dog.self, matchingFilters: ["id": 1])
````

> In order to retrieve objects, Swift currently imposes some [restictions on your classes](#howToRetrieveObjects)

##### Delete records
```Swift
database.deleteObjectsForType(Dog.self)
database.deleteObjectsForType(Dog.self, matchingFilters: ["name": "Max"])
```

#### Asynchronous access

##### Add or update a record
```Swift
database.asyncAddObject(dog) { (result) -> Void in
if let error = result.error {
// Handle error
}
}
````

##### Retrieve data

Retrieve data with datatypes matching those of the type's properties
```Swift
database.asyncDataForType(Dog.self) { (result) -> Void in
if let data = result.value {
// Process data
}
}
````

##### Retrieve objects

Retrieve data with datatypes matching those of the type's properties
```Swift
database.asyncObjectsForType(Dog.self) { (result) -> Void in
if let objects = result.value {
// Handle objects
}
}
````

> In order to retrieve objects, Swift currently imposes some [restictions on your classes](#howToRetrieveObjects)

##### Delete records
```Swift
database.asyncDeleteObjectsForType(Dog.self) { (result) -> Void in
if let error = result.error {
// Handle error
}
}
```

### Filter results

`Filter` objects are used to filter queries. All filters are translated to SQLite before querying the database.

#### Simple filters
The easiest way to define your filter, is by using a dictionary:
```Swift
database.objectsForType(Dog.self, matchingFilters: ["name": "Ghost"])
```
All objects with the name 'Ghost' will be retrieved

#### Complex filters

For more complex filters, you can instantiate a new `Filter` object, and define your filters

```Swift
let filter = Filter.equal("name", value: "Ghost")
.like("owner", pattern: "J_h%")
.greaterThan("id", value: 3)

database.objectsForType(Dog.self, matchingFilters: filter)
```

See all available filters in the [documentation](http://oyvindkg.github.io/swiftydb/docs/Classes/Filter.html).

> It is not possible to filter results using the content of stored collections as these are stored as blobs in the database

### Result format

All queries returns the result as a `Result`. It will either be a `.Success` wrapping data from the query, or an `.Error` wrapping the thrown error.

```Swift
enum Result: BooleanType {
case Success(A)
case Error(ErrorType)

var data: A?
var error: ErrorType?
var isSuccess: Bool
var boolValue: Bool {return isSuccess}
}
```

#### Handling results
The implementation of `Result` makes it a versatile tool that can (hopefully 😬) be adapted to your programming style

##### Handling values
You can capture the data from a query with the `value` property. If an error was thrown, this property will be `nil`.

```Swift
if let object = result.value {
// Process objects
}
```

##### Handling errors
You can detect an error like this
```Swift
if !database.addObject(dog) {
// An error occured
}
```
or capture it using the `error` property like this

```Swift
if let error = result.error {
// Process objects
}
```
If you want to, you can even bring your sledgehammer and start cracking some nuts
```Swift
switch result {
case .Success(let value):
// Process value
case .Error(let error):
// Handle error
}
```

### Defining your classes

Let's use this simple `Dog` class as an example

```Swift
class Dog {
var id: Int?
var name: String?
var owner: String?
var birth: NSDate?
}
```

All objects must conform to the `Storable` protocol.

```Swift
public protocol Storable {
init()
}
```

By adding the `Storable` protocol and implementing `init()`, you are already ready to go.

```Swift
class Dog: Storable {
var id: Int?
var name: String?
var owner: String?
var birth: NSDate?

required init() {}
}
```

> SwiftyDB supports inheritance. Valid properties from both the class and the superclass will be stored automatically

##### Primary keys
It is recommended to implement the `PrimaryKeys` protocol. The `primaryKeys()` method should return a set of property names which uniquely identifies an object.

```Swift
extension Dog: PrimaryKeys {
class func primaryKeys() -> Set {
return ["id"]
}
}
```

##### Ignoring properties
If your class contains properties that you don't want in your database, you can implement the `IgnoredProperties` protocol.

```Swift
extension Dog: IgnoredProperties {
class func ignoredProperties() -> Set {
return ["name"]
}
}
```
> Properties with datatypes that are not part of the `Value` protocol, will automatically be ignored by SwiftyDB

### How to retrieve objects

SwiftyDB can also retrieve complete objects with all properties assigned with data from the database. In order to achieve this, the type must be a subclass of `NSObject`, and all property types must be representable in in Objective-C. This is because pure Swift currently does not support dynamic assignment of properties.

**Dynamic property types**
- [x] `Int`
- [x] `UInt`
- [x] `Float`
- [x] `Double`
- [x] `Bool`
- [x] `String` / `String?`
- [x] `NSNumber` / `NSNumber?`
- [x] `NSString` / `NSString?`
- [x] `NSDate` / `NSDate?`
- [x] `NSData` / `NSData?`

An updated Dog class that can be used to retrieve complete objects from the database:

```Swift
class Dog: NSObject, Storable {
var id: NSNumber? // Notice that 'Int?' is not supported. Use NSNumber? instead
var name: String?
var owner: String?
var birth: NSDate?

override required init() {
super.init()
}
}
```

## Installation

SwiftyDB is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

```ruby
pod "SwiftyDB"
```

## Author

Øyvind Grimnes, [email protected]

## License

SwiftyDB is available under the MIT license. See the LICENSE file for more info.