Copy data between tables with some static values - android

I need to copy data from one table to another. Doing so, I'd like to set manually some static values that will override data from source table. Here is example:
INSERT INTO users (id_usr, name, description, mod_date, user_type) 
SELECT id_usr, name, description, '2014-03-19 15:15:09', 'public'
FROM users_temp
WHERE user_type="" OR user_type IS NULL;
'Datetime' string and 'public' are those static values.
I'd like to know if it is possible, because on Android phone(SQLite from external native library) it doesn't copy any records, but on Windows it works fine.

I've found the problem. My users_temp table was actually a virtual table created from file. While creating that virtual table I have defined wrong charset. It caused that, at the end of every value there was added some kind of white character and condition:
WHERE user_type="" OR user_type IS NULL;
was never fulfilled.
After fixing the problem, statement is executing correctly.

Related

Android Room alter View (add colum inside select)

I didn't find anything inside the docs. What is the propper way to alter a view in room? I tried with the way to create a migration, drop the existing view and create a new one with the sql text, but I still get the room error with the difference between "expected and found scheme" (even the sql-s seems identical, I checked with a comparison tool)
For everyone, obviously room is comparing raw strings not the table/view that is being generated from the provided sql text/entity. The problem in my case was that I had an extra space after a comma inside my altered view sql text, which led to a false result when comparing to the sql text room was generating from my entity (even though the generated views where the same).
For me it's a little bit of a surprise that room is using the raw sql strings in order to check for integrity..., but now I know.
Edit:
just one tip to always get the exact same sql string. Change the entity as you wish, and compile the app. Even if it crash, room will generate the right sql text for the change that was made inside the entity. Then just open the generated YOURDATABASE_Impl file and search for the table/view.

SQLite in Android adding quotes to start and end of datelike string

Interesting issue while using SQLite in Android. I am seeing an inconsistency in the string length and quoting of a string between what is stored in the database and the materialized value seen in Java.
We are using an ORM called SugarORM to query the DB, but I've traced the offending code to the internal android.database.sqlite.SQLiteCursor class used within SugarORM, specifically the cursor.getString(columnIndex) method.
I have a string in the database that is an ISO data string 2019-03-25T19:19:39.664Z and is stored in a VARCHAR column . I have confirmed using DB Browser for SQLite that the length of the string as its stored in the database is indeed 24 characters. SELECT LENGTH(MyStringColumn) FROM MyTable WHERE ...
When I get the value of this string via cursor.getString(columnIndex), it is returning the string "2019-03-25T19:19:39.664Z". Notice the leading and trailing quotes. Java reports to me that the string is 26 characters long.
Any value that I store in this column that is not an ISO data does not have this behavior. I tried tracing the SQLiteCursor source back, but ultimately it ends up being a Native method and that's where my skill set stops.
Can anyone explain what might be going on here? I am probably just going to write a wrapper around my queries to get rid of the quotes, but its all very perplexing. The date string is being fed to a JavaScript interpreter and causing it to fail when creating a JavaScript Date object.
If it helps, I have replicated the behavior on both my S7 physical device and a Pixel 6 emulator.
As a quick get around you could use :-
SELECT length(replace(mystringcolumn,'"','')) FROM mytable;
or before using the original SELECT use :-
UPDATE mytable SET mystringcolumn = replace(mystringcolumn,'"','');
If this doesn't fix the issue, then for some reason it is the code that retrieves the data that is at fault.
e.g. consider :-
DROP TABLE IF EXISTS mytable;
CREATE TABLE IF NOT EXISTS mytable (mystringcolumn VARCHAR);
INSERT INTO mytable VALUES('2019-03-25T19:19:39.664Z'),('"2019-03-25T19:19:39.664Z"');
SELECT length(mystringcolumn), length(replace(mystringcolumn,'"','')) FROM mytable;
which results in :-
i.e. The 2nd row, 2nd column retrieves the appropriate value by using the replace function to strip of the quotes, if they exist.
As to why the quotes exist could depend upon either the way that the data is inserted (perhaps you have inadvertenly coded the quotes but the db being looked at isn't the actual database as copied from the App) or the way in which the data is being retrieved that for some reason adds them.
I don't believe it likely that the Cursor getString method has a bug in which the quotes are added, otherwise such an issue would likely be a recurring issue.

How to check if ParseObject contains particular column in database (Parse Dashboard)?

I want to check if item has particular column in database. I'm using Parse Dashboard and value in this column is type String and there is not empty string but (undefined). And this is returning null value. So I want to check if actual column does exist.
So I've used ParseObject.containsKey("column_name"), but this is returning false. I know, that value in this column is empty/null, but I want to check not value, but if that column actually exist before I can put something there.
According to documentation, this function should do exactly what I want, but it obviously doesnt work.
I've checked objectId of this item and I've checked this item in database and object with this exact id is in Class table which contains column with exact name.
Documentation:
https://parseplatform.org/Parse-SDK-dotNET/api/html/M_Parse_ParseObject_ContainsKey.htm
The containsKey method on a ParseObject will tell you only if a value has been set for that instance, not if the class can accept that property. What you want to do is inspect the Schema.
Operations on the schema (including reading) require the master key, so it is not appropriate for a client SDK like Android to access the schema directly.
I don't know your use case, as it seems unlikely that your clients would need to know this, but if you wanted a client to know the answer, you'd have to set up a cloud function that could use the master key to inspect the schema.

SQLite: Will changing data type affect the database?

I need to change the data type for my SQLite. I am worry that it might effect users who update the App. However, after reading the SQLite document in the following link
https://sqlite.org/datatype3.html
It would seem changing the data type when creating a table column shouldn't break the App. From what I read it seems unlike other SQL database engines, SQLite datatype is associated with the value itself and not the column data type that I initially assigned.
I was going to alter the column data type when user updates the App, but it doesn't seem necessary (nor possible without dropping and recreating table). Am I reading this correctly or am I making a mistake?
The App seems to work well when I test updating, but I want to make sure I am not missing anything. Any feedback is appreciated.
Changing the type name in the column definition can affect the affinity.
This might change the type of some values (for example, attempting to store the string '123' in an INTEGER column will result in the number 123), and might change how comparisons work (WHERE SomeColumn = ? will try to convert the value to the same type as the column's affinity).
So you should change the type name only if you are sure that your app handles the values in this column correctly.

android - inserting long into SQLite Integer field

I am working on an app and need some help. I have a table where I store some informations and another which has a reference. The column where the reference is made is named "COLUMN_MODULE_ID". In my DBHelper, I have declared it as an Integer. But the value I get (which is the ID from the other inserted table row which I get as a long type) seems to not get into the table.
If I put i.e. 600 hard coded into the column "COLUMN_MODULE_ID", everything works fine. But if I set the long value "module_id" hard coded to 600 and put the variable into the column, it doesn't work.
Any suggestions?
edit:
Okay, after further inspection, I have the following code:
Uri moduleUri = mContext.getContentResolver().insert(DataContract.ModuleEntry.CONTENT_URI,
moduleValues);
String moduleId = moduleUri.getLastPathSegment();
Log.v("Module ID: ", moduleId);
getQuestionsArrayFromJson(moduleName, century, moduleId);
Lets expect, that the Log says "Module ID: 887". My App doesn't work.
But if I add
moduleId = "887"
after
String moduleId = moduleUri.getLastPathSegment();
, the log says the same but my App works. I have no clue why but I think it must be some type thing.
edit #2:
So I came further to the point where the whole thing blows up. When I fetch my data from a JSON String, I implement it into a table, which works fine. However, I get the _id from the inserted entry, which inserts just fine, with the following snippet:
long moduleId = ContentUris.parseId(moduleUri);
so when I log the variable moduleId, it shows the right _id.
When I try to insert it into another sqlite table, it doesn't work.
questionValues.put(DataContract.QuestionEntry.COLUMN_QUESTION_NO, questionNo);
questionValues.put(DataContract.QuestionEntry.COLUMN_QUESTION_TEXT, text);
questionValues.put(DataContract.QuestionEntry.COLUMN_MODULE_ID, moduleId);
Uri questionUri = mContext.getContentResolver().insert(DataContract.QuestionEntry.CONTENT_URI,
questionValues);
I just can't access it from my app. If I change the code to have a fix number in it like:
questionValues.put(DataContract.QuestionEntry.COLUMN_QUESTION_NO, questionNo);
questionValues.put(DataContract.QuestionEntry.COLUMN_QUESTION_TEXT, text);
questionValues.put(DataContract.QuestionEntry.COLUMN_MODULE_ID, 555);
Uri questionUri = mContext.getContentResolver().insert(DataContract.QuestionEntry.CONTENT_URI,
questionValues);
I can access the module with the id 555 just fine from my app. So I think it has something to do with the type that the ContentUris.parseId gives back.
I can also put the 555 in a long or int variable and put the variable into the questionValues.
Any suggestions?
Okay I figuered it out. My Code was fine. I had another problem, clearing the table everytime I fetched new data into my database. Bad mistake, sorry.

Categories

Resources