{"action":"created","comment":{"url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/comments/64562687","id":64562687,"diff_hunk":"@@ -0,0 +1,286 @@\n+//\n+//  CreateQueryIndexOperation.swift\n+//  SwiftCloudant\n+//\n+//  Created by Rhys Short on 18/05/2016.\n+//  Copyright (c) 2016 IBM Corp.\n+//\n+//  Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file\n+//  except in compliance with the License. You may obtain a copy of the License at\n+//    http://www.apache.org/licenses/LICENSE-2.0\n+//  Unless required by applicable law or agreed to in writing, software distributed under the\n+//  License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,\n+//  either express or implied. See the License for the specific language governing permissions\n+//  and limitations under the License.\n+//\n+\n+\n+import Foundation\n+\n+/**\n+    An operation to create JSON Query (Mango) Index.\n+ \n+    Usage example:\n+    ```\n+    let index = CreateJsonQueryIndexOperation()\n+    index.indexName = \"exampleIndex\"\n+    index.fields = [Sort(field:\"food\", sort: .Desc)]\n+    index.designDoc = \"examples\"\n+    index.completionHandler = { (response, httpInfo, error) in\n+        if let error = error {\n+            // handle the error\n+        } else {\n+            // Check the status code for success.\n+        }\n+ \n+    }\n+ \n+    database.add(operation: index)\n+    ```\n+ */\n+public class CreateJsonQueryIndexOperation: CouchDatabaseOperation, MangoOperation {\n+    \n+    /**\n+     The name of the index.\n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request\n+     and the server default will apply.\n+     */\n+    public var indexName: String?\n+    \n+    /**\n+     The fields which to apply the index to.\n+     \n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request\n+     and the server default will apply.\n+     */\n+    public var fields: [Sort]?\n+    \n+    /**\n+     The name of the design doc this index should be saved to.\n+     \n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request\n+     and the server default will apply.\n+     */\n+    public var designDoc: String?\n+\n+    private var jsonData: NSData?\n+    \n+    \n+    public override var httpMethod: String {\n+        return \"POST\"\n+    }\n+\n+    public override var httpRequestBody: NSData? {\n+        return self.jsonData\n+    }\n+    \n+    public override var httpPath: String {\n+        return \"/\\(self.databaseName!)/_index\"\n+    }\n+    \n+    public override func validate() -> Bool {\n+        if !super.validate(){\n+            return false\n+        }\n+        \n+        return fields != nil\n+    }\n+\n+    public override func serialise() throws {\n+\n+        var jsonDict: [String:AnyObject] = [\"type\": \"json\"]\n+\n+        if let fields = fields {\n+            var index: [String: AnyObject] = [:]\n+            index[\"fields\"] = transform(sortArray: fields) as NSArray\n+            jsonDict[\"index\"] = index as NSDictionary\n+        }\n+\n+        if let indexName = indexName {\n+            jsonDict[\"name\"] = indexName as NSString\n+        }\n+\n+        if let designDoc = designDoc {\n+            jsonDict[\"ddoc\"] = designDoc as NSString\n+        }\n+\n+\n+        jsonData = try NSJSONSerialization.data(withJSONObject:jsonDict as NSDictionary) \n+    }\n+    \n+}\n+\n+/**\n+  A struct to resprent a field in a Text index.\n+ */\n+public struct TextIndexField {\n+    /**\n+     The name of the field\n+    */\n+    let name: String\n+    /**\n+     The type of field.\n+     */\n+    let type: TextIndexFieldType\n+}\n+\n+/**\n+    The data types for a field in a Text index.\n+ */\n+public enum TextIndexFieldType : String {\n+    /**\n+     A boolean data type.\n+    */\n+    case Boolean = \"boolean\"\n+    /**\n+     A String data type.\n+    */\n+    case String = \"string\"\n+    /**\n+     A Number data type.\n+    */\n+    case Number =  \"number\"\n+}\n+\n+/**\n+ An Operation to create a Text Query (Mango) Index.\n+ \n+ Usage Example:\n+ ```\n+ let index = CreateTextQueryIndexOperation()\n+ index.indexName = \"example\"\n+ index.fields = [TextIndexField(name:\"food\", type: .String)\n+ index.defaultFieldAnalyzer = \"english\"\n+ index.defaultFieldEnabled = true\n+ index.selector = [\"type\": \"food\"]\n+ index.designDoc = \"examples\"\n+ index.completionHandler = { (response, httpInfo, error) in \n+ \n+ }\n+ */\n+public class CreateTextQueryIndexOperation: CouchDatabaseOperation, MangoOperation {\n+    \n+    /**\n+     The name of the index\n+     \n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request\n+     and the server default will apply.\n+     */\n+    public var indexName: String?\n+    \n+    /**\n+     The fields to be included in the index.\n+     \n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request\n+     and the server default will apply.\n+     */\n+    public var fields: [TextIndexField]?\n+    \n+    /**\n+     The name of the analyzer to use for $text operator with this index.\n+     \n+     - Note: Optional, if this parameter is not set, it will be ommitted from the request","path":"Source/CreateQueryIndexOperation.swift","position":null,"original_position":182,"commit_id":"edcf1a02f2d34bf2434f2dd02a6071099c0dae7d","original_commit_id":"c8f5f39adc0b2145527207b5c91463143d9eb316","user":{"login":"rhyshort","id":1616727,"avatar_url":"https://avatars.githubusercontent.com/u/1616727?v=3","gravatar_id":"","url":"https://api.github.com/users/rhyshort","html_url":"https://github.com/rhyshort","followers_url":"https://api.github.com/users/rhyshort/followers","following_url":"https://api.github.com/users/rhyshort/following{/other_user}","gists_url":"https://api.github.com/users/rhyshort/gists{/gist_id}","starred_url":"https://api.github.com/users/rhyshort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhyshort/subscriptions","organizations_url":"https://api.github.com/users/rhyshort/orgs","repos_url":"https://api.github.com/users/rhyshort/repos","events_url":"https://api.github.com/users/rhyshort/events{/privacy}","received_events_url":"https://api.github.com/users/rhyshort/received_events","type":"User","site_admin":false},"body":"fixed in edcf1a02f2d34bf2434f2dd02a6071099c0dae7d","created_at":"2016-05-25T12:25:54Z","updated_at":"2016-05-25T12:25:54Z","html_url":"https://github.com/cloudant/swift-cloudant/pull/74#discussion_r64562687","pull_request_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74","_links":{"self":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/comments/64562687"},"html":{"href":"https://github.com/cloudant/swift-cloudant/pull/74#discussion_r64562687"},"pull_request":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74"}}},"pull_request":{"url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74","id":70872155,"html_url":"https://github.com/cloudant/swift-cloudant/pull/74","diff_url":"https://github.com/cloudant/swift-cloudant/pull/74.diff","patch_url":"https://github.com/cloudant/swift-cloudant/pull/74.patch","issue_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/74","number":74,"state":"open","locked":false,"title":"Add ability to create Query (Mango) Indexes.","user":{"login":"rhyshort","id":1616727,"avatar_url":"https://avatars.githubusercontent.com/u/1616727?v=3","gravatar_id":"","url":"https://api.github.com/users/rhyshort","html_url":"https://github.com/rhyshort","followers_url":"https://api.github.com/users/rhyshort/followers","following_url":"https://api.github.com/users/rhyshort/following{/other_user}","gists_url":"https://api.github.com/users/rhyshort/gists{/gist_id}","starred_url":"https://api.github.com/users/rhyshort/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/rhyshort/subscriptions","organizations_url":"https://api.github.com/users/rhyshort/orgs","repos_url":"https://api.github.com/users/rhyshort/repos","events_url":"https://api.github.com/users/rhyshort/events{/privacy}","received_events_url":"https://api.github.com/users/rhyshort/received_events","type":"User","site_admin":false},"body":"## What\r\nAdd the ability to create Query indexes.\r\n\r\n## How\r\n- CreateJSONIndexOperation to create a JSON index.\r\n- CreateTextIndexOperation to create a text index.\r\n- Created internal protocol `MangoOperation`\r\n- Refactored the `transform` method from `FindDocumentsOperation` into a protocol extension for `MangoOperation`, this provides the transformation methods to only the operations which interact with Mango / Query. \r\n\r\nThis is split into two operations instead of one to make it possible to\r\nhave compile time type checking for the `fields` parameter. This makes it\r\nmore swift like with type safety.\r\n\r\n## Testing\r\n\r\nTests added to CreateQueryIndexTests which test each operation, it uses stubs for the http requests so we can run against CouchDB 1.6.x.\r\n\r\n## Reviewers\r\nreviewer: @brynh\r\n\r\n## Issues\r\nResolves #7 ","created_at":"2016-05-20T15:21:13Z","updated_at":"2016-05-25T12:25:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"81127f02234d8e3918aac199a7b1e415c8c66c02","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74/commits","review_comments_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74/comments","review_comment_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/comments{/number}","comments_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/74/comments","statuses_url":"https://api.github.com/repos/cloudant/swift-cloudant/statuses/edcf1a02f2d34bf2434f2dd02a6071099c0dae7d","head":{"label":"cloudant:7-create-mango-indexes","ref":"7-create-mango-indexes","sha":"edcf1a02f2d34bf2434f2dd02a6071099c0dae7d","user":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"repo":{"id":55980905,"name":"swift-cloudant","full_name":"cloudant/swift-cloudant","owner":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cloudant/swift-cloudant","description":"A Swift Lang client for Cloudant and CouchDB","fork":false,"url":"https://api.github.com/repos/cloudant/swift-cloudant","forks_url":"https://api.github.com/repos/cloudant/swift-cloudant/forks","keys_url":"https://api.github.com/repos/cloudant/swift-cloudant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloudant/swift-cloudant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloudant/swift-cloudant/teams","hooks_url":"https://api.github.com/repos/cloudant/swift-cloudant/hooks","issue_events_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/events{/number}","events_url":"https://api.github.com/repos/cloudant/swift-cloudant/events","assignees_url":"https://api.github.com/repos/cloudant/swift-cloudant/assignees{/user}","branches_url":"https://api.github.com/repos/cloudant/swift-cloudant/branches{/branch}","tags_url":"https://api.github.com/repos/cloudant/swift-cloudant/tags","blobs_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloudant/swift-cloudant/statuses/{sha}","languages_url":"https://api.github.com/repos/cloudant/swift-cloudant/languages","stargazers_url":"https://api.github.com/repos/cloudant/swift-cloudant/stargazers","contributors_url":"https://api.github.com/repos/cloudant/swift-cloudant/contributors","subscribers_url":"https://api.github.com/repos/cloudant/swift-cloudant/subscribers","subscription_url":"https://api.github.com/repos/cloudant/swift-cloudant/subscription","commits_url":"https://api.github.com/repos/cloudant/swift-cloudant/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloudant/swift-cloudant/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloudant/swift-cloudant/contents/{+path}","compare_url":"https://api.github.com/repos/cloudant/swift-cloudant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloudant/swift-cloudant/merges","archive_url":"https://api.github.com/repos/cloudant/swift-cloudant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloudant/swift-cloudant/downloads","issues_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues{/number}","pulls_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls{/number}","milestones_url":"https://api.github.com/repos/cloudant/swift-cloudant/milestones{/number}","notifications_url":"https://api.github.com/repos/cloudant/swift-cloudant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloudant/swift-cloudant/labels{/name}","releases_url":"https://api.github.com/repos/cloudant/swift-cloudant/releases{/id}","deployments_url":"https://api.github.com/repos/cloudant/swift-cloudant/deployments","created_at":"2016-04-11T14:47:54Z","updated_at":"2016-05-03T15:13:01Z","pushed_at":"2016-05-25T12:24:42Z","git_url":"git://github.com/cloudant/swift-cloudant.git","ssh_url":"git@github.com:cloudant/swift-cloudant.git","clone_url":"https://github.com/cloudant/swift-cloudant.git","svn_url":"https://github.com/cloudant/swift-cloudant","homepage":null,"size":398,"stargazers_count":0,"watchers_count":0,"language":"Swift","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":25,"forks":0,"open_issues":25,"watchers":0,"default_branch":"master"}},"base":{"label":"cloudant:master","ref":"master","sha":"0f4fc54561f3995e32cfc03750f31cd9111d0302","user":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"repo":{"id":55980905,"name":"swift-cloudant","full_name":"cloudant/swift-cloudant","owner":{"login":"cloudant","id":44642,"avatar_url":"https://avatars.githubusercontent.com/u/44642?v=3","gravatar_id":"","url":"https://api.github.com/users/cloudant","html_url":"https://github.com/cloudant","followers_url":"https://api.github.com/users/cloudant/followers","following_url":"https://api.github.com/users/cloudant/following{/other_user}","gists_url":"https://api.github.com/users/cloudant/gists{/gist_id}","starred_url":"https://api.github.com/users/cloudant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cloudant/subscriptions","organizations_url":"https://api.github.com/users/cloudant/orgs","repos_url":"https://api.github.com/users/cloudant/repos","events_url":"https://api.github.com/users/cloudant/events{/privacy}","received_events_url":"https://api.github.com/users/cloudant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/cloudant/swift-cloudant","description":"A Swift Lang client for Cloudant and CouchDB","fork":false,"url":"https://api.github.com/repos/cloudant/swift-cloudant","forks_url":"https://api.github.com/repos/cloudant/swift-cloudant/forks","keys_url":"https://api.github.com/repos/cloudant/swift-cloudant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/cloudant/swift-cloudant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/cloudant/swift-cloudant/teams","hooks_url":"https://api.github.com/repos/cloudant/swift-cloudant/hooks","issue_events_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/events{/number}","events_url":"https://api.github.com/repos/cloudant/swift-cloudant/events","assignees_url":"https://api.github.com/repos/cloudant/swift-cloudant/assignees{/user}","branches_url":"https://api.github.com/repos/cloudant/swift-cloudant/branches{/branch}","tags_url":"https://api.github.com/repos/cloudant/swift-cloudant/tags","blobs_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/refs{/sha}","trees_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/cloudant/swift-cloudant/statuses/{sha}","languages_url":"https://api.github.com/repos/cloudant/swift-cloudant/languages","stargazers_url":"https://api.github.com/repos/cloudant/swift-cloudant/stargazers","contributors_url":"https://api.github.com/repos/cloudant/swift-cloudant/contributors","subscribers_url":"https://api.github.com/repos/cloudant/swift-cloudant/subscribers","subscription_url":"https://api.github.com/repos/cloudant/swift-cloudant/subscription","commits_url":"https://api.github.com/repos/cloudant/swift-cloudant/commits{/sha}","git_commits_url":"https://api.github.com/repos/cloudant/swift-cloudant/git/commits{/sha}","comments_url":"https://api.github.com/repos/cloudant/swift-cloudant/comments{/number}","issue_comment_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues/comments{/number}","contents_url":"https://api.github.com/repos/cloudant/swift-cloudant/contents/{+path}","compare_url":"https://api.github.com/repos/cloudant/swift-cloudant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/cloudant/swift-cloudant/merges","archive_url":"https://api.github.com/repos/cloudant/swift-cloudant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/cloudant/swift-cloudant/downloads","issues_url":"https://api.github.com/repos/cloudant/swift-cloudant/issues{/number}","pulls_url":"https://api.github.com/repos/cloudant/swift-cloudant/pulls{/number}","milestones_url":"https://api.github.com/repos/cloudant/swift-cloudant/milestones{/number}","notifications_url":"https://api.github.com/repos/cloudant/swift-cloudant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/cloudant/swift-cloudant/labels{/name}","releases_url":"https://api.github.com/repos/cloudant/swift-cloudant/releases{/id}","deployments_url":"https://api.github.com/repos/cloudant/swift-cloudant/deployments","created_at":"2016-04-11T14:47:54Z","updated_at":"2016-05-03T15:13:01Z","pushed_at":"2016-05-25T12:24:42Z","git_url":"git://github.com/cloudant/swift-cloudant.git","ssh_url":"git@github.com:cloudant/swift-cloudant.git","clone_url":"https://github.com/cloudant/swift-cloudant.git","svn_url":"https://github.com/cloudant/swift-cloudant","homepage":null,"size":398,"stargazers_count":0,"watchers_count":0,"language":"Swift","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":25,"forks":0,"open_issues":25,"watchers":0,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74"},"html":{"href":"https://github.com/cloudant/swift-cloudant/pull/74"},"issue":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/issues/74"},"comments":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/issues/74/comments"},"review_comments":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74/comments"},"review_comment":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/pulls/74/commits"},"statuses":{"href":"https://api.github.com/repos/cloudant/swift-cloudant/statuses/edcf1a02f2d34bf2434f2dd02a6071099c0dae7d"}}}}
{"actor":{"display_login":"rhyshort"}}