Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Coding support #733

Merged
merged 6 commits into from
Sep 28, 2017
Merged
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
89 changes: 88 additions & 1 deletion Documentation/Index.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
- [Date-Time Values](#date-time-values)
- [Binary Data](#binary-data)
- [Custom Type Caveats](#custom-type-caveats)
- [Codable Types](#codable-types)
- [Other Operators](#other-operators)
- [Core SQLite Functions](#core-sqlite-functions)
- [Aggregate SQLite Functions](#aggregate-sqlite-functions)
Expand All @@ -72,7 +73,6 @@

[Carthage][] is a simple, decentralized dependency manager for Cocoa. To
install SQLite.swift with Carthage:

1. Make sure Carthage is [installed][Carthage Installation].

2. Update your Cartfile to include the following:
Expand Down Expand Up @@ -1296,6 +1296,93 @@ extension Row {
}
```

## Codable Types

Codable types were introduced as a part of Swift 4 to allow serializing and deserializing types. SQLite.swift
supports the insertion, updating, and retrieval of basic Codable types.

### Inserting Codable Types

Queries have a method to allow inserting an Encodable type.

``` swift
try db.run(users.insert(user))

```

There are two other parameters also available to this method:

- `userInfo` is a dictionary that is passed to the encoder and made available to encodable types to allow customizing their behavior.
- `otherSetters` allows you to specify additional setters on top of those that are generated from the encodable types themselves.

### Updating Codable Types

Queries have a method to allow updating an Encodable type.

``` swift
try db.run(users.update(user))

```

There are two other parameters also available to this method:

- `userInfo` is a dictionary that is passed to the encoder and made available to encodable types to allow customizing their behavior.
- `otherSetters` allows you to specify additional setters on top of those that are generated from the encodable types themselves.

### Retrieving Codable Types

Rows have a method to decode a Decodable type.

``` swift
let loadedUsers: [User] = try db.prepare(users).map { row in
return try row.decode()
}
```

You can also create a decoder to use manually yourself. This can be useful for example if you are using
the [Facade pattern](https://en.wikipedia.org/wiki/Facade_pattern) to hide subclasses behind a super class.
For example, you may want to encode an Image type that can be multiple different formats such as PNGImage, JPGImage,
or HEIFIamge. You will need to determine the correct subclass before you know which type to decode.

``` swift
enum ImageCodingKeys: String, CodingKey {
case kind
}

enum ImageKind: Int, Codable {
case png, jpg, heif
}

let loadedImages: [Image] = try db.prepare(images).map { row in
let decoder = row.decoder()
let container = try decoder.container(keyedBy: ImageCodingKeys.self)
switch try container.decode(ImageKind.self, forKey: .kind) {
case .png:
return try PNGImage(from: decoder)
case .jpg:
return try JPGImage(from: decoder)
case .heif:
return try HEIFImage(from: decoder)
}
}
```

Both of the above methods also have the following optional parameter:

- `userInfo` is a dictionary that is passed to the decoder and made available to decodable types to allow customizing their behavior.

### Restrictions

There are a few restrictions on using Codable types:

- The encodable and decodable objects can only use the following types:
- Int, Bool, Float, Double, String
- Nested Codable types that will be encoded as JSON to a single column
- These methods will not handle object relationships for you. You must write your own Codable and Decodable
implementations if you wish to support this.
- The Codable types may not try to access nested containers or nested unkeyed containers
- The Codable types may not access single value containers or unkeyed containers
- The Codable types may not access super decoders or encoders

## Other Operators

Expand Down
10 changes: 10 additions & 0 deletions SQLite.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,10 @@
3D67B3FB1DB2470600A4F4C6 /* SQLite-Bridging.h in Headers */ = {isa = PBXBuildFile; fileRef = EE91808D1C46E5230038162A /* SQLite-Bridging.h */; settings = {ATTRIBUTES = (Public, ); }; };
3D67B3FC1DB2471B00A4F4C6 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
3D67B3FD1DB2472D00A4F4C6 /* fts3_tokenizer.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AF01C3F06E900AE3E12 /* fts3_tokenizer.h */; };
49EB68C41F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
49EB68C51F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
49EB68C61F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
49EB68C71F7B3CB400D89D40 /* Coding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49EB68C31F7B3CB400D89D40 /* Coding.swift */; };
EE247AD71C3F04ED00AE3E12 /* SQLite.h in Headers */ = {isa = PBXBuildFile; fileRef = EE247AD61C3F04ED00AE3E12 /* SQLite.h */; settings = {ATTRIBUTES = (Public, ); }; };
EE247ADE1C3F04ED00AE3E12 /* SQLite.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE247AD31C3F04ED00AE3E12 /* SQLite.framework */; };
EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE247AEE1C3F06E900AE3E12 /* Blob.swift */; };
Expand Down Expand Up @@ -213,6 +217,7 @@
19A17B93B48B5560E6E51791 /* Fixtures.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Fixtures.swift; sourceTree = "<group>"; };
19A17E2695737FAB5D6086E3 /* fixtures */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = folder; path = fixtures; sourceTree = "<group>"; };
3D67B3E51DB2469200A4F4C6 /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libsqlite3.tbd; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS3.0.sdk/usr/lib/libsqlite3.tbd; sourceTree = DEVELOPER_DIR; };
49EB68C31F7B3CB400D89D40 /* Coding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Coding.swift; sourceTree = "<group>"; };
A121AC451CA35C79005A31D1 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE247AD31C3F04ED00AE3E12 /* SQLite.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SQLite.framework; sourceTree = BUILT_PRODUCTS_DIR; };
EE247AD61C3F04ED00AE3E12 /* SQLite.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SQLite.h; sourceTree = "<group>"; };
Expand Down Expand Up @@ -446,6 +451,7 @@
EE247B001C3F06E900AE3E12 /* Query.swift */,
EE247B011C3F06E900AE3E12 /* Schema.swift */,
EE247B021C3F06E900AE3E12 /* Setter.swift */,
49EB68C31F7B3CB400D89D40 /* Coding.swift */,
);
path = Typed;
sourceTree = "<group>";
Expand Down Expand Up @@ -779,6 +785,7 @@
buildActionMask = 2147483647;
files = (
03A65E801C6BB2FB0062603F /* CoreFunctions.swift in Sources */,
49EB68C61F7B3CB400D89D40 /* Coding.swift in Sources */,
03A65E761C6BB2E60062603F /* Blob.swift in Sources */,
03A65E7D1C6BB2F70062603F /* RTree.swift in Sources */,
03A65E791C6BB2EF0062603F /* SQLite-Bridging.m in Sources */,
Expand Down Expand Up @@ -834,6 +841,7 @@
buildActionMask = 2147483647;
files = (
3D67B3F91DB246E700A4F4C6 /* SQLite-Bridging.m in Sources */,
49EB68C71F7B3CB400D89D40 /* Coding.swift in Sources */,
3D67B3F71DB246D700A4F4C6 /* Foundation.swift in Sources */,
3D67B3F81DB246D700A4F4C6 /* Helpers.swift in Sources */,
3D67B3E91DB246D100A4F4C6 /* Statement.swift in Sources */,
Expand Down Expand Up @@ -862,6 +870,7 @@
buildActionMask = 2147483647;
files = (
EE247B0F1C3F06E900AE3E12 /* CoreFunctions.swift in Sources */,
49EB68C41F7B3CB400D89D40 /* Coding.swift in Sources */,
EE247B0A1C3F06E900AE3E12 /* RTree.swift in Sources */,
EE247B031C3F06E900AE3E12 /* Blob.swift in Sources */,
EE247B0B1C3F06E900AE3E12 /* Foundation.swift in Sources */,
Expand Down Expand Up @@ -917,6 +926,7 @@
buildActionMask = 2147483647;
files = (
EE247B6F1C3F3FEC00AE3E12 /* CoreFunctions.swift in Sources */,
49EB68C51F7B3CB400D89D40 /* Coding.swift in Sources */,
EE247B651C3F3FEC00AE3E12 /* Blob.swift in Sources */,
EE247B6C1C3F3FEC00AE3E12 /* RTree.swift in Sources */,
EE247B681C3F3FEC00AE3E12 /* SQLite-Bridging.m in Sources */,
Expand Down
Loading