Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ORMLite query with quote, Android

I'm using ORMLite, with the Table RecentSearch :

@DatabaseTable(tableName = LocalStorageConfig.SQL_RECENTS_TABLE_NAME)
public class RecentSearch {

    @DatabaseField
    public String search_text;
    public static String SQL_SEARCH_FIELD = "search_text";

    @DatabaseField
    public String location_text;
    public static String SQL_LOCATION_FIELD = "location_text";

    @DatabaseField
    public Date creation_date = new Date();
    public static String SQL_CREATION_DATE_FIELD = "creation_date";

It's working almost all the time, but when I discover the case with a String containing a ', then it appears to be a problem. Do you know how to solve this ? I couldn't find what I was looking for.

Here is my function to delete a recent

public boolean deleteRecent(RecentSearch search) {
    try {
        Dao<RecentSearch, Integer> recentsDao = recentsSqlManager.getRecentsDao();
        DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

        deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text()).and().eq(RecentSearch.SQL_LOCATION_FIELD, search.location_text);
        recentsDao.delete(deleteBuilder.prepare());
        return true;
    } catch (Exception e) {
        Log.e(TAG, "Database exception", e);
        return false;
    }
}

Here is the Exception i get :

java.sql.SQLException: Problems executing Android statement: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at com.j256.ormlite.misc.SqlExceptionUtil.create(SqlExceptionUtil.java:22)
    at com.j256.ormlite.android.AndroidCompiledStatement.runUpdate(AndroidCompiledStatement.java:66)
    at com.j256.ormlite.stmt.StatementExecutor.delete(StatementExecutor.java:425)
    at com.j256.ormlite.dao.BaseDaoImpl.delete(BaseDaoImpl.java:347)
...
Caused by: android.database.sqlite.SQLiteException: near "Allier": syntax error: , while compiling: DELETE FROM `recent_searches` WHERE (`search_text` = '' AND `location_text` = 'Villefranche-d'Allier, Allier' ) 
    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
    at android.database.sqlite.SQLiteStatement.<init>(SQLiteStatement.java:41)
    at android.database.sqlite.SQLiteDatabase.compileStatement(SQLiteDatabase.java:1149)
like image 506
Camille R Avatar asked Nov 21 '11 11:11

Camille R


2 Answers

when I discover the case with a String containing a ' (single quote), then it appears to be a problem.

In ORMLite, when you are trying to build a query with quotes, you should use the SelectArg feature which will generate a query with SQL ? arguments and then pass the string to the prepared statement directly. This gets around any problems with escaping of special characters as well as protects you from SQL injection security issues. See the documentation on SelectArg.

With SelectArg, you'd do something like:

DeleteBuilder<RecentSearch, Integer> deleteBuilder = recentsDao.deleteBuilder();

// create our argument which uses a SQL ?
SelectArg locationArg = new SelectArg(search.location_text);
deleteBuilder.where().eq(RecentSearch.SQL_SEARCH_FIELD, search.getSearch_text())
    .and().eq(RecentSearch.SQL_LOCATION_FIELD, locationArg);
recentsDao.delete(deleteBuilder.prepare());
...
like image 139
Gray Avatar answered Nov 15 '22 22:11

Gray


You can use the SelectArg object when binding to your query as this will escape any quotes so they don't generate invalid sql.

like image 21
Chris Avatar answered Nov 15 '22 20:11

Chris