Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 8828d56

Browse files
tanner0101gwynne
andauthored
FluentKit 1.0.0 GM (vapor#152)
* fluentkit gm * Include the new benchmarker suites for this driver's tests * new tests * gm update, tests * cleanup * macos formatting * fix macos tests * env var rename * update ci config * env var fixes * rm nested * version update Co-authored-by: Gwynne Raskind <gwynne@darkrainfall.org>
1 parent 2bf6bf2 commit 8828d56

File tree

8 files changed

+170
-103
lines changed

8 files changed

+170
-103
lines changed

β€Ž.github/workflows/test.ymlβ€Ž

Lines changed: 49 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,70 @@
11
name: Test Matrix
2-
on: ['pull_request']
3-
defaults:
4-
run:
5-
shell: bash
2+
on:
3+
- pull_request
64
jobs:
7-
PR-tests-linux:
5+
linux:
86
strategy:
97
fail-fast: false
108
matrix:
11-
dbimage: ['postgres:11', 'postgres:12']
12-
runner: [
13-
'swift:5.2-xenial', 'swift:5.2-bionic',
14-
'swiftlang/swift:nightly-5.2-xenial', 'swiftlang/swift:nightly-5.2-bionic',
15-
'swiftlang/swift:nightly-5.3-xenial', 'swiftlang/swift:nightly-5.3-bionic',
16-
'swiftlang/swift:nightly-master-xenial', 'swiftlang/swift:nightly-master-bionic',
17-
'swiftlang/swift:nightly-master-focal',
18-
'swiftlang/swift:nightly-master-centos8',
19-
'swiftlang/swift:nightly-master-amazonlinux2'
20-
]
21-
include:
22-
- installcmd: 'apt-get -q update && apt-get -q install -y postgresql-client'
23-
- { 'runner': 'swiftlang/swift:nightly-master-centos8', 'installcmd': 'dnf install -y zlib-devel postgresql' }
24-
- { 'runner': 'swiftlang/swift:nightly-master-amazonlinux2', 'installcmd': 'yum install -y zlib-devel postgresql' }
9+
dbimage:
10+
- postgres:11
11+
- postgres:12
12+
runner:
13+
# 5.2 Stable
14+
- swift:5.2-xenial
15+
- swift:5.2-bionic
16+
# 5.2 Unstable
17+
- swiftlang/swift:nightly-5.2-xenial
18+
- swiftlang/swift:nightly-5.2-bionic
19+
# 5.3 Unstable
20+
- swiftlang/swift:nightly-5.3-xenial
21+
- swiftlang/swift:nightly-5.3-bionic
22+
# Master Unsable
23+
- swiftlang/swift:nightly-master-xenial
24+
- swiftlang/swift:nightly-master-bionic
25+
- swiftlang/swift:nightly-master-focal
26+
- swiftlang/swift:nightly-master-centos8
27+
- swiftlang/swift:nightly-master-amazonlinux2
2528
container: ${{ matrix.runner }}
2629
runs-on: ubuntu-latest
2730
services:
28-
postgres:
31+
postgres-a:
2932
image: ${{ matrix.dbimage }}
30-
env: { POSTGRES_USER: vapor_username, POSTGRES_PASSWORD: vapor_password, POSTGRES_DB: vapor_database }
31-
env: { 'PGPASSWORD': 'vapor_password' }
33+
env:
34+
POSTGRES_USER: vapor_username
35+
POSTGRES_PASSWORD: vapor_password
36+
POSTGRES_DB: vapor_database
37+
postgres-b:
38+
image: ${{ matrix.dbimage }}
39+
env:
40+
POSTGRES_USER: vapor_username
41+
POSTGRES_PASSWORD: vapor_password
42+
POSTGRES_DB: vapor_database
3243
steps:
33-
- name: Install dependencies
34-
run: ${{ matrix.installcmd }}
35-
- name: Wait for Postgres server to be ready
36-
run: until echo | psql -hpostgres -Uvapor_username vapor_database; do sleep 1; done
37-
timeout-minutes: 5
38-
- name: Set up Postgres databases and privileges
39-
run: |
40-
for db in vapor_migration_extra; do createdb -hpostgres -Uvapor_username -Ovapor_username $db; done
4144
- name: Check out code
4245
uses: actions/checkout@v2
4346
- name: Run tests with Thread Sanitizer
4447
run: swift test --enable-test-discovery --sanitize=thread
45-
env: { 'POSTGRES_HOSTNAME': 'postgres' }
46-
PR-tests-macos:
48+
env:
49+
POSTGRES_HOSTNAME_A: postgres-a
50+
POSTGRES_HOSTNAME_B: postgres-b
51+
macos:
4752
strategy:
4853
fail-fast: false
4954
matrix:
5055
include:
51-
- {'formula': 'postgresql@11', 'datadir': 'postgresql@11'}
52-
- {'formula': 'postgresql@12', 'datadir': 'postgres'}
56+
- formula: postgresql@11
57+
datadir: postgresql@11
58+
- formula: postgresql@12
59+
datadir: postgres
5360
runs-on: macos-latest
54-
env: { 'PGPASSWORD': 'vapor_password' }
61+
env:
62+
PGPASSWORD: vapor_password
5563
steps:
5664
- name: Select latest available Xcode
5765
uses: maxim-lobanov/setup-xcode@1.0
58-
with: { 'xcode-version': 'latest' }
66+
with:
67+
xcode-version: latest
5968
- name: Blow away the default Postgres installation
6069
run: brew uninstall --force postgresql php && rm -rf /usr/local/{etc,var}/{postgres,pg}*
6170
- name: Install Postgres server from Homebrew
@@ -70,10 +79,13 @@ jobs:
7079
- name: Set up Postgres databases and privileges
7180
run: |
7281
createuser --createdb --login vapor_username
73-
for db in vapor_{database,migration_extra}; do
82+
for db in vapor_{database_a,database_b}; do
7483
createdb -Ovapor_username $db && psql $db <<<"ALTER SCHEMA public OWNER TO vapor_username;"
7584
done
7685
- name: Check out code
7786
uses: actions/checkout@v2
7887
- name: Run tests with Thread Sanitizer
7988
run: swift test --enable-test-discovery --sanitize=thread
89+
env:
90+
POSTGRES_DATABASE_A: vapor_database_a
91+
POSTGRES_DATABASE_B: vapor_database_b

β€ŽPackage.swiftβ€Ž

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ let package = Package(
1010
.library(name: "FluentPostgresDriver", targets: ["FluentPostgresDriver"]),
1111
],
1212
dependencies: [
13-
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.0.0-rc.1"),
13+
.package(url: "https://github.com/vapor/fluent-kit.git", from: "1.0.0-rc.2"),
1414
.package(url: "https://github.com/vapor/postgres-kit.git", from: "2.0.0"),
1515
],
1616
targets: [

β€ŽSources/FluentPostgresDriver/FluentPostgresDatabase.swiftβ€Ž

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ import FluentSQL
33
struct _FluentPostgresDatabase {
44
let database: PostgresDatabase
55
let context: DatabaseContext
6-
76
let encoder: PostgresDataEncoder
87
let decoder: PostgresDataDecoder
8+
let inTransaction: Bool
99
}
1010

1111
extension _FluentPostgresDatabase: Database {
@@ -72,13 +72,17 @@ extension _FluentPostgresDatabase: Database {
7272
}
7373

7474
func transaction<T>(_ closure: @escaping (Database) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
75-
self.database.withConnection { conn in
75+
guard !self.inTransaction else {
76+
return closure(self)
77+
}
78+
return self.database.withConnection { conn in
7679
conn.simpleQuery("BEGIN").flatMap { _ in
7780
let db = _FluentPostgresDatabase(
7881
database: conn,
7982
context: self.context,
8083
encoder: self.encoder,
81-
decoder: self.decoder
84+
decoder: self.decoder,
85+
inTransaction: true
8286
)
8387
return closure(db).flatMap { result in
8488
conn.simpleQuery("COMMIT").map { _ in
@@ -95,7 +99,13 @@ extension _FluentPostgresDatabase: Database {
9599

96100
func withConnection<T>(_ closure: @escaping (Database) -> EventLoopFuture<T>) -> EventLoopFuture<T> {
97101
self.database.withConnection {
98-
closure(_FluentPostgresDatabase(database: 0ドル, context: self.context, encoder: self.encoder, decoder: self.decoder))
102+
closure(_FluentPostgresDatabase(
103+
database: 0ドル,
104+
context: self.context,
105+
encoder: self.encoder,
106+
decoder: self.decoder,
107+
inTransaction: self.inTransaction
108+
))
99109
}
100110
}
101111
}

β€ŽSources/FluentPostgresDriver/FluentPostgresDriver.swiftβ€Ž

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ struct _FluentPostgresDriver: DatabaseDriver {
1616
database: self.pool.pool(for: context.eventLoop).database(logger: context.logger),
1717
context: context,
1818
encoder: self.encoder,
19-
decoder: self.decoder
19+
decoder: self.decoder,
20+
inTransaction: false
2021
)
2122
}
2223

β€ŽSources/FluentPostgresDriver/PostgresConverterDelegate.swiftβ€Ž

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,17 @@ struct PostgresConverterDelegate: SQLConverterDelegate {
2323
return nil
2424
}
2525
}
26+
27+
28+
func nestedFieldExpression(_ column: String, _ path: [String]) -> SQLExpression {
29+
switch path.count {
30+
case 1:
31+
return SQLRaw("\(column)->>'\(path[0])'")
32+
case 2...:
33+
let inner = path[0..<path.count - 1].map { "'\(0ドル)'" }.joined(separator: "->")
34+
return SQLRaw("\(column)->\(inner)->>'\(path.last!)'")
35+
default:
36+
fatalError()
37+
}
38+
}
2639
}

β€ŽSources/FluentPostgresDriver/PostgresRow+Database.swiftβ€Ž

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,48 +4,86 @@ extension PostgresRow {
44
internal func databaseOutput(using decoder: PostgresDataDecoder) -> DatabaseOutput {
55
_PostgresDatabaseOutput(
66
row: self,
7-
decoder: decoder,
8-
schema: nil
7+
decoder: decoder
98
)
109
}
1110
}
1211

1312
private struct _PostgresDatabaseOutput: DatabaseOutput {
1413
let row: PostgresRow
1514
let decoder: PostgresDataDecoder
16-
let schema: String?
1715

1816
var description: String {
1917
self.row.description
2018
}
2119

22-
func contains(_ path: [FieldKey]) -> Bool {
23-
return self.row.column(self.columnName(path)) != nil
20+
func decodeNil(_ key: FieldKey) throws -> Bool {
21+
if let data = self.row.column(self.columnName(key)) {
22+
return data.type == .null
23+
} else {
24+
return true
25+
}
26+
}
27+
28+
func contains(_ key: FieldKey) -> Bool {
29+
self.row.column(self.columnName(key)) != nil
2430
}
2531

2632
func schema(_ schema: String) -> DatabaseOutput {
27-
_PostgresDatabaseOutput(
28-
row: self.row,
29-
decoder: self.decoder,
33+
_SchemaDatabaseOutput(
34+
output: self,
3035
schema: schema
3136
)
3237
}
3338

34-
func decode<T>(
35-
_ path: [FieldKey],
36-
as type: T.Type
37-
) throws -> T where T : Decodable {
39+
func decode<T>(_ key: FieldKey, as type: T.Type) throws -> T
40+
where T: Decodable
41+
{
3842
try self.row.sql(decoder: self.decoder)
39-
.decode(column: self.columnName(path), as: T.self)
43+
.decode(column: self.columnName(key), as: T.self)
4044
}
4145

42-
private func columnName(_ path: [FieldKey]) -> String {
43-
let field = path.map { 0ドル.description }.joined(separator: "_")
44-
if let schema = self.schema {
45-
return "\(schema)_\(field)"
46-
} else {
47-
return field
46+
func columnName(_ key: FieldKey) -> String {
47+
switch key {
48+
case .id:
49+
return "id"
50+
case .aggregate:
51+
return key.description
52+
case .string(let name):
53+
return name
54+
case .prefix(let prefix, let key):
55+
return self.columnName(prefix) + self.columnName(key)
4856
}
57+
}
58+
}
59+
60+
private struct _SchemaDatabaseOutput: DatabaseOutput {
61+
let output: DatabaseOutput
62+
let schema: String
63+
64+
var description: String {
65+
self.output.description
66+
}
67+
68+
func schema(_ schema: String) -> DatabaseOutput {
69+
self.output.schema(schema)
70+
}
71+
72+
func contains(_ key: FieldKey) -> Bool {
73+
self.output.contains(self.key(key))
74+
}
75+
76+
func decodeNil(_ key: FieldKey) throws -> Bool {
77+
try self.output.decodeNil(self.key(key))
78+
}
79+
80+
func decode<T>(_ key: FieldKey, as type: T.Type) throws -> T
81+
where T: Decodable
82+
{
83+
try self.output.decode(self.key(key), as: T.self)
84+
}
4985

86+
private func key(_ key: FieldKey) -> FieldKey {
87+
.prefix(.string(self.schema + "_"), key)
5088
}
5189
}

0 commit comments

Comments
(0)

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /