Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ public struct FetchChangesCommand: MistDemoCommand, OutputFormatting {
--zone <name> Zone name (default: _defaultZone)
--fetch-all Auto-paginate all changes
--limit <count> Max results per page (1-200)
--fields <fields> Comma-separated fields (desiredKeys)
--record-types <types> Comma-separated record types to include
--database <type> Database to target
--output-format <format> Output format

Expand Down Expand Up @@ -109,6 +111,8 @@ public struct FetchChangesCommand: MistDemoCommand, OutputFormatting {
let (records, newToken) = try await service.fetchAllRecordChanges(
zoneID: zoneID,
syncToken: config.syncToken,
desiredKeys: config.desiredKeys,
desiredRecordTypes: config.desiredRecordTypes,
database: config.base.database
)
print("\n✅ Fetched \(records.count) record(s)")
Expand All @@ -127,6 +131,8 @@ public struct FetchChangesCommand: MistDemoCommand, OutputFormatting {
zoneID: zoneID,
syncToken: config.syncToken,
resultsLimit: config.limit ?? 10,
desiredKeys: config.desiredKeys,
desiredRecordTypes: config.desiredRecordTypes,
database: config.base.database
)
print("\n✅ Fetched \(result.records.count) record(s)")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ public struct ModifyCommand: MistDemoCommand, OutputFormatting {

OPTIONS:
--atomic Reject batch if any fails
--zone <name> Target zone for the operations
--fields <fields> Comma-separated fields (desiredKeys)
--numbers-as-strings Return numeric fields as strings
--output-format <format> Output format

NOTES:
Expand Down Expand Up @@ -100,6 +103,9 @@ public struct ModifyCommand: MistDemoCommand, OutputFormatting {
let results = try await client.modifyRecords(
operations,
atomic: config.atomic,
zoneID: config.zone.map { ZoneID(zoneName: $0, ownerName: nil) },
desiredKeys: config.desiredKeys,
numbersAsStrings: config.numbersAsStrings,
database: config.base.database
)
let succeeded = results.compactMap { result in
Expand Down
20 changes: 14 additions & 6 deletions Examples/MistDemo/Sources/MistDemoKit/Commands/QueryCommand.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public struct QueryCommand: MistDemoCommand, OutputFormatting {
--filter <filter> Filter: field:operator:value
--sort <field:order> Sort (asc/desc)
--limit <count> Max records (1-200)
--fields <fields> Comma-separated fields
--fields <fields> Comma-separated fields (desiredKeys)
--zone-wide Query across all zones
--numbers-as-strings Return numeric fields as strings
--output-format <format> Output format
"""

Expand All @@ -71,20 +73,26 @@ public struct QueryCommand: MistDemoCommand, OutputFormatting {
// Build filters
// NOTE: Zone, offset, and continuation marker support require
// enhancements to CloudKitService.queryRecords method (GitHub issues #145, #146)
let filters: [QueryFilter]? =
let filters: [QueryFilter] =
config.filters.isEmpty
? nil
? []
: try config.filters.map { try Self.parseFilter($0) }
let recordInfos = try await client.queryRecords(
let query = Query(
recordType: config.recordType,
filters: filters,
sortBy: nil,
sortBy: []
)
let result = try await client.queryRecords(
query,
limit: config.limit,
desiredKeys: config.fields,
zoneWide: config.zoneWide,
numbersAsStrings: config.numbersAsStrings,
database: config.base.database
)

// Format and output results
try await outputResults(recordInfos, format: config.output)
try await outputResults(result.records, format: config.output)
} catch {
throw QueryError.operationFailed(error.localizedDescription)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ public struct FetchChangesConfig: Sendable, ConfigurationParseable {
public let fetchAll: Bool
/// The optional limit on number of changes to fetch.
public let limit: Int?
/// The optional field names limiting the fields returned per record.
public let desiredKeys: [String]?
/// The optional record-type names limiting the change feed.
public let desiredRecordTypes: [String]?
/// The output format.
public let output: OutputFormat

Expand All @@ -56,13 +60,17 @@ public struct FetchChangesConfig: Sendable, ConfigurationParseable {
zone: String = "_defaultZone",
fetchAll: Bool = false,
limit: Int? = nil,
desiredKeys: [String]? = nil,
desiredRecordTypes: [String]? = nil,
output: OutputFormat = .table
) {
self.base = base
self.syncToken = syncToken
self.zone = zone
self.fetchAll = fetchAll
self.limit = limit
self.desiredKeys = desiredKeys
self.desiredRecordTypes = desiredRecordTypes
self.output = output
}

Expand All @@ -88,6 +96,12 @@ public struct FetchChangesConfig: Sendable, ConfigurationParseable {
let fetchAll =
configuration.bool(forKey: "fetch.all", default: false)
let limit = configuration.int(forKey: "limit")
let desiredKeys = configuration.commaSeparatedList(
forKey: MistDemoConstants.ConfigKeys.fields
)
let desiredRecordTypes = configuration.commaSeparatedList(
forKey: MistDemoConstants.ConfigKeys.desiredRecordTypes
)
let outputString =
configuration.string(forKey: "output.format", default: "table")
?? "table"
Expand All @@ -99,6 +113,8 @@ public struct FetchChangesConfig: Sendable, ConfigurationParseable {
zone: zone,
fetchAll: fetchAll,
limit: limit,
desiredKeys: desiredKeys,
desiredRecordTypes: desiredRecordTypes,
output: output
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,21 @@ public struct MistDemoConfiguration: Sendable {
)
}

/// Read an optional bool: `nil` when the key is absent, else its parsed value.
///
/// Distinguishes "flag not provided" (`nil` → omit from the request) from an
/// explicit `false`, unlike `bool(forKey:default:)` which collapses both.
public func optionalBool(forKey key: String) -> Bool? {
string(forKey: key) != nil ? bool(forKey: key) : nil
}

/// Read a comma-separated list of strings, or `nil` when the key is absent.
public func commaSeparatedList(forKey key: String) -> [String]? {
string(forKey: key)?
.split(separator: ",")
.map { String($0).trimmingCharacters(in: .whitespaces) }
}

/// Read a pipe-separated list of strings from configuration.
public func filterStrings(forKey key: String) -> [String] {
string(forKey: key)?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@ public struct ModifyConfig: Sendable, ConfigurationParseable {
public let operations: [ModifyOperationInput]
/// Whether to perform operations atomically.
public let atomic: Bool
/// The optional target zone for the operations.
public let zone: String?
/// The optional field names limiting the fields returned in the response.
public let desiredKeys: [String]?
/// Whether numeric field values are returned as strings.
public let numbersAsStrings: Bool?
/// The output format.
public let output: OutputFormat

Expand All @@ -52,11 +58,17 @@ public struct ModifyConfig: Sendable, ConfigurationParseable {
base: MistDemoConfig,
operations: [ModifyOperationInput],
atomic: Bool = false,
zone: String? = nil,
desiredKeys: [String]? = nil,
numbersAsStrings: Bool? = nil,
output: OutputFormat = .json
) {
self.base = base
self.operations = operations
self.atomic = atomic
self.zone = zone
self.desiredKeys = desiredKeys
self.numbersAsStrings = numbersAsStrings
self.output = output
}

Expand Down Expand Up @@ -85,6 +97,16 @@ public struct ModifyConfig: Sendable, ConfigurationParseable {
default: false
)

let zone = configReader.string(
forKey: MistDemoConstants.ConfigKeys.zone
)
let desiredKeys = configReader.commaSeparatedList(
forKey: MistDemoConstants.ConfigKeys.fields
)
let numbersAsStrings = configReader.optionalBool(
forKey: MistDemoConstants.ConfigKeys.numbersAsStrings
)

let outputString =
configReader.string(
forKey: MistDemoConstants.ConfigKeys.outputFormat,
Expand All @@ -96,6 +118,9 @@ public struct ModifyConfig: Sendable, ConfigurationParseable {
base: baseConfig,
operations: operations,
atomic: atomic,
zone: zone,
desiredKeys: desiredKeys,
numbersAsStrings: numbersAsStrings,
output: output
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ public struct QueryConfig: Sendable, ConfigurationParseable {
public let fields: [String]?
/// The optional continuation marker for pagination.
public let continuationMarker: String?
/// Whether to query across all zones rather than a single zone.
public let zoneWide: Bool?
/// Whether numeric field values are returned as strings.
public let numbersAsStrings: Bool?
/// The output format.
public let output: OutputFormat

Expand All @@ -70,6 +74,8 @@ public struct QueryConfig: Sendable, ConfigurationParseable {
offset: Int = 0,
fields: [String]? = nil,
continuationMarker: String? = nil,
zoneWide: Bool? = nil,
numbersAsStrings: Bool? = nil,
output: OutputFormat = .json
) {
self.base = base
Expand All @@ -81,6 +87,8 @@ public struct QueryConfig: Sendable, ConfigurationParseable {
self.offset = offset
self.fields = fields
self.continuationMarker = continuationMarker
self.zoneWide = zoneWide
self.numbersAsStrings = numbersAsStrings
self.output = output
}

Expand Down Expand Up @@ -112,6 +120,12 @@ public struct QueryConfig: Sendable, ConfigurationParseable {
offset: parsed.pagination.offset,
fields: parsed.pagination.fields,
continuationMarker: parsed.pagination.continuationMarker,
zoneWide: configReader.optionalBool(
forKey: MistDemoConstants.ConfigKeys.zoneWide
),
numbersAsStrings: configReader.optionalBool(
forKey: MistDemoConstants.ConfigKeys.numbersAsStrings
),
output: parsed.pagination.output
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public enum MistDemoConstants {
public static let atomic = "atomic"
/// Batch size configuration key for the auto-chunking `*-all` commands.
public static let batchSize = "batch.size"
/// Zone-wide query configuration key (query across all zones).
public static let zoneWide = "zone.wide"
/// Numbers-as-strings configuration key (return numeric fields as strings).
public static let numbersAsStrings = "numbers.as.strings"
/// Desired record types configuration key (limits the change feed).
public static let desiredRecordTypes = "record.types"
}

// MARK: - Field Names
Expand Down
Loading
Loading