SQLite rename fts3 rowid column - android

I'm using a tutorial here to provide an AutoCompleteTextView with a SimpleCursorAdapter. It works perfectly as is, but I've changed the database to use fts3 because I've heard it's faster (hence, the name).
It seems something in the code is hard-wired to use the column _id because after changing to an fts3 table, I get this error:
01-28 21:31:53.018: E/AndroidRuntime(16284): java.lang.IllegalArgumentException: column '_id' does not exist
01-28 21:31:53.018: E/AndroidRuntime(16284): at android.database.AbstractCursor.getColumnIndexOrThrow(AbstractCursor.java:314)
Even though I haven't declared the autoincrement key anywhere (as it's superceded by rowid in fts3). The error occurs in AbstractCursor, so there's not much I can do about it.
I'm thinking there might be a way to force the code to recognize rowid as _id by using SELECT rowid,* FROM mytable and then changing the column name somehow.. I'm pretty new to sql so any help is appreciated!

Renaming a column in SQLite can be done as described here. Note that it is highly advisable to do all these operations in transaction. One detail when you are doing this in Android - I don't know how you execute sql scripts in your solution, but keep in mind this if you use execSQL calls.
By the way if you prefer not to rename the column you can try the technique proposed here.

Related

Ormlite unknown ROWID

I have to find the physical location of a row by ROWID using Ormlite.
But when I tried to sort rows using ROWID it throws the exception.
java.lang.IllegalArgumentException: Unknown column name 'rowid' in table Deals
Code follows,
mDealsDao.queryBuilder().orderBy("rowid", true).query();
How can I overcome this worry ? Does any one have faced the Issue Prior... ?
Unknown column name 'rowid' in table Deals
In the future, you should show the entity in question. I suspect that your entity does not have rowid field. Rather, I guess that rowid is an internal database feature. If this is the case, you can deal with rowid in a raw sense but if you try to use it as a field, ORMLite is going to complain.
So you could use:
queryBuilder.orderByRaw("rowid") ("rowid DESC" for descending)
dao.queryRaw(...)
And other raw methods.

New to Android - Is _id a must for databases?

I have an already functioning app running on iOS whose database uses a composite primary key. For discussions sake, lets say "CID" and "RID" make up that composite pk, resulting in something that looks like:
CID-RID
F6uuDTEU1c-1
F6uuDTEU1c-2
F6uuDTEU1c-3
However, there are conditions under which the CID column is altered, resetting the RID column. For example:
CID-RID
...
F6uuDTEU1c-4
F6uuDTEU1c-5
WQq6JnyrDI-1
WQq6JnyrDI-2
WQq6JnyrDI-3
...etc
These databases are to be shared cross-platform (ios - android) and going back and editing the current ios structure is not an option. What issues am I going to run into not having an _id column as my pk running on Android?
I found this here on SO - which seems to state that the db itself does not have to have the _id column, only that ...
"The result set for the cursor must contain _id, not the cursor itself."
... but I could be reading this all wrong. Any input/help is much appreciated.
PS: I already looked at a few (what I thought were) similar questions here, here, and here.
You are free to have any database schema you want. Android doesn't impose any additional restrictrions there.
Only if you use a CursorAdapter, then the Cursor needs an _id column. Any app can be written without using CursorAdapter, it's just there to provide some convenience. sqlite tables always have a ROWID column that aliases to the INTEGER PRIMARY KEY column if the table has one. You can always select it as the _id, e.g. SELECT rowid AS _id ... if needed.

Changing a Column type in my Android App's Database

I have an app published in the play store.
The app uses a database which holds a table which has a column of type int.
I'm doing a new change where I need to change the column type to long.
How do I go about handling it in the DatabaseHandler I'v created.
I want to preserve the data stored in the older apps database, so what should ideally be the code in the onUpgrade() function???
You don't need to change the database column type. An INTEGER column will happily contain all the bits needed to represent a Java long.
In fact, there's no long column type in sqlite.
I think using SQLite, the best way is to create a temporary table, copy all your table content, drop the old table and recreate the table with the right type on your column, then you can just copy the content from the temporary table and drop it...
I know this don't fell like the best approach, but I don't think SQLite have some alter table function.
As far I know you can t do this . But You can drop your table if it exists and create it again . Maybe you can find out some useful information here SQLite Modify Column or here Modify a Column's Type in sqlite3

SQLite CREATE table with an alias for ROWID

Looking at this answer I was trying to work out how to actually create a table with a column that is just an alias for ROWID. I would like to do this as some android classes require a unique column named '_id' but i dont want that col to be a PRIMARY KEY. I cant use AUTO_INCREMENT on the col that not a PK either, so I would just like _id to be an alias. I know I could do that in the query but thats not practical for my situation. Any pointers? Is this even possible?
Thanks :)
EDIT: really i just want to be able to have my own PK but also have an id field for CursorAdapters to work correctly etc
EDIT: Looking at Do i have to use _ID as a SQlite primary key? and does it have to be an INT? (Android Dev) it suggests to do it in the query if my PK is a number type also, but what if its a TEXT col that im using for my PK? (sort of thinking aloud here) - I guess i could copy CursorAdaptor and just getString instead of a long for the _id col (plus, pass the name of the col to use as the PK in to cursor adapter, get rid of _id!) OR just add a alias for the ROWID as _id in the SELECT, feels a bit hacky though...
You may have a primary key that is completely independent of SQLite's built-in rowid.
Every row of every SQLite table has a 64-bit signed integer key that uniquely identifies the row within its table. This integer is usually called the "rowid". The rowid value can be accessed using one of the special case-independent names "rowid", "oid", or "rowid" in place of a column name.
You may formulate your query so that the built-in rowid is called _id for the benefit of the CursorAdaptor by prepending the hidden rowid column to your results:
select _rowid_ as _id, ...
The rowid is unique, but need not be the primary key. You can make the primary key anything you like in the CREATE TABLE statement.
TBH, I don't think that this is really feasible. You are required to have that kind of PK column (even though with a lot of hacking you could create some kind of workaround).
I would rather suggest to have the _id column as a technical PK and have an additional column as logical PK i.e. just a freely defined column with a unique constraint. Your program logic should then be able to simply use the logical PK for all operations. Of course this would require you to use custom queries for find operations etc. but that is usually more fitting anyways.
hth..

Normal SELECT on an SQLite FTS Table

I'm having an issue performing normal SELECT statements (that is, not the 'searches' they were designed to do- I'm not using MATCH). What I'm trying to do is query the table for all rows of an INTEGER column. However, the SELECT statement always returns no rows. I've inspected the database with an SQLite browser and the query should work. Here it is:
Here's the MAKE TABLE statement:
CREATE VIRTUAL TABLE FTS_journal USING fts3(journal_id INTEGER, journal_text_col TEXT)
And here's the SELECT:
SELECT journal_id FROM FTS_journal
Does it have something to do with my running a 'normal' query over a virtual table? I can't really think of any other reason
EDIT: I'm using Android's version of SQLite, meaning SQLite3. I know it supports FTS properly...
If any further information I can provide will help, please tell me and I will post it.
What you've written should work. Are you 100% positive you've actually inserted something into the table? Have you ran insert statements, and if so, are you sure they were successful?
I tested your statements, running the create statement, then the following statement:
insert into FTS_journal (journal_id, journal_text_col) values (1, 'test');
... then your select statement, and sqlite returned 1 row (journal_id, value 1) just as it should.

Categories

Resources