My understanding is that it will return -1 if all the code could be executed properly and a "EXPECTED" error happened. However, not all errors/exceptions are handled and some exceptions may still be triggered:
- SQLiteDatabaseCorruptException
- IllegalArgumentException
- RuntimeException
- Database is opened for read-only
- Trying to insert a duplicated key
HERE you can find the implementation of insert()
and insertOrThrow()
.
You can see that both methods are similar. However, insert()
handles SQLException
s for you. insertOrThrow()
does not handle any exception and you should do it by yourself.
public long insert(String table, String nullColumnHack, ContentValues values) {
try {
return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
} catch (SQLException e) {
Log.e(TAG, "Error inserting " + values, e);
return -1;
}
}
public long insertOrThrow(String table, String nullColumnHack, ContentValues values)
throws SQLException {
return insertWithOnConflict(table, nullColumnHack, values, CONFLICT_NONE);
}
Both methods calls insertWithOnConflict()
which implementation is HERE:
public long insertWithOnConflict(String table, String nullColumnHack,
ContentValues initialValues, int conflictAlgorithm) {
acquireReference();
try {
// CODE
try {
// ONLY HERE I return some value.... Otherwise, I'll raise an exception
return statement.executeInsert();
} finally {
statement.close();
}
} finally {
releaseReference();
}
}
In the implementation, you will see that it returns "-1" only if statement.executeInsert();
returns something (and it seems that "-1" came from here):
.../frameworks/base/core/jni/android_database_SQLiteConnection.cpp
static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz,
jlong connectionPtr, jlong statementPtr) {
SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
int err = executeNonQuery(env, connection, statement);
return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0
? sqlite3_last_insert_rowid(connection->db) : -1;
}
If any other error/exception happens in the middle, it will throws an exception.
If you follows the called methods, you can see that other errors are not handled. Also, you will notice that the SQLite will be in fact be executed by a C task (and not java). So, several non-expected errors can still happen.