Skip to content

Commit 8e44041

Browse files
authored
cleanup (#9)
1 parent e7b1b81 commit 8e44041

File tree

5 files changed

+60
-101
lines changed

5 files changed

+60
-101
lines changed

Sources/ClickHouseVapor/Application+ClickHouseNIO.swift

+9-8
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
// Created by Patrick Zippenfenig on 2020-11-10.
66
//
77

8-
import Vapor
98
import ClickHouseNIO
9+
import Vapor
1010

1111
@_exported import struct NIO.TimeAmount
1212

@@ -34,13 +34,14 @@ public struct ClickHousePoolConfiguration {
3434
public let maxConnectionsPerEventLoop: Int
3535
public let requestTimeout: TimeAmount
3636

37-
public init(hostname: String = "localhost",
38-
port: Int = ClickHouseConnection.defaultPort,
39-
user: String? = nil,
40-
password: String? = nil,
41-
database: String? = nil,
42-
maxConnectionsPerEventLoop: Int = 1,
43-
requestTimeout: TimeAmount = .seconds(10)
37+
public init(
38+
hostname: String = "localhost",
39+
port: Int = ClickHouseConnection.defaultPort,
40+
user: String? = nil,
41+
password: String? = nil,
42+
database: String? = nil,
43+
maxConnectionsPerEventLoop: Int = 1,
44+
requestTimeout: TimeAmount = .seconds(10)
4445
) throws {
4546
self.configuration = try ClickHouseConfiguration(
4647
hostname: hostname,

Sources/ClickHouseVapor/ClickHouseColumnConvertible.swift

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77

88
import ClickHouseNIO
99

10-
11-
1210
/// Define how a colun can be converted into a clickhose datatype
1311
public protocol ClickHouseColumnConvertible: AnyObject {
1412
var key: String { get }
@@ -33,7 +31,6 @@ public protocol ClickHouseColumnConvertibleTyped: ClickHouseColumnConvertible {
3331
associatedtype Value: ClickHouseDataType
3432
var wrappedValue: [Value] { get set }
3533
var columnMetadata: ClickHouseColumnMetadata? { get }
36-
3734
}
3835

3936
extension ClickHouseColumnConvertibleTyped {
@@ -89,7 +86,6 @@ public final class Field<Value: ClickHouseDataType>: ClickHouseColumnConvertible
8986
self
9087
}
9188

92-
9389
fileprivate init(
9490
key: String,
9591
isPrimary: Bool = false,
@@ -209,7 +205,7 @@ extension Array {
209205
/// Only include column rows where the isIncluded array is true
210206
func filtered(_ isIncluded: [Bool]) -> Self {
211207
precondition(count == isIncluded.count)
212-
var arr = Self.init()
208+
var arr = Self()
213209
let count = isIncluded.reduce(0, { $0 + ($1 ? 1 : 0) })
214210
arr.reserveCapacity(count)
215211
for (i, include) in isIncluded.enumerated() where include {

Sources/ClickHouseVapor/ClickHouseEngine.swift

+16-50
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
import Foundation
99
import enum ClickHouseNIO.ClickHouseTypeName
1010

11-
/// Abstract a clickhouse storage engine. For example the `ReplacingMergeTree` requires special CREATE syntax.
11+
/// Abstract a clickHouse storage engine. For example the `ReplacingMergeTree` requires special CREATE syntax.
1212
/// This could also be used to
13-
public protocol ClickHouseEngine {
13+
public protocol ClickHouseEngine: Sendable {
1414
/// Generate a SQL query to create the table using the defined model columns
1515
func createTableQuery(columns: [ClickHouseColumnConvertible]) -> String
1616

@@ -26,23 +26,23 @@ public protocol ClickHouseEngine {
2626

2727
extension ClickHouseEngine {
2828
public var isUsingCluster: Bool {
29-
cluster != nil
29+
self.cluster != nil
3030
}
3131

32-
/// Returns the tablename and database name encoded with a dot
32+
/// Returns the table name and database name encoded with a dot
3333
public var tableWithDatabase: String {
34-
if let database = database {
35-
return "`\(database)`.`\(table)`"
34+
if let database = self.database {
35+
return "`\(database)`.`\(self.table)`"
3636
}
37-
return "`\(table)`"
37+
return "`\(self.table)`"
3838
}
3939
}
4040

4141
public struct ClickHouseEngineReplacingMergeTree: ClickHouseEngine {
42-
public var table: String
43-
public var database: String?
44-
public var cluster: String?
45-
public var partitionBy: String?
42+
public let table: String
43+
public let database: String?
44+
public let cluster: String?
45+
public let partitionBy: String?
4646

4747
public init(table: String, database: String?, cluster: String?, partitionBy: String?) {
4848
self.table = table
@@ -77,7 +77,7 @@ public struct ClickHouseEngineReplacingMergeTree: ClickHouseEngine {
7777
PRIMARY KEY (\(ids.joined(separator: ",")))
7878
"""
7979
if let partitionBy = partitionBy {
80-
query += " PARTITION BY (\(partitionBy))"
80+
query += " PARTITION BY (\(partitionBy))"
8181
}
8282
query += " ORDER BY (\(order.joined(separator: ",")))"
8383
return query
@@ -89,50 +89,16 @@ extension ClickHouseTypeName {
8989
// basically all numerical data types except for Decimal support LowCardinality
9090
// https://clickhouse.tech/docs/en/sql-reference/data-types/lowcardinality/
9191
switch self {
92-
case .float:
93-
return true
94-
case .float64:
95-
return true
96-
case .int8:
97-
return true
98-
case .int16:
99-
return true
100-
case .int32:
101-
return true
102-
case .int64:
103-
return true
104-
case .uint8:
105-
return true
106-
case .uint16:
107-
return true
108-
case .uint32:
109-
return true
110-
case .uint64:
92+
case .float, .float64, .int8, .int16, .int32, .int64, .uint8, .uint16, .uint32, .uint64:
11193
return true
11294
case .uuid:
11395
return false
114-
case .fixedString(_):
115-
return true
116-
case .string:
96+
case .fixedString, .string:
11797
return true
11898
case .nullable(let type):
11999
return type.supportsLowCardinality
120-
case .array:
100+
case .array, .boolean, .date, .date32, .dateTime, .dateTime64, .enum16, .enum8:
121101
return false
122-
case .boolean:
123-
return false
124-
case .date:
125-
return false
126-
case .date32:
127-
return false
128-
case .dateTime(_):
129-
return false
130-
case .dateTime64(_):
131-
return false
132-
case .enum16(_):
133-
return false
134-
case .enum8(_):
135-
return false
136-
}
102+
}
137103
}
138104
}

Sources/ClickHouseVapor/ClickHouseModel.swift

+7-9
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,9 @@
55
// Created by Patrick Zippenfenig on 2020-11-10.
66
//
77

8+
import ClickHouseNIO
89
import Foundation
910
import Vapor
10-
import ClickHouseNIO
11-
1211

1312
public protocol ClickHouseModel: AnyObject {
1413
static var engine: ClickHouseEngine { get }
@@ -19,7 +18,7 @@ extension ClickHouseModel {
1918
/// Get the number of rows.
2019
/// In case only some rows are populated (e.g. only certain ), the first column with more than 0 rows is considered.
2120
public var count: Int {
22-
return properties.first(where: {$0.count > 0})?.count ?? 0
21+
return properties.first(where: { $0.count > 0 })?.count ?? 0
2322
}
2423

2524
/// Only include column rows where the isIncluded array is true.
@@ -55,7 +54,7 @@ extension ClickHouseModel {
5554
allMirrors.append(superMirror)
5655
}
5756
return allMirrors.reversed().flatMap { m in
58-
m.children.compactMap {
57+
m.children.compactMap {
5958
$0.value as? ClickHouseColumnConvertible
6059
}
6160
}
@@ -66,7 +65,7 @@ extension ClickHouseModel {
6665
on connection: ClickHouseConnectionProtocol,
6766
engine: ClickHouseEngine? = nil
6867
) -> EventLoopFuture<Void> {
69-
let fields = Self.init().properties
68+
let fields = Self().properties
7069
let engine = engine ?? Self.engine
7170
let query = engine.createTableQuery(columns: fields)
7271
connection.logger.debug("\(query)")
@@ -128,11 +127,11 @@ extension ClickHouseModel {
128127
sql: String
129128
) -> EventLoopFuture<Self> {
130129
connection.logger.debug("\(sql)")
131-
let this = Self.init()
130+
let this = Self()
132131
let properties = this.properties
133132
return connection.query(sql: sql).flatMapThrowing { res -> Self in
134133
try res.columns.forEach { column in
135-
guard let prop = properties.first(where: {$0.key == column.name}) else {
134+
guard let prop = properties.first(where: { $0.key == column.name }) else {
136135
return
137136
}
138137
try prop.setClickHouseArray(column.values)
@@ -153,9 +152,8 @@ extension ClickHouseModel {
153152
offset: Int? = nil,
154153
engine: ClickHouseEngine? = nil
155154
) -> EventLoopFuture<Self> {
156-
157155
let engine = engine ?? Self.engine
158-
let fields = fields ?? Self.init().properties.map { "`\($0.key)`" }
156+
let fields = fields ?? Self().properties.map { "`\($0.key)`" }
159157

160158
var sql = "SELECT "
161159
sql += fields.joined(separator: ",")

Tests/ClickHouseVaporTests/ClickHouseVaporTests.swift

+27-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import XCTest
2-
@testable import ClickHouseVapor
31
import Foundation
42
import Vapor
3+
import XCTest
4+
5+
@testable import ClickHouseVapor
56

67
extension Application {
78
func configureClickHouseDatabases() throws {
@@ -40,10 +41,9 @@ public class TestModel: ClickHouseModel {
4041
@Field(key: "dat")
4142
var dat: [ClickHouseDate]
4243

43-
4444
/// Not implemented on test-server
4545
// @Field(key: "dat32")
46-
// var dat32: [ClickHouseDate32]
46+
// var dat32: [ClickHouseDate32]
4747

4848
@Field(key: "datt")
4949
var datt: [ ClickHouseDateTime ]
@@ -53,22 +53,20 @@ public class TestModel: ClickHouseModel {
5353

5454
@Field(key: "datt64", precision: 3)
5555
var datt64: [ ClickHouseDateTime64 ]
56-
56+
5757
@Field(key: "datt64z", precision: 3, timeZone: "'GMT'")
5858
var datt64z: [ ClickHouseDateTime64 ]
59-
59+
6060
@Field(key: "en8", mapping: ["a": 0, "b": 1])
6161
var en8: [ ClickHouseEnum8 ]
62-
62+
6363
@Field(key: "en16", mapping: ["a": 12, "b": 1, "c": 600])
6464
var en16: [ ClickHouseEnum16 ]
6565

6666
@Field(key: "temperature")
6767
var temperature: [Float]
6868

69-
required public init() {
70-
71-
}
69+
public required init() {}
7270

7371
public static var engine: ClickHouseEngine {
7472
return ClickHouseEngineReplacingMergeTree(
@@ -105,7 +103,6 @@ public final class InheritedTestModel: TestParentClass, ClickHouseModel {
105103
}
106104

107105
final class ClickHouseVaporTests: XCTestCase {
108-
109106
static var allTests = [
110107
("testPing", testPing),
111108
("testModel", testModel),
@@ -134,7 +131,7 @@ final class ClickHouseVaporTests: XCTestCase {
134131

135132
model.id = [ "x010", "ax51", "cd22" ]
136133
model.fixed = [ "", "123456", "12345678901234" ]
137-
model.arr = [[1], [], [76, 56, 2]]
134+
model.arr = [[1], [], [76, 56, 2]]
138135
model.dat = [.clickhouseDefault, .clickhouseDefault, .clickhouseDefault]
139136
model.datt = [.clickhouseDefault, .clickhouseDefault, .clickhouseDefault]
140137
model.datt64 = [.clickhouseDefault, .clickhouseDefault, .clickhouseDefault]
@@ -144,7 +141,7 @@ final class ClickHouseVaporTests: XCTestCase {
144141
model.en16 = [.init(word: "a"), .init(word: "b"), .init(word: "c")]
145142
model.timestamp = [ 100, 200, 300 ]
146143
model.temperature = [ 11.1, 10.4, 8.9 ]
147-
144+
148145
let createQuery = TestModel.engine.createTableQuery(columns: model.properties)
149146
XCTAssertEqual(createQuery
150147
.replacingOccurrences(of: "Enum8('b'=1,'a'=0)", with: "Enum8('a'=0,'b'=1)")
@@ -166,16 +163,16 @@ final class ClickHouseVaporTests: XCTestCase {
166163
XCTAssertEqual(model.id, model2.id)
167164
XCTAssertEqual(["", "123456", "1234567890"], model2.fixed)
168165
XCTAssertEqual(model.timestamp, model2.timestamp)
169-
XCTAssertEqual(model.dat.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
170-
XCTAssertEqual(model2.dat.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
171-
XCTAssertEqual(model.datt.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
172-
XCTAssertEqual(model2.datt.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
173-
XCTAssertEqual(model.dattz.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
174-
XCTAssertEqual(model2.dattz.map { $0.date}, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
175-
XCTAssertEqual(model.en8.map { $0.word}, ["a", "b", "a"])
176-
XCTAssertEqual(model2.en8.map { $0.word}, ["a", "b", "a"])
177-
XCTAssertEqual(model.en16.map { $0.word}, ["a", "b", "c"])
178-
XCTAssertEqual(model2.en16.map { $0.word}, ["a", "b", "c"])
166+
XCTAssertEqual(model.dat.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
167+
XCTAssertEqual(model2.dat.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
168+
XCTAssertEqual(model.datt.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
169+
XCTAssertEqual(model2.datt.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
170+
XCTAssertEqual(model.dattz.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
171+
XCTAssertEqual(model2.dattz.map { $0.date }, [Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0), Date(timeIntervalSince1970: 0.0)])
172+
XCTAssertEqual(model.en8.map { $0.word }, ["a", "b", "a"])
173+
XCTAssertEqual(model2.en8.map { $0.word }, ["a", "b", "a"])
174+
XCTAssertEqual(model.en16.map { $0.word }, ["a", "b", "c"])
175+
XCTAssertEqual(model2.en16.map { $0.word }, ["a", "b", "c"])
179176
XCTAssertEqual(model.arr, [[1], [], [76, 56, 2]])
180177
XCTAssertEqual(model2.arr, [[1], [], [76, 56, 2]])
181178

@@ -192,7 +189,7 @@ final class ClickHouseVaporTests: XCTestCase {
192189
XCTAssertEqual(filtered.id, ["ax51", "x010"])
193190
XCTAssertEqual(filtered.timestamp, [200, 100])
194191

195-
/// Raw select query, that gets applied to
192+
// Raw select query, that gets applied to
196193
let model3 = try! TestModel.select(
197194
on: app.clickHouse,
198195
sql: "SELECT timestamp, stationID FROM default.test"
@@ -210,7 +207,8 @@ final class ClickHouseVaporTests: XCTestCase {
210207

211208
let model = InheritedTestModel()
212209
let createQuery = InheritedTestModel.engine.createTableQuery(columns: model.properties)
213-
XCTAssertEqual(createQuery,
210+
XCTAssertEqual(
211+
createQuery,
214212
"""
215213
CREATE TABLE IF NOT EXISTS `testInherited` (timestamp Int64,stationID LowCardinality(String),temperature Float32)
216214
ENGINE = ReplacingMergeTree()
@@ -222,7 +220,7 @@ final class ClickHouseVaporTests: XCTestCase {
222220
try! InheritedTestModel.deleteTable(on: app.clickHouse).wait()
223221
// create table
224222
try! InheritedTestModel.createTable(on: app.clickHouse).wait()
225-
223+
226224
// fill model with data and insert it
227225
model.id = [ "x010", "ax51", "cd22" ]
228226
model.timestamp = [ 100, 200, 300 ]
@@ -232,9 +230,9 @@ final class ClickHouseVaporTests: XCTestCase {
232230
// select the data again
233231
let model2 = try! InheritedTestModel.select(on: app.clickHouse).wait()
234232

235-
XCTAssertEqual(model2.id, model.id)
236-
XCTAssertEqual(model2.timestamp, model.timestamp)
237-
XCTAssertEqual(model2.temperature, model.temperature)
233+
XCTAssertEqual(model2.id, model.id)
234+
XCTAssertEqual(model2.timestamp, model.timestamp)
235+
XCTAssertEqual(model2.temperature, model.temperature)
238236
}
239237

240238
/// insert should fail if some columns are not set, but others are

0 commit comments

Comments
 (0)