How to retrieve data from all pages? - android

I want to get some data from all users in Users table. I've found that I have to use Data paging. I've written the same code as described in Feature 47->https://backendless.com/feature-47-loading-data-objects-from-server-with-sorting/ (because I also
have to sort) , but then I've figured out that this code takes data only from first page. Then , I decided that I have to go to the next page and read it , until its size is not equal to zero. Below,you can see my wrong solution:
QueryOptions queryOptions = new QueryOptions();
List<String> list = new ArrayList<String>() ;
list.add("point DESC") ;
queryOptions.setSortBy(list);
BackendlessDataQuery backendlessDataQuery = new BackendlessDataQuery();
backendlessDataQuery.setQueryOptions(queryOptions);
Backendless.Data.of(BackendlessUser.class).find(backendlessDataQuery, new AsyncCallback<BackendlessCollection<BackendlessUser>>() {
#Override
public void handleResponse(BackendlessCollection<BackendlessUser> one) {
while(one.getCurrentPage().size()>0) {
Iterator<BackendlessUser> it = one.getCurrentPage().iterator();
while (it.hasNext()) {
//something here,not so important
}
one.nextPage(this);// here I want to get next page,
//but seems like it does not work, cause my loop became infinite
}
}
I think that I have to use nextPage method with AsyncCallback instead of one.nextPage(this) , but if I do so , the method couldn't keep up with the loop. So, how can I solve my problem?

I actually can't find the problem with your solution, but I solved this problem using:
int tot = response.getTotalObjects()
to get the total number of objects at the first response. Then use a loop until your list of objects has size = tot. In each loop you make a query setting the offset equals to the current size of the list.

Related

Unable to fetch the first entry in SQLlite Database using cursors in android

I am trying to fetch all the entries in a database table using SQLite. I ran a query, stored the values in a cursor and then via a loop I fetched all the values. However I can access all the entries except for the first one. Here is my code :
mydb1=new Database_CustomTransaction(getApplicationContext());
Cursor c12 = mydb1.executeQuery("Select * from table1");
System.out.println(c12);
if(c12 == null)
{
TextView nodataView = new TextView(this);
nodataView.setId(20);
nodataView.setText("No Data here !");
nodataView.setTextSize(20);
}
else
{
if(flagValue == false)
{
c12.moveToFirst();
flagValue = true;
}
while(c12.moveToNext())
{
type=c12.getString(0);
amount = c12.getInt(1);
spentOn = c12.getString(2);
date = c12.getString(3);
listType.add(i,type);
listSpentOn.add(i,spentOn);
listAmount.add(i,amount);
listDate.add(i,date);
i++;
}
}
latesttrans2.setAdapter(new TestAdapter2(this, listType, listSpentOn,listAmount,listDate));
Any ideas what I am doing wrong ?
c12.moveToFirst();
This moves to the first row.
while(c12.moveToNext())
This moves to the next row after the first row.
I would guess that the first call should be just dropped, but only you know what you intended with flagValue.
Use do while instead of using just while.I think it is skipping the first entry and straight away moving to next entry.

Parse sees only first element from array in Android

I am using Parse.com as my backend, and I want to download data from server. I have tags which filter these data. Unfortunately it works wrong. Lets say I have two tags "city1" and "city2", now I only get data for "city1".
public ArrayList<Dataset> getDatasetFromServer(Context context) {
ParseQuery<ParseObject> query = ParseQuery.getQuery("Dataset");
List<String> cities = DatabaseAdapter.getCityNames(context);
//cities list contains "city1" and "city2"
query.whereContainedIn("cities", Arrays.asList(cities.toArray(new String[cities.size()])));
ArrayList<Dataset> dataset = new ArrayList<>();
try {
List<ParseObject> parseDataset = query.find();
dataset = setDatasetList(parseDataset);
} catch (ParseException e) {
e.printStackTrace();
}
return dataset;
}
The problem is with this : Arrays.asList(cities.toArray(new String[cities.size()]).
Don't know why, but this convertion works wrong with Parse.
However, if I change above line to this
String[] array = {"city1", "city2"};
query.whereContainedIn("cities", Arrays.asList(array));
Everything works fine and I get data for city1 and city2.
My question is, what's the difference between these two solutions and how to fix this so the first solution works?
EDIT :
This also doesn't work :
query.whereContainedIn("cities", DatabaseAdapter.getCityNames(context));
getCityNames returns List<String>
Instead of converting your list to an array and then back to a list, just do this:
query.whereContainedIn("cities", cities);
The problem was my fault. Both solutions work good.
The reason it didn't worked was that my method
DatabaseAdapter.getCityNames(context) put a whitespace on the beggining of second element which I didn't saw.

OrmLite: Advanced where logic

I have these tables in an Android based application where I'm using OrmLite for the database management.
What I want to have an x number of array list depending on how many of the product type FOLDER I have.
So in this case I want to a list of products where the productId equals parentId.
So I want a list where
if(productType = FOLDER) {
if(productId = parentId){
//add product
}
}
Basically what I want to end up with, in this case three lists with each containing a list of products where parentId is the same for every product.
I've tried many things, and some works better than others, but a code I want to run actually throws a nullpointer.
DatabaseHelper dbHelper = getHelper();
List<Product> productsParents = null;
try {
Dao<Product, Integer> dao = dbHelper.getDao();
PreparedQuery<Product> prepQu = dao.queryBuilder().where()
.eq("parentId", dao.queryBuilder().selectColumns("productId").where()
.eq("productType", ProductType.FOLDER).prepare()).prepare();
productsParents = dao.query(prepQu);
} catch (SQLException e) {
...
}
This code isn't working because productParents returns null, and it does not do what I want, even though it's a slight hint. If someone know how to do this in code that would be sufficient also, or more likely a mix of java and ormlite.
Have you had a chance to RTFM around building queries? The ORMLite docs are pretty extensive:
http://ormlite.com/docs/query-builder
Your problem is that a prepared query cannot be an argument to the eq(...) method. Not sure where you saw an example of that form.
So there are a couple ways you can do this. The easiest way is to do a different query for each productType:
Where<Product, Integer> where = dao.queryBuilder().where();
where.eq("parentId", parentId).and().eq("productType", ProductType.FOLDER);
productsParents = where.query();
// then do another similar query again with ProductType.PRODUCT, ...
If you want to do just one query then you can get all products that match the parentId and then separate them using code:
Where<Product, Integer> where = dao.queryBuilder().where();
where.eq("parentId", parentId);
productsParents = where.query();
List<Product> productFolders = new ArrayList<Product>();
List<Product> productProducts = new ArrayList<Product>();
...
for (Product product : productsParents) {
if (product.getProductType() == ProductType.FOLDER) {
productFolders.add(product);
} else if (product.getProductType() == ProductType.PRODUCT) {
productProducts.add(product);
} else ...
}

How to check if an Array contains specific term - Android

I currently have a statement which reads
if(Arrays.asList(results).contains("Word"));
and I want to add at least several more terms to the .contains parameter however I am under the impression that it is bad programming practice to have a large number of terms on one line..
My question is, is there a more suitable way to store all the values I want to have in the .contains parameters?
Thanks
You can use intersection of two lists:
String[] terms = {"Word", "Foo", "Bar"};
List<String> resultList = Arrays.asList(results);
resultList.retainAll(Arrays.asList(terms))
if(resultList.size() > 0)
{
/// Do something
}
To improve performance though, it's better to use the intersection of two HashSets:
String[] terms = {"Word", "Foo", "Bar"};
Set<String> termSet = new HashSet<String>(Arrays.asList(terms));
Set<String> resultsSet = new HashSet<String>(Arrays.asList(results));
resultsSet.retainAll(termSet);
if(resultsSet.size() > 0)
{
/// Do something
}
As a side note, the above code checks whether ANY of the terms appear in results. To check that ALL the terms appear in results, you simply make sure the intersection is the same size as your term list:
resultsSet.retainAll(termSet);
if(resultSet.size() == termSet.size())
You can utilize Android's java.util.Collections
class to help you with this. In particular, disjoint will be useful:
Returns whether the specified collections have no elements in common.
Here's a code sample that should get you started.
In your Activity or wherever you are checking to see if your results contain a word that you are looking for:
String[] results = {"dog", "cat"};
String[] wordsWeAreLookingFor = {"foo", "dog"};
boolean foundWordInResults = this.checkIfArrayContainsAnyStringsInAnotherArray(results, wordsWeAreLookingFor);
Log.d("MyActivity", "foundWordInResults:" + foundWordInResults);
Also in your the same class, or perhaps a utility class:
private boolean checkIfArrayContainsAnyStringsInAnotherArray(String[] results, String[] wordsWeAreLookingFor) {
List<String> resultsList = Arrays.asList(results);
List<String> wordsWeAreLookingForList = Arrays.asList(wordsWeAreLookingFor);
return !Collections.disjoint(resultsList, wordsWeAreLookingForList);
}
Note that this particular code sample will have contain true in foundWordInResults since "dog" is in both results and wordsWeAreLookingFor.
Why don't you just store your results in a HashSet? With a HashSet, you can benefit from hashing of the keys, and it will make your assertion much faster.
Arrays.asList(results).contains("Word") creates a temporary List object each time just to do linear search, it is not efficient use of memory and it's slow.
There's HashSet.containsAll(Collection collection) method you can use to do what you want, but again, it's not efficient use of memory if you want to create a temporary List of the parameters just to do an assertion.
I suggest the following:
HashSet hashSet = ....
public assertSomething(String[] params) {
for(String s : params) {
if(hashSet.contains(s)) {
// do something
break;
}
}
}

How to efficiently manage search suggestion using Android QSB?

I try to make a dictionary using Quick Search Box in Android. As shown in the SearchableDictionary tutorial, it loads all (999 definitions)data and uses them as matches to the input text to get the search suggestion. in my case, I have 26963 rows of data that need to be suggest while user input a word on QSB. therefore, I want to grab the char data one by one from the QSB, so that it will be efficiently load necessary suggestion. how can i do this?
here's the code i use...
bringit(200);
if (Intent.ACTION_VIEW.equals(intent.getAction())) {
// from click on search results
//Dictionary.getInstance().ensureLoaded(getResources());
String word = intent.getDataString();
//if(word.length() > 3){bringit(10);}
Dictionary.Word theWord = Dictionary.getMatches(word).get(0);
launchWord(theWord);
finish();
} else if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
//SearchManager.
//String bb =
mTextView.setText(getString(R.string.search_results, query));
WordAdapter wordAdapter = new WordAdapter(Dictionary.getMatches(query));
//letsCount(query);
mList.setAdapter(wordAdapter);
mList.setOnItemClickListener(wordAdapter);
}
Log.d("dict", intent.toString());
if (intent.getExtras() != null) {
Log.d("dict", intent.getExtras().keySet().toString());
}
}
private void letsCount(String query) {
// TODO Auto-generated method stub
for(int i=0; i<query.length(); i++){
definite[i] = query.charAt(i);
}
}
public void bringit(int sum) {
// TODO Auto-generated method stub
String[] ss = new String[10];
Log.d("dict", "loading words");
for(int i=1; i<=sum; i++){
KamusDbAdapter a = new KamusDbAdapter(getApplicationContext());
a.open();
Cursor x = a.quick(String.valueOf(i));startManagingCursor(x);
if(x.moveToFirst()){
ss[0] = x.getString(1);
ss[1] = x.getString(2);
}
Dictionary.addWord(ss[0].trim(), ss[1].trim());
Log.v("Debug",ss[0]+" "+ss[1]);
//onStop();
}
}
I use SQLite to collect data. and the other code is just same as the tutorial...
Retrieving a cursor is generally slow. You only want to retrieve one cursor which contains all the matching results.
You should perform the searching using SQL rather than fetching everything. A FULL_TEXT search is usually fastest for text matching, it is however slightly more complicated to implement than a simple LIKE, but I highly recommend you give it a try.
So you want to execute an SQL statement like:
SELECT * FROM my_table WHERE subject_column MATCH 'something'
See SQLite FTS Extension for more information. You can also use wild-cards to match part of a word.
In terms of search suggestions there is really no point returning more than around ~100 results since generally no users ever bother to scroll down that far, so you can further speed things up by adding a LIMIT 0, 100 to the end of your SQL statement.
If possible only start getting cursors once the user has entered more than X number of characters (usually 3 but in you're case this may not be appropriate). That way you're not performing searches that could potentially match thousands of items.
You seem to be leaving lots of cursors open until the application closes them even though you don't actually need them anymore: instead of calling startManagingCursor just make sure to call x.close() after your if (x.moveToFirst()) { ... } - this will free up memory faster.
On an unrelated note: please don't name your variables and methods things like ss or bringIt() as it makes code hard to read -- what is ss and what does bringIt() bring exactly?
You could have a look at the full text search extension in SQL Lite. Idea is to have a SQL query that fetches only the matching results, not all the results and then filter.
There is also a sample for the Android SDK: com/example/android/searchabledict/DictionaryDatabase

Categories

Resources