I'm using Sugar ORM to query a list of apps. I have a boolean column for tagging fields in this using:
#Setter #Getter public boolean isNew = false;
Now after API call I will update and save the record to tag all new apps and then for display I will just query it using:
List<AppsModel> app_list = AppsModel.find(AppsModel.class, "is_new = ?", "true");
Problem is that it returns 0 entry where it to have 3 on my end. To check I get all the list and check the column one by one to check its values:
List<AppsModel> test = AppsModel.listAll(AppsModel.class);
for(int i=0;i<test.size();i++){
Log.e("Test app size", String.valueOf(test.get(i).isNew()));
}
And it returns 3 as expected with true values. I can make use of this loop for list but I don't want to as I want to keep my code clean as possible.
Am I missing something here?
Okay I found the answer here from satyan himself
So basically, using "true" will match it as String. So instead use:
List<AppsModel> app_list = AppsModel.find(AppsModel.class, "is_new = ?", "1");
As SQlite store boolean values as 0 and 1.
Related
I have a table like this
table:
boolean field
string field
I want to set a constraint which says that if the boolean field is True then the string field must not be NULL, but if the boolean field is False, the string field can be anything ?
Is that possible?
Thank you
First, note that according to the SQLite docs:
SQLite does not have a separate Boolean storage class. Instead, Boolean values are stored as integers 0 (false) and 1 (true).
With that in mind, assuming your boolean is named bool_column and your string is string_column:
CHECK (bool_column = 0 OR (bool_column = 1 AND string_column IS NOT NULL))
I want to know how can i use MAX MIN command with ORMLITE.
For example lets say we have this table
Table Name = Example
Column 1 = id
Column 2 = name
In ORMLITE how can i get max id ? I looked here but i didnt't understand exactly..
Can someone show me example about Max min in ORMLITE ?
QueryBuilder<Account, Integer> qb = accountDao.queryBuilder();
qb.selectRaw("MIN(orderCount)", "MAX(orderCount)");
// the results will contain 2 string values for the min and max
results = accountDao.queryRaw(qb.prepareStatementString());
String[] values = results.getFirstResult();
I found this from documentation
This is how I query for max ID in my code:
QueryBuilder<Example, String> builder = dao.queryBuilder();
builder.orderBy("id", false); // true or false for ascending so change to true to get min id
Example example = dao.queryForFirst(builder.prepare());
String id = null;
if (example == null)
id = "-1";
else
id = example.getId();
A couple of alternative answers can also be found here:
ORMLite - return item w/ maximum ID (or value)
You can use:
dao.queryRawValue("select MAX(columnName) from tableName")
It will directly return long value.
refer: http://ormlite.com/javadoc/ormlite-core/doc-files/ormlite_5.html#DAO-Methods
queryRawValue(String query, String... arguments)
Perform a raw query that returns a single value (usually an aggregate function like MAX or COUNT). If the query does not return a single long value then it will throw a SQLException.
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.
I have a database in my app with several columns of which 3 are: _id name selected.
Now, I want to read a single selected value from a row with the name being a string I get from some code. What would be the best way to do this?
Thanks
P.S. I am getting that value to check if it's 0 or 1 (only two possible values), so I want to ask how to make a kind of an if statement in the return field? I have seen some people do it with something resembling this: return true ? ... false
EDIT:
Okay, this is my code atm, haven't checked it yet since I need to do some other things to get it all up, but I think there may be a better way to do this.
public boolean isBandSelected(String name) {
// TODO Auto-generated method stub
Cursor cursor = mDb.query("bands", new String[] { "selected" }, "name="
+ name, null, null, null, null);
int index = cursor.getColumnIndex("selected");
String selected = cursor.getString(index);
return selected == "1";
}
You can use regular expression to match rows whose name field being string. Many databases can support regular expression.
The ternary operator(? :) can be used to make return statement like this.
return value == 0 ? false : true
But it depends on what kind of data type you what to return. Code above returns boolean data type.
The last line of your code above will always return false. This is because the == operator compares the reference of the two objects. you can use:
return "1".equals(selected);
I created database table in my android app. I used this query:
CREATE TABLE foo (_id INTEGER PRIMARY KEY AUTOINCREMENT, mybool BOOLEAN)
Than I added row to the table, that the value of mybool will be true.
I ran the sqlite3 command to see the value in the table, and I saw:
_id | mybool
----------------------
1 | 1
That is corret, the true value became to 1.
The strange thing is in the reading. I read the table like that:
ContentValues values = new ContentValues();
Cursor cursor = db.rawQuery("SELECT * FROM foo", null);
DatabaseUtils.cursorRowToContentValues(cursor, values);
Then I get strange result:
values.getAsBoolean("mybool"); // return false - WRONG
values.getAsInteger("mybool"); // return 1 = true - CORRECT
I use the code like that to get boolean value:
values.getAsInteger("mybool") != 0;
But it's strange.
Why I get always false in the getAsBoolean function? Is there any bug in the ContentValues class? Anyone else having this problem?
DatabaseUtils.cursorRowToContentValues() stores everything as strings (except blobs). ContentValues.getAsBoolean() will attempt to convert the string to a boolean (using Boolean.valueOf()), but that only works if the string is equal to "true", not "1".
This looks like an Android bug to me.
You've skipped some code here.
What's your proof that values.getAsBoolean("mybool") returns false? You have to return a Boolean. How are you checking it?
ContentValues.getAs returns a value if the key can be found, or null if it can't or if the value can't be converted. Be sure that you're doing a full test.
getAsBoolean does not return a boolean but a Boolean wrapper object, which can be either null, Boolean.FALSE, or Boolean.TRUE.
If you can ensure that there aren't NULLs, use values.getAsBoolean("mybool").booleanValue() to get the actual value.
I don't know if it's the best solution for this problem, but this code below works for me:
Integer result = contentValues.getAsInteger(attributeName);
if(result == null || result == 0) {
parameter = false;
} else {
parameter = true;
}
Get boolean result like below:
boolean result = values.getAsInteger("mybool") == 1;