Swiftpack.co - Swift Packages by SwifQL

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.

Packages published by SwifQL

SwifQL/SwifQL 2.0.0-beta.3.21.2
๐Ÿ’Ž A Swift DSL for type-safe, extensible, and transformable SQL queries.
โญ๏ธ 292
๐Ÿ•“ 33 weeks ago
๐Ÿ”– Release Notes

Releases

The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
๐Ÿผ Order by random using new `SwifQLHybridOperator` by @tierracero #53
47 weeks ago
This allows to use `ORDER BY random()` operator with one handler that adapts to the proper syntax of `psql` and `mysql` e.g. `.orderBy(.random)` will be processed as: `ORDER BY .rand()` in MySQL, and `ORDER BY .random()` in Postgres by @tierracero #53
๐Ÿ‘จโ€๐Ÿ”งImplement SwifQLNull
3 years ago
By default when you compare SwifQLable with `nil` it uses `IS NULL` ```swift "hello" == nil // produce: 'hello' IS NULL ``` to reach exact `= NULL` use this way ```swift "hello" == SwifQLNull // produce: 'hello' = NULL ```
โšก๏ธConform `Operator` to `SwifQLable`
3 years ago
So now you will be able to use operators right in query like this ```swift SwifQL.select(Operator.null) ```
Implement `KeypathEncodable`
3 years ago
In case if you use @Column names with underscores but variable names are in `camelCase` you may experience problems when while encoding fetched data you're getting names with underscores. To solve this problem now we have `KeyPathEncodable` protocol. Simply conform your table to `KeyPathEncodable` and it will always be encoded with property names the same as variable names declared in your model. ## Examples ### To get as-is ```swift final class User: Table { @Column("id") var id: Int @Column("first_name") var firstName: String } ``` this will be encoded as ```json { "id": 1, "first_name": "John" } ``` ### To get with variable names ```swift final class User: Table, KeyPathEncodable { @Column("id") var id: Int @Column("first_name") var firstName: String } ``` this will be encoded as ```json { "id": 1, "firstName": "John" } ```
Implement Column, Alias, Table, and builders
4 years ago
### Breaking changes `SwifQLAlias` renamed to `TableAlias` ### Now we're able to build table models ```swift final class User: Table { @Column("id") var id: UUID @Column("email") var email: String } ``` and access table columns through keyPath like this `\User.$id` and `\User.$email` ### New `@Alias` property wrapper ```swift struct Result: Aliasable { @Alias("anything") var emailAddress: String } let query = SwifQL.select(\User.$email => \Result.$emailAddress).from(User.table) // SELECT "User"."email" as "anything" FROM "User" ```
Implement schema support ๐Ÿพ
4 years ago
## Breaking change Aliases syntax has been changed was ```swift let u = User.as("u") u~\.$id ``` became ```swift let u = User.as("u") u.$id ``` ## Schema > schema for `postgres` is the same as database for `mysql`. How to declare some schema ```swift struct Deleted: Schemable { static var schemaName: String { "deleted" } } ``` or right into your model (example for [Bridges](https://github.com/SwifQL/Bridges)) ```swift final class DeletedUser: Table, Schemable { static var schemaName: String { "deleted" } static var tableName: String { "user" } @Column("id") var id: UUID @Column("email") var email: String } ``` ### Usage examples ```swift // if `User` model conforms to `Schemable` it will use `public` schema all the time \User.$id // result: "public"."user"."id" // otherwise it will be printed simply without any schema \User.$id // result: "user"."id" // `DeletedUser` model conforms to `Schemable` and has custom schema name \DeletedUser.$id // result: "deleted"."user"."id" // Alternatively we can wrap any model to any schema User.inSchema("deleted").$id // result: "deleted"."user"."id" // also we can use aliases with tables with schemas DeletedUser.as("du") // result: "deleted"."user" as "du" // or User.inSchema("deleted").as("du") // result: "deleted"."user" as "du" ``` ## New alias features ```swift let u = User.as("u") // to reach \User.$id we now can simply call u.$id // result: "u"."id" // the same for aliases with schemas // declare aliases easily let hu = User.inSchema("hello").as("hu") // or even struct HelloSchema: Schemable { static var schemaName: String { "hello" } } let hu = User.inSchema(HelloSchema.self).as("hu") // use alias as table hu.table // result: "hello"."user" as "hu" // or simply call its columns hu.$id // result: "hu"."id" ``` ## Custom aliases for subqueries ```swift let u = SwifQLAlias("u") let subQueryWithAlias = |SwifQL.select(User.table.*).from(User.table)| => u // result: (SELECT "hello"."user".* FROM "hello"."user") as "u" // and then also use its paths easily u.id // result: "u"."id" // even with any fantasy columns u.heeeeey // result: "u"."heeeeey" ```
Add UNION and WITH (#19)
4 years ago
### `union` functionality ```swift let table1 = Table("Table1") let table2 = Table("Table2") let table3 = Table("Table3") let sql = Union( SwifQL.select(table1.*).from(table1), SwifQL.select(table2.*).from(table2), SwifQL.select(table3.*).from(table3) ) ``` will give ```sql (SELECT "Table1".* FROM "Table1") UNION (SELECT "Table2".* FROM "Table2") UNION (SELECT "Table3".* FROM "Table3" ``` ### `with` support ```swift let with = With( Table("Table1"), SwifQL.select(Table("Table2").*).from(Table("Table2")) ) SwifQL.with(with) .select(Table("Table1").*) .from(Table("Table1")) ``` will give ```sql WITH "Table1" as (SELECT "Table2".* FROM "Table2") SELECT "Table1".* FROM "Table1" ``` Thanks to @hiimtmac
Make OrderBy.Direction public (#18)
4 years ago
In case when you want to set order direction in runtime now you could do it this way ```swift SwifQL.orderBy(.direction(.asc, \User.email)) SwifQL.orderBy(.direction(.desc, \User.email)) ```
Implement `Column` and `Table`
4 years ago
```swift SwifQL.select(Column("id")) // SELECT "id" SwifQL.select(Table("Todo")) // SELECT "Todo" SwifQL.select(Table("Todo").column("id")) // SELECT "Todo"."id" ```
Implement `generate_series` by @hiimtmac
4 years ago
### Example 1 ```swift SwifQL.select(Fn.generate_series(1, 4) ``` will generate ```sql SELECT generate_series(1, 4) ``` ### Example 2 ```swift SwifQL.select(Fn.generate_series("2019-10-01", "2019-10-04", "1 day")) ``` will generate ```sql SELECT generate_series('2019-10-01', '2019-10-04', '1 day') ``` ### Example 3 ```swift SwifQL.select(Fn.generate_series("2019-10-01" => .date, "2019-10-04" => .date, "1 day")) ``` will generate ```sql SELECT generate_series('2019-10-01', '2019-10-04', '1 day') ``` ### Example 4 ```swift let df = DateFormatter() df.dateFormat = "yyyy-MM-dd HH:mm:ss" df.timeZone = TimeZone(secondsFromGMT: 0) SwifQL.select(Fn.generate_series(df.date(from: "2019-10-01 00:00:00")!, df.date(from: "2019-10-04 00:00:00")!, "1 day")) ``` will generate ```sql SELECT generate_series( (TIMESTAMP 'EPOCH' + make_interval(secs => 1569888000.0)), (TIMESTAMP 'EPOCH' + make_interval(secs => 1570147200.0)), '1 day' ) ```
macOS
SwifQL/Bridges 1.0.0-rc.4.13.6
๐ŸŒ‰ SwifQL+NIO provider to Postgres and MySQL
โญ๏ธ 56
๐Ÿ•“ 2 years ago
๐Ÿ”– Release Notes

Releases

The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
๐Ÿ‡ Implement `TableUpsert`
3 years ago
Thanks to @EthanLozano for the inspiration โšก๏ธ We already have conveniences for `insertInto` and `update` and obviously `upsert` is needed too! And now we have it! ```swift let newUser = User(id: UUID(), email: "[email protected]", firstName: "Ethan", lastName: "Lozano") /// we could simply insert it newUser.insert(on: conn) /// we could simply update it newUser.update(on: \.$id, on: conn) /// now we can upsert it on conflicting column newUser.upsert(conflictColumn: \.$id, on: conn) newUser.upsert(conflictColumn: \.$email, on: conn) /// we even can exclude one or more columns from update, e.g. excluding id may be necessary for update by email newUser.upsert(conflictColumn: \.$email, excluding: \User.$id, on: conn) /// we also can upsert on conflicting constraint newUser.upsert(conflictConstraint: "User_pkey", on: conn) newUser.upsert(conflictConstraint: "User_email_key", on: conn) newUser.upsert(conflictConstraint: "User_email_key", excluding: \User.$id, on: conn) ```
๐Ÿ‚ Decode custom model even with convenience method
3 years ago
Let's say you have a `Goods` table and you want to query a list of goods but only their `id` and `name` columns using this simple model ```swift struct ListModel: Content { let id: UUID let name: String } ``` We have simple and convenient method for querying all records from table in `Bridges` ```swift Goods.query(on: .psql, on: req).all() ``` but the problem in current situation is that it returns exactly `Goods` model and we have to do additional for-loop for its transformation Ok, since we're advanced SwifQL users we will use it to decode exactly into `ListModel` ```swift SwifQL.select(Goods.table.*).from(Goods.table).execute(on: .psql, on: req).all(decoding: ListModel.self) ``` and it's cool, but too long as for me **New addition to first convenience method solves this problem** ```swift Goods.query(on: .psql, on: req).all(decoding: ListModel.self) ``` That's it ๐Ÿ˜ƒ
๐Ÿ’ซ Enum array support
3 years ago
Now you're able to use enum array columns in your tables! **Preparation** ```swift enum Permission: String, BridgesEnum { case create, edit, delete } final class User: Table, Content { @Column("id") var id: UUID @Column("permissions") var permissions: [Permission] init () {} init(permissions: [Permission] = []) { self.id = UUID() self.permissions = permissions } } struct CreateUserMigration: TableMigration { typealias Table = User static func prepare(on conn: BridgeConnection) -> EventLoopFuture<Void> { createBuilder .column("id", .uuid, .primaryKey) .column("permissions", .auto(from: [Permission].self), .default("{}"), .notNull) .execute(on: conn) } static func revert(on conn: BridgeConnection) -> EventLoopFuture<Void> { dropBuilder.execute(on: conn) } } ``` **Usage examples** Where clause ```sql SELECT * FROM "User" WHERE "permissions" @> '{edit}' ``` ```swift SwifQL.select(User.table.*).from(User.table).where(\User.$permissions ||> [Permission.edit]) ``` Convenient update ```swift // let user: User // already fetched user user.permissions = [.create, .edit, .delete] user.update(on: \.$id, on: conn) ``` Pure update ```sql UPDATE "User" SET "permissions" = '{edit,delete}' WHERE "permissions" @> '{edit}' ``` ```swift SwifQL.update(User.table) .set[items: \User.$permissions == [Permission.edit, .delete]] .where(\User.$permissions ||> [Permission.edit]) ``` Convenient insert ```swift User(permissions: [.create, .edit, .delete]).insert(on: conn) ``` Pure insert ```sql INSERT INTO "User" ("id", "permissions") VALUES (..., '{create,edit,delete}') ``` ```swift SwifQL.insertInto(User.table, fields: \User.$id, \User.$permissions) .values .values(UUID(), [Permission.create, .edit, .delete]) .execute(on: conn) ```
๐Ÿ“SwifQLable: Implement convenient execute method
3 years ago
When you have only one complex query in route handler and it shouldn't be wrapped into transaction you could use this convenient method which will establish database connection by itself ```swift func someComplexQueryHandler(_ req: Request) throws -> EventLoopFuture<[CustomResult]> { SwifQL /// your complex query here .execute(.psqlEnvironment, on: req) .all() // or explicit .all(decoding: CustomResult.self) // .first() // or explicit .first(decoding: CustomResult.self) // .count() } ```
More conveniences
3 years ago
Examples below shows how to use new conveniences with demo `User` table ```swift /// without connection, useful if you have only one query there func databaseRequest(on req: Request) -> EventLoopFuture<SomeResult> { User.query(on: .psqlEnvironment, on: req) // optionally use `where` clause with all SwifQL's power .where(\User.$email == "[email protected]") /// also available // .join(...) // .groupBy(...) // .having(...) // .orderBy(...) // .offset(...) // .limit(...) /// and select one of methods listed below to get the result .first() // to get `EventLoopFuture<User?>` .all() // to get `EventLoopFuture<[User]>` .count() // to get EventLoopFuture<Int64> .delete() // to execute DELETE FROM "User" query, returns Void } /// with connection func databaseRequest(on req: Request) -> EventLoopFuture<[User]> { req.postgres.connection(to: .psqlEnvironment) { conn in // you could build query the same way as shown in above example User.query(on: conn).all() } } ``` > ๐Ÿ’ก available for all dialects
3 years ago
I've pimped `DatabaseIdentifier` to use it for conveniences. It is not breaking change, but if someone is using custom `DatabaseIdentifier` in case if he will try to use new conveniences it will throw an error and print a message in console that he should use explicit initialization for identifier. So e.g. this ```swift extension DatabaseIdentifier { static var dev_psql: DatabaseIdentifier { .init(name: "dev_test", host: DatabaseHost(hostname: "127.0.0.1", port: 5432, username: "root", password: "qwerty"), maxConnectionsPerEventLoop: 1) } } ``` should be replaced with ```swift extension DatabaseIdentifier { static var dev_psql: DatabaseIdentifier { .psql(name: "dev_test", host: DatabaseHost(hostname: "127.0.0.1", port: 5432, username: "root", password: "qwerty"), maxConnectionsPerEventLoop: 1) } } ``` ## Conveniences ```swift MyTable.all(on: .psqlEnvironment, on: req) // or on: application MyTable.first(on: .psqlEnvironment, on: req) // or on: application ``` **Later** I gonna use this fundament for generic select builder which I want to be available the same way like ```swift Table.where(\.$name == "John").all(on: .psqlEnvironment, on: req) ```
AnyMigration: replace `name` with `migrationName`
3 years ago
Since we use `tableName` for tables we realized that we have to use `migrationName` for migrations for consistency. `name` will still work since it is `release candidate` already ๐Ÿ™‚
TableInsert: implement batch insert
4 years ago
```swift let user1 = User(...) let user2 = User(...) let user3 = User(...) [user1, user2, user3].batchInsert(on: conn) // returns EventLoopFuture<Void> ```
macOS
SwifQL/VaporBridges 1.0.0-rc.1.4.0
๐Ÿ’งVapor wrapper for Bridges
โญ๏ธ 7
๐Ÿ•“ 2 years ago
macOS
SwifQL/VaporFluentDriver 2.3.2
Helper library for SwifQL and Vapor
โญ๏ธ 4
๐Ÿ•“ 12 weeks ago
macOS
SwifQL/PostgresBridge 1.0.0-rc.4.6.1
๐Ÿ˜ Pure SwifQL+NIO bridge to Postgres
โญ๏ธ 4
๐Ÿ•“ 3 weeks ago
๐Ÿ”– Release Notes

Releases

The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
๐Ÿ‘จโ€๐Ÿ”งSupport new version of `postgres-nio`
2 years ago
`postgres-nio` doesn't log queries anymore. So now `PostgresBridge` printing queries in `debug` logger mode.
๐Ÿ‘จโ€๐Ÿ”ง Temporary stick to `postgres-nio` 1.4.4 cause of bugs in 1.5.0
3 years ago
โš ๏ธ You might experience unexpected bugs if you updated your packages in last two days and received `postgres-nio` 1.5.0 which has a lot of changes under the hood and gave us production bugs. I decided to stick PostgresBridge to previous stable version of `postgres-nio` to prevent these new unresolved problems. https://github.com/vapor/postgres-nio/issues/143
๐Ÿ€ Implement `requestConnection` method
3 years ago
Thanks to @YorkFieldX now we can use `PostgresConnection` in tests simply this way ```swift // retrieve a connection let connection = try application.postgres.requestConnection(to: .my_awesome_database).wait() // execute any queries let users = try SwifQL.select(User.table.*) .from(User.table) .execute(on: connection) .all(decoding: User.self) .wait() // don't forget to close a connection try connection.close().wait() ``` > โš ๏ธUse this way only in tests cause you can only close a connection but not return it back to a pool, so it may affect app performance.
Implement PG_SSL environment key
3 years ago
Set `PG_SSL=1` or `PG_SSL=true` or `PG_SSL=require` environment variable to enable SSL for `.psqlEnvironment` database identifier.
macOS
SwifQL/MySQLBridge 1.0.0-rc.2.2.0
๐Ÿ˜ Pure SwifQL+NIO bridge to MySQL
โญ๏ธ 2
๐Ÿ•“ 12 weeks ago
๐Ÿ”– Release Notes

Releases

The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
๐Ÿ€ Implement `requestConnection` method
3 years ago
Thanks to @YorkFieldX now we can use `MySQLConnection` in tests simply this way ```swift // retrieve a connection let connection = try application.mysql.requestConnection(to: .my_awesome_database).wait() // execute any queries let users = try SwifQL.select(User.table.*) .from(User.table) .execute(on: connection) .all(decoding: User.self) .wait() // don't forget to close a connection try connection.close().wait() ``` > โš ๏ธUse this way only in tests cause you can only close a connection but not return it back to a pool, so it may affect app performance.
macOS

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics