Need help adding a column to table in SQLite database - android
I have spent the day reading through various articles, but I can't seem to find an answer to my problem. Months ago, I created an app in android studio that uses SQLite. Now, I have gotten to the point that I need to add a column to the table. I am able to add the column in the adapter class with no problem, but I am having a problem in the 'MainActivity.class'. The code is as follows...
private void setData() {
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 0; i++) {
dbAdapter.insertSpace(String.valueOf(i+1),"Confined Space " + (i+1),"description "+(i+1),"","","","","","","","","","",
"","","","","","","","","","","","","","","","",
"","","","");
}
try {
// Execute insert function
} catch (SQLiteConstraintException e) {
Toast.makeText(context, "Error inserting record", Toast.LENGTH_SHORT).show();
}
}
}).start();
}
}
and the error message I am getting is...
error: method insertSpace in class DBAdapter cannot be applied to given types;
required: String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String
found: String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String,String
reason: actual and formal argument lists differ in length
My required content shows 34 columns, and found is 33. What do I need to do to make these equal, and where do I need to make the adjustments? I added a column once before, but just can't remember how I did it :(
I am sorry all. This was entirely my own mess-up. I had only changed the structure of the add query... I had neglected to make the same changes to my update, and my listview. Every call to the database in the app needed to be edited, not jus.t the add record
Related
SQLite injection - Doing something wrong with querying
I'm trying to do some Sqlite querying but I don't know if I'm doing it correctly because this feels really unsave to do. So my question is how do I fix this. I'm new to the whole Xamarin and Sqlite usage. I'm only making a Android project so it is not a cross platform application. I also cant seem to figure out where to get Mono.Data.Sqlite if I even need it. Everything is welcome. static public List<Users> SelectUser(string name) { try { var dbConn = new SQLiteConnection(DatabasePath); { return dbConn.Query<Users>("SELECT name, email FROM TblUsers where name = " + name+ ";"); } } catch (SQLiteException ex) { return null; } }
You should use Prepared Statements. There is an official java documentation about Prepared Statements from Oracle here. You can also search it on google. There are a lot of guides on how to use prepared statements.
Android and Azure Read from _deleted
so I'm learning microsoft azure, and I'm trying to understand the reading from columns, now I'm able to do that with a new column I've made, but I'm trying to obtain all values from my text column, based on the whichever one is deleted looking at the _deleted column (Automatically made by azure). Currently I am doing it as follows: mClient.getTable(Item.class).where().field("_deleted").eq(false) .execute(new TableQueryCallback<Item>() { public void onCompleted(List<Item> result, int count, Exception exception, ServiceFilterResponse response) { if (exception == null) { for (Item item : result) { Log.i("ITEM", "Read object with ID " + item.Text); } } } }); If I use other field and eq values I can confirm it works. But I can't seem to get this to work with the _deleted column and was hoping if anyone had some insights? Thanks
Apologies guys, turns out I did a super noob mistake, the column "_deleted" is actually "__deleted" I couldn't see those two underscores there since the text was quite small. Hits palm into face
Ormlite Android bulk inserts
can anyone explain why my inserts are taking so long in Ormlite? Doing 1,700 inserts in one sqlite transaction on the desktop takes less than a second. However, when using Ormlite for Android, it's taking about 70 seconds, and I can see each insert in the debugging messages. When I try and wrap the inserts into one transaction it goes at exactly the same speed. I understand that there is overhead both for Android and for Ormlite, however, I wouldn't expect it to be that great. My code is below: this.db = new DatabaseHelper(getApplicationContext()); dao = db.getAddressDao(); final BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().openRawResource(R.raw.poi))); try { dao.callBatchTasks(new Callable<Void>() { public Void call() throws Exception { String line; while ((line = reader.readLine()) != null) { String[] columns = line.split(","); Address address = new Address(); // setup Address dao.create(address); } return null; } }); } catch (SQLException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); }
I've had the same problem, and found a reasonable workaround. This took insert time from 2 seconds to 150ms: final OrmLiteSqliteOpenHelper myDbHelper = ...; final SQLiteDatabase db = myDbHelper.getWritableDatabase(); db.beginTransaction(); try{ // do ormlite stuff as usual, no callBatchTasks() needed db.setTransactionSuccessful(); } finally { db.endTransaction(); } Update: Just tested this on Xperia M2 Aqua (Android4.4/ARM) and callBatchTasks() is actually faster. 90ms vs 120ms. So I think more details are in order. We have 3 tables/classes/DAOs: Parent, ChildWrapper, Child. Relations: Parent to ChildWrapper - 1 to n, ChildWrapper to Child - n to 1. Code goes like this: void saveData(xml){ for (parents in xml){ parentDao.createOrUpdate(parent); for (children in parentXml){ childDao.createOrUpdate(child); childWrapperDao.createOrUpdate(generateWrapper(parent, child)); } } } I've got original speed up on a specific Android4.2/MIPS set-top-box (STB). callBatchTasks was the first option because that's what we use througout all the code and it works well. parentDao.callBatchTasks( // ... saveData(); // ... ); But inserts were slow, so we've tried to nest callBatchTasks for every used DAO, set autocommit off, startThreadConnection and probably something else - don't remember at the moment. To no avail. From my own experience and other similar posts it seems the problem occurs when several tables/DAOs are involved and it has something to do with implemetation specifics of Android (or SQLite) for concrete devices.
Unfortunately, this may be "expected". I get similar performance when I do that number of inserts under my emulator as well. The batch-tasks and turning off auto-commit don't seem to help. If you are looking to load a large amount of data into a database, you might consider replaying a database dump instead. See here: Android OrmLite pre-populate database
My guess would be that you are slowing somewhat because you are doing two IO tasks at one time (at least in the code shown above). You are reading from a file and writing to a database (which is a file). Also, from what I understand transactions should be a reasonable size. 1600 seems like a very high number. I would start with 100 but play around with the size. So essentially I suggest you "chunk" your reads and inserts. Read 100 lines to a temp Array, then insert that 100. Then read the next 100, then insert, etc.
Robolectric: Testing with ormlite
I'm trying to test ORMLite DAOs with robolectric, but database behaviour is not the same as when it's used from my android app. My DAOs are working perfectly well on the android application. Reading about robolectric shadows and debugging code, I encountered ShadowSQLiteOpenHelper (code here). Does anyone know if this Shadow is enough to test ormlite daos? Or I have to create my own shadow to achieve that? Any clue/tip/suggestion/example here? Thanks in advance. Extra info: Test method: #Test public void basicTest() throws SQLException { assertNotNull(randomStringResource); // Injection of an android resource: OK assertThat(randomStringResource, equalTo("Event")); // With correct value: OK assertNotNull(eventDao); // Dao injection: OK assertThat(eventDao.countOf(), equalTo(0L)); // Table empty: OK Event e1 = new Event("e1", new Date()); eventDao.create(e1); assertNotNull(e1.getId()); // ID generated by OrmLite: OK assertThat(eventDao.countOf(), equalTo(1L)); // Table not empty: OK assertThat("e1", equalTo(eventDao.queryForId(e1.getId()).getName())); // Query for inserted event: Throws exception } Some of the problems encountered running this test: Errors querying entities with "camelCased" property names: error thrown at last line of test (related problem). Never had a problem like this running the android app. When I changed one of these properties name (e.g., isEnabled to enabled) in order to avoid the camelCase problem, the previous error persisted... seems like memory database didn't apply the changes that I made on the entity. Versions used: Robolectric 1.1 OrmLite 4.41
Sorry for resurrecting your topic but I ran into the same problem. I'm using OrmLite 4.45 and Robolectric 2.1. In ShadowSQLiteCursor.java, cacheColumnNames method calls toLowerCase on each column name. So I decided to extend ShadowSQLiteCursor with my own (which doesn't call toLowerCase): /** * Simulates an Android Cursor object, by wrapping a JDBC ResultSet. */ #Implements(value = SQLiteCursor.class, inheritImplementationMethods = true) public class ShadowCaseSensitiveSQLiteCursor extends ShadowSQLiteCursor { private ResultSet resultSet; public void __constructor__(SQLiteCursorDriver driver, String editTable, SQLiteQuery query) {} /** * Stores the column names so they are retrievable after the resultSet has closed */ private void cacheColumnNames(ResultSet rs) { try { ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); columnNameArray = new String[columnCount]; for(int columnIndex = 1; columnIndex <= columnCount; columnIndex++) { String cName = metaData.getColumnName(columnIndex); this.columnNames.put(cName, columnIndex - 1); this.columnNameArray[columnIndex - 1] = cName; } } catch(SQLException e) { throw new RuntimeException("SQL exception in cacheColumnNames", e); } } } My answer obviously comes too late but may help others!
Sqlite Out of Memory when preparing update statement
I have one problem with my application. I create a one AsyncTask for downloading list of files from server . When all the files are download after that i update the database. But when i called the update query its give me the below error. Failure 21 (out of memory) on 0x0 when preparing update Can any one tell me why this error occurs ? Sample Code public void setStatus(int index) { try { db.OpenDatabase(); db.updateStatus(id.get(index), 1); db.closeDatabase(); } catch(Exception e) { e.printStackTrace(); } } Above function called from the AsyncTask .... public void updateStatus(int id,int status) { try { db.execSQL("update sample set status =" + status + " where id = " + id); } catch(Exception e){e.printStackTrace();} }
This may not be related to the database pe se, but rather to the fact that the memory (heap) is almost full and opening the database completely fills it up. Remember that most handsets have 48MB of heap or even less.
Sometime while working I also got the same error. I used this link "Failure 21 (out of memory)" when performing some SQLite operations It said that this error occurs when you try to work on a closed DB. I looked back into my code and found that I was also doing the same. Got it working afterwards I think you are also trying to work on a closed DB.
Have you tried to use the update() method instead of execSQL()? public void updateStatus(int id,int status) { try { ContentValues values = new ContentValues(); values.put("status", status); db.update ("sample", values, "id = ?", new String[]{Integer.toString(id)}); } catch(Exception e){e.printStackTrace();} }
I has "out of memory" error (21) when I try to call sqlite3_prepare() with a NULL pointer to database handle. Check if your handle is valid and the database is opened.