Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RealmCursor #1090

Closed
wants to merge 24 commits into from
Closed

RealmCursor #1090

wants to merge 24 commits into from

Conversation

cmelchior
Copy link
Contributor

Fixes #438

Missing
ContentProviders exposes a cursor, which works fine if used within a app. However it breaks if shared with another app:

  • Accessing an ContentProvider in another app is done using IPC (Blocked by Add multi process support #1091)
  • The ContentProvider is started on App1 main thread
  • App2 is accessing ContentProvider using a Binder thread, meaning that opening the Realm in onCreate causes Thread exceptions.

We can ship RealmCursor with the explicit caveat that it doesn't work with ContentProviders across apps, but it is not ideal.

Description
This 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.

The 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.

This has the following implications:

// Simple types
Boolean:  becomes a Cursor.INTEGER and will return 0 or 1 when calling Cursor.getInt()
Date: becomes a Cursor.INTEGER. getLong() return ms. since epoch. getInt() and getShort() will throw exception.

// 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?
int calculatedIndex = cursor.getIndex("foo.columnString");
int calculatedIndex = cursor.getIndex("fooList[0].columnString");

I 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.

Note 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.

@emanuelez @kneth @bmunkholm

@cmelchior cmelchior added the PR label May 6, 2015
cursor = realm.allObjects(AllTypes.class).getCursor();
}

private void populateTestRealm(Realm realm, int objects) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We use this is almost all our test modules. Why don't we move to a helper class?

table = null; // Instead of closing the table, we just release it. Original RealmResults would also be closed otherwise.
realm.removeChangeListener(changeListener);
dataSetObservable.notifyInvalidated();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's safe to call contentObservable.unregisterAll() at this point.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. It has been added.

@cmelchior
Copy link
Contributor Author

Reverting to WIP status. There are some details about ContentObservers and NotificationUri's that needs to be discussed as it is probably also part of #989

@cmelchior cmelchior added the WIP label Jun 3, 2015
@cmelchior cmelchior added P1 and removed PR labels Jun 12, 2015
Conflicts:
	realm/src/androidTest/java/io/realm/RealmResultsTest.java
	realm/src/androidTest/java/io/realm/RealmTest.java
	realm/src/androidTest/java/io/realm/TestHelper.java
private static final int FIELD_TYPE_STRING;
private static final int FIELD_TYPE_BLOB;
static {
if (android.os.Build.VERSION.SDK_INT >= 11) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This branch can be removed.

Constant values are always inlined(http://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html#jls-13.1-110-C).
This means there will be no reference to Cursor.FIELD* in class file.

@yuriy-larin
Copy link

Is Cursor example still not ready?

@cmelchior
Copy link
Contributor Author

No, there is work on it here though: realm/realm-android-adapters#53
Anything in particular you are missing?

@yuriy-larin
Copy link

I'm trying to switch from SQLite to Realm while I'm on early stage of project.
I have code with :
implements LoaderCallbacks
SimpleCursorAdapter
static class MyCursorLoader extends CursorLoader
trying to rewrite it for Realm.
As I understand, I have to use something like:
RealmResults results = realm.where(User.class).findAll();
in Fragment class instead. Is that correct?

@yuriy-larin
Copy link

What is also not quite clear for me from documentation...
How to fetch limited number of instances, something equal to 'LIMIT 10' functionality?

@cmelchior
Copy link
Contributor Author

realm.where(User.class).findAllAsync() is better as that will run the query on a background thread. No need for loaders in that case.

We don't support LIMIT yet, but since RealmResults are lazy-loaded, you normally don't need it anyway. You can use results.subList() instead though if you want to restrict the result.

@yuriy-larin
Copy link

yuriy-larin commented Jul 8, 2016

Thank you for suggestion.

Today I also stumbled upon the limitation trying to extend class from external library.
#761
Inheritance / Polymorphism
I had to make copy of code instead.

@cmelchior
Copy link
Contributor Author

Closing this PR as it is now being tracked realm/realm-android-adapters#6 instead

@cmelchior cmelchior closed this Aug 1, 2016
@cmelchior cmelchior deleted the cm-cursor branch September 2, 2017 11:50
@cmelchior cmelchior restored the cm-cursor branch September 2, 2017 11:51
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Android component: RealmCursor
7 participants