A fast, pure swift MongoDB driver based on Swift NIO built for Server Side Swift

Overview

OpenKitten

OpenKitten

Installation | Tutorial | Basic usage | About BSON | Codable | Community | How to help

A fast, pure swift MongoDB driver based on Swift NIO built for Server Side Swift. It features a great API and a battle-tested core. Supporting both MongoDB in server and embedded environments.

โญ๏ธ Please leave a star to support MongoKitten โ€“ it really helps!

๐Ÿˆ Community & Docs

Join our Discord for any questions and friendly banter.

Read the Docs at our sponsor's website.

Projects

A couple of MongoKitten based projects have arisen, check them out!

๐Ÿค How to help

Support MongoKitten development

You can sponsor the creator via GitHub.. This enables us to provide a higher quality and more documentation as well as building more tools.

Backers

The App

MongoKitten App can help you browse your dataset, support customers and debug complex aggregates.

The Company

MongoKitten is developed by Orlandos. Hire us!

Contribute to MongoKitten

  • Donate so that we can spend more time on improving the docs.
  • See CONTRIBUTING.md for info on contributing to MongoKitten
  • You can help us out by resolving TODOs and replying on issues
  • Of course, all feedback, positive and negative, also really helps to improve the project

๐Ÿ•ถ Installation

Set up MongoDB server

If you haven't already, you should set up a MongoDB server to get started with MongoKitten

For development, this can be on your local machine.

Install MongoDB for Ubuntu, macOS or any other supported Linux Distro.

Alternatively, make use of a DAAS (Database-as-a-service) like MongoDB Atlas, MLab, IBM Cloud or any other of the many services.

Add MongoKitten to your Swift project ๐Ÿš€

If you're using a SwiftNIO 1.x framework such as Vapor 3, use MongoKitten 5 instead.

MongoKitten supports the Swift Package Manager for server-side applications. Add MongoKitten to your dependencies in your Package.swift file:

.package(url: "https://github.com/OpenKitten/MongoKitten.git", from: "6.0.0")

Also, don't forget to add "MongoKitten" as a dependency for your target.

FAQ

I can't connect to MongoDB, authentication fails!
  1. Make sure you've specified authSource=admin, unless you know what your authSource is. MongoDB's default value is really confusing.
  2. If you've specified an authMechanism, try removing it. MongoKitten can detect the correct one automatically.

๐Ÿšฒ Basic usage

Check out my Ray Wenderlich Article to learn the basics!

Connect to your database

import MongoKitten

let db = try MongoDatabase.synchronousConnect("mongodb://localhost/my_database")

Vapor users should register the database as a service.

extension Request {
    public var mongoDB: MongoDatabase {
        return application.mongoDB.hopped(to: eventLoop)
    }
    
    // For Meow users only
    public var meow: MeowDatabase {
        return MeowDatabase(mongoDB)
    }
    
    // For Meow users only
    public func meow<M: ReadableModel>(_ type: M.Type) -> MeowCollection {
        return meow[type]
    }
}

private struct MongoDBStorageKey: StorageKey {
    typealias Value = MongoDatabase
}

extension Application {
    public var mongoDB: MongoDatabase {
        get {
            storage[MongoDBStorageKey.self]!
        }
        set {
            storage[MongoDBStorageKey.self] = newValue
        }
    }
    
    // For Meow users only
    public var meow: MeowDatabase {
        MeowDatabase(mongoDB)
    }
    
    public func initializeMongoDB(connectionString: String) throws {
        self.mongoDB = try MongoDatabase.lazyConnect(connectionString, on: self.eventLoopGroup)
    }
}

And make sure to call app.initializeMongoDB!

NIO Futures

MongoKitten relies on Swift NIO to provide support for asynchronous operations. All MongoKitten operations that talk to the server are asynchronous, and return an EventLoopFuture of some kind.

You can learn all about NIO by reading its readme or the article on RayWenderlich.com, but here are the basics:

Asynchronous operations return a future. NIO implements futures in the EventLoopFuture type. An EventLoopFuture is a holder for a result that will be provided later. The result of the future can either be successful yielding a result of T, or unsuccessful with a result of a Swift Error. This is the asynchronous representation of a successful return or a thrown error.

If you're using Vapor 4, please refer to their Async documentation. Vapor's Async module provides additional helpers on top of NIO, that make working with instances of EventLoopFuture easier.

If you use Vapor or another Swift-NIO based web framework, never use the wait() function on EventLoopFuture instances.

CRUD (Create, Read, Update, Delete)

// The collection "users" in your database
let users = db["users"]

Create (insert)

= users.insert(myUser) future.whenSuccess { _ in print("Inserted!") } future.whenFailure { error in print("Insertion failed", error) } ">
let myUser: Document = ["username": "kitty", "password": "meow"]

let future: EventLoopFuture = users.insert(myUser)

future.whenSuccess { _ in
	print("Inserted!")
}

future.whenFailure { error in
	print("Insertion failed", error)
}

Read (find) and the query builder

To perform the following query in MongoDB:

{
	"username": "kitty"
}

Use the following MongoKitten code:

users.findOne("username" == "kitty").whenSuccess { (user: Document?) in
	// Do something with kitty
}

To perform the following query in MongoDB:

{
	"$or": [
		{ "age": { "$lte": 16 } },
		{ "age": { "$exists": false } }
	]
}

Use the following MongoKitten code:

users.find("age" <= 16 || "age" == nil).forEach { (user: Document) in
	// Print the user's name
	print(user["username"] as? String)
}

You can also type out the queries yourself, without using the query builder, like this:

users.findOne(["username": "kitty"])

Cursors

Find operations return a Cursor. A cursor is a pointer to the result set of a query. You can obtain the results from a cursor by iterating over the results, or by fetching one or all of the results.

Fetching results

You can fetch all results as an array:

let results: EventLoopFuture<[Document]> = users.find().getAllResults()

Note that this is potentially dangerous with very large result sets. Only use getAllResults() when you are sure that the entire result set of your query fits comfortably in memory.

Iterating over results

For more efficient handling of results, you can lazily iterate over a cursor:

let doneIterating: EventLoopFuture<Void> = users.find().forEach { (user: Document) in
	// ...
}
Cursors are generic

Find operations return a FindCursor. As you can see, FindCursor is a generic type. You can lazily transform the cursor into a different result type by using map, which works similar to map on arrays or documents:

users.find()
	.map { document in
		return document["username"] as? String
	}
	.forEach { username: String? in
		print("user: \(username)")
	}

Update

users.updateMany(where: "username" == "kitty", setting: ["age": 3]).whenSuccess { _ in
	print("๐Ÿˆ")
}

Delete

users.deleteOne(where: "username" == "kitty").whenSuccess { reply in
	print("Deleted \(reply.deletes) kitties ๐Ÿ˜ฟ")
}

๐Ÿ“ฆ About BSON & Documents

MongoDB is a document database that uses BSON under the hood to store JSON-like data. MongoKitten implements the BSON specification in its companion project, OpenKitten/BSON. You can find out more about our BSON implementation in the separate BSON repository, but here are the basics:

Literals

You normally create BSON Documents like this:

let documentA: Document = ["_id": ObjectId(), "username": "kitty", "password": "meow"]
let documentB: Document = ["kitty", 4]

From the example above, we can learn a few things:

  • A BSON document can represent an array or a dictionary
  • You can initialize a document like you initialize normal dictionaries and arrays, using literals
  • The values in a Document (either the array elements or the values of a dictionary pair) can be of any BSON primitive type
  • BSON primitives include core Swift types like Int, String, Double and Bool, as well as Date from Foundation
  • BSON also features some unique types, like ObjectId

Just another collection

Like normal arrays and dictionaries, Document conforms to the Collection protocol. Because of this, you can often directly work with your Document, using the APIs you already know from Array and Dictionary. For example, you can iterate over a document using a for loop:

for (key, value) in documentA {
	// ...
}

for value in documentB.values {
	// ...
}

Document also provides subscripts to access individual elements. The subscripts return values of the type Primitive?, so you probably need to cast them using as? before using them.

let username = documentA["username"] as? String

Think twice before converting between Document and Dictionary

Our Document type is implemented in an optimized, efficient way and provides many useful features to read and manipulate data, including features not present on the Swift Dictionary type. On top of that, Document also implements most APIs present on Dictionary, so there is very little learning curve.

๐Ÿ’พ Codable

MongoKitten supports the Encodable and Decodable (Codable) protocols by providing the BSONEncoder and BSONDecoder types. Working with our encoders and decoders is very similar to working with the Foundation JSONEncoder and JSONDecoder classes, with the difference being that BSONEncoder produces instances of Document and BSONDecoder accepts instances of Document, instead of Data.

For example, say we want to code the following struct:

struct User: Codable {
	var profile: Profile?
	var username: String
	var password: String
	var age: Int?
	
	struct Profile: Codable {
		var profilePicture: Data?
		var firstName: String
		var lastName: String
	}
}

We can encode and decode instances like this:

let user: User = ...

let encoder = BSONEncoder()
let encoded: Document = try encoder.encode(user)

let decoder = BSONDecoder()
let decoded: User = try decoder.decode(User.self, from: encoded)

A few notes:

  • BSONEncoder and BSONDecoder work very similar to other encoders and decoders
  • Nested types can also be encoded and are encouraged
    • Nested structs and classes are most often encoded as embedded documents
  • You can customize the representations using encoding/decoding strategies

Codable and cursors

When doing a find query, the Cursor's results can be transformed lazily. Lazy mapping is much more efficient than keeping the entire result set in memory as it allows for forEach- loops to be leveraged efficiently reducing the memory pressure of your application. You can leverage cursors using Codable as well.

// Find all and decode each Document lazily as a `User` type
users.find().decode(User.self).forEach { user in
	print(user.username)
}

โ˜ ๏ธ License

MongoKitten is licensed under the MIT license.

Comments
  • Cannot create dynamic Document for arrays and nested jsons

    Cannot create dynamic Document for arrays and nested jsons

    var username = "mongo"
    var array = [1,2,3,4]
    var dict = ["name": "kitten", "type": "cat"]
    
    let userCollection = database["users"]
    
    let userDocument: Document = [
                "username":  .string(username),
                "array": .array(arr),
                "dictionary": .array(dict),
            ]
    
    try userCollection.insert(userDocument)
    
    error: cannot convert value of type '[Int]' to expected argument type 'Document'
                  array: .array(array),
                                ^~~~~
    

    Why do you need Document type and why can't we create it dynamically?

    Please provide JSON or Dictionary datatype support for queries in mongodb or atleast provide raw query support so that we can use raw strings to query mongo database

    opened by sujaykakkad 50
  • Not returning error when index clash

    Not returning error when index clash

    When a collection has a unique index and I try to add an object which would clash with an existing object, MongoKitten does not throw an error, but the object is not added.

    Steps to reproduce:

    1. Create a database with a unique index on a field (in the example it is field "value")
    {
      "unique": true,
      "key": { "value": 1 }
    }
    
    1. Add an object with value "A"
    let document: MongoKitten.Document = [
          "value": "A"
    ]
    try MongoManager.database["tests"].insert(document)
    
    1. Verify document was inserted
    [{"value":"A","_id":"bb964958d7260b8fbaf1a0e8"}]
    
    1. Add a second object with value "A"
    let document: MongoKitten.Document = [
          "value": "A"
    ]
    try MongoManager.database["tests"].insert(document)
    
    1. Verify document was inserted (fails, only original document exists, but no error thrown by MongoKitten)
    [{"value":"A","_id":"bb964958d7260b8fbaf1a0e8"}]
    

    Other details

    If this same steps are done directly in mongo an error is returned as expected.

    bug 
    opened by gabriellanata 26
  • cant connect mlab replicaset

    cant connect mlab replicaset

    this example is my problem server = try Server("mongodb://heroku_xxxxx:[email protected]:23372,serveraddress-a1.mlab.com:23372/xxxxxxx?replicaSet=rs-xxxxxx", automatically: true) thow error, MongoDB is not available on the given host and port Socket failed with code 61 ("No data available") [connectFailed] "Unknown error"

    enhancement help wanted 
    opened by sezgin-zz 23
  • Mongo Cursor Iteration is very slow

    Mongo Cursor Iteration is very slow

    Ok I have a collection which has over 100000 documents. I just want to iterate over the all documents once So I wrote a simple program to iterate

    import MongoKitten
    import Foundation
    
    let server = try Server(mongoURL: "mongodb://localhost")
    let database = server["samespace_dev"]
    
    let now = Date()
    let cursor = try database["collection"].find()
    
    var arr: [Document] = []
    for document in cursor{
        arr.append(document)
    }
    
    print(Date().timeIntervalSince(now))
    

    I just printed the start time and end time. The iteration took over 186 seconds(over 3 minutes). I guess the driver is converting to document type everytime which is making iteration slow. Is there a faster way to iterate. I just ran a basic find query in node and it took only 5 seconds. I just want to take documents from one collection do some changes and insert to another collection.

    opened by sujaykakkad 21
  • Failed to compile

    Failed to compile

    Package.swift

    import PackageDescription
    
    let package = Package(
        name: "daemon",
        dependencies: [
            .Package(url: "https://github.com/vapor/vapor.git", majorVersion: 1),
            .Package(url: "https://github.com/OpenKitten/MongoKitten.git", majorVersion: 2)
        ],
        exclude: [
            "Config",
            "Database",
            "Localization",
            "Public",
            "Resources",
            "Tests",
        ]
    )
    

    I'm trying to build template project which vapor generates. The only change I'm doing is adding dependency to beta MongoKitten. With this dependency it fails to build on Ubuntu. Compiler fails with the following error:

    /whatever/daemon/Packages/CryptoKitten-0.0.0/Sources/Cryptography/SHA1/SHA1.swift:200:18: error: expression was too complex to be solved in reasonable time; consider breaking up the expression into distinct sub-expressions
            hashCode = [
            ~~~~~~~~~^~~
    

    Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-38-generic x86_64) Vapor Toolbox v1.0.3 Swift version 3.0-dev (LLVM b9bd56d1b8, Clang 23f1b289cf, Swift edd2ecdf0c) Target: x86_64-unknown-linux-gnu

    bug 
    opened by pkcs12 21
  • Exporting large number of documents cause memory problem

    Exporting large number of documents cause memory problem

    Hello!

    I'm trying to export a large number of documents. But getting memory exhausted error. What I'm doing wrong? Do I need to clear something on each iteration?

    func testExport() {
        
        let server = try! Server("mongodb://176.112.204.83:27017")
        
        let database = server["test-db"]
        let collection = database["images"]
        
        let documents: MongoKitten.CollectionSlice<BSON.Document> = try! collection.find()
        
        while let document = documents.next() {
            
            print("DOC: " + document.makeExtendedJSONString(typeSafe: true))
        }
        
        print("Done")
    }
    
    opened by bushev 20
  • Insert of multiple documents with errors

    Insert of multiple documents with errors

    The insert method won't return any object ids, if a duplicate key error happens, but it throws an error.

    This behaviour would be acceptable if the stoppingOnError parameter is true, but this parameter suggests that if the insertion contains a "bad object", the work continues, and the result outcome should be the array of the inserted identifiers.

    do {
        let identifiers = try collection.insert(documents, stoppingOnError: false)
    }
    catch {
        //this is gona be called... :(
        print(error) 
    }
    

    Is is possible to get back the inserted identifiers after the error happens?

    The ideal solution would be to alternate the insert function behaviour, and check the stoppingOnError property & handle the outcome according to it. Does this make any sense or am I missing something?

    opened by tib 20
  • Cursor timeouts

    Cursor timeouts

    I get hit with this fatal error: Error fetching extra data from the server in MongoKitten.Cursor<heroku_6pxt0cxh.browseitems> with error: timeout: file /tmp/build_0e4a544672ea566050f30beb848fe070/Packages/MongoKitten-1.7.0/Sources/MongoKitten/Cursor.swift, line 79

    Doesn't matter, happens on both read and writes.

    I suspect it's related to https://jira.mongodb.org/browse/SERVER-8188

    Any takes?

    bug 
    opened by seivan 17
  • [v6] Can't fetch more than 100 items

    [v6] Can't fetch more than 100 items

    I have the following code working with v5:

         do {
            let db = try Database.synchronousConnect(mongo_link)
            
            let collection = db[collection_name]
            collection.find().forEach {
                debugPrint("Adding \($0)")
            }.wait()
    
        }
        catch {
            debugPrint("Unexpected error: \(error).")
        }
    

    Now, when I try to do the same with v6 it doesn't work... as it crash. If I omit the .wait() I get only the first 100 entries.

         do {
            let db = try MongoDatabase.synchronousConnect(mongo_link)
            
            let collection = db[collection_name]
            collection.find().forEach {
                debugPrint("Adding \($0)")
            }
           //.wait() <--- crash 
    
        }
        catch {
            debugPrint("Unexpected error: \(error).")
        }
    
    help wanted question 
    opened by vim-zz 16
  • Value of type 'UnsafePointer<Any>' has no member 'reversed'

    Value of type 'UnsafePointer' has no member 'reversed'

    Using the brand new XCode Version 9.3 (9E145):

    In CRUD.swift, in func insert(documents:ordered:writeConcern:timeout:connection:), inside the nested func throwErrors() I am getting the error "Value of type 'UnsafePointer' has no member 'reversed'" on the line for position in positions.reversed()

    It seems that the compiler is having trouble inferring the correct value type for that line, which looks to be Array<InsertErrors.InsertError> and not UnsafePointer<Any>

    This issue has been seen before in the earlier, now-closed issue https://github.com/OpenKitten/MongoKitten/issues/101

    Any workarounds or changes I can make? I just installed MongoKitten today after updating my XCode, so i don't know if this is traceable to the new XCode 9.3/Swift 4.1 or not.

    opened by natebirkholz 15
  • MongoKitten and Swift Playground

    MongoKitten and Swift Playground

    Hi,

    I'm trying to use MongoKitten in a Swift Playground for Data Science purposes. Unfortunately, I cannot get it to work, because it will not find the CNIOOpenSSL module.

    Does anyone know a solution to this problem?

    Best, Keyan

    opened by kzahedi 14
  • Setup macOS CI for unit tests

    Setup macOS CI for unit tests

    Using GH actions macOS runner, to test transactions we need to setup a cluster locally through the installed mongoDB without using docker. Docker isn't officially installed on macOS and there's some weirdness when installing it via a separate action.

    We should ideally build a script that manually starts the mongod instance and sets up the cluster manually before we run the tests. This article should provide some good steps and serve as a starting point.

    bug 
    opened by Andrewangeta 0
  • MongoDB transactions not working in Mongo 4.2 on linux

    MongoDB transactions not working in Mongo 4.2 on linux

    Describe the bug In mongo 4.2 transactions seems to be failing.

    <EXPR>:0: error: TransactionTests.test_transaction : 
    threw error "MongoServerError(document: ["errorLabels": ["TransientTransactionError"], 
    "operationTime": BSON.Timestamp(increment: 302, timestamp: 1661199200), 
    "ok": 0.0, "errmsg": "Transaction 1 has been aborted.", 
    "code": 251, "codeName": "NoSuchTransaction", "$clusterTime": ["clusterTime": BSON.Timestamp(increment: 302, timestamp: 1661199200),
     "signature": ["hash": BSON.Binary(subType: BSON.Binary.SubType.generic, storage: ByteBuffer { readerIndex: 0, writerIndex: 20, readableBytes: 20, capacity: 20, storageCapacity: 1024, slice: _ByteBufferSlice { 262..<282 }, storage: 0x00007fca100ee8e0 (1024 bytes) }), "keyId": 0]]])"
    

    To Reproduce Run the transaction tests against a mongo cluster.

    Server-side Swift:

    • OS: Linux
    • Swift Version: 5.6
    • MongoKitten Version: 7.0.0
    bug hacktoberfest 
    opened by Andrewangeta 0
  • Improve Meow and MongoKitten debugability

    Improve Meow and MongoKitten debugability

    Is your feature request related to a problem? Please describe. It's frustrating to debug some MongoDB queries, because MongoKitten errors don't (always) capture the whole context.

    Describe the solution you'd like Either or all of the below:

    • Track the original request/query that was sent
    • Log the error string/number and metadata as sent by MongoDB
    • Add the MongoKitten error to Meow's (error/response) types
    enhancement help wanted hacktoberfest 
    opened by Joannis 0
  • Implemented server api versioning

    Implemented server api versioning

    This pull request implements server api versioning as specified in https://github.com/mongodb/specifications/blob/master/source/versioned-api/versioned-api.rst

    opened by linus-hologram 0
Releases(7.2.10)
  • 7.2.2(Aug 26, 2022)

    What's Changed

    • Adds tests and fixes for transaction. by @Andrewangeta and @Joannis in https://github.com/orlandos-nl/MongoKitten/pull/294

    Full Changelog: https://github.com/orlandos-nl/MongoKitten/compare/7.2.1...7.2.2

    Source code(tar.gz)
    Source code(zip)
  • 7.2.1(Aug 14, 2022)

    What's Changed

    • add link to swiftinit docs by @kelvin13 in https://github.com/orlandos-nl/MongoKitten/pull/292
    • implement workaround for compiler crash #60380 by @kelvin13 in https://github.com/orlandos-nl/MongoKitten/pull/291

    New Contributors

    • @kelvin13 made their first contribution in https://github.com/orlandos-nl/MongoKitten/pull/292

    Full Changelog: https://github.com/orlandos-nl/MongoKitten/compare/7.2.0...7.2.1

    Source code(tar.gz)
    Source code(zip)
  • 7.2.0(Aug 8, 2022)

    additions:

    • The .buildIndexes method
    • Adds typesafe indexes to Meow

    Typesafe indexes allow for fully typesafe migrations such as:

    try await meow.migrate("Unique Email", on: User.self) { migrator in
        migrator.add { users in
            try await users.buildIndexes { user in
                UniqueIndex(named: "unique-email", field: user.$email)
            }
        }
    }
    

    fixes:

    • Small fix for upserting returning a failed result when adding a new entry to the database. This resulted in migrations throwing an error (even though the migration itself might have succeeded) when running migrations on an empty database.
    Source code(tar.gz)
    Source code(zip)
  • 6.7.6(Aug 8, 2022)

    Small fix for upserting returning a failed result when adding a new entry to the database. This resulted in migrations throwing an error (even though the migration itself might have succeeded) when running migrations on an empty database.

    Source code(tar.gz)
    Source code(zip)
  • 7.1.0(Jul 22, 2022)

    What's Changed

    • Allow users to provide their own eventloopgroup in a cluster's initializer by @Joannis in https://github.com/orlandos-nl/MongoKitten/pull/287

    Full Changelog: https://github.com/orlandos-nl/MongoKitten/compare/7.0.2...7.1.0

    Source code(tar.gz)
    Source code(zip)
  • 7.0.1(Jul 8, 2022)

  • 7.0.0(Jul 3, 2022)

    After a long time of hard work, we're finally able to release a 7.0!

    Highlights

    This time, we're putting async/await in the drivers seat! Not only are all API's over from EventLoopFuture to async/await, but we've also added support for AsyncSequence to cursors. If a cursor's Task gets cancelled, the cursor will also stop iterating.

    KeyPath Queries

    Meow was actually the place of invention of KeyPath queries - years ago. But we were never quite happy with the final solution. This time around, we're happy with the result and are excited to share it!

    Source code(tar.gz)
    Source code(zip)
  • 7.0.0-beta.1(May 15, 2022)

    After a long time of hard work, we're finally able to release a 7.0 beta!

    Some highlights

    This time, we're putting async/await in the drivers seat! Not only are all API's over from EventLoopFuture to async/await, but we've also added support for AsyncSequence to cursors. If a cursor's Task gets cancelled, the cursor will also stop iterating.

    KeyPath Queries

    Meow was actually the place of invention of KeyPath queries - years ago. But we were never quite happy with the final solution. This time around, we're happy with the result and are excited to share it!

    Source code(tar.gz)
    Source code(zip)
  • 6.7.4(Feb 9, 2022)

  • 6.7.3(Feb 5, 2022)

  • 6.7.0(Oct 26, 2021)

    Async-Await Support. Use the helpers through the .async properties on MongoDatabase and MongoCollection to get access to the async-await API for that type.

    Source code(tar.gz)
    Source code(zip)
  • 6.6.3(Aug 25, 2020)

    1. This release contains a bugfix in a helper that would cause findAndRemove operations to result in a failure.
    2. A lot of new tests have been added in this release
    3. A low-level optimisation has been added, which will result in a lower performance for each message sent to MongoDB.

    BSON

    While updating MongoKitten is great, we've also made a huge step in the BSON library. The new BSON release has seen improved performance up to 150x faster in regular usage.

    Source code(tar.gz)
    Source code(zip)
  • 6.6.2(Aug 8, 2020)

  • 6.6.0(Jun 19, 2020)

  • 6.5.2(Jun 3, 2020)

    Before this release, there was a small chance that disconnecting the cluster would crash because of a simultaneous access with cluster discovery.

    Source code(tar.gz)
    Source code(zip)
  • 6.5.1(May 30, 2020)

  • 6.5.0(May 4, 2020)

  • 6.4.0(May 3, 2020)

Owner
Kittenlishiously awesome Swift libraries
null
This Project domonstrate the latest Swift on Server to create RESTFul API's connected via Database: MongoDB NoSql

Swift is a general-purpose programming language built using a modern approach to safety & performance that make it specifically suitable for Server applications. Vapor is a web framework for Swift, allowing you to write backends, web apps APIs and HTTP servers in Swift

Furqan 3 Aug 23, 2022
Add Strictly Typed NIO Channel Builders for Swift 5.7

โš ๏ธ Requires Swift 5.7 Omnibus is a set of helpers for SwiftNIO that allow you to leverage Swift's generics type system to create NIO Channels. It depe

Orlandos 6 Jun 10, 2022
MySQL driver for Swift 3 (macOS and Linux)

MySQL MySQL Usage // do your magic Installation import PackageDescription let package = Package( dependencies: [ .Package(url: "https://g

Zewo Graveyard 29 Jan 29, 2022
Commmunity-supported Swift Driver for FaunaDB

Commmunity-supported Swift Driver for FaunaDB FaunaDB's Swift driver is now "community-supported". New features won't be exposed in the driver unless

Fauna, Inc. 22 May 30, 2022
A stand-alone Swift wrapper around the mongo-c client library, enabling access to MongoDB servers.

This package is deprecated in favour of the official Mongo Swift Driver. We advise users to switch to that pack

PerfectlySoft Inc. 54 Jul 9, 2022
A MongoDB interface for Swift [Not under active development]

MongoDB #This library is no longer under active development. I highly recommend using the robust, pure-swift alternative MongoKitten. A Swift MongoDB

Dan Appel 266 Jan 29, 2022
A type-safe, protocol-based, pure Swift database offering effortless persistence of any object

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.

ร˜yvind Grimnes 489 Sep 9, 2022
Swift APIs for SQLite: Type-safe down to the schema. Very, very, fast. Dependency free.

Lighter Lighter is a set of technologies applying code generation to access SQLite3 databases from Swift, e.g. in iOS applications or on the server. L

Lighter.swift 330 Dec 26, 2022
An elegant, fast, thread-safe, multipurpose key-value storage, compatible with all Apple platforms.

KeyValueStorage An elegant, fast, thread-safe, multipurpose key-value storage, compatible with all Apple platforms. Supported Platforms iOS macOS watc

null 3 Aug 21, 2022
CoreXLSX is a Excel spreadsheet (XLSX) format parser written in pure Swift

CoreXLSX Excel spreadsheet (XLSX) format parser written in pure Swift CoreXLSX is a library focused on representing the low-level structure of the XML

null 684 Dec 21, 2022
๐Ÿ”ฅ ๐Ÿ”ฅ ๐Ÿ”ฅSupport for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

?? ?? ??Support for ORM operation,Customize the PQL syntax for quick queries,Support dynamic query,Secure thread protection mechanism,Support native operation,Support for XML configuration operations,Support compression, backup, porting MySQL, SQL Server operation,Support transaction operations.

null 60 Dec 12, 2022
Web server serving local files

swift-web A web server serving local static files. Installation Using Mint The easiest way to install swift-web is via mint. mint install adam-fowler/

Adam Fowler 10 Dec 10, 2022
Sharing SQL queries between Server and Mobile databases

Sharing SQL queries between Server and Mobile databases Overview As we all know, code is expensive to maintain, and the more complex the code, the mor

Aaron LaBeau 4 May 24, 2022
Server-driven SwiftUI - Maintain iOS apps without making app releases.

ServerDrivenSwiftUI Maintain ios apps without making app releases. Deploy changes to the server and users will receive changes within minutes. This pa

null 9 Dec 29, 2022
๐Ÿงก SQLiteOrm-Swift is an ORM library for SQLite3 built with Swift 5

?? Easy to use SQLite ORM library written with Swift

Yevgeniy Zakharov 25 Oct 6, 2022
YapDB is a collection/key/value store with a plugin architecture. It's built atop sqlite, for Swift & objective-c developers.

YapDatabase is a collection/key/value store and so much more. It's built atop sqlite, for Swift & Objective-C developers, targeting macOS, iOS, tvOS &

Yap Studios 3.3k Dec 29, 2022
Steppe Payment Built With Swift

SteppePayment Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements Installation Step

null 0 Mar 21, 2022
Disk is a powerful and simple file management library built with Apple's iOS Data Storage Guidelines in mind

Disk is a powerful and simple file management library built with Apple's iOS Data Storage Guidelines in mind

Saoud Rizwan 3k Jan 3, 2023