Clear Sugar database table column records after every start - android

I have a listview with some name and url.. After my app starts I check if there is any record in my local database First clear my old records then fill table columns with listview data and if there isn't just insert data... this is how I'm doing it :
List<LocalProduct> allAuthors = LocalProduct.listAll(LocalProduct.class);
if (allAuthors == null) {
for (int allList=0;allList<adapter.getCount();allList++){
Product my = adapter.getItem(allList);
String offline_name = my.name.toString().trim();
String offline_url = my.image_url.toString().trim();
LocalProduct book = new LocalProduct(offline_name, offline_url);
book.save();
}
}else {
allAuthors.clear(); //I tried this
allAuthors.removeAll(allAuthors); //And this
for (int allList=0;allList<adapter.getCount();allList++){
Product my = adapter.getItem(allList);
String offline_name = my.name.toString().trim();
String offline_url = my.image_url.toString().trim();
LocalProduct book = new LocalProduct(offline_name, offline_url);
book.save();
}
}
But my table records are still storing same records after every start ..
What is the correct way !?

Insert this line before intialize LocalProduct class list:
SugarRecord.deleteAll(LocalProduct.class);
Example:
SugarRecord.deleteAll(LocalProduct.class);
List<LocalProduct> allAuthors = LocalProduct.listAll(LocalProduct.class);

clear() and removeAll() only remove item from List (which is in memory when loaded) not remove record in database.
If you want to clear record in database you need to use :
db.delete(TABLE_NAME, null, null);

Related

accessing sqlite database with each item in listview

I have a listview that show some items, each item contains attribute called category Id, this is attribute is related to one of my database taples
I need for each item to open database, make a query to get category object where id = item category id and then show data in the listview
it is very heavy to open database to read record by record
can anyone advice how to solve this problem without opening database many times?
Thanks
you can red the data base once. Get all data at the same time. then read the desired data from the returned array.
//returns data from DB
String[] array = getInfoDataBase();
//array example
array = ["id1", "name1", "data2","id2", "name2", "data2", ....]
for (int i = 0; i < array.length; i = i+3) {
if (array[i] == //desired id) {
//get your data from the array like name1, data1
break; // to stop the fro loop
}
}
You can use JOINS for this purpose.
SELECT * FROM item INNER JOIN category ON item.categoryId = category.id WHERE item.id in (id1, id2, id3)
You will have to replace (id1, id2, id3) with the item Ids in your table.

How to delete specific field using Objectify?

I'm trying to delete specific field from my DB table. But unfortunately unsuccessfully. I tried this code:
Query<Movie> query = ofy().load().type(Movie.class).filter("name =", "movie name");
QueryResultIterator<Movie> queryIterator = query.iterator();
while (queryIterator.hasNext()){
Movie m = queryIterator.next();
if(p.getYear()!= null){
ofy().delete().entity(p.getYear()).now();
}
}
I also tried this:
Movie m = ofy().load().type(Movie.class).id("movie id").now();
List<Long> actors = m.getActor();
ofy().delete().entity(actors).now();
But it also didn't work.
What did i miss?
You need to set the property to delete to null and then save the entity. A delete will delete the whole entity, not any single property.
Example:
Movie m = ofy().load().type(Movie.class).id("movie id").now();
m.actors = null;
ofy().save().entity(m).now();

Parse - Empty Table Checking

How to check if table is empty using parse , I'm having a problem with the code below :
private String[] getMaxDateMessage() throws ParseException {
final String[] msgData = new String[3];
ParseObject ob = null;
String[] userIds = {currentUserId, recipientId};
ParseQuery<ParseObject> query = ParseQuery.getQuery("ParseMessage");
query.whereContainedIn("senderId", Arrays.asList(userIds));
query.whereContainedIn("recipientId", Arrays.asList(userIds));
query.orderByDescending("createdAt");
if(query.hasCachedResult())
{
ob = query.getFirst();
if (ob.isDataAvailable()) {
//for (int i = 0; i < 1; i++) {
//createdDate[0] = messageList.get(i).get("createdAt").toString();
msgData[0] = ob.getCreatedAt().toString();
msgData[1] = ob.get("senderId").toString();
msgData[2] = ob.get("recipientId").toString();
// }
}
}
The thing is that the table is empty , so the query should return null , but no exception is been throwed , it just crashes the app .
So how can I check if the table is empty before trying to fetch any data ?
Update : The solution that I have found is to use query.count().
If the count returns a value that is not 0 then the table is not empty .
Using query.count() to determine if the table is empty is not an optimal solution. While this is perfectly fine when actually run against an empty table, using query.count() will almost always result in a sub-optimal query when there's more than one object in the table. The reason for this is quite clear: you only care about the first object matched by this query, yet a query.count() will scan the whole table in order to return the total of objects that match your query.
Therefore, the ideal solution is to simply use query.getFirst() and check if you get any results. You should be able to handle the case where ob is not a ParseObject, e.g. the collection is either empty or no objects match your query.

Android SQLite: How to generate big table for testing purpose?

I am testing the capabilities of the device -- to show the customer the size of data that can be stored inside the device, how fast it can be retrieved, how fast the search works, etc.
I am using my content provider to access the product database table with few columns. I have already moved the code to the content provider to avoid the extra communication when inserting the test records. The following code is called via menu from an activity to fill the table with the test content
Uri uri = Uri.parse(DemoContentProvider.PRODUCTS_CONTENT_URI + "/insertdemo");
getContentResolver().insert(uri, null);
The URI is recognized in the .insert method of the content provider and the following private method (of the same content provider) is called to fill the table (notice the 100 thousands of items):
private void insertDemoProducts() {
for (int i = 1; i <= 100000; ++i) {
String id = Integer.toString(i);
insertProduct(id, "Test product " + id, "100", "75.50", "70.27");
}
}
The inner insertProduct() looks like that:
private void insertProduct(String code, String name, String stock,
String price, String listprice) {
SQLiteDatabase sqlDB = database.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(ProductTable.COLUMN_CODE, code);
values.put(ProductTable.COLUMN_NAME, name);
values.put(ProductTable.COLUMN_STOCK, stock);
values.put(ProductTable.COLUMN_PRICE, price);
values.put(ProductTable.COLUMN_LISTPRICE, listprice);
sqlDB.insert(ProductTable.TABLE_PRODUCT, null, values);
}
It works, but it takes "forever". How can I make it faster? What is the fastest method you know to fill the table?
Just some numbers to consider: 1000 items takes about 20 seconds to be created.
You need to use transactions when writing to a sqlite-database, otherwise it will persist the data for every insert i.e save it to sd which will take "forever".
for instance, make insertProduct take a list of products and save them in one transaction:
private void insertProducts(List<Product> products) {
try {
db.beginTransaction();
for(Product product : products) {
insertProduct(...);
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
This is how you can implement it in your existing code:
private void insertDemoProducts() {
SQLiteDatabase sqlDB = database.getWritableDatabase();
try {
sqlDB.beginTransaction();
for (int i = 1; i <= 100000; ++i) {
String id = Integer.toString(i);
insertProduct(id, "Test product " + id, "100", "75.50", "70.27");
}
sqlDB.setTransactionSuccessful();
} finally {
sqlDB.endTransaction();
}
}
Anyway, I am not completely satisfied with the accepted question because I do not understand the reason why adding the transaction makes it faster.
Looking at the Android sources, I have found that the sqlDB.insert(...) calls insertWithOnConflict(...) and that one construct the string for the SQL command using the StringBuilder class (with questionmarks as placeholders for the inserted values). Only then the string is passed to the SQLiteStatement constructor together with array of the inserted values. This means that string with the SQL command is being built again and again.
Further, a string representation of an SQL command template can be precompiled thus avoiding also the repeated compilation of the command. Then .bindXxx and .execute methods can be used for inserting the wanted records into the table. When put together, I did use the followig code (iside the outer transaction as Dean suggested):
StringBuilder sql = new StringBuilder();
sql.append("INSERT INTO ");
sql.append(ProductTable.TABLENAME);
sql.append("(");
sql.append(ProductTable.COLUMN_CODE);
sql.append(",");
sql.append(ProductTable.COLUMN_NAME);
sql.append(",");
sql.append(ProductTable.COLUMN_STOCK);
sql.append(",");
sql.append(ProductTable.COLUMN_PRICE);
sql.append(",");
sql.append(ProductTable.COLUMN_LISTPRICE);
sql.append(") VALUES (?, ?, 100, 75.50, 70.27)");
SQLiteStatement insert = sqldb.compileStatement(sql.toString());
for (int i = 1; i <= 300000; ++i) {
insert.bindLong(1, i);
insert.bindString(2, "Test product " + i);
insert.execute();
}
When compared with adding the transaction only, the result is about 3-times faster. The 300 thousands records were inserted in about 3 minutes and 15 seconds on Nexus 7.

Android: having basic problems with sqlite database

I am having some trouble implementing a sqlite database in my simple android application:
a user is displayed a list of animals in a Listview.Upon selecting an animal the user is brought to an activity "Animal",which will display a picture of the animal and give them options to
view Animal Bio
Back
All very simple so far, right?
I have working the database, which will populate the listView of animals.Database currently looks like
Table Animal-
_ID,
Name
Table Biography-
_ID,
Bio
This is where I would welcome any helpful advice on my problem, or on how to improve my implementation.
Currently populating the DB as follows
long populateDB(){
String[] animalName = {"Lion" "Zebra", "Tiger", "Gorilla",...};
String[] animalBios = {"Found in the "...}
ContentValues animalNameVals = new ContentValues();
ContentValues animalBioVals = new ContentValues();
long[] rowIds = new long[animalName.length];
// Populate the animal table
for(int i = 0; i < animalName.length; i++){
animalNameVals.put(KEY_ANIMALNAME, animalName[i]);
rowIds[i] = db.insert(ANIMAL_TABLE, null, animalNameVals);
}
// Populate the Bio table
for(int j = 0; j < bios.length; j++){
animalBioVals.put(KEY_BIO, bios[j]);
rowIds[j] = db.insert(BIOS_TABLE, null, animalBioVals);
}
return rowIds[0];
}
And had planned on being able to tell database which animal on list was selected by passing extras with the intent, eg if position on listItemClick == 1, pass in tiger and retrieve tiger bio from db.
Problems:
Then on the Animal activity page is getExtra() == tiger, telling the activity that tiger was selected from the list and to load this bio from the DB..well, I cannot see an efficient method of implementation for this idea and am struggling to do so.
My second headache comes from adding the bio to the application from the Db.Originally I had a test bio hardcoded in a string, shown in a TextView.Is there a way to retrieve a string from a cursor and add it to the TextView id?I understand I will need some adapter, what I do not understand is why cant it be as simple as setResource(R.id.bio) = bio.
Thanks you for reading and any help is much appriciated.
First problem: First of all, I'm not sure why you don't have the column Bio in the Animal-table? As no Bio would fit to any other animal than itself, you can safely do this. By doing this you can query the database upon selection and pass the entire object (including name of animal and bio) to the next Activity and use this to get your information. If this was somewhat unclear, let me know and I'll try to explain it better.
Second problem: You can get values from tables (there of also Strings) using a Cursor. To get the String you can do something like this where cursor is the Cursor with your result from the database:
String bio;
// Move Cursor to its first element
if(cursor.moveToFirst()) {
// Make sure the cursor is not null
if(cursor != null) {
bio = cursor.getString(cursor.getColumnIndex("Bio")));
}
}
Sidenote: If I read the code correctly, it seems that you use long for ID's? The usual thing to go about ID's is integers as far as I know.

Categories

Resources