Skip to content
This repository has been archived by the owner on May 1, 2020. It is now read-only.

Using SquidCursor

Sam Bosley edited this page Aug 22, 2016 · 6 revisions

SquidCursor is a decorator that wraps a low-level ICursor object. (ICursor is a platform-agnostic re-declaration of android.database.Cursor). SquidDatabase's query() method returns a SquidCursor, and is the only method in the framework to do so. SquidCursor itself implements the ICursor interface, so you can use it in the same way you would use an Android cursor -- methods like moveToFirst(), moveToNext(), isAfterLast() etc. all work in exactly the same way as a standard Android cursor.

If in an Android app you need an actual instance of android.database.Cursor, you can cast the result of SquidCursor.getCursor() like so:

SquidCursor<Person> myCursor = ...;
Cursor androidCursor = (Cursor) myCursor.getCursor();

So what's special about SquidCursor?

Typesafe getter

There is only one additional method in SquidCursor that you may find yourself using on a regular basis: get(Property<T>). This get method leverages SquiDB's type safety features to get the correct type out of a cursor column without needing to know the index of the column or which cursor getter to call.

String firstName = cursor.get(Person.FIRST_NAME);
long personId = cursor.get(Person.ID);

Of course, those methods would throw exceptions if those columns weren't present in the cursor.

The typesafe getter can be useful when you're working with a cursor, but only need one specific field and don't want to instantiate a new model object for the entire row. While model objects are very lightweight and don't cost much to inflate, sometimes it's easier to just work with the cursor directly.

Type parameter

You may have noticed that SquidCursor has a type parameter that extends AbstractModel. When you call query() on a SquidDatabase, you pass a model class object that your SquidCursor will be parametrized by. This type parameter is not very strict--it's really just a hint to consumers what kind of model object they might want to use with that cursor. For example, model objects can be constructed from their type of cursor:

SquidCursor<Person> personCursor = database.query(Person.class, Query.select()...);
personCursor.moveToFirst();
Person firstPerson = new Person(personCursor);

While you can only call the model constructor with an appropriately-typed instance of that cursor, you can still read a cursor's columns into any type of model object. For example, you can do this:

SquidCursor<ProfilePicture> cursor = database.query(ProfilePicture.class,
    Query.select(ProfilePicture.URL, Person.FIRST_NAME)
    .innerJoin(Person.TABLE, ProfilePicture.PERSON_ID.eq(Person.ID)));

cursor.moveToFirst();
// Can't construct directly from the cursor since it's parametrized by ProfilePicture...
Person person = new Person();
// ...so read it separately
person.readPropertiesFromCursor(cursor);
// This works as usual
String firstName = person.getFirstName();
// Person doesn't have a getter for this property, but can still access it with get()
String url = person.get(ProfilePicture.URL);

See also: