Repository navigation
Expand file tree
/
Copy pathModel.swift
More file actions
129 lines (102 loc) · 4.86 KB
/
Copy pathModel.swift
File metadata and controls
129 lines (102 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//
// Model.swift
// PostgresClientKit-iOS-Example
//
// Copyright 2019 David Pitfield and the PostgresClientKit contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
import Foundation
import PostgresClientKit
class Model {
//
// MARK: Model and connection lifecycle
//
init(environment: Environment, user: String, password: String) {
// Configure a connection pool with, at most, a single connection. Using a connection pool
// allows the connection to be lazily created, automatically re-creates the connection if
// there is an unrecoverable error, and performs database operations on a background thread.
var connectionPoolConfiguration = ConnectionPoolConfiguration()
connectionPoolConfiguration.maximumConnections = 1
// Configure how connections are created in that connection pool.
var connectionConfiguration = ConnectionConfiguration()
connectionConfiguration.host = environment.host
connectionConfiguration.port = environment.port
connectionConfiguration.ssl = environment.ssl
connectionConfiguration.database = environment.database
connectionConfiguration.user = user
connectionConfiguration.credential = .scramSHA256(password: password)
connectionPool = ConnectionPool(connectionPoolConfiguration: connectionPoolConfiguration,
connectionConfiguration: connectionConfiguration)
}
/// A pool of (at most) a single connection.
var connectionPool: ConnectionPool
/// Closes any existing connection to the Postgres server.
func disconnect() {
// Close the current connection pool
connectionPool.close()
// And create a new one. Its connection will be lazily created.
connectionPool = ConnectionPool(
connectionPoolConfiguration: connectionPool.connectionPoolConfiguration,
connectionConfiguration: connectionPool.connectionConfiguration)
}
//
// MARK: Entities and operations
//
/// A record of the weather at a particular city on a particular date.
struct Weather {
let city: String
let date: PostgresDate
let lowTemperature: Int
let highTemperature: Int
let precipitation: Double?
}
/// Gets the weather records for the specified city.
///
/// - Parameters:
/// - city: the city
/// - completion: a completion handler, invoked with either the weather records or an error.
func weatherHistoryForCity(_ city: String,
completion: @escaping (Result<[Weather], Error>) -> Void) {
connectionPool.withConnection { connectionResult in
let result = Result<[Weather], Error> {
let connection = try connectionResult.get()
let text = "SELECT city, temp_lo, temp_hi, prcp, date FROM weather WHERE city = $1;"
let statement = try connection.prepareStatement(text: text)
defer { statement.close() }
let cursor = try statement.execute(parameterValues: [ city ])
defer { cursor.close() }
var weatherHistory = [Weather]()
for row in cursor {
let columns = try row.get().columns
let city = try columns[0].string()
let tempLo = try columns[1].int()
let tempHi = try columns[2].int()
let prcp = try columns[3].optionalDouble()
let date = try columns[4].date()
let weather = Weather(city: city,
date: date,
lowTemperature: tempLo,
highTemperature: tempHi,
precipitation: prcp)
weatherHistory.append(weather)
}
return weatherHistory
}
DispatchQueue.main.async { // call the completion handler in the main thread
completion(result)
}
}
}
}
// EOF