how to retrieve password value from the database - android

In this userdetails.java i am creating creating a table by name userdetails and inserting values
public class userdetails extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_userdetails);
Button dbsave = (Button)findViewById(R.id.save);
dbsave.setOnClickListener(this);
SQLiteDatabase db;
db = openOrCreateDatabase( "Student.db" , SQLiteDatabase.CREATE_IF_NECESSARY , null );
try {
final String UserDetails = "CREATE TABLE IF NOT EXISTS UserDetails ("
+ "NAME,"
+ "MOB_NO,"
+ "Q_NO,"
+ "Q_ANS,"
+ "MAIL_ID,"
+ "PASSWD);";
db.execSQL(UserDetails);
Toast.makeText(userdetails.this, "table created ", Toast.LENGTH_LONG).show();
}
catch (Exception e) {
Toast.makeText(userdetails.this, "ERROR "+e.toString(), Toast.LENGTH_LONG).show();
}
}
public void onClick(View view){
SQLiteDatabase db;
if(view.getId()==R.id.save)
{
EditText e1 = (EditText) findViewById(R.id.editText1);
String s1=e1.getText().toString();
EditText e2 = (EditText) findViewById(R.id.editText2);
EditText e3 = (EditText) findViewById(R.id.editText3);
String s3=e3.getText().toString();
EditText e4 = (EditText) findViewById(R.id.editText4);
String s4=e4.getText().toString();
EditText e5 = (EditText) findViewById(R.id.editText5);
String s5=e5.getText().toString();
EditText e6 = (EditText) findViewById(R.id.editText6);
String s6 =e6.getText().toString();
// Toast.makeText(Databasedb.this, "table created ", Toast.LENGTH_LONG).show();
String sql =
"INSERT or replace INTO UserDetails (" +
"Name, " +
"Mob_no, " +
"Q_no, " +
"Q_ans,"+
"Mail_id,"+
"Passwd) " +
"VALUES('"+s1+"','"+e2+"','"+s6+"','"+s3+"','"+s4+"','"+s5+"')" ;
db = openOrCreateDatabase( "Student.db" , SQLiteDatabase.CREATE_IF_NECESSARY , null );
db.execSQL(sql);
AlertDialog alertDialog = new AlertDialog.Builder(userdetails.this).create();
// alertDialog.setTitle("Alert Dialog");
alertDialog.setMessage("uservalues are successfully added/updated to the database");
alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(userdetails.this, Login.class);
userdetails.this.startActivity(intent);
}
});
alertDialog.show();
}}
}
and here is my login.java file from where i need to access the userdetails table
public class Login extends Activity implements OnClickListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button login = (Button) findViewById(R.id.login);
login.setOnClickListener(this);
Button exit = (Button) findViewById(R.id.exit);
exit.setOnClickListener(this);
TextView txt = (TextView) findViewById(R.id.sub);
txt.setOnClickListener(this);
TextView forgot = (TextView) findViewById(R.id.code);
forgot.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if(view.getId() == R.id.login)
{
EditText p1 = (EditText)findViewById(R.id.inputpasswd);
String s = p1.getText().toString();
Intent intent1= new Intent(this,homepage.class);
startActivity(intent1);
}
else
if(view.getId()==R.id.sub)
{
Intent intent2 = new Intent(this, userdetails.class);
startActivity(intent2);
}
else
{
Intent intent3 = new Intent(this, Forgotpassword.class);
startActivity(intent3);
}
}
}
please any one help me to retrieve values(from login.java) from the database`and comapare that value from the user entered value
thanx in advance....

You don't.
You execute a query of the general form
SELECT COUNT(*) FROM USERS WHERE USERNAME = ? AND PASSWORD = ?
and see whether the count returned is 1 or 0.
That way it's the database that does the comparing.
Also you don't have to deal with details of the password hashing in your code, as you would if you received and compared yourself.
Also there is much less data movement.
Also this procedure means that you can't leak to the user whether his username or his password was incorrect in the event of a failure, which conforms with good security design practice.

To check whether user have entered the proper credentials or not. Use this following code.
String username="";
String password="";
Cursor c = mydb.rawQuery("select * from Users where Username="+username+ " and Password="+password);
if(c.getCount()>0){
Toast.makeText(getApplicationContext(), "Login Succesful",Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(getApplicationContext(), "Login Failed", Toast.LENGTH_LONG).show();
}

Related

SQLiteDatabase.query() method not returning any data in the cursor

I tried using query method in my login system.My logic is simple.Once a user has registered using Email and Password,then he can login if the email and password matches in the Database.For the starter code, i wanted to read the row from the database that matches the email ad password.And if the query method only returns 1 row,then the user is taken to the next page.
But the problem is that query method does not return any row.I have provided the code below.Thanks
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login_signup);
demoText = (TextView) findViewById(R.id.demoText);
input_email = (EditText) findViewById(R.id.login_email);
input_password = (EditText) findViewById(R.id.login_password);
login = (Button) findViewById(R.id.login);
register = (Button) findViewById(R.id.register);
login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
login_email = input_email.getText().toString();
login_password = input_password.getText().toString();
Log.v("login_signup","Email= "+login_email+" Password"+login_password);
if(checkEntry(login_email,login_password)){
Intent i = new Intent(login_signup.this,anotherscreen.class);
startActivity(i);
Toast.makeText(login_signup.this,"Login Successful",Toast.LENGTH_SHORT).show();
}
else Toast.makeText(login_signup.this,"Login Failed",Toast.LENGTH_SHORT).show();
}
});
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(login_signup.this,Register.class);
startActivity(i);
}
});
toolbar= (Toolbar) findViewById(R.id.app_bar);
setSupportActionBar(toolbar);
getSupportActionBar().setIcon(R.drawable.text_icon);
dbHelper = new scannerDbHelper(this);
}
public boolean checkEntry(String email,String password){
db = dbHelper.getReadableDatabase();
String projection[] = {loginEntry.COLUMN_EMAIL_ID,loginEntry.COLUMN_PASSWORD};
String selection = loginEntry.COLUMN_EMAIL_ID + "= ?"+" AND "+loginEntry.COLUMN_PASSWORD + "= ?";
String selectionArgs[] = {email,password};
Cursor cursor = db.query(loginEntry.TABLE_NAME,projection,selection,selectionArgs,null,null,null);
demoText.setText("Rows returned "+ cursor.getCount());
if(cursor.getCount()== 1)
return true;
else
return false;
}

Android Studio get data from sqlite

I had some problem about get data from sqlite different database.One database that save user's name and phone and they can update as they like. While another is house information but also contain user's name and phone.
My problem is i just realize that the phone that had been update in user database is not same with phone that previous store in house database. So i wanna call the user's phone from user database and use for phone call function and message function. But it does not work.And i trying to match the fullname that in user database with house database to call the phone data but still cant.
here is my call and message function
public class HouseDetail extends AppCompatActivity {
EditText etAddress,etDetail,etPhone;
TextView txType,txProperty,txPrice,txState,txTitle,txOther,txSize,txFullname;
ImageButton bPhone,bMessage;
String type,property,price,state,address,title,other,size,detail,fullnames,fullname,phone;
HousesDB db = new HousesDB(this);
Houses houses;
DatabaseOperations Udb = new DatabaseOperations(this);
PersonalData profileInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_house_detail);
txType = (TextView) findViewById(R.id.txTypes);
txProperty = (TextView) findViewById(R.id.txProperty);
txPrice = (TextView) findViewById(R.id.txPrice);
txState = (TextView) findViewById(R.id.txState);
etAddress = (EditText) findViewById(R.id.etAddress);
txTitle = (TextView) findViewById(R.id.txTitle);
txOther = (TextView) findViewById(R.id.txOther);
txSize = (TextView) findViewById(R.id.txSize);
txFullname = (TextView) findViewById(R.id.txFullname);
etPhone = (EditText) findViewById(R.id.etPhone);
etDetail = (EditText) findViewById(R.id.etDetail);
bPhone = (ImageButton) findViewById(R.id.bPhone);
bMessage = (ImageButton) findViewById(R.id.bMessage);
fullnames = txFullname.getText().toString();
type = txType.getText().toString();
property = txProperty.getText().toString();
price = txPrice.getText().toString();
state = txState.getText().toString();
address = etAddress.getText().toString();
title = txTitle.getText().toString();
other = txOther.getText().toString();
size = txSize.getText().toString();
detail = etDetail.getText().toString();
phone = etPhone.getText().toString();
Intent i = getIntent();
property = i.getStringExtra("house_property");
txProperty.setText(property);
houses = db.getInfo(property);
txType.setText(houses.getTypes());
txFullname.setText(houses.getFullname());
txPrice.setText(houses.getPrice());
txState.setText(houses.getState());
etAddress.setText(houses.getAddress());
txTitle.setText(houses.getTitle());
txOther.setText(houses.getOther());
txSize.setText(houses.getSize());
etDetail.setText(houses.getDetail());
this.fullnames = fullname;
profileInfo = Udb.getNumber(fullname);
etPhone.setText(profileInfo.get_phone());
bPhone.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent callIntent =new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + etPhone));
startActivity(callIntent);
}
});
bMessage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("sms:" + etPhone)));
}
});
}
Here is my user database that get the phone number
public PersonalData getNumber(String fullname)
{
SQLiteDatabase SQ = this.getWritableDatabase();
String query = "select FullName,Phone from "+ Table_NAME;
Cursor CR = SQ.rawQuery(query,null);
String a;
PersonalData info = new PersonalData();
if (CR.moveToFirst())
{
do {
a = CR.getString(0);
if (a.equals(fullname)) {
info._phone = CR.getString(1);
break;
}
}while (CR.moveToNext());
}
return info;
}
try this:
public PersonalData getNumber(String fullName) {
SQLiteDatabase database = this.getReadableDatabase();
String table = "YOUR TABLE NAME";
String[] columns = {
"FullName" ,
"Phone"
};
Cursor cursor = database.query(table , columns , null , null , null , null , null);
cursor.moveToPosition(-1);
PersonalData info = new PersonalData();
while (cursor.moveToNext()) {
String name = cursor.getString(0);
if (name.equals(fullName)) {
info._phone = cursor.getString(1);
break;
}
}
cursor.close();
return info;
}
Replace
a = CR.getString(0);
if (a.equals(fullname)) {
info._phone = CR.getString(1);
break;
}
with
a = CR.getString(CR.getColumnIndex("Fullname"));
if (a.equals("FullName")) {
info._phone = CR.getString(CR.getColumnIndex("Phone"));
break;
}
your data gotten by query maybe not be ordered as you want,in your case that is, the result maybe not in "Fullname,Phone",so you should use getColumnIndex() to get data for each column.

Retrieving values from input texts android

I am trying to retrieve the values from the edit text input boxes and store them in a database. I am getting a null pointer exception and I am not sure why. Thanks in advance for the help :)
This is my code where I am retrieving the values and passing them as parameters to be stored in the database:
public class MyPage extends Activity {
final Context context = this;
public String stringName;
public int intAge;
public int intWeight;
public int intHeight;
public String stringGoal;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_page);
final Button button = (Button) findViewById(R.id.btn_addInfo);
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// custom dialog
final Dialog dialog = new Dialog(context);
dialog.setContentView(R.layout.dialogue_userinfo);
dialog.setTitle("Add Your Information");
Button dialogButton = (Button) dialog.findViewById(R.id.btnDone);
// if button is clicked, close the custom dialog
dialogButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
EditText textName = (EditText)findViewById(R.id.txtName);
stringName = textName.getText().toString();
EditText textAge = (EditText)findViewById(R.id.txtAge);
intAge = Integer.parseInt(textAge.getText().toString());
EditText textWeight = (EditText)findViewById(R.id.txtWeight);
intWeight = Integer.parseInt(textWeight.getText().toString());
EditText textHeight = (EditText)findViewById(R.id.txtHeight);
intHeight = Integer.parseInt(textHeight.getText().toString());
EditText textGoal = (EditText)findViewById(R.id.txtGoal);
stringGoal = textGoal.getText().toString();
DatabaseAccess();
dialog.dismiss();
}
});
dialog.show();
Window window = dialog.getWindow();
window.setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
}
});
}
private void DatabaseAccess(){
DatabaseHandler db = new DatabaseHandler(this);
/**
* CRUD Operations
* */
// Inserting User
Log.d("Insert: ", "Inserting ..");
db.addUser(new User(stringName, intAge, intWeight, intHeight, stringGoal));
//db.addUser(new User("Peter Parker", 23, 50, 150, "Hi"));
// Reading all users
Log.d("Reading: ", "Reading all contacts..");
List<User> users = db.getAllUsers();
for (User us : users) {
String log = "Id: "+us.getId()+" ,Name: " + us.getName() + " ,Age: " + us.getAge()
+ " ,Weight: " + us.getWeight() + " ,Height: " + us.getHeight()
+ " ,Goal: " + us.getGoal()
+ " ,BMI: " + us.getBmi();
Log.d("Name: ", log);
}
}
}
if All EditText's inside Dialog dialogue_userinfo layout then use Dialog instance for initializing EditText's instances on Button click. do it as:
EditText textName = (EditText)dialog.findViewById(R.id.txtName);
stringName = textName.getText().toString();
EditText textAge = (EditText)dialog.findViewById(R.id.txtAge);
intAge = Integer.parseInt(textAge.getText().toString());
//....same for others...
getText will return Editable Object. If your edittext has no any characters, it maybe return the null Object. So you have to check whether getText() return a null object.
if(youreditView.getText() != null ) {
String content = youreditView.getText().toString();
}

SQL query and force close challenge

here i tried to take name and password from database if the user have already an account, or sign up him by enter his data.
This is the first activity which has force close by clicking on first button to log into the data base
public class SelesMeter2Activity extends Activity implements OnClickListener {
EditText ed1;
EditText ed2;
Button b1;
Button b2;
SQLiteDatabase sql;
Cursor c;
Intent in;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ed1 = (EditText) findViewById(R.id.ed1);
ed2 = (EditText) findViewById(R.id.ed2);
b1 = (Button) findViewById(R.id.bt1);
b2 = (Button) findViewById(R.id.bt2);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
sql = openOrCreateDatabase("db", 0, null);
sql.execSQL("CREATE TABLE if not exists "
+ "Employee2 (password integer NOT NULL PRIMARY KEY,name text NOT NULL)");
}
#Override
public void onClick(View arg0) {
// log in
if (arg0.getId() == R.id.bt1) {
int p = 0;
String name = ed1.getText().toString();
String sp = ed2.getText().toString();
try {
// Attempt to parse the number as an integer
p = Integer.parseInt(sp);
} catch (NumberFormatException nfe) {
// parseInt failed, so tell the user it's not a number
Toast.makeText(this,
"Sorry, " + sp + " is not a number. Please try again.",
Toast.LENGTH_LONG).show();
}
if (c.getCount() != 0) {
c = sql.rawQuery("select * from Employee", null);
while (c.moveToNext()) {
if (name.equals("c.getString(1)") && p == c.getInt(0)) {
in = new Intent(this, secondview.class);
startActivity(in);
break;
}
}
}
else {
Toast.makeText(this,
"please sign up first or enter " + "correct data", 2000)
.show();
}
} else if (arg0.getId() == R.id.bt2) {
// sign up
Intent in2 = new Intent(this, signup.class);
startActivity(in2);
}
}
}
the second class that enter the new user which is not working as expected,
the toast does not work :
public class signup extends Activity implements OnClickListener {
EditText e1;
EditText e2;
SQLiteDatabase sql;
Button b;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.singupx);
Intent in = getIntent();
e1 = (EditText) findViewById(R.id.ed1s);
e2 = (EditText) findViewById(R.id.ed2s);
b = (Button) findViewById(R.id.bt1s);
b.setOnClickListener(this);
}
#Override
public void onClick(View v) {
String n = e1.getText().toString();
String sp = e2.getText().toString();
try {
// Attempt to parse the number as an integer
int p = Integer.parseInt(sp);
// This insertion will *only* execute if the parseInt was successful
// sql.execSQL("insert into Employee2(password,name)values('"+n+"',"+p+")");
ContentValues values = new ContentValues();
values.put("password", p);
values.put("name", n);
sql.insert("Employee2", null, values);
Toast.makeText(this, "Data inserted", Toast.LENGTH_LONG).show();
Intent in2 = new Intent(this, secondview.class);
startActivity(in2);
} catch (NumberFormatException nfe) {
// parseInt failed, so tell the user it's not a number
Toast.makeText(this,
"Sorry, " + sp + " is not a number. Please try again.",
Toast.LENGTH_LONG).show();
}
}
}
In the SelesMeter2Activity you'll have a NullPointerException at the line:
if (c.getCount() != 0) {
as you don't initialize the Cursor before that line. Move the query before the above line:
c = sql.rawQuery("select * from Employee", null);
if (c.getCount() != 0) {
// ...
You should post the exception you get from the logcat.
Also regarding your signup activity please don't instantiate the first activity to access fields from it. Open the database again in the second activity and insert the values.
This is why you are getting error
// you are calling the `c.getCount();` before you are assigning
// It will throw null pointer exception
if (c.getCount() != 0) {
c = sql.rawQuery("select * from Employee", null);
while (c.moveToNext()) {
if (name.equals(c.getString(1)) && p == c.getInt(0)) {
in = new Intent(this, secondview.class);
startActivity(in);
break;
}
}
}
Change the logic like
c = sql.rawQuery("select * from Employee", null);
c.moveToFirst();
if(!c.isAfterLast()) {
do {
if (name.equals(c.getString(1)) && p == c.getInt(0)) {
in = new Intent(this, secondview.class);
startActivity(in);
break;
}
} while (c.moveToNext());
}
and name.equals("c.getString(1)") should be name.equals(c.getString(1))
EDIT
Example of insert method
ContentValues values = new ContentValues();
values.put("password", n);
values.put("name", p);
database.insert("Employee2", null, values);

Intent data not displaying right

I'm having a issue where when I go to the next activity and pass then data with the intent it is only showing me the last entry off the DB and not the clicked items info.
.java
public class TimsFavs extends ListActivity implements OnItemClickListener {
/** Called when the activity is first created. */
ArrayList<String> results = new ArrayList<String>();
// Database results
String col0,col1,col2,col3,col4,col5,col6,col7;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.timsfavs);
DBAdapter db = new DBAdapter(this);
//---get all Locations---
db.open();
Cursor c = db.getAllLocation();
if (c.moveToFirst())
{
do {
col0 = c.getString(c.getColumnIndex(DBAdapter.KEY_ROWID));
col1 = c.getString(1);
col2 = c.getString(2);
col3 = c.getString(3);
col4 = c.getString(4);
col5 = c.getString(5);
col6 = c.getString(6);
col7 = c.getString(7);
results.add(col0);
} while (c.moveToNext());
}
db.close();
setListAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,results));
ListView lv;
lv = getListView();
lv.setTextFilterEnabled(true);
lv.setBackgroundColor(Color.rgb(83, 05, 14));
lv.setOnItemClickListener((OnItemClickListener) this);
}
public void onItemClick(AdapterView<?> TimsFavs, View view, int position, long id) {
Intent i = new Intent(getApplicationContext(), TimsFavsMore.class);
i.putExtra("ct_id_pass", col0);
i.putExtra("ct_storeid_pass", col1);
i.putExtra("ct_address_pass", col2);
i.putExtra("ct_city_pass", col3);
i.putExtra("ct_province_pass", col4);
i.putExtra("ct_country_pass", col5);
i.putExtra("ct_pcode_pass", col6);
i.putExtra("ct_phnum_pass", col7);
startActivity(i);
finish();
}
}
and my other activity is
`public class TimsFavsMore extends Activity {
DBAdapter db = new DBAdapter(this);
String rowId;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.timsfavsmore);
Intent i = getIntent();
Bundle b = i.getExtras();
final String rowId = b.getString("ct_id_pass");
final String phnum = b.getString("ct_phnum_pass");
final String storeid = b.getString("ct_storeid_pass");
final String address = b.getString("ct_address_pass");
final String city = b.getString("ct_city_pass");
final String province = b.getString("ct_province_pass");
final String country = b.getString("ct_country_pass");
final String pcode = b.getString("ct_pcode_pass");
TextView title = (TextView) findViewById(R.id.textview);
title.setText(Html.fromHtml("<br>Row ID: " + rowId + "<br><b><u>Location Address:</u></b><br><br>Store #" + storeid + "<br><br>" + address + "<br>" + city + ", " + province + "<br>" + country +"<br>" + pcode +"<br><br><b><u>Contact Info:</b></u><br><br>" + phnum +"<br>"));
// open to Nav
final Button button1 = (Button) findViewById(R.id.gohere);
button1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String uri = "google.navigation:q=Tim%20Hortons,%20" + address + ",%20" + city + ",%20" + province + ",%20" + pcode + "";
Intent i2 = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(i2);
}
});
// open to maps
final Button button2 = (Button) findViewById(R.id.showmap);
button2.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String uri2 = "geo:0,0?q=Tim%20Hortons,%20" + address + ",%20" + city + ",%20" + province + ",%20" + pcode + "";
Intent i3 = new Intent(Intent.ACTION_VIEW, Uri.parse(uri2));
startActivity(i3);
}
});
// Add to My Timmies List
final Button button3 = (Button) findViewById(R.id.removefav);
button3.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//---add 2 SQLite---
db.open();
if (db.deleteLocation(rowId))
Toast.makeText(getApplicationContext(), " Delete successful.",
Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(), "Delete failed.",
Toast.LENGTH_LONG).show();
db.close();
Intent i = new Intent(getApplicationContext(), MyTimmies.class);
startActivity(i);
finish();
}
});
final Button button4 = (Button) findViewById(R.id.favsdone);
button4.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent i4 = new Intent(getApplicationContext(), MyTimmies.class);
startActivity(i4);
finish();
}
});
}
}`
Any Ideas?
You are iterating through your cursor and assigning the values to your strings. when it completes the iteration, your strings only contain the last value you assigned and then you pass that.
You should bind your list to a SimpleCursorAdapter instead of creating a whole different string array. Then in your onClickListener, you can just pass the key that identifies your row of data in the database.

Categories

Resources