Not sure of the absolute utility of this but seems as though it should be possible and useful.
Can you extend ContentProvider to provide URIs representing new queries (i.e., joins across multiple tables not specified by existing URIs) for an existing system database?
The alternative seems to be that I need to write a series of cursor queries then join them -- seems like a lot of unnecessary code duplication.
I have been trying this for the contacts database as an exercise, but no love so far.
The crux seems to be that I cannot open a database in another package during the setup phase.
Am I just completely out in left field here?
It's possible as I am new to both Java and Android.
Comments and/or pointers to relevant resources are appreciated.
Thanks,
Steve
Can you extend ContentProvider to
provide URIs representing new queries
(i.e., joins across multiple tables
not specified by existing URIs) for an
existing system database?
Not really, only because you don't have direct access to existing system databases, in terms of SQLite. Now, creating a ContentProvider that performs your joins for you, as a reusability measure, is certainly doable, though I would get worried about the performance overhead of multiple cross-process hops.
Related
I am doing application for learning words in foreign language, so I have this words stored in my database. These words are separated for example into 3 levels of difficulty. Every level is made of some groups of words, these groups introduces TABLES of SQLite db. I am using SQLiteOpenHelper as communication between application and databases.
Now my question. What is better?
Make 3 smaller databases, each for every level and use own
SQLiteOpenHelper, so together 3 dbs with 3 open helpers.
Make 1 large database, where will be that 3 levels, which means
many TABLES, but just only 1 SQLiteOpenHelper.
Thanks for any advice or opininon.
I suggest 1 large database (DB).
You should not be worried about making large DBs, DBs are invented to store a large amount of data (and even many-many tables). It is much easier to create and maintain one DB than multiple ones and your code will be much clearer using one DB.
And I don't know your program, but I would go even further: I would rather store all words in the same table if you store the same information of them, and add a column to show the level and another one to show the group which they belong to.
The main idea of SQL is that you don't really care how much space your DB will require and how much time it gonna take to find the result of a query because DataBase Managent Systems (in your case the SQLiteOpenHelper and SQLite) are insanely efficient considering space and time. Instead you should rather concentrate on designing a system that can be expanded easily (for example if you want to add another column to tables containing words (e.g. you want to store a new information about words) or want to add new levels or groups in a later stage of development) and has clear structure. You might lose a few milliseconds separating groups and levels via the SELECT command of SQL, but your DB will be much more flexible - you can add levels and groups and add more information about words with ease. The key of desinging a good DB: You should store different kind of data in different tables and same kind of data in same table...
The error that you mention in your comment is almost certainly a bug in your application code. There is no reason that an application with multiple databases should encounter that sort of error.
That said, my answer to your original question is that it is objectively "better" to use a single database.
It is better because you will have less code to maintain, no possibility of attempting to access the wrong database in a given situation, and the code will be more idiomatic - i.e. there's no benefit to using multiple databases, so if you were to use multiple databases, anyone reading your code would spend a lot of time trying to figure out why you did it.
I have a SQLite database which has a table (of course) named Object. In my application, I need to access that table and all of its fields. I am able to query the database and get all of the information I want from a cursor with no issues. The problem comes with deciding what to do with the cursor next. Right now I am thinking of creating a class called Object and it will have fields for every column in the table which will be set by the query. This just seems so... inefficient. I'm not sure how to do this without needing to write out every column that is in the table for the object to use, which seems to violate DRY. Are there any better ways to do this?
My end goal is to be able to access every row in the table and get whatever information I want for that row. For example I will be using this to populate a ListView. If this is too ambiguous let me know and I'll try to clarify.
Thanks!
Edit: I've found the library db40 and it seems to do what I want. The library seems to be kind of big though (40 mb) for a mobile application. Does anybody have experience with this? Everything I've read seems to indicate it is good. I'll post more if I find information.
Are there any better ways to do this?
This is very "wide" question and depends on personal requirements and what is for developer more comfortable. I'm using your idea that is for me the best one you can use.
Generally we can say you want to create ORM (object-relation mapping). It's very clean and efficient approach (my opinion). Of course sometimes is not the best solution to use ORM ( i never met with this case but heard about it). I almost always use my own defined ORM for sure it takes some time but results are significant against done frameworks.
Both have advantages and disadvantages. Own ORM has much more higher performance because it's designated and optimized for concrete solution (mainly queries etc.).
I suggest you to do what you mentioned -> create object that will represent table in database with properties equal to columns. I'm using this in work and we never had problems with performance or too much battery consumption with our applications.
It's also much more safe if you'll show user some data not directly from database but "copies" in objects. Users can do whatever want with dislayed results (they can add some dangerous symbols and hacks) but now you can easily check this before you'll want to update database(s) with changes.
Your source-code looks good, another developer won't be lost in your code, everything will be clear and easy to do updates for future.
I provided you "my opinion" on this thing so hope it'll help you with make a decision.
I want to share data across multiple applications, instead of having a ContentResolver->ContentProvider mechanism, I can just define a client library which talks to the process which does the SQLite DB operations right?
What does the ContentProvider brings in here which we cannot achieve by having a Process expose the data?
You can find answer Exact Difference between “Content-Provider” and “SQLite Database”.
But I like to explain this..
What does the ContentProvider brings in here which we cannot achieve by have a Process expose the data?
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.
Also It's good practice to provide the extra level of abstraction over your data to make it easier to change internally. What if you decide to change the underlying database structure at a later time? If you use a ContentProvider you can contain all the structural changes within it, where as if you don't use one, you are forced to change all areas of the code that are affected by the structural changes. Besides, it's nice to be able to re-use the same standard API for accessing data rather than littering your code with low-level access to the database.
You can check the thread below:
Exact Difference between "Content-Provider" and "SQLite Database"
This is my first time trying to work with a database, so bear with me.
I need to write a program that will use a database that I do not have access to yet. I know there is MySQL, SQLite, and a bunch of other SQL things, but I'm not sure what the difference between them is. Do I need to know what kind of database it is before I can use it (i.e., is a MySQL .db file different from a SQLite .db file?), or is the file itself going to be the same and the difference is how it is accessed?
EDIT: I am programming for an Android tablet, that probably matters. But I will not be creating the database, it will be given to me and I have to work with it.
You might want to run through a view tutorials creating a MySQL database, and a SQLite instance to see how they work and how you can easily interact with them.
The access to each involves adapters, notwithstanding creating the tables you'll need, the user access (username / password / role to access the table).
Here's a straight-forward sqlite tutorial:
http://zetcode.com/db/sqlite/
https://zetcode.com/php/mysqli/
http://zetcode.com/php/pdo/
Here's a staight-forward sql with C# tutorial:
https://zetcode.com/csharp/mysql/
I remember being overwhelmed with databases my first time. My advice is to start with something well-supported, with a nice community, and search results a-plenty of tutorials, where you can grasp the fundamentals.
Then, based on your application requirements, and platform constraints, you can determine where to pivot. But reviewing the differences between databases without actually having worked with them is like trying pieces of sushi without ever eating fish.
EDIT:
If you're building on Android, yep, learn SQLite.
I highly recommend this tutorial to help you see SQLite used in an Android project:
https://developer.android.com/training/data-storage/sqlite
For data abstraction / ORM, you should familiarize yourself with Content Providers and Cursors (http://developer.android.com/guide/topics/providers/content-providers.html)
Good Querying!
First off, you'll need to know what type of database it is before you can connect to it as you'll need to use the appropriate database driver for your platform. mySQL, Oracle, Postgres, SQL Server, etc will all use different drivers as the binary protocol used to talk to them (authenticate and transfer information back and forth) is different.
As far as your actual SQL code, it depends. For the most part, you can count on SELECT * FROM Foo working with any SQL compliant database on the planet. However, once you start doing anything more complicated or using non-standard keywords, you might run into trouble. For example, some databases support the USING keyword for JOINs and some don't.
One thing you might look into is an ORM. This will allow you to abstract the actual SQL dialect from your program and then (for the most part) not have to worry about the actual SQL. Some popular ORMs are ActiveRecord (for Ruby on Rails) and Entity Framework for .NET. Hope this helps!
UPDATE:
Since the Android tag was just added to the post, I did a quick search for SqlLite ORMs that support Android and came up with this. Maybe worth checking into, or perhaps someone can comment on whether it's any good :)
Database Abstraction Layer is the strategy of having a smart middleman so you can program without knowing exactly which database system you have underneath. Database Abstraction isn't as utopian in practice as it sounds, and most people end up programming directly for a particular database. You will likely find that the more experience you get with your database of choice, the more you wish you knew its particular nuances better. So the short answer is there is enough difference to matter!
If you use a software architectural pattern like Model-View-Controller, it can enable you to do a lot of your programming irrespective of the database you use. Taking Model-View-Controller as an example, you could program your Controllers and your Views without knowing what database you are using.
The limitation to what you can do before deciding on a database system is the inconvenient fact that good programming practice calls for fat Models and skinny Controllers. So a big part of your actual programming effort is held hostage by your choice of a database solution.
If I didn't know what database would be used, I would start programming my View and then my Controller. If PHP is your language, you may find a CodeIgniter tutorial enlightening.
An article about "Appropriate Uses For SQLite"
http://www.sqlite.org/whentouse.html
Summary:Checklist For Choosing The Right Database Engine
Is the data separated from the application by a network? → choose client/server
Many concurrent writers? → choose client/server
Big data? → choose client/server
Otherwise → choose SQLite!
I'm a bit confused in the question, if it's better to use ContentProvider or Database. Or it makes no difference if I don't want to share any data with other applications.
If I've understood it right, content providers based on SQLite DBs and it's also possible that content of them is only accessable for my application.
Can you give some explanations?
Thank you very much,
Mur
There certainly are worthwhile problems for which a provider is a solution, particularly for cross-app data publishing. For example, you need to use a content provider to supply search suggestions to a Quick Search Box.
However, for internal use within an application, I am not a fan. The benefits IMHO are outweighed by the costs (e.g., reduced flexibility, additional overhead).
If you do implement a content provider, bear in mind that they are accessible by other applications by default. You need to include android:exported="false" in the <provider> element to make them private to your app.
Using a content provider will give you a more modular design, and make your life easier if you at some point in future would like to reach the data from other applications.
If you are certain that the data will only ever be needed from one application, you might as well operate directly on the database.
There is one particular SQLite limitation you should be aware of and that is that SQLite is single-user only. What this really means is that you will need to guard your database from being accessed from multiple threads at the same time. This is generally not a problem in a content provider, since they almost always have a single-threaded implementation.
Reasons to use content provider are here.
In summary:
Easily change the underlying data source (you can change your db from Sqlite to Mongo or to a JSON file without any app changes)
Leverage functionality of some Android Classes (SyncAdapter, Loaders, CursorAdapter) - These classes require content provider and you cant use them if you dont have one
Allow many apps to access, use and modify a single data securely. (which is really the main reason for using it)