Skip to content

Commit 47e09a5

Browse files
committed
Fix creating request url
1 parent 7725d13 commit 47e09a5

File tree

3 files changed

+130
-70
lines changed

3 files changed

+130
-70
lines changed

Sources/ServiceStack/JsonServiceClient.swift

+15-3
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,21 @@ open class JsonServiceClient: NSObject, ServiceClient, IHasBearerToken, IHasSess
203203

204204
var sb = ""
205205
for prop in AnyEncodable.properties(dto) {
206-
sb += sb.count == 0 ? "?" : "&"
207-
let val = try! toJsv(prop.value)?.urlEncode()
208-
sb += "\(prop.key)=\(val ?? "")"
206+
do {
207+
var rawValue = prop.value.value as? String
208+
if rawValue == nil {
209+
rawValue = try toJsv(prop.value)
210+
}
211+
if let jsvValue = rawValue {
212+
if jsvValue != "[]" && jsvValue != "{}" {
213+
let encVal = jsvValue.urlEncode()
214+
sb += sb.count == 0 ? "?" : "&"
215+
sb += "\(prop.key)=\(encVal ?? "")"
216+
}
217+
}
218+
} catch let e {
219+
Log.error("createUrl(): \(prop.key):\(prop.value)", error: e)
220+
}
209221
}
210222

211223
for (key, value) in query {

Tests/ServiceStackTests/AutoQueryTests.swift

+26-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@ class AutoQueryTests: XCTestCase {
2929
}
3030
}
3131

32+
func test_Can_call_query_FindTechnologies_VendorName() {
33+
let request = FindTechnologies()
34+
request.vendorName = "Google"
35+
request.take = 3
36+
request.orderByDesc = "ViewCount"
37+
request.fields = "Id,Name,VendorName,Tier,ProductUrl"
38+
39+
do {
40+
let response = try client.get(request)
41+
42+
XCTAssertEqual(response.total, 15)
43+
XCTAssertEqual(response.results.count, 3)
44+
let names = response.results.map { $0.name! }.joined(separator: ",")
45+
XCTAssertEqual(names,"AngularJS,Go,Protocol Buffers")
46+
let ids = response.results.map { "\($0.id!)" }.joined(separator: ",")
47+
XCTAssertEqual(ids,"7,18,77")
48+
let tiers = response.results.map { "\($0.tier!)" }.joined(separator: ",")
49+
XCTAssertEqual(tiers,"Client,ProgrammingLanguage,Server")
50+
} catch let e {
51+
XCTFail("\(e)")
52+
}
53+
}
54+
3255

3356
func test_Can_call_FindTechnologies_ServiceStack() {
3457
let request = FindTechnologies()
@@ -39,7 +62,7 @@ class AutoQueryTests: XCTestCase {
3962
print("Request URL: \(url)")
4063
let response = try client.get(request)
4164

42-
XCTAssertEqual(response.total, 0) // @Alex: API for unknown reason returning total: 0
65+
XCTAssertEqual(response.total, 1)
4366
let dto = response.results[0]
4467
XCTAssertEqual(dto.id, 1)
4568
XCTAssertEqual(dto.name, "ServiceStack")
@@ -51,4 +74,6 @@ class AutoQueryTests: XCTestCase {
5174
XCTFail("\(e)")
5275
}
5376
}
77+
78+
5479
}

Tests/ServiceStackTests/TechStacks.dtos.swift

+89-66
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* Options:
2-
Date: 2021-03-09 07:19:50
2+
Date: 2021-03-18 17:23:07
33
SwiftVersion: 5.0
44
Version: 5.105
55
Tip: To override a DTO option, remove "//" prefix before updating
@@ -310,7 +310,7 @@ public class UpdateOrganizationMemberInvite : IReturn, IPut, Codable
310310
}
311311

312312
// @Route("/posts", "GET")
313-
public class QueryPosts : QueryDb<Post>, IReturn, IGet
313+
public class QueryPosts : QueryDb_1<Post>, IReturn, IGet
314314
{
315315
public typealias Return = QueryResponse<Post>
316316

@@ -698,9 +698,9 @@ public class GetAllTechnologies : IReturn, IGet, Codable
698698

699699
// @Route("/technology/search")
700700
// @AutoQueryViewer(DefaultSearchField="Tier", DefaultSearchText="Data", DefaultSearchType="=", Description="Explore different Technologies", IconUrl="octicon:database", Title="Find Technologies")
701-
public class FindTechnologies : QueryDb<Technology>, IReturn, IGet
701+
public class FindTechnologies : QueryDb_2<Technology, TechnologyView>, IReturn, IGet
702702
{
703-
public typealias Return = QueryResponse<Technology>
703+
public typealias Return = QueryResponse<TechnologyView>
704704

705705
public var ids:[Int] = []
706706
public var name:String?
@@ -744,9 +744,9 @@ public class FindTechnologies : QueryDb<Technology>, IReturn, IGet
744744
}
745745

746746
// @Route("/technology/query")
747-
public class QueryTechnology : QueryDb<Technology>, IReturn, IGet
747+
public class QueryTechnology : QueryDb_2<Technology, TechnologyView>, IReturn, IGet
748748
{
749-
public typealias Return = QueryResponse<Technology>
749+
public typealias Return = QueryResponse<TechnologyView>
750750

751751
public var ids:[Int] = []
752752
public var name:String?
@@ -897,9 +897,9 @@ public class HourlyTask : IReturn, IGet, Codable
897897

898898
// @Route("/techstacks/search")
899899
// @AutoQueryViewer(DefaultSearchField="Description", DefaultSearchText="ServiceStack", DefaultSearchType="Contains", Description="Explore different Technology Stacks", IconUrl="material-icons:cloud", Title="Find Technology Stacks")
900-
public class FindTechStacks : QueryDb<TechnologyStack>, IReturn, IGet
900+
public class FindTechStacks : QueryDb_2<TechnologyStack, TechnologyStackView>, IReturn, IGet
901901
{
902-
public typealias Return = QueryResponse<TechnologyStack>
902+
public typealias Return = QueryResponse<TechnologyStackView>
903903

904904
public var ids:[Int] = []
905905
public var name:String?
@@ -943,9 +943,9 @@ public class FindTechStacks : QueryDb<TechnologyStack>, IReturn, IGet
943943
}
944944

945945
// @Route("/techstacks/query")
946-
public class QueryTechStacks : QueryDb<TechnologyStack>, IReturn, IGet
946+
public class QueryTechStacks : QueryDb_2<TechnologyStack, TechnologyStackView>, IReturn, IGet
947947
{
948-
public typealias Return = QueryResponse<TechnologyStack>
948+
public typealias Return = QueryResponse<TechnologyStackView>
949949

950950
public var ids:[Int] = []
951951
public var name:String?
@@ -1320,7 +1320,7 @@ public class ImportUserVoiceSuggestion : IReturn, IPost, Codable
13201320
}
13211321

13221322
// @Route("/posts/comment", "GET")
1323-
public class QueryPostComments : QueryDb<PostComment>, IReturn, IGet
1323+
public class QueryPostComments : QueryDb_1<PostComment>, IReturn, IGet
13241324
{
13251325
public typealias Return = QueryResponse<PostComment>
13261326

@@ -1397,49 +1397,6 @@ public class QueryPostComments : QueryDb<PostComment>, IReturn, IGet
13971397
}
13981398
}
13991399

1400-
// @Route("/admin/technology/search")
1401-
// @AutoQueryViewer(DefaultSearchField="Tier", DefaultSearchText="Data", DefaultSearchType="=", Description="Explore different Technologies", IconUrl="octicon:database", Title="Find Technologies Admin")
1402-
public class FindTechnologiesAdmin : QueryDb<Technology>, IReturn
1403-
{
1404-
public typealias Return = QueryResponse<Technology>
1405-
1406-
public var id:Int?
1407-
public var name:String?
1408-
public var vendorName:String?
1409-
public var nameContains:String?
1410-
public var vendorNameContains:String?
1411-
1412-
required public init(){ super.init() }
1413-
1414-
private enum CodingKeys : String, CodingKey {
1415-
case id
1416-
case name
1417-
case vendorName
1418-
case nameContains
1419-
case vendorNameContains
1420-
}
1421-
1422-
required public init(from decoder: Decoder) throws {
1423-
try super.init(from: decoder)
1424-
let container = try decoder.container(keyedBy: CodingKeys.self)
1425-
id = try container.decodeIfPresent(Int.self, forKey: .id)
1426-
name = try container.decodeIfPresent(String.self, forKey: .name)
1427-
vendorName = try container.decodeIfPresent(String.self, forKey: .vendorName)
1428-
nameContains = try container.decodeIfPresent(String.self, forKey: .nameContains)
1429-
vendorNameContains = try container.decodeIfPresent(String.self, forKey: .vendorNameContains)
1430-
}
1431-
1432-
public override func encode(to encoder: Encoder) throws {
1433-
try super.encode(to: encoder)
1434-
var container = encoder.container(keyedBy: CodingKeys.self)
1435-
if id != nil { try container.encode(id, forKey: .id) }
1436-
if name != nil { try container.encode(name, forKey: .name) }
1437-
if vendorName != nil { try container.encode(vendorName, forKey: .vendorName) }
1438-
if nameContains != nil { try container.encode(nameContains, forKey: .nameContains) }
1439-
if vendorNameContains != nil { try container.encode(vendorNameContains, forKey: .vendorNameContains) }
1440-
}
1441-
}
1442-
14431400
public class GetOrganizationResponse : Codable
14441401
{
14451402
public var cache:Int?
@@ -2245,18 +2202,18 @@ public class PostCommentReportInfo : Codable
22452202
required public init(){}
22462203
}
22472204

2248-
public class QueryDb<T : Codable> : QueryBase
2249-
{
2250-
required public init(){ super.init() }
2251-
2252-
required public init(from decoder: Decoder) throws {
2253-
try super.init(from: decoder)
2254-
}
2255-
2256-
public override func encode(to encoder: Encoder) throws {
2257-
try super.encode(to: encoder)
2258-
}
2259-
}
2205+
//public class QueryDb_1<T : Codable> : QueryBase
2206+
//{
2207+
// required public init(){ super.init() }
2208+
//
2209+
// required public init(from decoder: Decoder) throws {
2210+
// try super.init(from: decoder)
2211+
// }
2212+
//
2213+
// public override func encode(to encoder: Encoder) throws {
2214+
// try super.encode(to: encoder)
2215+
// }
2216+
//}
22602217

22612218
public class PostComment : Codable
22622219
{
@@ -2424,6 +2381,46 @@ public class TechnologyHistory : TechnologyBase
24242381
}
24252382
}
24262383

2384+
//public class QueryDb_2<From : Codable, Into : Codable> : QueryBase
2385+
//{
2386+
// required public init(){ super.init() }
2387+
//
2388+
// required public init(from decoder: Decoder) throws {
2389+
// try super.init(from: decoder)
2390+
// }
2391+
//
2392+
// public override func encode(to encoder: Encoder) throws {
2393+
// try super.encode(to: encoder)
2394+
// }
2395+
//}
2396+
2397+
public class TechnologyView : Codable
2398+
{
2399+
public var id:Int?
2400+
public var name:String?
2401+
public var vendorName:String?
2402+
public var vendorUrl:String?
2403+
public var productUrl:String?
2404+
public var logoUrl:String?
2405+
public var Description:String?
2406+
public var created:Date?
2407+
public var createdBy:String?
2408+
public var lastModified:Date?
2409+
public var lastModifiedBy:String?
2410+
public var ownerId:String?
2411+
public var slug:String?
2412+
public var logoApproved:Bool?
2413+
public var isLocked:Bool?
2414+
public var tier:TechnologyTier?
2415+
public var lastStatusUpdate:Date?
2416+
public var organizationId:Int?
2417+
public var commentsPostId:Int?
2418+
public var viewCount:Int?
2419+
public var favCount:Int?
2420+
2421+
required public init(){}
2422+
}
2423+
24272424
public protocol IRegisterStats
24282425
{
24292426
}
@@ -2472,6 +2469,32 @@ public class TechnologyStackHistory : TechnologyStackBase
24722469
}
24732470
}
24742471

2472+
public class TechnologyStackView : Codable
2473+
{
2474+
public var id:Int?
2475+
public var name:String?
2476+
public var vendorName:String?
2477+
public var Description:String?
2478+
public var appUrl:String?
2479+
public var screenshotUrl:String?
2480+
public var created:Date?
2481+
public var createdBy:String?
2482+
public var lastModified:Date?
2483+
public var lastModifiedBy:String?
2484+
public var isLocked:Bool?
2485+
public var ownerId:String?
2486+
public var slug:String?
2487+
public var details:String?
2488+
public var detailsHtml:String?
2489+
public var lastStatusUpdate:Date?
2490+
public var organizationId:Int?
2491+
public var commentsPostId:Int?
2492+
public var viewCount:Int?
2493+
public var favCount:Int?
2494+
2495+
required public init(){}
2496+
}
2497+
24752498
public class UserInfo : Codable
24762499
{
24772500
public var userName:String?

0 commit comments

Comments
 (0)