How to store only unique entries in text file - java

I have an application that stores users data in a text file and I need to store only unique entries (e.g. a phone book), where out of the following fields: name, mobile number, and address, mobile number would be the unique key.
I'm using the following code to write my file:
try {
line = mUserName.getText().toString() + ","
phone.getText().toString() + ","
address.getText().toString();
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
String FILENAME = path + "/UsersData.txt"; // External is the text file name
FileWriter fWriter;
BufferedWriter writer;
fWriter = new FileWriter(FILENAME, true);
writer = new BufferedWriter(fWriter);
writer.append(line);
writer.newLine();
writer.close();
} catch (Exception e) {
result.append("\n" + e.getMessage());
}
What I'd like is for the application to check whether the phone number already exists in the file before it writes the new data, and if it does we tell the user that it's already in the file.
Is it possible to do this without harming application performance?
There's another option that we could store the data in a database, then convert it to a text file when they ask for it, would that be better?

If you write 2 or more thing with single line without seperate them with a character(i.e: #,% etc) will not be logical. If username ends with a number, you will not determine that this number is character of username or phone number.
So "line = mUserName.getText().toString() + phone.getText().toString() + address.getText().toString();" is wrong.
You should create a object class which has fields as userName, phoneNumber and address as:
public class Contact {
private String userName;
private String phoneNumber; //should be string it may start with +1 123...
private String address;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Then set your contact informations as a list, save and retrieve your contact list via using GSon and shared preferences via this answer: store and retrieve a class object in shared preference
You can search user contact information via retrieving your list from shared preferences.

Related

How to insert from an extended class

My information is read in via CSV for "banking information", A person CSV is
5
1,Tony,Stark,C,tonys,naslvj34-t934,stark#hmmm.org;tony#gmail.com;tostark55#yaho.com
2,Patrick,Hart,C,phart2,sdlwgl5034i52,hart#hmmm.org;hart1#who.org
3,Tom,Baker,E,bake95,kweojtnefq567,
4,Kevin,Black,C,keb765,prjhohier99,black#mail.org
5,Alex,Codd,E,alcodd,andlqjr78,codd#DBMS.org;alex#gmail.com
my Account CSV is,
5
1,313001,S,35881.12
2,313002,G,772400.34
3,313003,C,250002.15
4,313004,P,96310.66
5,313005,P,15624.15
1,313006,C,39950.99
In the Account CSV the 2nd token is My "Account type", so S = "Savings" G = "Gold Savings" C = "Checkings" and so on. When reading these in my CSV parser class, an object was made of the types, so A Checking class was made and when the CSV was tokenized when token[2] was equal to "C".
My Persons class is set up as so, excluding my getters and setters
private int personId;
private String firstName;
private String lastName;
private String type;
private String usrname;
private String password;
private ArrayList<String> emails;
public Person(int personId, String firstName, String lastName, String type, String usrname, String password,
ArrayList<String> emails) {
super();
And my Account class is set up as so.
private Person accountHolder;
private int accountNumber;
private double currentBalance;
public Account() {}
public Account(Person accountHolder, int accountNumber, double currentBalance) {
this.accountHolder = accountHolder;
this.accountNumber = accountNumber;
this.currentBalance = currentBalance;
}
This is one of my example account types (there are multiple)
public class CheckingAccount extends Account {
public CheckingAccount(Person p, int i, double d) {
super(p,i, d);
}
This is my database adder
public static void DbAddAccount(Person personId, Account accountHolder){
Connection conn = null;
try {
conn = DriverManager.getConnection(DatabaseInfo.URL, DatabaseInfo.USERNAME, DatabaseInfo.PASSWORD);
} catch (SQLException e) {
System.out.println("Connection Failed");
throw new RuntimeException(e);
}
String accountQuery = "insert into Account (accountId,accountNumber,currentBalance,type,personId) values (?,?,?,?,?);";
PreparedStatement accountPs = null;
ResultSet accountKeys = null;
int accountId = 0;
try {
//These are my prepare Statements for my queries
accountPs = conn.prepareStatement(accountQuery);
accountPs.setInt(1, accountId+ 1 );
accountPs.setInt(2, accountHolder.getAccountNumber());
accountPs.setDouble(3, accountHolder.getCurrentBalance());
accountPs.setString(4, ??????????????????????????????????);
accountPs.setInt(5, personId.getPersonId());
accountPs.executeUpdate();
accountPs.close();
conn.close();
}
catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
JDBC is not adding anything when running.
I think your code has following issues:
Account Object:
Object is missing field to store "Account Type"
Setting incorrect account type in DbAddAccount method
At line accountPs.setString(4, ??????????????????????????????????);
you are number of question marks (without enclosing in quote to make string) as account type which appears it is not correct.
series of ??? wont get converted to string without enclosed in quotes.
Even if you enclose in quotes, I think it wont be intended account number;
Solution
for Issue 1; declare account_type in Account Object.
for issue 2; instead of using accountPs.setString(4, ??????????????????????????????????);
use:
accountPs.setString(4, account.getAccountType());

Convert String to Enum to enable a file to be read

Im writing code that needs to take a file input and then reconstruct the values into an ArrayList.
This is the code ive done so far to convert a file to an object.
public static ArrayList<User> fileToObject() {
ArrayList<User> FileToObject = new ArrayList<>();
Scanner in = null;
boolean err0 = false;
try {
in = new Scanner(Paths.get("User_info.txt"));
} catch (IOException ex) {
err0 = true;
}
if (!err0) // if couldn't open file then skip
{
while (in.hasNext()) {
String theUser = in.nextLine();
String[] Line = theUser.split(",");
User user = null;
try {
if ( Line.length == 10) {
// reconstruct Address
Address a1 = new Address( Line[2], Line[3], Line[4], Line[5], Line[6],
Integer.parseInt( Line[7]));
// reconstruct Customer
user = new Customer( Line[0], Line[1], Line[2], Line[3], Line[4], Line[5], Line[6], Line[7],a1, Line[14]);
FileToObject.add(user);
} else {
return null;
}
} catch (NoSuchElementException ex) {
System.out.println("File improperly formed. Terminating.");
}
}
in.close();
}
// write object back to file.
File f1 = new File(Paths.get("User_info.txt").toUri());
Formatter out = null;
boolean err = false;
try {
out = new Formatter(f1);
} catch (FileNotFoundException ex) {
err = true;
}
if (!err) {
//System.out.println(e3.size());
for (User i : FileToObject) {
out.format("%s%n", i.toString()); // output the card object to cvs format
}
out.close();
}
}
}
My issue here is that element Line[5] of the array User( user = new Customer(Line[0], Line[1], Line[2], Line[3], Line[4], Line[5)) is of Type enum(as seen in the first constructor of the below customer class) so i get an error "Incompatible Type, String cannot be converted to UserType(UserType being the Enum).
import java.util.ArrayList;
public class Customer extends Billing {
Address customerAddress;
public Customer(String id, String firstName, String lastName, String userName, String password, UserType userType, PermissionType permission, Boolean Status, Address billingAddress, String email, Address customerAddress) {
super(id, firstName, lastName, userName, password, userType, permission, Status, billingAddress, email);
this.customerAddress = customerAddress;
permission = PermissionType.Booking;
userType = UserType.VIP;
setId(id);
setPermission(permission);
setCustomerAddress(billingAddress);
}
public Customer(String id, String firstName, String lastName, String userName, String password, UserType userType, PermissionType permission, Boolean Status, Address billingAddress, String email) {
super(id, firstName, lastName, userName, password, userType, permission, Status, billingAddress, email);
}
public Address getCustomerAddress() {
return customerAddress;
}
public void setCustomerAddress(Address customerAddress) {
this.customerAddress = customerAddress;
}
I spoke to my Tutor and he told me i need to convert the String to an Enum. Im unsure of what he meant by this as he wouldnt explain any Further. Is he talking about the String Array or do i need to convert the String within the file im reading to an enum? Im a bit lost so any help is greatly appreciated
If UserType is an enum, you can convert it with the static UserType.valueOf() method, i.e.:
UserType userType = UserType.valueOf(Line[5]);
Now you can use userType in place of Line[5] in the following code.
Note that Line[5] must exactly match the spelling of any of the enum types, or an IllegalArgumentException will be thrown.
If UserType.valueOf could not provide what you need, add a static method that returns specific UserType instance. For example:-
public enum UserType{
CUSTOMER("customer");
private String name;
UserType(String name){
this.name = name;
}
//A Map that holds user type name as key.
private static Map<String,UserType> userTypeMap = new HashMap<>();
//Populate userTypeMap with UserType instance
static{
for(UserType type : values()){
userTypeMap.put(type.name, type);
}
}
public static UserType of(String name){
return userTypeMap.get(name);
}
}
Callers could get UserType instance as below:-
UserType type = UserType.of("customer");
your solution is so long. there is an elegant way of doing this
Properties properties = new Properties();
properties.load(new FileInputStream(new File("FileLocation")));
properties.values();
File can contain, list of values, key value pairs. At line no 2 file is loaded in Properties object. Now u can process it according to your need.

how to fix the problem of not entering to Try block in android studio?

I am developing an android application. actually, my database is on localhost. I've developed my API using PHP. for the login page in android studio, I need to check if the user login credential is correct or not. I'm facing a problem when I want to deserialize the json that I've gotten from the API; the problem of not entering to the Try block!would you please check it and write for me what is the solution?
I checked if my API is working and I'm getting right json; this is a json from one of my login attempt:
{"status":"success","user_count":1,"user":{"id":"2","username":"yasi","password":"yasi"}}
I put a "Log" command at first of my class to check if the class is called and starts; it starts but is ignoring Try block and goes to the Catch block.
public void jsonToUser (String jsonUser){
String username,password,user_count;
try {
JSONObject jsonObject=new JSONObject(jsonUser);
username = jsonObject.getString("username");
password = jsonObject.getString("password");
user_count=jsonObject.getString("user_count");
if(user_count.equals("1"))
{
if (!username.equals("admin"))
{
Intent intent = new Intent(getActivity(), HomePageActivity.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(getActivity(), AdminHomePageActivity.class);
startActivity(intent);
}
}
else
Toast.makeText(getActivity(),"User not Found",Toast.LENGTH_LONG).show();
}
catch (JSONException e){
Log.d("error",e.getMessage());
}
}
I expect the next activity to be shown if I enter correct user login credential.
First of all, I am working on a Fragment and not an Activity.
secondly, this is the code to call my API in OnCreateView():
btnLogin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
new CheckUserLoginAsync().execute("http://10.0.2.2:80/whereToEatAPI/api/check_user_login_api.php"
,txtUsername.getText().toString()
,txtPassword.getText().toString());
Your JSON has this structure:
{
"status":"success",
"user_count":1,
"user": {
"id":"2",
"username":"yasi",
"password":"yasi"
}
}
So this line
username = jsonObject.getString("username");
is not going to return "yasi" as you probably expect, because "username" is a field of "user," not of the top level object. It is either going to throw an exception, or return null, in which case the code that checks if username is "admin" will throw an exception. Either way, you wind up in the catch.
Simply printing the result of getMessage() when you catch an exception is usually not a good idea because the "message" for NullPointerException is simply "null." (Not sure if this is because there is no message, or because the message actually says "null," but the effect is the same.) NPEs are very common, and "null" is rarely a useful error message, so you should always print at least the type of exception, or call printStackTrace, or just pass the entire exception to the logger, which will usually do the right thing with it.
Use Gson for best and optimized code
Add Gson dependency in gradle :
implementation 'com.google.code.gson:gson:2.8.5'
Now add two model classes in project
Login.class
public class Login {
#SerializedName("status")
#Expose
private String status;
#SerializedName("user_count")
#Expose
private Integer userCount;
#SerializedName("user")
#Expose
private User user;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Integer getUserCount() {
return userCount;
}
public void setUserCount(Integer userCount) {
this.userCount = userCount;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
and User.class
public class User {
#SerializedName("id")
#Expose
private String id;
#SerializedName("username")
#Expose
private String username;
#SerializedName("password")
#Expose
private String password;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
now replace json deserialization with this
public void jsonToUser (String jsonUser){
String username,password,user_count;
try {
Gson gson = new Gson();
Login login =gson.fromJson(jsonUser, Login.class);
username = login.getUser().getUsername();
user_count = String.valueOf(login.getUserCount());
password = login.getUser().getPassword();
if(user_count.equals("1"))
{
if (!username.equals("admin"))
{
Intent intent = new Intent(getActivity(), HomePageActivity.class);
startActivity(intent);
}
else
{
Intent intent = new Intent(getActivity(), AdminHomePageActivity.class);
startActivity(intent);
}
}
else
Toast.makeText(MainActivity.this,"User not Found",Toast.LENGTH_LONG).show();
}
catch (Exception e){
Log.e("error",e.getMessage());
}
}
This is an optimized and better way to do json parsing rather than manual parsing.
You are accessing username direct but it is in user object. So first get user object then try to get username and other fieilds.
JSONObject jsonObject=new JSONObject(jsonUser);
JSONObject jsonObjectUser=jsonObject.getJSONObject("user");
username = jsonObjectUser.getString("username");
password = jsonObjectUser.getString("password");
user_count=jsonObjectUser.getString("user_count");

Using Sugar ORM with UUID or Joda-Time

I'm creating a mobile application that will have users as defined below:
public class UserObject extends SugarRecord<UserObject>
{
public UUID Id;
public String Name;
public int DefaultSort;
public String Username;
public Date LastLogin;
public UserObject()
{
}
public UserObject(UUID id, String name, int defaultSort, String username, String password, Date lastLogin)
{
this.Id = id;
this.Name = name;
this.DefaultSort = defaultSort;
this.Username = username;
this.LastLogin = lastLogin;
}
}
These users will be retrieved from an API - the IDs are stored in the Database as uniqueidentifiers (or GUIDs in C#).
When I enter a new record into the users table, everything works just fine:
DateTime dt = new DateTime();
UUID newUID = UUID.randomUUID();
UserObject newUser = new UserObject(newUID, "David", 1, "userOne", "password", dt.toDate());
newUser.save();
However, when I try and retrieve the value back out I get an error:
Class cannot be read from Sqlite3 database. Please check the type of field Id(java.util.UUID)
Does Sugar ORM (or SQLite) simply not support UUIDs? If I try with the Joda DateTime, replacing the "LastLogin", the table just won't build at all so it looks as if it can create the fields, just not retrieve/store them...
You should not use var with name Id. Sugar record uses Id to store index values. Use anything except Id
public class UserObject extends SugarRecord{
public UUID uId;
public String Name;
public int DefaultSort;
public String Username;
public Date LastLogin;
public UserObject()
{
}
public UserObject(UUID uId, String name, int defaultSort, String username, String password, Date lastLogin)
{
this.uId= uId;
this.Name = name;
this.DefaultSort = defaultSort;
this.Username = username;
this.LastLogin = lastLogin;
}
}
from the v1.4 it is no longer need to use SugarRecord
Sugar ORM won't be able to build the date object again when retrieving data from the database. If you take a look at your database, it's probably storing strings (that's the case with me, and I'm using JODA).
In my case I overcame this issue by using strings instead of data objects. You will have to parse them after you retrieve the data from the database, but I believe that's the only option you have, since SQLite only support a few data types.

Creating new user MySQL syntax error

Hi I'm developing app for a school project and I want need to create a user which will be saved in the database.
I've created a Profile class
public class Profile{
private String username;
private String password;
public Profile(String _username, String _password){
this.username = _username;
this.password = _password;
}
public void setUsername(String username){
this.username = username;
}
public String getUsername(){
return this.username;
}
public void setPassword(String _password){
this.password = _password;
}
public String getPassword(){
return this.password;
}
Than I have created a DBConnect class which will contain all the methods one of them being CreateProfile which I want to user to Insert the values for new profile into the database "user" table.
public class DBConnect {
private Connection dbConnection;
public DBConnect(){
try{
dbConnection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=root");
}catch(Exception ex){
System.out.println("Connection failed :" +ex);
}
}
public void createProfile(Profile profile){
Statement stm = null;
try{
stm = dbConnection.createStatement();
stm.executeUpdate("INSERT INTO User (Username,Password) VALUES (\"" + profile.getUsername() + "\", \"" + profile.getPassword()+ "\"");
}catch(SQLException ex){
System.out.println(ex);
}
}
Finally in my JFrame I have two textFeilds username and password which I want to use in order to pass on the parameters for profile constructor. Once this is done I DBConnect object to start of the connection and than I'm calling the Create Profile method which is declared in the DBConnect.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
Profile p = new Profile(jTextField1.getText(), jPasswordField1.getText());
DBConnect dbc = new DBConnect();
dbc.createProfile(p);
Everything compiles but when I run the program and try to create a new Profile I get this Error.
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
My MySQL tables is a simple table with two columns called 'Username' and 'Password'
You need to put the right parenthesis inside the string:
stm.executeUpdate("INSERT INTO User (Username,Password) VALUES (\"" + profile.getUsername() + "\", \"" + profile.getPassword()+ "\")";

Categories