-
Notifications
You must be signed in to change notification settings - Fork 4
ContentQuery
ContentQuery
is an extension library that allows you write DbQuery
-style query to ContentProvider
.
NOTE ContentQuery
depends on DbQuery
. This wiki is written with assumption that you are familiar with DbQuery
library. Please see https://github.com/bingzer/DbQuery/wiki for more information
Uri uri = ...
IResolver resolver = ContentQuery.resolve(uri, getContext());
Cursor cursor = resolver.select("name = ? or display like ?", "John", "John%")
.columns("_id", "name")
.orderBy("name desc", "_id")
.query();
It is a wrapper around ContextResolver
that allows you to write DbQuery
-style query. There are two types of resolvers: IResolver
and IStrictResolver
. Basically, IStrictResolver
offers a strict and less functionalities than the normal IResolver
.
To get resolver objects there are several options:
IStrictResolver
String uriString = ...
IStrictResolver strictResolver = ContentQuery.strictlyResolve(uriString, getContext());
// or
Uri uri = ...
IStrictResolver strictResolver = ContentQuery.strictlyResolve(uri, getContext());
IResolver
String uriString = ...
IResolver resolver = ContentQuery.resolve(uriString, getContext());
// or
Uri uri = ...
IResolver resolver = ContentQuery.resolve(uri, getContext());
-
IStrictResolver
provides a strict implementation. This type of resolver restrict theLIMIT
clause inside a query. So pagination orSELECT TOP
is not implemented -
IResolver
provides a lenient implementation. This type of resolver allowsPAGING
andSELECT TOP
implementation
The rule of thumb is to always refer to your ContentProvider
's documentation. If you're not familiar with the ContentProvider
, you should NEVER use IResolver
because your query may break the ContentProvider
implementation.
ContentConfig
is used to configure your resolver. These are some configurations that are optionally needed to query from Android built-in providers:
IStrictResolver resolver = ContentQuery.strictlyResolve(UserDictionary.Words.CONTENT_URI, getContext());
// sets the 'Id' naming convention. Default is '_id'
resolver.getConfig().setIdNamingConvention("_id");
// sets the default projections
resolver.getConfig().setDefaultProjections("_id", "word");
// sets the default authority (used in 'bulk-insert')
resolver.getConfig().setDefaultAuthority(UserDictionary.AUTHORITY);
Important Always configure before doing query
- Most of the
ContentProvider
uses_id
(lowercase) as their id. By default,ContentQuery
uses_id
asId
. Again, consult yourContentProvider
's documentation. -
ContentConfig.setDefaultProjections()
determines the default projections (columns) to return if otherwise being overriden inSelect.columns()
method. The default value for thisContentConfig.getIdNamingConvention()
. Ifnull
is specified, the value will also beContentConfig.getIdNamingConvention()
-
ContentConfig.setDefaultAuthority()
provides the authorityString
when doing bulk-insert.
#IResolver.count()
-
IResolver.count()
returns the total records. -
IResolver.count(String condition)
returns the total records that matches the condition -
IResolver.count(String whereClause, Object... args)
returns the total records that matches thewhereClause
. This is more preferred way then callingcount(condition)
.
#IResolver.has()
-
IResolver.has(int id)
returnstrue
if a record with the sameid
exists;false
if otherwise -
IResolver.has(String condition)
returnstrue
if a record or more exists that matches the condition;false
if otherwise -
IResolver.has(String whereClause, Object... args)
returnstrue
if a record or more exists that matches the specifiedwhereClause
; false if otherwise
As found in DbQuery
implementation, SELECT
is implemented the same way:
IStrictResolver resolver = ...
resolver.getConfig().setDefaultProjections("_id", "word");
// select "_id" and "word" and order by word DESCENDING
Cursor cursor = resolver.select()
.orderBy("word DESC")
.query();
-
Paging
is available only when you're usingIResolver
.Paging
is made possible by appendingLIMIT X OFFSET Y
argument toOrderBy
clause. Again, you should always consult yourContentProvider
documentation before doingPaging
as it may break the provider's implementation.
IResolver resolver = ...
resolver.getConfig().setDefaultProjections("_id", "word");
// select "_id" and "word" and order by word DESCENDING
IQuery.Paging paging = resolver.select()
.orderBy("word DESC")
.paging(10); // ten in a row
...
Cursor cursor = paging.query();
assertTrue(paging.getPageNumber() == 0); // first page
...
cursor = paging.next().query();
assertTrue(paging.getPageNumber() == 1); // second page
Many options to do an INSERT
operations:
- Using
ContentValues
As always,ContentValues
is a first-citizen inContentQuery
IStrictResolver resolver = ...
// or
IResolver resolver = ...
ContentValues values = new ContentValues();
values.put("word", "OLA");
int newId = resolver.insert(values);
- Others:
IStrictResolver resolver = ...
// or
IResolver resolver = ...
int newId = resolver.insert("word")
.val("ABCDEFG")
.query();
// or
int newId = resolver.insert(
new String[]{"word"},
new Object[]{"ABCDEFG"})
.query();
- How do I get the
Uri
?Insert
object stores theUri
as string in thetoString()
method.
IStrictResolver resolver = ...
// or
IResolver resolver = ...
IQuery.Insert insert = resolver.insert("word")
.val("ABCDEFG");
int newId = insert.query();
String uriString = insert.toString();
Uri uri = Uri.parse(uriString);
To do an UPDATE
operation:
- Using
ContentValues
.
IStrictResolver resolver = ...
// or
IResolver resolver = ...
ContentValues values = new ContentValues();
values.put("word", "Baloteli-Updated");
int id = ...
int numUpdated = resolver.update(values, id)
.query();
// or
int numUpdated = resolver.update(values, "word = ?", "Baloteli")
.query();
- Others:
IStrictResolver resolver = ...
// or
IResolver resolver = ...
int id = ...
int numUpdated = resolver.update(
new String[]{"word"},
new Object[]{"Baloteli-Updated"},
id);
// or
int numUpdated = resolver.update(
new String[]{"word"},
new Object[]{"Baloteli-Updated"},
"word like ?",
"Baloteli");
To perform delete:
IStrictResolver resolver = ...
// or
IResolver resolver = ...
// By Id
int id = ...
int numDeleted = resolver.delete(id)
.query();
// By Condition (maybe bulk-delete)
// bulk-delete any word that ends with 'ed'
int numDeleted = resolver.delete("word like ?", "%ed")
.query();
IEntity
and IEntityList
are both supported in ContentQuery
:
public class Word implements IEntity{
...
}
...
public class WordList extends LinkedList<Word> implements IEntityList<Word>{
@Override
public List<Word> getEntityList() {
return this;
}
@Override
public Word newEntity() {
return new Word();
}
}
IStrictResolver resolver = ...
// or
IResolver resolver = ...
WordList wordList = new WordList();
resolver.select().query(wordList);
assertTrue(wordList.size() > 0); // populated!