Skip to content

Commit d50a3d0

Browse files
authored
docs: add example how to use Combine to prepare batches for write into InfluxDB (#44)
1 parent d7e9b67 commit d50a3d0

File tree

8 files changed

+4212
-1
lines changed

8 files changed

+4212
-1
lines changed

.circleci/config.yml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ jobs:
118118
parameters:
119119
xcode-version:
120120
type: string
121-
default: "12.3.0"
121+
default: &default-xcode "12.5.1"
122122
influxdb-package-version:
123123
type: string
124124
default: "2.0.4"
@@ -265,13 +265,40 @@ jobs:
265265
- Examples/InfluxDBStatus/Package.resolved
266266
- Examples/InfluxDBStatus/.build/repositories
267267

268+
check-examples-macOS:
269+
macos:
270+
xcode: << parameters.xcode-version >>
271+
parameters:
272+
xcode-version:
273+
type: string
274+
default: *default-xcode
275+
steps:
276+
- checkout
277+
- restore_cache:
278+
name: Restoring Example Cache
279+
keys:
280+
- &cache-example-key example-macOS-cache-v0-{{ checksum "Examples/WriteDataInBatches/Package.swift" }}
281+
- example-macOS-cache-v0-
282+
- run: |
283+
HOMEBREW_NO_AUTO_UPDATE=1
284+
brew install swiftlint
285+
- check-example:
286+
directory: WriteDataInBatches
287+
- save_cache:
288+
name: Saving Example Cache
289+
key: *cache-example-key
290+
paths:
291+
- Examples/WriteDataInBatches/Package.resolved
292+
- Examples/WriteDataInBatches/.build/repositories
293+
268294
workflows:
269295
version: 2
270296
build:
271297
jobs:
272298
- check-code-style
273299
- check-documentation
274300
- check-examples
301+
- check-examples-macOS
275302
- tests-linux
276303
- tests-linux:
277304
name: tests-linux-5.4

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## 0.9.0 [unreleased]
22

3+
### Documentation
4+
1. [#44](https://github.com/influxdata/influxdb-client-swift/pull/44): Add an example how to use `Combine` to prepare batches for write into InfluxDB
5+
36
## 0.8.0 [2021-10-22]
47

58
### Features

Examples/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Writes
44
- [WriteData](WriteData#writedata) - How to write data with Data Point structure
5+
- [WriteDataInBatches](WriteDataInBatches#writedatainbatches) - How to use Combine to prepare batches for write into InfluxDB
56

67
## Queries
78
- [QueryCpu](QueryCpu#querycpu) - How to query data into sequence of `FluxRecord`
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
opt_in_rules:
2+
- array_init
3+
- collection_alignment
4+
- contains_over_first_not_nil
5+
- closure_end_indentation
6+
- closure_spacing
7+
- conditional_returns_on_newline
8+
- empty_count
9+
- empty_string
10+
- explicit_init
11+
- explicit_self
12+
- fatal_error_message
13+
- first_where
14+
- implicit_return
15+
- missing_docs
16+
- modifier_order
17+
- multiline_arguments
18+
- multiline_literal_brackets
19+
- multiline_parameters
20+
- operator_usage_whitespace
21+
- pattern_matching_keywords
22+
- redundant_nil_coalescing
23+
- redundant_type_annotation
24+
- sorted_first_last
25+
- sorted_imports
26+
- trailing_closure
27+
- unneeded_parentheses_in_closure_argument
28+
- unused_import
29+
- unused_declaration
30+
- vertical_parameter_alignment_on_call
31+
- vertical_whitespace_closing_braces
32+
- vertical_whitespace_opening_braces
33+
34+
excluded:
35+
- Package.swift
36+
- .build/
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// swift-tools-version:5.3
2+
3+
import PackageDescription
4+
5+
let package = Package(
6+
name: "WriteDataInBatches",
7+
platforms: [
8+
.macOS(.v11)
9+
],
10+
products: [
11+
.executable(name: "write-data-in-batches", targets: ["WriteDataInBatches"])
12+
],
13+
dependencies: [
14+
.package(name: "influxdb-client-swift", path: "../../"),
15+
.package(url: "https://github.com/apple/swift-argument-parser", from: "0.3.0")
16+
],
17+
targets: [
18+
.target(name: "WriteDataInBatches", dependencies: [
19+
.product(name: "InfluxDBSwift", package: "influxdb-client-swift"),
20+
.product(name: "ArgumentParser", package: "swift-argument-parser")
21+
], resources: [.process("vix-daily.csv")])
22+
]
23+
)

Examples/WriteDataInBatches/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# WriteDataInBatches
2+
3+
How to use Combine to prepare batches for write into InfluxDB
4+
5+
## Prerequisites:
6+
- macOS 11+
7+
- Cloned examples:
8+
```bash
9+
git clone [email protected]:influxdata/influxdb-client-swift.git
10+
cd Examples/WriteDataInBatches
11+
```
12+
13+
## Sources:
14+
- [Package.swift](/Examples/WriteDataInBatches/Package.swift)
15+
- [main.swift](/Examples/WriteDataInBatches/Sources/WriteDataInBatches/main.swift)
16+
17+
## How to test:
18+
1. Start InfluxDB:
19+
```bash
20+
docker run --rm \
21+
--name influxdb_v2 \
22+
--detach \
23+
--publish 8086:8086 \
24+
influxdb:latest
25+
```
26+
1. Configure your username, password, organization, bucket and token:
27+
```bash
28+
docker run --rm \
29+
--link influxdb_v2 \
30+
curlimages/curl -s -i -X POST http://influxdb_v2:8086/api/v2/setup \
31+
-H 'accept: application/json' \
32+
-d '{"username": "my-user", "password": "my-password", "org": "my-org", "bucket": "my-bucket", "token": "my-token"}'
33+
```
34+
1. Write data by:
35+
```bash
36+
swift run write-data-in-batches --bucket my-bucket --org my-org --token my-token --url http://localhost:8086
37+
```
38+
39+
## Expected output
40+
41+
```bash
42+
Writing 500 items ...
43+
> success
44+
Writing 500 items ...
45+
> success
46+
Writing 500 items ...
47+
> success
48+
Writing 500 items ...
49+
> success
50+
Writing 500 items ...
51+
> success
52+
Writing 500 items ...
53+
> success
54+
Writing 500 items ...
55+
> success
56+
Writing 452 items ...
57+
> success
58+
Import finished!
59+
```
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
//
2+
// Created by Jakub Bednář on 04/11/2021.
3+
//
4+
5+
import ArgumentParser
6+
import Combine
7+
import CSV
8+
import Foundation
9+
import InfluxDBSwift
10+
11+
struct WriteDataInBatches: ParsableCommand {
12+
@Option(name: .shortAndLong, help: "The name or id of the bucket destination.")
13+
private var bucket: String
14+
15+
@Option(name: .shortAndLong, help: "The name or id of the organization destination.")
16+
private var org: String
17+
18+
@Option(name: .shortAndLong, help: "Authentication token.")
19+
private var token: String
20+
21+
@Option(name: .shortAndLong, help: "HTTP address of InfluxDB.")
22+
private var url: String
23+
24+
public func run() throws {
25+
guard let settingsURL = Bundle.module.url(forResource: "vix-daily", withExtension: "csv") else {
26+
return
27+
}
28+
29+
guard let stream = InputStream(url: settingsURL) else {
30+
return
31+
}
32+
33+
var subscriptions = Set<AnyCancellable>()
34+
35+
let dateFormatter = DateFormatter()
36+
dateFormatter.dateFormat = "yyyy-MM-dd"
37+
38+
// Initialize Client with default Bucket and Organization
39+
let client = InfluxDBClient(
40+
url: url,
41+
token: token,
42+
options: InfluxDBClient.InfluxDBOptions(bucket: self.bucket, org: self.org))
43+
44+
// Initialize WriteAPI
45+
let writeAPI = client.makeWriteAPI()
46+
47+
// Prepare batches by Combine
48+
let batches = try CSVReader(stream: stream, hasHeaderRow: true)
49+
.publisher
50+
// create Point from CSV line
51+
.map { row in
52+
toPoint(row: row, dateFormatter: dateFormatter)
53+
}
54+
// specify size of batch
55+
.collect(500)
56+
// write batch
57+
.flatMap(maxPublishers: .max(1)) { batch -> AnyPublisher<Void, InfluxDBClient.InfluxDBError> in
58+
print("Writing \(batch.count) items ...")
59+
return writeAPI.write(points: batch)
60+
}
61+
62+
batches
63+
.sink(receiveCompletion: { result in
64+
// process result of import
65+
switch result {
66+
case .finished:
67+
print("Import finished!")
68+
case let .failure(error):
69+
print("Unexpected error: \(error)")
70+
}
71+
self.atExit(client: client)
72+
}, receiveValue: {
73+
// batch is successfully written
74+
print(" > success")
75+
})
76+
.store(in: &subscriptions)
77+
78+
// Wait to end of script
79+
RunLoop.current.run()
80+
}
81+
82+
/// Parse the CSV line into Point
83+
///
84+
/// - Parameters:
85+
/// - row: CSV line
86+
/// - dateFormatter: for parsing date
87+
/// - Returns: parsed InfluxDBClient.Point
88+
private func toPoint(row: [String], dateFormatter: DateFormatter) -> InfluxDBClient.Point {
89+
InfluxDBClient
90+
.Point("financial-analysis")
91+
.addTag(key: "type", value: "vix-daily")
92+
.addField(key: "open", value: .double(Double(row[1])!))
93+
.addField(key: "high", value: .double(Double(row[2])!))
94+
.addField(key: "low", value: .double(Double(row[3])!))
95+
.addField(key: "close", value: .double(Double(row[4])!))
96+
.time(time: .date(dateFormatter.date(from: row[0])!))
97+
}
98+
99+
private func atExit(client: InfluxDBClient, error: InfluxDBClient.InfluxDBError? = nil) {
100+
// Dispose the Client
101+
client.close()
102+
// Exit script
103+
Self.exit(withError: error)
104+
}
105+
}
106+
107+
// extension CSVReader: Sequence { }
108+
109+
WriteDataInBatches.main()

0 commit comments

Comments
 (0)