Can I make SQLiteDatabase complain about missing parameters?

I recently had several errors due to code like this:

Cursor myCursor = myDb.rawQuery( "SELECT ... " + " FROM ...complicated join... " + " WHERE field1 = ? AND (field2 = ? OR field3 = ?) ", new String[] {myField1, myField2}); // Oops, forgot about field3 

When this happens, the request simply silently ignores the missing parameter, as a result of which the errors go unnoticed. Is there any pedantic parameter or something else that I can use to create SQLite criticism (at run time) when the number of placeholders and the number of fields do not match?

I know that I could create my own shell, but I wonder if there is something built-in ...

+4
source share
1 answer

Android basically just passes arguments not marked in native sqlite, see http://www.sqlite.org/c3ref/bind_blob.html

If something is not connected, it is simply considered to be associated with NULL. Binding too much should lead to an error, although

I don't know / did not see any debugging option in the Android source for this kind of checks, but you could probably write code that checks your sql syntax:

 SQLiteChecker mDbChecked = new SQLiteChecker(mDb); Cursor c = mDbChecked.rawQuery("select complicated from table where stuff=?", new String[] {"one", "two"}); 

where SQLiteChecker will be something like rows

 /** * Simple Delegate for SQLiteDatabase */ public class SQLiteChecker { private final SQLiteDatabase mDbDelegate; public SQLiteChecker(SQLiteDatabase db) { mDbDelegate = db; } // ------------ Delegate methods --------------------// public int delete(String table, String whereClause, String[] whereArgs) { checkSQL(whereClause, whereArgs); return mDbDelegate.delete(table, whereClause, whereArgs); } public int update(String table, ContentValues values, String whereClause, String[] whereArgs) { checkSQL(whereClause, whereArgs); return mDbDelegate.update(table, values, whereClause, whereArgs); } public void execSQL(String sql, Object[] bindArgs) throws SQLException { checkSQL(sql, bindArgs); mDbDelegate.execSQL(sql, bindArgs); } public Cursor rawQuery(String sql, String[] selectionArgs) { checkSQL(sql, selectionArgs); return mDbDelegate.rawQuery(sql, selectionArgs); } // add more if you need // -------------- checking logic -------------------// private static void checkSQL(String query, Object[] args) { // bit unreliable but simple: // just check if amount of ? matches args.length int expected = countChar(query, '?'); int actual = args != null ? args.length : 0; if (expected != actual) { Log.e("CHECK", "You seem to have messed up [" + query + "]"); Log.e("CHECK", "expected:" + expected + " actual:" + actual); } } private static int countChar(String string, char ch) { if (string == null) return 0; int count = 0; for (int i = 0; i < string.length(); i++) { if (string.charAt(i) == ch) count++; } return count; } } 
+1
source

Source: https://habr.com/ru/post/1445531/


All Articles