{"action":"created","comment":{"url":"https://api.github.com/repos/realm/realm-java/pulls/comments/30779934","id":30779934,"diff_hunk":"@@ -0,0 +1,757 @@\n+/*\n+ * Copyright 2015 Realm Inc.\n+ *\n+ * Licensed under the Apache License, Version 2.0 (the \"License\");\n+ * you may not use this file except in compliance with the License.\n+ * You may obtain a copy of the License at\n+ *\n+ * http://www.apache.org/licenses/LICENSE-2.0\n+ *\n+ * Unless required by applicable law or agreed to in writing, software\n+ * distributed under the License is distributed on an \"AS IS\" BASIS,\n+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+ * See the License for the specific language governing permissions and\n+ * limitations under the License.\n+ */\n+\n+package io.realm.android;\n+\n+import android.content.ContentResolver;\n+import android.database.CharArrayBuffer;\n+import android.database.ContentObserver;\n+import android.database.Cursor;\n+import android.database.CursorIndexOutOfBoundsException;\n+import android.database.DataSetObservable;\n+import android.database.DataSetObserver;\n+import android.net.Uri;\n+import android.os.Bundle;\n+\n+import io.realm.Realm;\n+import io.realm.RealmChangeListener;\n+import io.realm.RealmResults;\n+import io.realm.internal.ColumnType;\n+import io.realm.internal.TableOrView;\n+\n+/**\n+ * This class exposes {@link io.realm.RealmResults} as a cursor.\n+ * <p>\n+ * Many Android framework classes require the presences of an \"_id\" field. Instead of adding such a field to your\n+ * model class it is instead possible to use {@link #setIdColumn(String)}.\n+ * <p>\n+ * A RealmCursor has the same thread restrictions as RealmResults, so it is not possible to move a RealmCursor between\n+ * threads.\n+ * <p>\n+ * A RealmCursor is currently limited to only being able to display data from a single RealmClass, ie. it is not\n+ * possible to follow links to other objects.\n+ */\n+public class RealmCursor implements Cursor {\n+\n+    private static final String DEFAULT_ID_COLUMN = \"_id\";\n+\n+    // Needed because constants are only available from API 11\n+    private static final int FIELD_TYPE_NULL;\n+    private static final int FIELD_TYPE_INTEGER;\n+    private static final int FIELD_TYPE_FLOAT;\n+    private static final int FIELD_TYPE_STRING;\n+    private static final int FIELD_TYPE_BLOB;\n+    static {\n+        if (android.os.Build.VERSION.SDK_INT >= 11) {\n+            FIELD_TYPE_NULL = Cursor.FIELD_TYPE_NULL;\n+            FIELD_TYPE_INTEGER = Cursor.FIELD_TYPE_INTEGER;\n+            FIELD_TYPE_FLOAT = Cursor.FIELD_TYPE_FLOAT;\n+            FIELD_TYPE_STRING = Cursor.FIELD_TYPE_STRING;\n+            FIELD_TYPE_BLOB = Cursor.FIELD_TYPE_BLOB;\n+        } else {\n+            FIELD_TYPE_NULL = 0;\n+            FIELD_TYPE_INTEGER = 1;\n+            FIELD_TYPE_FLOAT = 2;\n+            FIELD_TYPE_STRING = 3;\n+            FIELD_TYPE_BLOB = 4;\n+        }\n+    }\n+\n+    private final Realm realm;\n+    private TableOrView table;\n+    private int rowIndex;\n+    private boolean closed;\n+    private long idColumnIndex = -1; // Column index for the \"_id\" field. -1 means it hasn't been set\n+    private final DataSetObservable dataSetObservable = new DataSetObservable();\n+    private RealmChangeListener changeListener = new RealmChangeListener() {\n+        @Override\n+        public void onChange() {\n+            if (dataSetObservable != null) {\n+                dataSetObservable.notifyChanged(); // TODO Should be replaced with something more fine grained.\n+            }\n+        }\n+    };\n+\n+\n+    /**\n+     * Exposes a query result as a cursor. Use {@link RealmResults#getCursor()} instead of this\n+     * constructor\n+     *\n+     * @param table Table view representing the query results.\n+     */\n+    public RealmCursor(Realm realm, TableOrView table) {\n+        this.table = table;\n+        this.rowIndex = -1;\n+        this.realm = realm;\n+        realm.addChangeListener(changeListener);\n+    }\n+\n+    /**\n+     * Returns the numbers of rows in the cursor.\n+     *\n+     * @return the number of rows in the cursor.\n+     */\n+    @Override\n+    public int getCount() {\n+        checkClosed();\n+        return (int) table.size();\n+    }\n+\n+    /**\n+     * Returns the current position of the cursor in the row set.\n+     * The value is zero-based. When the row set is first returned the cursor\n+     * will be at position -1, which is before the first row. After the\n+     * last row is returned another call to next() will leave the cursor past","path":"realm/src/main/java/io/realm/android/RealmCursor.java","position":117,"original_position":117,"commit_id":"b2df416da986e0664803f96249a174ecfc5245cb","original_commit_id":"b2df416da986e0664803f96249a174ecfc5245cb","user":{"login":"kneth","id":1225363,"avatar_url":"https://avatars.githubusercontent.com/u/1225363?v=3","gravatar_id":"","url":"https://api.github.com/users/kneth","html_url":"https://github.com/kneth","followers_url":"https://api.github.com/users/kneth/followers","following_url":"https://api.github.com/users/kneth/following{/other_user}","gists_url":"https://api.github.com/users/kneth/gists{/gist_id}","starred_url":"https://api.github.com/users/kneth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kneth/subscriptions","organizations_url":"https://api.github.com/users/kneth/orgs","repos_url":"https://api.github.com/users/kneth/repos","events_url":"https://api.github.com/users/kneth/events{/privacy}","received_events_url":"https://api.github.com/users/kneth/received_events","type":"User","site_admin":false},"body":"Can you link to the methods?","created_at":"2015-05-21T07:56:31Z","updated_at":"2015-05-21T07:56:31Z","html_url":"https://github.com/realm/realm-java/pull/1090#discussion_r30779934","pull_request_url":"https://api.github.com/repos/realm/realm-java/pulls/1090","_links":{"self":{"href":"https://api.github.com/repos/realm/realm-java/pulls/comments/30779934"},"html":{"href":"https://github.com/realm/realm-java/pull/1090#discussion_r30779934"},"pull_request":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1090"}}},"pull_request":{"url":"https://api.github.com/repos/realm/realm-java/pulls/1090","id":34808074,"html_url":"https://github.com/realm/realm-java/pull/1090","diff_url":"https://github.com/realm/realm-java/pull/1090.diff","patch_url":"https://github.com/realm/realm-java/pull/1090.patch","issue_url":"https://api.github.com/repos/realm/realm-java/issues/1090","number":1090,"state":"open","locked":false,"title":"RealmCursor","user":{"login":"cmelchior","id":406066,"avatar_url":"https://avatars.githubusercontent.com/u/406066?v=3","gravatar_id":"","url":"https://api.github.com/users/cmelchior","html_url":"https://github.com/cmelchior","followers_url":"https://api.github.com/users/cmelchior/followers","following_url":"https://api.github.com/users/cmelchior/following{/other_user}","gists_url":"https://api.github.com/users/cmelchior/gists{/gist_id}","starred_url":"https://api.github.com/users/cmelchior/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cmelchior/subscriptions","organizations_url":"https://api.github.com/users/cmelchior/orgs","repos_url":"https://api.github.com/users/cmelchior/repos","events_url":"https://api.github.com/users/cmelchior/events{/privacy}","received_events_url":"https://api.github.com/users/cmelchior/received_events","type":"User","site_admin":false},"body":"Fixes #438 \r\n\r\n**Missing**\r\n- [x] Missing unit tests\r\n- [x] JavaDoc\r\n- [x] Figure out how to handle RealmLists: First release. disallow LINK and LINK_LIST\r\n- [x] Figure out if Cursor should be decoupled from RealmResults. \r\n- [x] Make Gradle respect @inheritDoc: Copy JavaDoc instead. Doesn't seem possible. \r\n\r\n\r\n**Description**\r\nThis adds a Cursor implementation for Realm data. The main challenge is mapping the very limited types in SQLite to the more expressive types in Realm.\r\n\r\nThe current approach is to respect the Cursor interface as much as possible as that is what will be exposed in ContentProviders and other framework classes.\r\n\r\nThis has the following implications:\r\n```\r\n// Simple types\r\nBoolean:  becomes a Cursor.INTEGER and will return 0 or 1 when calling Cursor.getInt()\r\nDate: becomes a Cursor.INTEGER. getLong() return ms. since epoch. getInt() and getShort() will throw exception.\r\n\r\n// Links/LinkLists: No immediately good solution is available. Suggestion is adding support  for the following syntax. Disallowing accessing RealmLists might also be an option as it doesn't map well to a table layout anyway?\r\nint calculatedIndex = cursor.getIndex(\"foo.columnString\");\r\nint calculatedIndex = cursor.getIndex(\"fooList[0].columnString\");\r\n```\r\n\r\nI have a single new method ```setIdColumn(String columnName)``` that creates a virtual \"_id\" field used by many framework classes. This should be acceptable as it is defined when the Cursor is created and the developer know it is a ReamCursor. Adding other nice methods like ```getDate()``` should be avoided as client code should only interact with the cursor using the Interface.\r\n\r\nNote that RealmCursor just reuses the tableview backing the RealmResults. This means that any changes to RealmResults will be reflected in the RealmCursor. I am not sure this behaviour is developer friendly but AFAIK we cannot lock the tableview until we start implementing Async queries.\r\n\r\n@emanuelez @kneth @bmunkholm \r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n","created_at":"2015-05-06T11:19:06Z","updated_at":"2015-05-21T07:56:31Z","closed_at":null,"merged_at":null,"merge_commit_sha":"fe29a9ba2aef89b805823c721ff0fac627bcec32","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/realm/realm-java/pulls/1090/commits","review_comments_url":"https://api.github.com/repos/realm/realm-java/pulls/1090/comments","review_comment_url":"https://api.github.com/repos/realm/realm-java/pulls/comments{/number}","comments_url":"https://api.github.com/repos/realm/realm-java/issues/1090/comments","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/b2df416da986e0664803f96249a174ecfc5245cb","head":{"label":"realm:cm-cursor","ref":"cm-cursor","sha":"b2df416da986e0664803f96249a174ecfc5245cb","user":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"repo":{"id":4084908,"name":"realm-java","full_name":"realm/realm-java","owner":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/realm/realm-java","description":"Realm is a mobile database: a replacement for SQLite & ORMs","fork":false,"url":"https://api.github.com/repos/realm/realm-java","forks_url":"https://api.github.com/repos/realm/realm-java/forks","keys_url":"https://api.github.com/repos/realm/realm-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/realm/realm-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/realm/realm-java/teams","hooks_url":"https://api.github.com/repos/realm/realm-java/hooks","issue_events_url":"https://api.github.com/repos/realm/realm-java/issues/events{/number}","events_url":"https://api.github.com/repos/realm/realm-java/events","assignees_url":"https://api.github.com/repos/realm/realm-java/assignees{/user}","branches_url":"https://api.github.com/repos/realm/realm-java/branches{/branch}","tags_url":"https://api.github.com/repos/realm/realm-java/tags","blobs_url":"https://api.github.com/repos/realm/realm-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/realm/realm-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/realm/realm-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/realm/realm-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/{sha}","languages_url":"https://api.github.com/repos/realm/realm-java/languages","stargazers_url":"https://api.github.com/repos/realm/realm-java/stargazers","contributors_url":"https://api.github.com/repos/realm/realm-java/contributors","subscribers_url":"https://api.github.com/repos/realm/realm-java/subscribers","subscription_url":"https://api.github.com/repos/realm/realm-java/subscription","commits_url":"https://api.github.com/repos/realm/realm-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/realm/realm-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/realm/realm-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/realm/realm-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/realm/realm-java/contents/{+path}","compare_url":"https://api.github.com/repos/realm/realm-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/realm/realm-java/merges","archive_url":"https://api.github.com/repos/realm/realm-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/realm/realm-java/downloads","issues_url":"https://api.github.com/repos/realm/realm-java/issues{/number}","pulls_url":"https://api.github.com/repos/realm/realm-java/pulls{/number}","milestones_url":"https://api.github.com/repos/realm/realm-java/milestones{/number}","notifications_url":"https://api.github.com/repos/realm/realm-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/realm/realm-java/labels{/name}","releases_url":"https://api.github.com/repos/realm/realm-java/releases{/id}","created_at":"2012-04-20T09:18:42Z","updated_at":"2015-05-20T15:48:52Z","pushed_at":"2015-05-20T19:41:50Z","git_url":"git://github.com/realm/realm-java.git","ssh_url":"git@github.com:realm/realm-java.git","clone_url":"https://github.com/realm/realm-java.git","svn_url":"https://github.com/realm/realm-java","homepage":"http://realm.io","size":56797,"stargazers_count":1792,"watchers_count":1792,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":157,"mirror_url":null,"open_issues_count":119,"forks":157,"open_issues":119,"watchers":1792,"default_branch":"master"}},"base":{"label":"realm:master","ref":"master","sha":"bf0fb9ef2b8a9e6b0e3e5c1539eeb17402274f58","user":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"repo":{"id":4084908,"name":"realm-java","full_name":"realm/realm-java","owner":{"login":"realm","id":7575099,"avatar_url":"https://avatars.githubusercontent.com/u/7575099?v=3","gravatar_id":"","url":"https://api.github.com/users/realm","html_url":"https://github.com/realm","followers_url":"https://api.github.com/users/realm/followers","following_url":"https://api.github.com/users/realm/following{/other_user}","gists_url":"https://api.github.com/users/realm/gists{/gist_id}","starred_url":"https://api.github.com/users/realm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/realm/subscriptions","organizations_url":"https://api.github.com/users/realm/orgs","repos_url":"https://api.github.com/users/realm/repos","events_url":"https://api.github.com/users/realm/events{/privacy}","received_events_url":"https://api.github.com/users/realm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/realm/realm-java","description":"Realm is a mobile database: a replacement for SQLite & ORMs","fork":false,"url":"https://api.github.com/repos/realm/realm-java","forks_url":"https://api.github.com/repos/realm/realm-java/forks","keys_url":"https://api.github.com/repos/realm/realm-java/keys{/key_id}","collaborators_url":"https://api.github.com/repos/realm/realm-java/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/realm/realm-java/teams","hooks_url":"https://api.github.com/repos/realm/realm-java/hooks","issue_events_url":"https://api.github.com/repos/realm/realm-java/issues/events{/number}","events_url":"https://api.github.com/repos/realm/realm-java/events","assignees_url":"https://api.github.com/repos/realm/realm-java/assignees{/user}","branches_url":"https://api.github.com/repos/realm/realm-java/branches{/branch}","tags_url":"https://api.github.com/repos/realm/realm-java/tags","blobs_url":"https://api.github.com/repos/realm/realm-java/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/realm/realm-java/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/realm/realm-java/git/refs{/sha}","trees_url":"https://api.github.com/repos/realm/realm-java/git/trees{/sha}","statuses_url":"https://api.github.com/repos/realm/realm-java/statuses/{sha}","languages_url":"https://api.github.com/repos/realm/realm-java/languages","stargazers_url":"https://api.github.com/repos/realm/realm-java/stargazers","contributors_url":"https://api.github.com/repos/realm/realm-java/contributors","subscribers_url":"https://api.github.com/repos/realm/realm-java/subscribers","subscription_url":"https://api.github.com/repos/realm/realm-java/subscription","commits_url":"https://api.github.com/repos/realm/realm-java/commits{/sha}","git_commits_url":"https://api.github.com/repos/realm/realm-java/git/commits{/sha}","comments_url":"https://api.github.com/repos/realm/realm-java/comments{/number}","issue_comment_url":"https://api.github.com/repos/realm/realm-java/issues/comments{/number}","contents_url":"https://api.github.com/repos/realm/realm-java/contents/{+path}","compare_url":"https://api.github.com/repos/realm/realm-java/compare/{base}...{head}","merges_url":"https://api.github.com/repos/realm/realm-java/merges","archive_url":"https://api.github.com/repos/realm/realm-java/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/realm/realm-java/downloads","issues_url":"https://api.github.com/repos/realm/realm-java/issues{/number}","pulls_url":"https://api.github.com/repos/realm/realm-java/pulls{/number}","milestones_url":"https://api.github.com/repos/realm/realm-java/milestones{/number}","notifications_url":"https://api.github.com/repos/realm/realm-java/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/realm/realm-java/labels{/name}","releases_url":"https://api.github.com/repos/realm/realm-java/releases{/id}","created_at":"2012-04-20T09:18:42Z","updated_at":"2015-05-20T15:48:52Z","pushed_at":"2015-05-20T19:41:50Z","git_url":"git://github.com/realm/realm-java.git","ssh_url":"git@github.com:realm/realm-java.git","clone_url":"https://github.com/realm/realm-java.git","svn_url":"https://github.com/realm/realm-java","homepage":"http://realm.io","size":56797,"stargazers_count":1792,"watchers_count":1792,"language":"Java","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":157,"mirror_url":null,"open_issues_count":119,"forks":157,"open_issues":119,"watchers":1792,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1090"},"html":{"href":"https://github.com/realm/realm-java/pull/1090"},"issue":{"href":"https://api.github.com/repos/realm/realm-java/issues/1090"},"comments":{"href":"https://api.github.com/repos/realm/realm-java/issues/1090/comments"},"review_comments":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1090/comments"},"review_comment":{"href":"https://api.github.com/repos/realm/realm-java/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/realm/realm-java/pulls/1090/commits"},"statuses":{"href":"https://api.github.com/repos/realm/realm-java/statuses/b2df416da986e0664803f96249a174ecfc5245cb"}}}}