Skip to content

Commit

Permalink
Merge pull request #991 from giantramen/master
Browse files Browse the repository at this point in the history
Fix SQLite Cache Key Bug
  • Loading branch information
designatednerd authored Feb 10, 2020
2 parents 7e8ace5 + 5c8d9a2 commit dabfb13
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 6 deletions.
21 changes: 17 additions & 4 deletions Sources/ApolloSQLite/SQLiteNormalizedCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,24 @@ public final class SQLiteNormalizedCache {
}

private func recordCacheKey(forFieldCacheKey fieldCacheKey: CacheKey) -> CacheKey {
var components = fieldCacheKey.components(separatedBy: ".")
if components.count > 1 {
components.removeLast()
let components = fieldCacheKey.components(separatedBy: ".")
var updatedComponents = [String]()
if components.first?.contains("_ROOT") == true {
for component in components {
if updatedComponents.last?.last?.isNumber ?? false && component.first?.isNumber ?? false {
updatedComponents[updatedComponents.count - 1].append(".\(component)")
} else {
updatedComponents.append(component)
}
}
} else {
updatedComponents = components
}

if updatedComponents.count > 1 {
updatedComponents.removeLast()
}
return components.joined(separator: ".")
return updatedComponents.joined(separator: ".")
}

private func createTableIfNeeded() throws {
Expand Down
40 changes: 39 additions & 1 deletion Tests/ApolloCacheDependentTests/LoadQueryFromStoreTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,45 @@ class LoadQueryFromStoreTests: XCTestCase {
}
}
}



func testLoadingQueryWithFloats() throws {
let starshipLength = 1234.5
let coordinates = [[38.857150, -94.798464]]

let initialRecords: RecordSet = [
"QUERY_ROOT": ["starshipCoordinates(coordinates:\(coordinates))": Reference(key: "starshipCoordinates(coordinates:\(coordinates))")],
"starshipCoordinates(coordinates:\(coordinates))": ["__typename": "Starship",
"name": "Millennium Falcon",
"length": starshipLength,
"coordinates": coordinates]
]

withCache(initialRecords: initialRecords) { (cache) in
store = ApolloStore(cache: cache)

let query = StarshipCoordinatesQuery(coordinates: coordinates)

load(query: query) { result in
switch result {
case .success(let graphQLResult):
XCTAssertNil(graphQLResult.errors)

guard let data = graphQLResult.data else {
XCTFail("No data returned with result")
return
}

XCTAssertEqual(data.starshipCoordinates?.name, "Millennium Falcon")
XCTAssertEqual(data.starshipCoordinates?.length, starshipLength)
XCTAssertEqual(data.starshipCoordinates?.coordinates, coordinates)
case .failure(let error):
XCTFail("Unexpected error: \(error)")
}
}
}
}

// MARK: - Helpers

private func load<Query: GraphQLQuery>(query: Query, resultHandler: @escaping GraphQLResultHandler<Query.Data>) {
Expand Down
115 changes: 115 additions & 0 deletions Tests/StarWarsAPI/API.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5556,6 +5556,121 @@ public final class StarshipQuery: GraphQLQuery {
}
}

public final class StarshipCoordinatesQuery: GraphQLQuery {
/// The raw GraphQL definition of this operation.
public let operationDefinition =
"""
query StarshipCoordinates($coordinates: [[Float!]!]) {
starshipCoordinates(coordinates: $coordinates) {
__typename
name
coordinates
length
}
}
"""

public let operationName = "StarshipCoordinates"

public let operationIdentifier: String? = "8dd77d4bc7494c184606da092a665a7c2ca3c2a3f14d3b23fa5e469e207b3406"

public var coordinates: [[Double]]?

public init(coordinates: [[Double]]?) {
self.coordinates = coordinates
}

public var variables: GraphQLMap? {
return ["coordinates": coordinates]
}

public struct Data: GraphQLSelectionSet {
public static let possibleTypes = ["Query"]

public static let selections: [GraphQLSelection] = [
GraphQLField("starshipCoordinates", arguments: ["coordinates": GraphQLVariable("coordinates")], type: .object(StarshipCoordinate.selections)),
]

public private(set) var resultMap: ResultMap

public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}

public init(starshipCoordinates: StarshipCoordinate? = nil) {
self.init(unsafeResultMap: ["__typename": "Query", "starshipCoordinates": starshipCoordinates.flatMap { (value: StarshipCoordinate) -> ResultMap in value.resultMap }])
}

public var starshipCoordinates: StarshipCoordinate? {
get {
return (resultMap["starshipCoordinates"] as? ResultMap).flatMap { StarshipCoordinate(unsafeResultMap: $0) }
}
set {
resultMap.updateValue(newValue?.resultMap, forKey: "starshipCoordinates")
}
}

public struct StarshipCoordinate: GraphQLSelectionSet {
public static let possibleTypes = ["Starship"]

public static let selections: [GraphQLSelection] = [
GraphQLField("__typename", type: .nonNull(.scalar(String.self))),
GraphQLField("name", type: .nonNull(.scalar(String.self))),
GraphQLField("coordinates", type: .list(.nonNull(.list(.nonNull(.scalar(Double.self)))))),
GraphQLField("length", type: .scalar(Double.self)),
]

public private(set) var resultMap: ResultMap

public init(unsafeResultMap: ResultMap) {
self.resultMap = unsafeResultMap
}

public init(name: String, coordinates: [[Double]]? = nil, length: Double? = nil) {
self.init(unsafeResultMap: ["__typename": "Starship", "name": name, "coordinates": coordinates, "length": length])
}

public var __typename: String {
get {
return resultMap["__typename"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "__typename")
}
}

/// The name of the starship
public var name: String {
get {
return resultMap["name"]! as! String
}
set {
resultMap.updateValue(newValue, forKey: "name")
}
}

public var coordinates: [[Double]]? {
get {
return resultMap["coordinates"] as? [[Double]]
}
set {
resultMap.updateValue(newValue, forKey: "coordinates")
}
}

/// Length of the starship, along the longest axis
public var length: Double? {
get {
return resultMap["length"] as? Double
}
set {
resultMap.updateValue(newValue, forKey: "length")
}
}
}
}
}

public final class ReviewAddedSubscription: GraphQLSubscription {
/// The raw GraphQL definition of this operation.
public let operationDefinition: String =
Expand Down
8 changes: 8 additions & 0 deletions Tests/StarWarsAPI/Starship.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,11 @@ query Starship {
coordinates
}
}

query StarshipCoordinates($coordinates: [[Float!]!]) {
starshipCoordinates(coordinates: $coordinates) {
name
coordinates
length
}
}
4 changes: 4 additions & 0 deletions Tests/StarWarsAPI/operationIdsPath.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@
"name": "Starship",
"source": "query Starship {\n starship(id: 3000) {\n __typename\n name\n coordinates\n }\n}"
},
"8dd77d4bc7494c184606da092a665a7c2ca3c2a3f14d3b23fa5e469e207b3406": {
"name": "StarshipCoordinates",
"source": "query StarshipCoordinates($coordinates: [[Float!]!]) {\n starshipCoordinates(coordinates: $coordinates) {\n __typename\n name\n coordinates\n length\n }\n}"
},
"38644c5e7cf4fd506b91d2e7010cabf84e63dfcd33cf1deb443b4b32b55e2cbe": {
"name": "ReviewAdded",
"source": "subscription ReviewAdded($episode: Episode) {\n reviewAdded(episode: $episode) {\n __typename\n episode\n stars\n commentary\n }\n}"
Expand Down
41 changes: 40 additions & 1 deletion Tests/StarWarsAPI/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,45 @@
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "starshipCoordinates",
"description": "",
"args": [
{
"name": "coordinates",
"description": "",
"type": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "LIST",
"name": null,
"ofType": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "Float",
"ofType": null
}
}
}
}
},
"defaultValue": null
}
],
"type": {
"kind": "OBJECT",
"name": "Starship",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
}
],
"inputFields": null,
Expand Down Expand Up @@ -2184,4 +2223,4 @@
]
}
}
}
}

0 comments on commit dabfb13

Please sign in to comment.