I have a widget that currently takes a random string from an array and sets it to text view on update. The issue here is that the same item can be re-used multiple times in a row due to the string being 'random'
In order to solve this I was going to create a table that held String text, and int viewednum and increment the viewed number each time 'get text' was called. (on update in the widget).
My Question: If I put the insert statements in the widget, won't the data be inserted every time 'on update' is called?
Would it be better for it to go in the DBadapter class somewhere? I'm just unsure about the best way to make sure I don't enter duplicate data. If there is a better alternative like saving a csv file somewhere and using that I'm open to it, it seemed like a sqlite database was the way to go.
Thank you for your time.
That depends on what your onUpdate method does. If each time onUpdate is called it gets a random String from the database, then that would be the place to put it. However, if you are not getting the String during onUpdate, then you should put it in the method where you are accessing your database. I think your confusion is about the purpose of onUpdate. onUpdate doesn't get called every time the user scrolls by the homepage and sees your widget; it gets called regularly on a timescale you specify, and the whole purpose of it is, in a case like yours, to get a new String from the database.
As for your second question, yes, SQlite databases are the way to do it :) I haven't tried saving a csv file or something like that, but I imagine that would be a lot more complex than just using a database.
Declare your database with a UNIQUE constraint on the columns you want to keep unique, then set the desired behaviour via ON CONFLICT in the INSERT statement. ON CONFLICT REPLACE... means the most recent INSERT overwrites. ON CONFLICT IGNORE... keeps the older version.
Related
Suppose, In my app I have a sqlite table that can contain at most 20 row. Each row has 2 column(id, name). Where I frequently need to search by Id to get Name. For this frequent need I have two solution:
Solution 1: Get rows in a arraylist<model> and then find name from array.
Solution 2: Every time search on sqlite table.
Now please give your opinion which one is better?
Remember again, I need this search in my recycleView item, so it call so frequently.
Thanks
I don't really get what is your real intent, but if your task is to search by id often, I would use
LongSparseArray<String> idsToNames; // or LongSparseArray<Model>
Which will map primitive long to Strings in a more memory-efficient way than Map and will have a better performance than ArrayList when searching.
The advantage over querying SQLite here is that you can do it in a blocking manner instead of having to query database on a background thread every time the lookup runs.
The disadvantage is that whenever data changes in SQLite, you will have to rebuild your idsToNames map. Also, if the number of entries in SQLite will eventually grow, you will end up in a large collection. So I would recommend this approach only if the updates to the database during this session will not happen, and if the data size is always predictable or fixed.
I have two tables, SyncedComments and QueuedComments, the latter holds local comments until they are synced with a webserver, when they are synced succesfully they get placed in the synced table, my application should be indifferent to each type. I load in the comments through a CursorLoader, and they may be moved to the synced table while users are reading them. Let's say the user can also edit comments, perhaps while they are being moved, so the application should know where the comment is, regardless of it's table.
To support this, I've thought of having a table with 3 columns, local_id, synced_id and queued_id, the local_id is persistent and simply serves as a reference to either one of the two other id's. When a comment is created a new row is inserted with it's sync_id set to NULL and the queue id it's been given, when a comment is moved then the queue_id is set to NULL and the sync_id is set. This way my application only needs to reference the local id at all times.
How does this solution look? Any flaws? Could it be done smarter?
I would in the first place put all the comments in one table, with flag for whether the comment is synchronized (actually it would probably be ID on server, set to NULL until synchronized and the value obtained from server afterwards). That will take you down to 1 table instead of 3, make it easier to show all comments (because you won't need to do union) and above all avoid problems when the comment is synchronized while being shown, because the comment will not be moving anywhere. And it does less writes to the database file, so it causes less fragmentation and fewer writes to the flash device.
I currently successfully use a SQLite database which is populated with data from the web. I create an array of values and add these as a row to the database.
Currently to update the database, on starting the activity I clear the database and repopulate it using the data from the web.
Is there an easy method to do one of the following?
A: Only update a row in the table if data has changed (I'm not sure how I could do this unless there was a consistent primary key - what would happen is a new row would be added with the changed data, however there would be no way to know which of the old rows to remove)
B: get all of the rows of data from the web, then empty and fill the database in one go rather than after getting each row
I hope this makes sense. I can provide my code but I don't think it's especially useful for this example.
Context:
On starting the activity, the database is scanned to retrieve values for a different task. However, this takes longer than it needs to because the database is emptied and refilled slowly. Therefore the task can only complete when the database is fully repopulated.
In an ideal world, the database would be scanned and values used for the task, and that database would only be replaced when the complete set of updated data is available.
Your main concern with approach (b) - clearing out all data and slowly repopulating - seems to be that any query between the empty and completion of the refill would need to be refused.
You could simply put the empty/repopulate process in a transaction. Thereby the database will always have data to offer for reading.
Alternatively, if that's not a viable solution, how about appending newer results to the existing ones, but inserted as with an 'active' key set to 0. Then, once the process of adding entries is complete, use a transaction to find and remove currently active entries, and (in the same transaction) update the inactive entries to active.
I have an application that uses a pre-polulated database to list events. The app allows people to save these events to their favorites by setting a '1' to the column isFavorite. Then the user can view only a list of 'favorited' events which searches for all rows that have isFavorite = 1.
If any changes happen to the events or I need to add more to the list, I have to make those changes and then push the update to the app which completely writes over the table, clearing out their favorites.
Is there any way that I can, on upgrade, save a list of id's of all the events that they have set to their favorites, then after the new database has been loaded, to set all id's in that list to 1 so the user doesn't lose their favorited data?
If there are any other better solutions to this problem I would really appreciate it, this has been the biggest hurdle for me so far.
I guess, you have a SQLiteOpenHelper-class? This class must be extended and then provides two functions: onCreate (which is called when the Database is queried and it doesn't exist (Normally creates your Database in the first place)) and onUpdate (which is queried when the Database structure should be updated).
The onUpdate-method has an SQLiteDatabase-Object parameter, which is your Database. You can then Query the information you need, save them and then create the new Database-tables. After that, you can insert your saved data back into the Database.
Can't you cope with thus in your DB design? Have a user favourites table that holds id's. So long as these id's don't change upgrade won't affect it surely?
One possible solution is backing up part or all of your database to restore at a later time. I found this guide quite handy http://www.screaming-penguin.com/node/7749
Alternatively, you may save their favorites as a SharedPreferences. http://developer.android.com/reference/android/content/SharedPreferences.html for more information on that.
So my fundamentals of creating and manipulating databases are a bit messed up. My aim here is that whenever the app is launched, the user is allowed to specify a table name, and whatever data is then collected is put into that table.
However, I'm confused as to how to do this. Do I simply pass the value of a user entered variable as the table name in my contentprovider class and execute sqlite statements to create it?
I've read/reading the documentation already, so if anyone has any insight or clarity, or even better, code snippets, it would be great.
Why not simply use one table, and create a value that stands for the current app-session, and insert that value with each row. This would make your code simpler, and would still allow you to segregate/filter out the values from a particular app-session. If you want to give the user the ability to enter the value (as you are giving them the ability to choose the table name) you'd just want to check to see if that value had already been used, just as you would have to see if the table-name had already been used.