I think you've hit the nail on the head Itamar.

Why shouldn't I be able to perform arbitrary SQL join queries across
arbitrary tables in arbitrary (sqlite-based) content providers? And
why should a SQL-like API exist for non sqlite-based content
providers?

Perhaps the content resolver could be enhanced to map content urls/
mime types to different content provider interfaces?

Regards,
Chris Harris


Itamar Rogel wrote:
> Hi everyone,
> Having developed for Android, I have some thoughts about the content
> providers API which I think might be worth sharing; I believe there is
> room for some improvements to be made to the content providers API
> before it is stabilized and would be interested to hear if there are
> other developers who feel the same way.
>
> What's wrong about content providers, you ask? Well, as the API docs
> put it, content providers are meant to "encapsulate data and provide
> it to applications through the single ContentResolver interface. A
> content provider is only required if you need to share data between
> multiple applications". So, content providers are meant to allow data
> sharing between applications, and as such they must perform some
> encapsulation over the data. The question is - to what degree are the
> content providers meant to abstract over the data representation &
> storage mechanism?
> This is important because it deeply affects the way the content
> providers API is designed, and thus on anyone writing or using content
> providers. And it doesn't seem to me that the API, as it's currently
> designed, makes a clear choice on this issue.
>
> On one hand, while most of the content providers rely on an SQLite DB
> for their data storage, the API does seem to be designed in an attempt
> to abstract over the SQL database. This has various implications, such
> as:
> 1. Not allowing natural usage of join queries, even in cases where it
> might make sense. The process performing the query is at the mercy of
> the implementor of the content provider - did she choose to allow for
> a specific join case or not? And of course, the implementor can only
> support joins in an ad-hoc way, e.g. by supplying content addresses
> which represent specific cases of joins, or by detecting columns which
> belong in different tables in the 'projection' argument and adding the
> respective table and adjusting the SQL query correspondingly.
> Naturally, not every reasonable usage can be accommodated for this
> way. (Personally, I've bumped into such limitations when trying to
> perform some non-trivial queries on Android's built-in contacts
> database).
> 2. Compiled SQL statements can't be used, reducing efficiency for
> repeating queries.
> 3. Some useful SQL constructs (e.g. SELECT DISTINCT) aren't
> accessible.
> 4. Only string placeholders are allowed.
> Direct access to the SQLite database would naturally make all these
> limitations void (IPC issues aside, for a moment). In general, putting
> the content provider in the accessing process' way to the data hurts
> both sides: The accessing process loses flexibility and efficiency and
> the content provider needs to perform various manipulations and
> parsing actions in order to generate a proper SQL query to hand the
> DB. And because the columns and table names are, by convention,
> visible as constants,  there is actually not much abstraction going on
> in most cases. Of course, we do gain inherent data sharing & lookup
> (courtesy of the ContentResolver), and we do want a content provider
> to validate all modifying operations, but the current API is simply a
> bit limiting.
>
> On the other hand, there seems to be an implicit assumption that all
> data sources are indeed backed by an SQL database (specifically, by
> SQLite). E.g., say we're implementing a non-SQLite-backed content
> provider. What shall we do with the 'selection' parameter of the
> query() method, which is effectively a WHERE clause? As far as I can
> see, our options are mainly:
> 1. Implement the WHERE parsing & filtering logic by ourselves - would
> require some work for us to reinvent the wheel.
> 2. Ignore the WHERE clause and instead perhaps give some REST-like
> URIs for some specific specialized queries we predict usage for - like
> is done i.e. in apps-for-android. This is fine, but obviously creates
> a less consistent & pleasant experience for developers using our
> content provider.
> 3. Apply the query (including the WHERE clause) on a temporary memory-
> backed SQLite DB built for this purpose. This would allow flexible
> queries, but would probably be an inefficient overkill on a mobile
> phone. Also, our data model might not fit the relational model so
> well.
> 4. Specify a different, simpler format for the 'selection' parameter.
> Easy to do, but inconsistent with the API and less nice for a
> developer using our content provider.
>
> The rest of the content provider API isn't particularly adequate for
> non-DB-backed content providers as well, i.e. the whole notion of
> 'columns' and 'projection' isn't necessarily relevant for a document-
> centric data store. I think there are many cases where we wouldn't
> want a content provider to rely on an SQLite DB - it might rely on a
> remote data source, an RDF triple store, some other storage mechanism
> which is optimized for some specific type of data, etc...
>
> Now, if we're building an SQLite-backed content provider, we can just
> hand the WHERE clause as-is to SQLite, but then a user-supplied
> parameter would rely on a specific table structure, negating much of
> the abstraction's power (if we change our data scheme in the future,
> we'll have to perform some preprocessing before handing the query to
> SQLite)... Additionally, our data scheme is pretty much exposed
> anyway, as we will (by convention and for convenient usage) define
> constants for the columns, and we're probably just taking the user's
> other query parameters (projection, selection arguments & sort order)
> and handing them more-or-less verbatim to SQLite as well. What then do
> we gain by limiting the developer using our content provider to the
> API of the ContentResolver's query() method, except data sharing &
> lookup? We can provide the missing features mentioned above and still
> maintain the same abstraction level.
>
> So, to summarize my view - the content providers API isn't designed in
> a way that makes a clear choice about the abstraction level. True SQL-
> bound content providers lose efficiency & convenience while exposing
> quite a bit of their data scheme, and non-SQL-bound content providers
> must bend to fit to the required API, which might result in an
> inconsistent usage experience for a developer accessing that content
> provider.
>
> I think this can be remedied in several ways, including:
>
> A. Offer a basic, generic content provider mechanism, where a specific
> content provider can implement one (or possibly more than one) of a
> few pre-defined interfaces - e.g. the two basic and most important
> interfaces would probably be one that is SQL-centric and one that is
> document-centric. In future versions of the platform, additional
> interfaces may be added - e.g. a triple-store centric one. This option
> introduces the developer to additional content provider interfaces to
> work against, but I think it's better than having a single content
> provider interface that is limited and behaves differently for
> different content providers.
>
> B. Enrich the content provider API in a way that allows efficient
> usage of SQLite, but allows non-SQLite-backed content providers to
> just ignore the extra methods / parameters (I don't think this is
> elegant, but it will work).
>
> C. Some other creative way that someone here would suggest :-)
>
> I hope there's some Google Android team member reading this... Anyone
> has thoughts about this?
>
> Itamar Rogel, Briox
> http://www.briox.com
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[EMAIL PROTECTED]
Announcing the new M5 SDK!
http://android-developers.blogspot.com/2008/02/android-sdk-m5-rc14-now-available.html
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to