I'm writing an android app where I have a java class which should represent a Table in DB.
class Table1 {
String row1;
String row2;
}
If I have to create a table in database I should do something like this.
mydatabase.execSQL("CREATE TABLE IF NOT EXISTS Table1(row1 VARCHAR,row2 VARCHAR);");
But the problem here is I'm duplicating the class structure in the SQL query. This is error prone and will require changes at multiple places whenever I need to change the attributes of the table. Is there a better way to do this. Something like mydatabase.createTableFrom(Table1.class) that I could use instead?
Related
Im receiving throught BLE data stored in an SD Card. This data is organized in multiple text files, with each file corresponding to a date.
When receiving this data on android i want to save it on a SQlite database.
Thought about using the same logic, creating a table for each day. My question is if its possible to automatically create tables depending on the number of days that is going to be transfered. After some research i found how to add new tables using the onUpgrade method and changing the database version, but this seems only possible by changing the database version manually.
Another option would be by creating a single table for all the data, and add the date as a column.
Any feedback is valuable!
Typically you would use a single table with the date as a column.
It would be possible to dynamically create tables, if they don't exist outside of the onUpgrade method. For each date/file you could, when receiving the file and before loading/inserting the data, either :-
use CREATE TABLE IF NOT EXISTS the_table_with_a_name_that_relates_to_the_date (the_column_definitions)
i.e. if the table exists then the above is effectively a NOOP.
use something like (the below assumes this method is in the DatabaseHelper)
:-
public bolean checkAndAddTable(String tableName) {
boolean rv = false;
SQLiteDatabase = this.getWriteableDatabase();
Cursor csr = db.query("sqlite_master",null,"name=? AND type='table'",new String[]{tableName},null,null,null);
if (csr.getCount() < 1) {
db.execSQL("CREATE TABLE IF NOT EXISTS " + tableName + "(......SQL TO CREATE THE COLUMN DEFINITIONS......)");
rv = true;
}
csr.close();
return rv;
}
Note the code is in-principle code ans has not been run or tested and my therefore have some errors.
However, extracting the data from multiple tables would/should need to check if the table exists, to see if data can be extracted which would incur additional processing/complications (e.g. what to do if it doesn't exist).
I am in a situation where the user has a sqlite database that has data that should not be tampered with at all. Essentially I want to import a table from a .csv file or something along those lines into their database without touching any of the data.
I notice that there is no library frmo what I can see that does explicitly this. My knowledge with SQLite isn't as comfortable as I'd like it to be so I'm unsure of where to go here.
Should I just read the file line per line copying the data and then inserting it into the created table? Each table will have 400 records, not too many so I figure it can't be that inefficient. My inexperience is what worries me thinking I will somehow damage the data. Hoping to prevent mistakes and liability here..
Here's one way:
Create a new temporary database table without a primary key (so you can verify it before copying it.)
e.g.
CREATE TABLE salespeopleTMP (
id INTEGER,
first_name TEXT NOT NULL,
last_name TEXT NOT NULL,
commission_rate REAL NOT NULL
);
and there is existing data in the table that looks like this:
sqlite> select * from salespeople;
1|Fred|Flinstone|10.0
2|Barney|Rubble|10.0
If I now have a CSV data file named people.txt that looks like this:
3,John,Doe,5.0
4,Jane,Smith,5.0
Import the CSV data into that temporary SQLite table
You can import the CSV data into my SQLite table with these two commands:
sqlite> .separator ','
sqlite> .import people.txt salespeopleTMP
Use the INSERT INTO command to import the data from your temporary
table into your actual table
insert into salespeople select * from salespeopleTMP
Delete your temporary table salespeopleTMP
based on and bug fixed from https://alvinalexander.com/android/sqlite-csv-import-data-table-primary-key
How to dynamically create table in database using greendao or ORMLite? I want to create new table in database when user pressed button, for each new table in database, data model is same but I need table with diffrent name. Is that possible ?
Concerning greendao:
It's not possible to dynamically create a new table. With greendao the code for handling your database is created on your development station by a J2SE-Application (using the daogenerator).
Concerning Ormlite:
I haven't been using Ormlite until now, but I doupt that generating new tables at runtime is possible.
Conclusion:
IMHO a database design, where you have to create new tables at runtime is bad practice, because you won't beable to benefit from ORM-frameworks. A design like that is also very difficult to maintain (if not impossible) and/or to test. On top of that a design like that may be difficult to understand for other developers as it is really uncommon.
Thus you should redesign your database schema.
You can use SQLite
public void createUserTable(DatabaseOperations d, String user) {
final SQLiteDatabase db = getWritableDatabase();
String CREATE_TABLE_NEW_USER = "CREATE TABLE " + user + " (" + UserInfo.NOTES + " TEXT)";
db.execSQL(CREATE_TABLE_NEW_USER);
db.close();
}
I am on Android and this question is of Sqlite :
I have a table (USERLOGIN) which holds the user's credentials (username and password) in it. I have another table ($USER$_PROJS) which holds information of projects for a particular user. Users can create and add projects in there.
[ $USER$ will be a variable which comes from the column username in USERLOGIN table. So its basically a dynamic table creation. ]
Both of these tables are in the same database USER.db.
I have only one LoginDatabseAdapter class and DatabseHelper class which manages both of these.
Now initially when user logs-in, the database is behaving properly. But when inside the user profile when a user tries to create/add project its not inserting the values into $USER$_PROJS table.
I think i need to use the USE TABLE (once the user successfully logs-in his profile) like statement but its giving an error when i try to use it.
I have searched almost all the resources on net but was unable to find the solution !!
Any help would be appreciated !!
CODE RESPONSIBLE FOR CREATING TABLE :
public void createprojtable(String u){
db.execSQL(
"create table if not exists "+u+"_PROJS(ID integer primary key autoincrement,
PROJ_NAME text,DATE text); ");
}
public void insertProjEntry(String u,String projName,
String projdate) {
//db.execSQL("use table "+u+"_PROJS;");
ContentValues newValues = new ContentValues();
newValues.put("PROJ", projName);
newValues.put("DATE", projdate);
db.insert(u+"_PROJS", null, newValues);
}
Have a look at the Cursors for Sqlite in Android. You get Cursors specific to a table. Using the Cursors you can read data from a specific table as such. While updating the data also you can specify table name as one of the parameters. So you can pretty much get what you are looking for using existing APIs.
Have a look at following links :
Android SQLite Database and ContentProvider - Tutorial
android.database.sqlite
I am using a SQLite database to store data that can be used to reconstruct some objects that I am using in the application I am developing. I am storing CheckIns, Recipients, and ContactMethods.
These objects are related as follows:
CheckIn <--many -- to -- many--> Recipient
Recipient <--one -- to -- many--> ContactMethod
In Java, these objects' fields are defined as follows:
public class CheckIn {
private int id;
private boolean isEnabled;
private Date startTime;
private Repetition repetition;
private Set<Recipient> recipients;
}
public class Recipient {
private String name;
private Set<ContactMethod> contactMethods;
}
public class ContactMethod {
private String type;
private String address;
}
The database schema I have come up with for these objects is defined as follows:
CREATE TABLE checkIn(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
isEnabled INTEGER,
startTime INTEGER,
repetitionNum INTEGER,
repetitionUnits TEXT
);
CREATE TABLE recipient(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT
);
CREATE TABLE contactMethod(
_id INTEGER PRIMARY KEY AUTOINCREMENT,
type TEXT,
address TEXT,
recipientID INTEGER,
FOREIGN KEY(recipientID) REFERENCES recipient(_id) ON DELETE CASCADE
);
CREATE TABLE checkIn_recipient(
checkInID INTEGER,
recipientID INTEGER,
FOREIGN KEY(checkInID) REFERENCES checkIn(_id),
FOREIGN KEY(recipientID) REFERENCES recipient(_id)
);
I have two questions.
1. How do I efficiently INSERT a CheckIn to the database, along with its related objects?
To be more specific, if I have a CheckIn object in Java, not yet committed to the database, how can I structure an INSERT statement that will insert the CheckIn to the CheckIn table, but also store the new CheckIn's relation to one or more Recipients? It seems like to store the relation to the Recipients, I would need to already know the checkIn._id, which hasn't been set yet, since the CheckIn hasn't been entered into the database yet.
2. In Android, what is the best way to rebuild a CheckIn object, for example, from a database query?
I think I know the SQL query that I will need to get the right data:
SELECT checkIn.*, recipient.name, contactMethod.type, contactMethod.address
FROM checkIn
JOIN checkIn_recipient
ON (checkIn._id = checkIn_recipient.checkInID)
JOIN recipient
ON (checkIn_recipient.recipientID = recipient._id)
JOIN contactMethod
ON (recipient._id = contactMethod.recipientID)
This query will get me rows of data containing all of the information I need to build an object for every CheckIn and Recipient in the database, and I know how to get a Cursor object that will iterate through these rows. However, since the data required for a single CheckIn appears on multiple rows, I am confused about the best way to construct individual CheckIn objects. If I am trying to write a method like public Set<CheckIn> getAllCheckIns() that will return a set of all CheckIns that are stored in the database, do I need to run the query above, then loop through each row with the same checkIn._id, and within that loop, every row with the same recipient._id, and so forth? Is there any better way to do this?
I am sorry for the long question. I have only been working with SQL beyond single table databases since this morning, and I didn't want to leave out any important information. Let me know if I missed something.
Answer to Question 1: There are 2 possible ways.
a. You find the ID of the inserted row and use that to insert into the 2nd table. You can find the ID of inserted row if you are using the Android Insert method as documented here:
http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#insert%28java.lang.String,%20java.lang.String,%20android.content.ContentValues%29
Here you must ensure that all DB tables are committed or none.
b. You can create triggers. Triggers are database operations that are automatically performed when a specified database event occurs.
Learn how to create triggers: http://www.sqlite.org/lang_createtrigger.html
So for e.g. you can create a AFTER INSERT trigger that will be fired when a row in inserted in check in table. Then in that trigger you can insert a row into another table.
When the trigger is fired, you have access to the newly inserted row.
Answer to question 2:
I usually do the following :
Select from table 1 - Check In table
Iterate over the cursor and prepare the Check In object.
Within the loop, select from table 2 - Recipient table
Iterate over the recipient table and prepare the Check in object.
This would involve too many DB selects.
Alternatively, you could select all data once and then iterate to prepare the objects.
The point I am trying to make is that you have to iterate :D