Skip to content

Commit

Permalink
1.3.0 (#14)
Browse files Browse the repository at this point in the history
* swift-docc-plugin 1.3.0

* async-http-client 1.19.0

* replaced deprecated .createNew with the new .singleton

* Adding _find capability. (#13)

* docs

* tabs

* renames

* added test for find method with body

* docs added

* findError added

* tests renamed

* added test for find method with generic type

* docs

* README updated

* updated dependencies

* docs updated

* try Swift 5.7.1

* Update build-ubuntu.yml

* Swift 5.7.3

* Revert "Swift 5.7.3"

This reverts commit ab8f67a.

---------

Co-authored-by: Gregório Gevartosky Torrezan <[email protected]>
  • Loading branch information
makoni and gevartosky authored Jan 16, 2024
1 parent 42da8ad commit 8e0707c
Show file tree
Hide file tree
Showing 9 changed files with 221 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
name: Build on Ubuntu with Swift ${{matrix.swift}}
strategy:
matrix:
swift: [5.8.1, 5.7.3, 5.6.3]
swift: [5.9, 5.8.1, 5.7.3]
runs-on: ubuntu-latest
container:
image: swift:${{matrix.swift}}
Expand Down
55 changes: 41 additions & 14 deletions Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,35 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
"revision" : "16f7e62c08c6969899ce6cc277041e868364e5cf",
"version" : "1.19.0"
"revision" : "291438696abdd48d2a83b52465c176efbd94512b",
"version" : "1.20.1"
}
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms",
"state" : {
"revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
"version" : "1.2.0"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "6c89474e62719ddcc1e9614989fff2f68208fe10",
"version" : "1.1.0"
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
"version" : "1.0.4"
"revision" : "d029d9d39c87bed85b1c50adee7c41795261a192",
"version" : "1.0.6"
}
},
{
Expand All @@ -45,6 +54,15 @@
"version" : "1.0.0"
}
},
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"state" : {
"revision" : "1827dc94bdab2eb5f2fc804e9b0cb43574282566",
"version" : "1.0.2"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
Expand All @@ -59,26 +77,26 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "cf281631ff10ec6111f2761052aa81896a83a007",
"version" : "2.58.0"
"revision" : "702cd7c56d5d44eeba73fdf83918339b26dc855c",
"version" : "2.62.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "0e0d0aab665ff1a0659ce75ac003081f2b1c8997",
"version" : "1.19.0"
"revision" : "798c962495593a23fdea0c0c63fd55571d8dff51",
"version" : "1.20.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "a8ccf13fa62775277a5d56844878c828bbb3be1a",
"version" : "1.27.0"
"revision" : "3bd9004b9d685ed6b629760fc84903e48efec806",
"version" : "1.29.0"
}
},
{
Expand All @@ -95,8 +113,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "e7403c35ca6bb539a7ca353b91cc2d8ec0362d58",
"version" : "1.19.0"
"revision" : "ebf8b9c365a6ce043bf6e6326a04b15589bd285e",
"version" : "1.20.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
}
],
Expand Down
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.6
// swift-tools-version:5.7.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,13 @@ print(dbs)
// prints: ["_global_changes", "_replicator", "_users", "yourDBname"]
```

Find documents in DB by selector:
```swift
let selector = ["selector": ["name": "Sam"]]
let docs: [ExpectedDoc] = try await couchDBClient.find(in: "databaseName", selector: selector)
print(docs)
```

### Using with Vapor
Here's a simple [tutorial](https://spaceinbox.me/docs/couchdbclient/tutorials/couchdbclient/vaportutorial) for Vapor.

1 change: 1 addition & 0 deletions Sources/CouchDBClient/CouchDBClient.docc/CouchDBClient.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Currently CouchDBClient supports:
- Get databases list.
- Get document by id or documents using view.
- Insert/update documents.
- Find documents by selector.
- Delete documents.
- CouchDB authorization.

Expand Down
2 changes: 2 additions & 0 deletions Sources/CouchDBClient/CouchDBClient.docc/Extensions/Client.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,7 @@ A CouchDB client class with methods using Swift Concurrency.
- ``insert(dbName:doc:dateEncodingStrategy:eventLoopGroup:)``
- ``update(dbName:doc:dateEncodingStrategy:eventLoopGroup:)``
- ``update(dbName:uri:body:eventLoopGroup:)``
- ``find(in:body:eventLoopGroup:)``
- ``find(in:selector:dateDecodingStrategy:eventLoopGroup:)``
- ``delete(fromDb:doc:eventLoopGroup:)``
- ``delete(fromDb:uri:rev:eventLoopGroup:)``
94 changes: 94 additions & 0 deletions Sources/CouchDBClient/CouchDBClient.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public enum CouchDBClientError: Error {
case insertError(error: CouchDBError)
/// Update request wasn't successful.
case updateError(error: CouchDBError)
/// Find request wasn't successful.
case findError(error: CouchDBError)
/// Uknown response from CouchDB.
case unknownResponse
/// Wrong username or password.
Expand All @@ -41,6 +43,8 @@ extension CouchDBClientError: LocalizedError {
return "Insert request wasn't successful: \(error.localizedDescription)"
case .updateError(let error):
return "Update request wasn't successful: \(error.localizedDescription)"
case .findError(let error):
return "Find request wasn't successful: \(error.localizedDescription)"
case .unknownResponse:
return "Uknown response from CouchDB."
case .unauthorized:
Expand Down Expand Up @@ -478,6 +482,96 @@ public class CouchDBClient {
throw parsingError
}
}

/// Find data in DB by selector.
///
/// Example:
///
/// ```swift
/// // find documents in DB by selector
/// let selector = ["selector": ["name": "Sam"]]
/// let docs: [ExpectedDoc] = try await couchDBClient.find(in: testsDB, selector: selector)
/// ```
///
/// - Parameters:
/// - in dbName: DB name.
/// - selector: Codable representation of json selector query.
/// - eventLoopGroup: NIO's EventLoopGroup object. New will be created if nil value provided.
/// - Returns: Array of documents [T].
public func find<T: Codable & CouchDBRepresentable>(in dbName: String, selector: Codable, dateDecodingStrategy: JSONDecoder.DateDecodingStrategy = .secondsSince1970, eventLoopGroup: EventLoopGroup? = nil) async throws -> [T] {
let encoder = JSONEncoder()
let selectorData = try encoder.encode(selector)

let findResponse = try await find(
in: dbName,
body: .data(selectorData),
eventLoopGroup: eventLoopGroup
)

guard var body = findResponse.body, let bytes = body.readBytes(length: body.readableBytes) else {
throw CouchDBClientError.unknownResponse
}

let data = Data(bytes)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = dateDecodingStrategy

do {
let doc = try decoder.decode(CouchDBFindResponse<T>.self, from: data)
return doc.docs
} catch let parsingError {
if let couchdbError = try? decoder.decode(CouchDBError.self, from: data) {
throw CouchDBClientError.findError(error: couchdbError)
}
throw parsingError
}
}

/// Find data in DB by selector.
///
/// Example:
/// ```swift
/// let selector = ["selector": ["name": "Greg"]]
/// let bodyData = try JSONEncoder().encode(selector)
/// var findResponse = try await couchDBClient.find(in: testsDB, body: .data(bodyData))
///
/// let bytes = findResponse.body!.readBytes(length: findResponse.body!.readableBytes)!
/// let docs = try JSONDecoder().decode(CouchDBFindResponse<ExpectedDoc>.self, from: Data(bytes)).docs
/// ```
/// - Parameters:
/// - dbName: DB name.
/// - body: Request body data.
/// - eventLoopGroup: NIO's EventLoopGroup object. New will be created if nil value provided.
/// - Returns: Request response.
public func find(in dbName: String, body: HTTPClient.Body, eventLoopGroup: EventLoopGroup? = nil) async throws -> HTTPClient.Response {
try await authIfNeed(eventLoopGroup: eventLoopGroup)

let httpClient: HTTPClient
if let eventLoopGroup = eventLoopGroup {
httpClient = HTTPClient(eventLoopGroupProvider: .shared(eventLoopGroup))
} else {
httpClient = HTTPClient(eventLoopGroupProvider: .singleton)
}

defer {
DispatchQueue.main.async {
try? httpClient.syncShutdown()
}
}

let url = buildUrl(path: "/" + dbName + "/_find", query: [])
var request = try buildRequest(fromUrl: url, withMethod: .POST)
request.body = body
let response = try await httpClient
.execute(request: request, deadline: .now() + .seconds(requestsTimeout))
.get()

if response.status == .unauthorized {
throw CouchDBClientError.unauthorized
}

return response
}

/// Update data in DB.
///
Expand Down
13 changes: 13 additions & 0 deletions Sources/CouchDBClient/Models/CouchDBFindResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// CouchDBFindResponse.swift
//
//
// Created by Gregorio Gevartosky Torrezan on 2023-11-15.
//

import Foundation

public struct CouchDBFindResponse<T: Codable & CouchDBRepresentable>: Codable {
var docs: [T]
var bookmark: String?
}
Loading

0 comments on commit 8e0707c

Please sign in to comment.