Parse - Empty Table Checking - android

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.

Related

Fetch a single column from Realm Database (Android)

I'm a beginner in Realm.
I have a table with 3 columns which named Id, Name, Email,Address.
To get the data of Name column, we use a query like 'SELECT Name from table_name' for SQLite.
If we using Realm in Android, then which method do we have to use for fetching the data of only one column?
I searched alot on Google & documentation but to no avail.
Could anyone help me?
Update:
What I am tried:
RealmResults<User> results = query.findAll();
ArrayList<String> name = new Arraylist();
for(i=0; i<results.size; i++){
name.add(result.get(i).getName();
}
My problem:
results.size() > 10k. So I want to avoid 10k iteration
for(i=0; i<results.size; i++){
}
Look at queries section at the documentation:
All fetches (including queries) are lazy in Realm, and the data is never copied.
This mean, that data of particular column (property) will be fetched when you call getMyProperty() method. Not after call of finadAll() method of RealmQuery object
If we using Realm in Android, then which method do we have to use for fetching the data of only one column?
You can't, because Realm is an object store, it doesn't have concept of "columns".
My problem:
results.size() > 10k. So I want to avoid 10k iteration
for(i = 0; i < results.size(); i++){
}
Solution: don't iterate?
RealmResults<User> results = query.findAll();
//List<String> name = new ArrayList<>();
//for(i = 0; i < results.size(); i++){
// name.add(result.get(i).getName();
//}
return results;
// ...
String name = results.get(position).getName();

Is it possible to 'randomly' select a row from a table using ormlite?

I would like to select a row from a table, but I only want to get one row and the row will be selected randomly.
I would like to select a row from a table, but I only want to get one row and the row will be selected randomly.
There isn't any special method calls which do this but there are ways that you can use the QueryBuilder to accomplish this.
If you have a numerical id, something like like should work:
qb = dao.queryBuilder();
qb.where().raw("id >= (ABS(RANDOM()) % MAX(id) + 1)");
entity = qb.queryForFirst();
Sqlite RANDOM() returns a large positive or negative integer. ABS() makes it just positive, MAX(id) allows us to then mod by the maximum id value. The +1 allows us to actually choose the max id row.
You can use queryRaw:
Relation result = null;
String query = "SELECT * from relations ORDER BY RANDOM() LIMIT 1";
try {
result = queryRaw(query, getRawRowMapper()).getFirstResult();
} catch (SQLException e) {
e.printStackTrace();
}
What I actually did was to get the List<> of the selected items from the database and then use a Random object, using the size() of the return list as the maxInt. And yes I did check for nulls.
Dao dao = getHelper().getObjectDao();
PreparedQuery<Object> query = dao.queryBuilder().[query].prepare();
Object object = null;
List<Object> resultList = dao.query(query);
if(resultList != null && resultList.size() > 0){
Random random = new Random();
int selected = random.nextInt(resultList.size() - 1);
object = resultList.get(selected);
}
It works for me:
dao.queryBuilder().orderByRaw("RANDOM()").queryForFirst();

Multiple Query Condition in Android using ORMLITE

i want to make a simple query, with multiple conditions
I use OrmLite to map entity object.
Now I want to search for an object into my table.
Supposing i have a Person entity that maps PERSON table, what I want to do is to initialize an object with some parameters and search it.
Suppose a function searchPerson(Person oPerson)
If i pass an object OPerson like this
Id = null
Name = John
Age = null
Sex = male
Is possible to write a query to reach that goal? Something like this pseudo-code
pers = (from p in db.Table<Person>()
where (if OPerson.Id !=null) p.Id==OPerson.Id}
AND {(if OPerson.Name !=null) p.Name.Contains(OPerson.Name)}
AND {(if condition) where-contion}
select p).ToList();
I know that i can do multiple query in this way
list=PersonDao.queryBuilder().where().eq("name",OPerson.name)
.and().eq("sex",OPerson.sex").query();
but I want also to check if the value exists
where (if OPerson.Id !=null) p.Id==OPerson.Id}
#ArghArgh is close but doesn't have the ANDs right. The problem is that the AND statements are conditional on whether there were any previous statements. I'd do something like:
QueryBuilder<Person, Integer> queryBuilder = dao.queryBuilder();
Where<Person, Integer> where = queryBuilder.where();
int condCount = 0;
if (oPerson.id != null) {
where.eq("id", oPerson.id);
condCount++;
}
if (oPerson.name != null) {
where.like("name", "%" + oPerson.name + "%");
condCount++;
}
...
// if we've added any conditions then and them all together
if (condCount > 0) {
where.and(condCount);
}
// do the query
List<Persion> personList = queryBuilder.query();
This makes use of the where.and(int) method which takes a number of clauses on the stack and puts them together with ANDs between.
I think that you must use the QueryBuilder.
Try something like this
QueryBuilder<Person, Integer> queryBuilder = PersonDao.queryBuilder();
// get the WHERE object to build our query
Where<Person, String> where = queryBuilder.where();
if(oPerson.Name!=null)
where.like("Name", "%"+oPerson.Name+"%");
// and
where.and();
if(Person.Sex!=null)
where.like("Sex", "%"+oPerson.sex+"%");
PreparedQuery<Person> preparedQuery = queryBuilder.prepare();
Than you can call it in this way
List<Person> list = PersontDao.query(preparedQuery);

ORMLite joins queries and Order by

I'm tring to make join in two tables and get all columns in both, I did this:
QueryBuilder<A, Integer> aQb = aDao.queryBuilder();
QueryBuilder<B, Integer> bQb = bDao.queryBuilder();
aQb.join(bQb).prepare();
This equates to:
SELECT 'A'.* FROM A INNER JOIN B WHERE A.id = B.id;
But I want:
SELECT * FROM A INNER JOIN B WHERE A.id = B.id;
Other problem is when taking order by a field of B, like:
aQb.orderBy(B.COLUMN, true);
I get an error saying "no table column B".
When you are using the QueryBuilder, it is expecting to return B objects. They cannot contain all of the fields from A in B. It will not flesh out foreign sub-fields if that is what you mean. That feature has not crossed the lite barrier for ORMLite.
Ordering on join-table is also not supported. You can certainly add the bQb.orderBy(B.COLUMN, true) but I don't think that will do what you want.
You can certainly use raw-queries for this although it is not optimal.
Actually, I managed to do it without writing my whole query as raw query. This way, I didn't need to replace my query builder codes (which is pretty complicated). To achieve that, I followed the following steps:
(Assuming I have two tables, my_table and my_join_table and their daos, I want to order my query on my_table by the column order_column_1 of the my_join_table)
1- Joined two query builders & used QueryBuilder.selectRaw(String... columns) method to include the original table's + the columns I want to use in foreign sort. Example:
QueryBuilder<MyJoinTable, MyJoinPK> myJoinQueryBuilder = myJoinDao.queryBuilder();
QueryBuilder<MyTable, MyPK> myQueryBuilder = myDao.queryBuilder().join(myJoinQueryBuilder).selectRaw("`my_table`.*", "`my_join_table`.`order_column` as `order_column_1`");
2- Included my order by clauses like this:
myQueryBuilder.orderByRaw("`order_column_1` ASC");
3- After setting all the select columns & order by clauses, it's time to prepare the statement:
String statement = myQueryBuilder.prepare().getStatement();
4- Get the table info from the dao:
TableInfo tableInfo = ((BaseDaoImpl) myDao).getTableInfo();
5- Created my custom column-to-object mapper which just ignores the unknown column names. We avoid the mapping error of our custon columns (order_column_1 in this case) by doing this. Example:
RawRowMapper<MyTable> mapper = new UnknownColumnIgnoringGenericRowMapper<>(tableInfo);
6- Query the table for the results:
GenericRawResults<MyTable> results = activityDao.queryRaw(statement, mapper);
7- Finally, convert the generic raw results to list:
List<MyTable> myObjects = new ArrayList<>();
for (MyTable myObject : results) {
myObjects.add(myObject);
}
Here's the custom row mapper I created by modifying (just swallowed the exception) com.j256.ormlite.stmt.RawRowMapperImpl to avoid the unknown column mapping errors. You can copy&paste this into your project:
import com.j256.ormlite.dao.RawRowMapper;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.table.TableInfo;
import java.sql.SQLException;
public class UnknownColumnIgnoringGenericRowMapper<T, ID> implements RawRowMapper<T> {
private final TableInfo<T, ID> tableInfo;
public UnknownColumnIgnoringGenericRowMapper(TableInfo<T, ID> tableInfo) {
this.tableInfo = tableInfo;
}
public T mapRow(String[] columnNames, String[] resultColumns) throws SQLException {
// create our object
T rowObj = tableInfo.createObject();
for (int i = 0; i < columnNames.length; i++) {
// sanity check, prolly will never happen but let's be careful out there
if (i >= resultColumns.length) {
continue;
}
try {
// run through and convert each field
FieldType fieldType = tableInfo.getFieldTypeByColumnName(columnNames[i]);
Object fieldObj = fieldType.convertStringToJavaField(resultColumns[i], i);
// assign it to the row object
fieldType.assignField(rowObj, fieldObj, false, null);
} catch (IllegalArgumentException e) {
// log this or do whatever you want
}
}
return rowObj;
}
}
It's pretty hacky & seems like overkill for this operation but I definitely needed it and this method worked well.

ORMLite: Query empty foreign field

I have two entities: EntityA and EntityB. EntityB has a foreign field of EntityA:
#DatabaseField(foreign=true, columnName=ENT_A_NAME)
private EntityA entityA;
Now I want to query all entries of EntityB where EntityA is null. So I've made the following query:
bDao.queryBuilder().where().isNull(EntityB.Ent_A_NAME).prepare();
If I execute the query I get an empty result set back.
If I execute queryAll() I see that the entries of EntityB have always an associated Order-Object with all values set to null/0.
How can I execute my query?
I'm not sure #Toni4780. The following test case works for me. I don't see anything that you are doing wrong.
In the table for EntityB, ORMLite actually stores the id of the EntityA so I am wondering if it is null or 0. Have you tried the following?
bDao.queryBuilder().where().eq(EntityB.Ent_A_NAME, 0).prepare();
or both:
bDao.queryBuilder().where().isNull(EntityB.Ent_A_NAME).
or().eq(EntityB.Ent_A_NAME, 0).prepare();
Here's my unit test code that works:
Dao<Order, Integer> orderDao =
DaoManager.createDao(connectionSource, Order.class);
TableUtils.createTable(connectionSource, Order.class);
int numOrders = 10;
for (int orderC = 0; orderC < numOrders; orderC++) {
Order order = new Order();
order.val = orderC;
assertEquals(1, orderDao.create(order));
}
List<Order> results = orderDao.queryBuilder().where()
.isNull(Order.ACCOUNT_FIELD_NAME).query();
assertNotNull(results);
assertEquals(numOrders, results.size());

Categories

Resources