Dynamic table creation on button click in SQLite - android

I am creating a login application and I wanted to create a table for each user when they click the register button. The problem is, I am using their unique email id as table name. Later I learned that table names cannot have special characters like "#". Please suggest me a way to create table with names having special characters like "#". Or else, please suggest me a way to create tables with unique names for each user when they click the register button.
Please Note :"TABLE_NAME" in the code given below is another table containing registered user details.
The code is given below:
public boolean insertData(String name, String email, String mobile, String pass){
SQLiteDatabase db = this.getWritableDatabase();
db.execSQL("create table "+email+"(Choice TEXT, Q1 INTEGER, Q2 INTEGER, Q3 INTEGER, Q4 INTEGER, Q5 INTEGER)");
ContentValues cv = new ContentValues();
cv.put(NAME, name);
cv.put(EMAIL, email);
cv.put(MOBILE, mobile);
cv.put(PASSWORD, pass);
long result = db.insert(TABLE_NAME,null,cv);
db.close();
if(result == -1)
return false;
else
return true;
}

In SQL, identifiers can be quoted with double quotes. Any double quotes inside the identifier must be doubled to escape them; and in Java strings, double quotes must be escaped with a backslash:
String sqlTableName = "\"" + email.replace("\"", "\"\"") + "\"";
db.execSql("CREATE TABLE " + sqlTableName + "...");
However, putting data into the table name is a bad idea, because it cannot be queried and modified like all your other data.
Better use a single table, and put that information into another column:
CREATE TABLE Users(EMail TEXT, Choice TEXT, Q...);

Related

Contacts are saved multiple times in Database

Hi guys i have code to add data into Database and that code is called on oncreate. but every time fragment is created its saves data into database again and again. I dont want that. how can i prevent that here is my code to get data and save it to database.
public void getcontacts(){
Cursor phones;
phones = getActivity().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext()){
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
DataBaseOperations hell = new DataBaseOperations(getActivity());
SQLiteDatabase db = hell.getWritableDatabase();
hell.SaveContacts(name, phoneNumber, db);
}
phones.close();
}
here is code for saving in database.
public void SaveContacts(String Name,String phone,SQLiteDatabase db ){
ContentValues sv = new ContentValues();
sv.put(mDatabase.Tableinfo.Contacts_name, Name);
sv.put(mDatabase.Tableinfo.Contacts_phone, phone);
db.insert(mDatabase.Tableinfo.contacts, null, sv);
}
EDIT- Here is what i have done so far but how do i set a constraint on which it will conflict.I have added an auto increment primary key as unique key but how will they conflict?? but still its saving values again in database.where do i set a primery key as constraint?????
public void SaveContacts(String Name,String phone,SQLiteDatabase db ){
ContentValues sv = new ContentValues();
sv.put(mDatabase.Tableinfo.Contacts_name, Name);
sv.put(mDatabase.Tableinfo.Contacts_phone, phone);
db.insertWithOnConflict(mDatabase.Tableinfo.contacts, null, sv, SQLiteDatabase.CONFLICT_REPLACE);
EDIT- 2 - how would i make unique columns in this kind of query???
private static final String Contacts_Table = "CREATE TABLE "+
mDatabase.Tableinfo.contacts +"("
+mDatabase.Tableinfo.Contacts_name+" TEXT,"
+mDatabase.Tableinfo.Contacts_phone+" TEXT NOT NULL UNIQUE,"
+mDatabase.Tableinfo.isChattris+" TEXT,"
+mDatabase.Tableinfo.status_contact+" TEXT,"
+mDatabase.Tableinfo.Contact_pic+" BLOB"+")";
just Added NOT NULL UNIQUE.
This is the constraint.
Keep the status of the contacts saving in unrelated storage, e.g SharedPreferences. You don't want to rely on any lifecycle triggers, not even Application.onCreate, since that will happen again and again when the app is launched.
Try to update existing entries instead of adding new ones. Decide what the database key should be, and then you can use insertWithOnConflict with the CONFLICT_REPLACE flag to insert if not already in the table or update if it is.
EDIT: to define the constraints so the conflict behavior will trigger, change your CREATE TABLE statement. e.g this will cause duplicate (name,phone) pairs to trigger it. You may want to use some kind of contact ID instead though.
CREATE TABLE mytable (
name TEXT,
phone TEXT,
UNIQUE(name, phone)
)

How is it possible to insert row into SQLite table without specifying value for the primary key

I'm working on a project and don't understand this part of this code that I found online. (I have also looked at other examples and they do the exact same thing but I don't quite understand why)
When they are inserting something into the table, they have no value for the primary key. Could someone explain to me why that is the case?
Here is 2 examples of code that I found that do what I have stated above.
Thanks.
// As you can see a contact has 3 attributes.
int _id;
String _name;
String _phone_number;
// Where they create a table. As you can see the primary key is ID
#Override
public void onCreate(SQLiteDatabase db)
{
String CREATE_CONTACTS_TABLE = "CREATE TABLE " + TABLE_CONTACTS + "("
+ KEY_ID + " INTEGER PRIMARY KEY," + KEY_NAME + " TEXT," + KEY_PH_NO + " TEXT" + ")";
db.execSQL(CREATE_CONTACTS_TABLE);
}
// Adding new contact
// This is what I don't understand. Why don't they get an ID for the contact.
// They only have values for the name and phone number when they insert it into the table.
public void addContact(Contact contact)
{
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, contact.getName()); // Contact Name
values.put(KEY_PH_NO, contact.getPhoneNumber()); // Contact Phone Number
// Inserting Row
db.insert(TABLE_CONTACTS, null, values);
db.close(); // Closing database connection
}
Here's another example but this is using a book.
A book has 3 attributes, an id (the primary key), an author and the book name. And once again, they don't get the value for the primary key.
public void addBook(Book book)
{
Log.d("addBook", book.toString());
// 1. get reference to writable DB
SQLiteDatabase db = this.getWritableDatabase();
// 2. create ContentValues to add key "column"/value
ContentValues values = new ContentValues();
values.put(KEY_TITLE, book.getTitle()); // get title
values.put(KEY_AUTHOR, book.getAuthor()); // get author
// 3. insert
db.insert(TABLE_BOOKS, // table
null, //nullColumnHack
values); // key/value -> keys = column names/ values = column values
// 4. close
db.close();
}
because primary key is Autoincrement as it is an alias for ROWID.
from the documentation:
In SQLite, table rows normally have a 64-bit signed integer ROWID
which is unique among all rows in the same table. (WITHOUT ROWID
tables are the exception.)
You can access the ROWID of an SQLite table using one the special
column names ROWID, ROWID, or OID. Except if you declare an ordinary
table column to use one of those special names, then the use of that
name will refer to the declared column not to the internal ROWID.
If a table contains a column of type INTEGER PRIMARY KEY, then that
column becomes an alias for the ROWID. You can then access the ROWID
using any of four different names, the original three names described
above or the name given to the INTEGER PRIMARY KEY column. All these
names are aliases for one another and work equally well in any
context.
When a new row is inserted into an SQLite table, the ROWID can either
be specified as part of the INSERT statement or it can be assigned
automatically by the database engine. To specify a ROWID manually,
just include it in the list of values to be inserted. For example:
so in the examples you have given id is being assigned by database engine. for most of the use cases this is good enough.
You can create the table like
static final String DATABASE_CREATE = "create table "+TABLE_NAME+"( ID integer primary key autoincrement,user_name text,user_phone text,user_email text); ";
Then it will increment automatically
See this link http://www.freakyjolly.com/android-sqlite-integration/
http://www.freakyjolly.com/android-sqlite-how-to-insert-rows-in-database/

SQLite Database Error(Glitch in bridge between two tables)

I have two tables as USER_TABLE where i have all the user details as username,firstname etc and similarly i have another table named RESUME_TABLE where i have aim,degree,university etc.
The columns common to both are KEY_USERID(created dynamically) and i use this id to match the two tables.
Question :
I register a user and his details gets stored in the USER_TABLE and say his KEY_USERID automatically generated(primary key) is 1 and then i create a resume for him in the RESUME_TABLE using the same KEY_USERID 1. I pass on the KEY_USERID obtained from the first table as a argument while inserting and retrieving the resume contents from the RESUME_TABLE.
Say, i do this again for another user thereby generating KEY_USERID 2 but i fill only the
USER_TABLE and the RESUME_TABLE IS EMPTY.
When i repeat this again filling both the tables, then the RESUME_TABLE is not able to fetch the data cause the second user did not fill the details in RESUME_TABLE and that acts as a glitch while retrieving the KEY_USERID for the 3rd user.
How do i rectify this ?
CODE :
DBAdapter.java :
public String get_user_id(String name) {
String[] column = new String[]{KEY_USERID};
String where = KEY_USERNAME + "=?";
Cursor c = mDB.query(DATABASE_TABLE, column, where,new String[]{""+ name + ""}, null, null,null);
String user_id = "";
int iuser_id = c.getColumnIndex(KEY_USERID);
if (c != null)
c.moveToFirst();
user_id = user_id + c.getString(iuser_id) + "\t";
c.close();
return user_id;
}
ViewResume.java
if(get_from_create!=null)
{
if(get_from_create.hasExtra("UserId_Create"))
{
String user_id_create = get_from_create.getExtras().getString("UserId_Create"); // This is where i get the user id from the first table which is created dynamically.
dbAdapter.open();
Log.i("In_View Resume_from_create",user_id_create);
objective.setText(dbAdapter.getObjective(user_id_create));
degree.setText(dbAdapter.getDegree(user_id_create));
passed_out.setText(dbAdapter.getPassedOut(user_id_create));
university.setText(dbAdapter.getUniversity(user_id_create));
field.setText(dbAdapter.getField(user_id_create));
years_of_experience.setText(dbAdapter.getyears_of_experience(user_id_create));
areas_of_interest.setText(dbAdapter.getareas_of_interest(user_id_create));
dbAdapter.close();
}
NOTE:
KEY_USERID is auto incremented only for USER_TABLE and not for RESUME_TABLE.
You can't have two automatic keys referring same elements on different tables.
You should only have automatic primary key in USER_TABLE. KEY_USERID can not be automatic, it must alwys be matched with USER_TABLE.KEY_USERID - effectively, a foreign key.
Furthermore, to understand why you are getting wrong id in code, you must post get_from_create function.

Create Android SQL Database with a few pre populate data

I've gone through many examples here, but all seem complicated and most of them are for large data. I'm new to both Android and also SQL. What I want to do is just pre-populate my SQL database with some data.
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE restaurants (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, address TEXT, type TEXT, notes TEXT, feed TEXT, lat REAL, lon REAL);");
ContentValues cv=new ContentValues();
cv.put("name", "Hi");
cv.put("address", "There");
cv.put("type", "delivery");
cv.put("notes", "");
cv.put("feed", "");
cv.put("lat", "");
cv.put("lon", "");
getWritableDatabase().insert("restaurants", "name", cv);
}
There is no error but unfortunately no data is inserted as well. This should be very simple, please help me?
Use db.insert("restaurants", "name", cv);
Your approach is fine, inside SQLiteOpenHelper#onCreate() is the right place to put initial data since that is where you create the database in the state you like it to be.
But inside onCreate you use db.insert("restaurants", "name", cv) directly. You are not finished to create the writable database you try to get via getWritableDatabase() at that point. Not sure if that is the problem but it could be.

How can I store an ArrayList<GeoPoint> in SQLite?

First and foremost, I've never worked with databases before. After reading through multiple post, it sounded a good idea to store the data that my program is gathering in an SQLite database. At the moment, my problem deals with storing an ArrayList of GeoPoints. I know that this can not be stored in an sqlite database. I've read through some of the other like questions and found that a solution may be to create a seperate table, and store all of the points in two columns of that table.
In my Database Adapter, I wrote:
// Make a New GeoPoint Table
public void geopointTable(String routeName)
{
String GeoTable = "CREATE TABLE " + routeName + "geopoints (_id INTEGER PRIMARY KEY, "
+ "KEY_GEOLONG REAL, "
+ "KEY_GEOLAT REAL);";
db.execSQL(GeoTable);
}
// Insert into GeoPoint Table
public long insertGeopoints (double longitude, double latitude, String routeName)
{
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_GEOLONG, longitude);
initialValues.put(KEY_GEOLAT, latitude);
return db.insert(routeName + "geopoints", null, initialValues);
}
In my main activity that gathers the geopoints and stores them in an array, I wrote:
db.open();
db.geopointTable(routeName);
Iterator<GeoPoint> i = points.iterator();
while (i.hasNext()) {
db.insertGeopoints(i.next().getLongitudeE6(), i.next()
.getLatitudeE6(), routeName);
This results in a fatal exception. I guess, in the end, I'd like to have a column in my row that hosts the name of the table that hosts the geopoints. Does anyone know an easier way to do this, or perhaps can see the problem(s) with the code.
while (i.hasNext()) {
db.insertGeopoints(i.next().getLongitudeE6(), i.next()
.getLatitudeE6(), routeName);
i.next() moves iterator to the next element, so for each iteration, you are inserting longitude from one elem, and latitude from next. If number of elements in array is odd, you are getting OutOfBound exception
About SQL: You probably should use one table for all routes:
CREATE TABLE route (id INTEGER PRIMARY KEY,
route_name text,
KEY_GEOLONG REAL,
KEY_GEOLAT REAL)"

Categories

Resources