Skip to content

Commit 2d5a1d2

Browse files
ayushi2103“Ayushi
andauthored
Get Range (#8)
* get key range * Updated get and tests. * Updated get to use rangeRequest * Updated PR comments --------- Co-authored-by: “Ayushi <“[email protected]”>
1 parent c2e008d commit 2d5a1d2

File tree

4 files changed

+114
-26
lines changed

4 files changed

+114
-26
lines changed

Sources/ETCD/ETCDClient.swift

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,13 @@ public final class EtcdClient: @unchecked Sendable {
6363
try await set(key.utf8, value: value.utf8)
6464
}
6565

66-
/// Fetch the value for a key from the ETCD server.
66+
/// Fetches a range from the ETCD server.
6767
///
68-
/// - Parameter key: The key to fetch the value for. Parameter is of type Sequence<UInt8>.
68+
/// - Parameter rangeRequest: The rangeRequst to get
6969
/// - Returns: A `Value` containing the fetched value, or `nil` if no value was found.
70-
public func get(_ key: some Sequence<UInt8>) async throws -> Data? {
71-
var rangeRequest = Etcdserverpb_RangeRequest()
72-
rangeRequest.key = Data(key)
73-
74-
let call = client.range(rangeRequest)
70+
public func getRange(_ rangeRequest: RangeRequest) async throws -> Data? {
71+
let protoRangeRequest = rangeRequest.toProto()
72+
let call = client.range(protoRangeRequest)
7573
let response = try await call.response.get()
7674

7775
guard let kv = response.kvs.first else {
@@ -80,14 +78,6 @@ public final class EtcdClient: @unchecked Sendable {
8078
return kv.value
8179
}
8280

83-
/// Fetch the value for a key from the ETCD server.
84-
///
85-
/// - Parameter key: The key to fetch the value for. Parameter is of type String.
86-
/// - Returns: A `Value` containing the fetched value, or `nil` if no value was found.
87-
public func get(_ key: String) async throws -> Data? {
88-
return try await get(key.utf8)
89-
}
90-
9181
/// Delete the value for a key from the ETCD server.
9282
///
9383
/// - Parameter key: The key to delete. Parameter is of type Sequence<UInt8>.

Sources/ETCD/RangeRequest.swift

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the swift-etcd-client-gsoc open source project
4+
//
5+
// Copyright (c) 2024 Apple Inc. and the swift-etcd-client-gsoc project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of swift-etcd-client-gsoc project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import Foundation
16+
17+
public struct RangeRequest {
18+
public enum SortOrder: Int {
19+
case none = 0
20+
case ascend = 1
21+
case descend = 2
22+
}
23+
24+
public enum SortTarget: Int {
25+
case key = 0
26+
case version = 1
27+
case create = 2
28+
case mod = 3
29+
case value = 4
30+
}
31+
32+
public var key: Data
33+
public var rangeEnd: Data?
34+
public var limit: Int = 0
35+
public var revision: Int = 0
36+
public var sortOrder: SortOrder = .none
37+
public var sortTarget: SortTarget = .key
38+
public var serializable: Bool = false
39+
public var keysOnly: Bool = false
40+
public var countOnly: Bool = false
41+
public var minModRevision: Int = 0
42+
public var maxModRevision: Int = 0
43+
public var minCreateRevision: Int = 0
44+
public var maxCreateRevision: Int = 0
45+
46+
47+
init(protoRangeRequest: Etcdserverpb_RangeRequest) {
48+
self.key = protoRangeRequest.key
49+
self.rangeEnd = protoRangeRequest.rangeEnd
50+
self.limit = Int(protoRangeRequest.limit)
51+
self.revision = Int(protoRangeRequest.revision)
52+
self.sortOrder = SortOrder(rawValue: protoRangeRequest.sortOrder.rawValue) ?? .none
53+
self.sortTarget = SortTarget(rawValue: protoRangeRequest.sortTarget.rawValue) ?? .key
54+
self.serializable = protoRangeRequest.serializable
55+
self.keysOnly = protoRangeRequest.keysOnly
56+
self.countOnly = protoRangeRequest.countOnly
57+
self.minModRevision = Int(protoRangeRequest.minModRevision)
58+
self.maxModRevision = Int(protoRangeRequest.maxModRevision)
59+
self.minCreateRevision = Int(protoRangeRequest.minCreateRevision)
60+
self.maxCreateRevision = Int(protoRangeRequest.maxCreateRevision)
61+
}
62+
63+
public init(key: Data, rangeEnd: Data? = nil) {
64+
self.key = key
65+
self.rangeEnd = rangeEnd
66+
}
67+
68+
func toProto() -> Etcdserverpb_RangeRequest {
69+
var protoRangeRequest = Etcdserverpb_RangeRequest()
70+
protoRangeRequest.key = self.key
71+
protoRangeRequest.rangeEnd = self.rangeEnd ?? Data()
72+
protoRangeRequest.limit = Int64(self.limit)
73+
protoRangeRequest.revision = Int64(self.revision)
74+
protoRangeRequest.sortOrder = Etcdserverpb_RangeRequest.SortOrder(rawValue: self.sortOrder.rawValue) ?? .none
75+
protoRangeRequest.sortTarget = Etcdserverpb_RangeRequest.SortTarget(rawValue: self.sortTarget.rawValue) ?? .key
76+
protoRangeRequest.serializable = self.serializable
77+
protoRangeRequest.keysOnly = self.keysOnly
78+
protoRangeRequest.countOnly = self.countOnly
79+
protoRangeRequest.minModRevision = Int64(self.minModRevision)
80+
protoRangeRequest.maxModRevision = Int64(self.maxModRevision)
81+
protoRangeRequest.minCreateRevision = Int64(self.minCreateRevision)
82+
protoRangeRequest.maxCreateRevision = Int64(self.maxCreateRevision)
83+
return protoRangeRequest
84+
}
85+
}

Sources/ETCDExample/ETCDExample.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,16 @@ struct Example {
3838
try await Task.sleep(for: .seconds(1))
3939

4040
try await etcdClient.set("foo", value: "bar")
41-
if let value = try await etcdClient.get("foo") {
41+
let key = "foo".data(using: .utf8)!
42+
let rangeRequest = RangeRequest(key: key)
43+
if let value = try await etcdClient.get(rangeRequest: rangeRequest) {
4244
if let stringValue = String(data: value, encoding: .utf8) {
4345
print("Value is: \(stringValue)")
4446
try await etcdClient.delete("foo")
4547
print("Key deleted")
4648

4749
// Trying to get the value again
48-
let deletedValue = try await etcdClient.get("foo")
50+
let deletedValue = try await etcdClient.get(rangeRequest: rangeRequest)
4951
if deletedValue == nil {
5052
print("Key not found after deletion")
5153
} else {

Tests/ETCDTests/ETCDTests.swift

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,18 @@ final class EtcdClientTests: XCTestCase {
2626

2727
func testSetAndGetStringValue() async throws {
2828
try await etcdClient.set("testKey", value: "testValue")
29-
let result = try await etcdClient.get("testKey")
29+
let key = "testKey".data(using: .utf8)!
30+
let rangeRequest = RangeRequest(key: key)
31+
let result = try await etcdClient.getRange(rangeRequest)
3032

3133
XCTAssertNotNil(result)
3234
XCTAssertEqual(String(data: result!, encoding: .utf8), "testValue")
3335
}
3436

3537
func testGetNonExistentKey() async throws {
36-
let result = try await etcdClient.get("nonExistentKey")
38+
let key = "nonExistentKey".data(using: .utf8)!
39+
let rangeRequest = RangeRequest(key: key)
40+
let result = try await etcdClient.getRange(rangeRequest)
3741
XCTAssertNil(result)
3842
}
3943

@@ -42,24 +46,27 @@ final class EtcdClientTests: XCTestCase {
4246
let value = "testValue"
4347
try await etcdClient.set(key, value: value)
4448

45-
var fetchedValue = try await etcdClient.get(key)
49+
let rangeRequestKey = "testKey".data(using: .utf8)!
50+
let rangeRequest = RangeRequest(key: rangeRequestKey)
51+
var fetchedValue = try await etcdClient.getRange(rangeRequest)
4652
XCTAssertNotNil(fetchedValue)
4753

4854
try await etcdClient.delete(key)
4955

50-
fetchedValue = try await etcdClient.get(key)
56+
fetchedValue = try await etcdClient.getRange(rangeRequest)
5157
XCTAssertNil(fetchedValue)
5258
}
5359

5460
func testDeleteNonExistentKey() async throws {
55-
let key = "testKey"
61+
let key = "testKey".data(using: .utf8)!
62+
let rangeRequest = RangeRequest(key: key)
5663

57-
var fetchedValue = try await etcdClient.get(key)
64+
var fetchedValue = try await etcdClient.getRange(rangeRequest)
5865
XCTAssertNil(fetchedValue)
5966

6067
try await etcdClient.delete(key)
6168

62-
fetchedValue = try await etcdClient.get(key)
69+
fetchedValue = try await etcdClient.getRange(rangeRequest)
6370
XCTAssertNil(fetchedValue)
6471
}
6572

@@ -68,14 +75,18 @@ final class EtcdClientTests: XCTestCase {
6875
let value = "testValue"
6976
try await etcdClient.set(key, value: value)
7077

71-
let fetchedValue = try await etcdClient.get(key)
78+
let rangeRequestKey = "testKey".data(using: .utf8)!
79+
let rangeRequest = RangeRequest(key: rangeRequestKey)
80+
let fetchedValue = try await etcdClient.getRange(rangeRequest)
7281
XCTAssertNotNil(fetchedValue)
7382
XCTAssertEqual(String(data: fetchedValue!, encoding: .utf8), value)
7483

7584
let updatedValue = "updatedValue"
7685
try await etcdClient.put(key, value: updatedValue)
7786

78-
let fetchedUpdatedValue = try await etcdClient.get(key)
87+
let rangeRequestUpdatedKey = "testKey".data(using: .utf8)!
88+
let rangeRequestUpdated = RangeRequest(key: rangeRequestUpdatedKey)
89+
let fetchedUpdatedValue = try await etcdClient.getRange(rangeRequestUpdated)
7990
XCTAssertNotNil(fetchedUpdatedValue)
8091
XCTAssertEqual(String(data: fetchedUpdatedValue!, encoding: .utf8), updatedValue)
8192
}

0 commit comments

Comments
 (0)