Phonegap app SQLite db initial set up - javascript

What are the best practices to build an app's database schema on first execution?
In other words what I am trying to find out is:
SQLite does not support comma separated queries to be executed as a one statement batch. How to replace that so that the code stays future proof? (I don't see myself putting all the create statements in tx.executeSQL("") chained sequentially it would turn my code into a horrible piece of cr*p).

What I do, in native code as well as in Sencha/Phonegap is to use a DatabaseHelper Class that I refer to. In that class you can see the version of the Database with :
public DataBaseHelper(Context context) {
super(context, DB_NAME, null, 2);
this.myContext = context;
}
public void createDataBase() throws IOException {
boolean dbExist = checkDataBase();
if (dbExist) {
// do nothing - database already exist
openDataBase();
int cVersion = myDataBase.getVersion();
if(cVersion != 2){
onUpgrade(myDataBase, myDataBase.getVersion(), 2);}
close();
} ....}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
this.getReadableDatabase();
try{
db.execSQL("ADD SQL QUERY HERE TO ADD TABLE");
}
catch(Exception e){}
}
private boolean checkDataBase() {
SQLiteDatabase checkDB = null;
try {
String myPath = DB_PATH + DB_NAME;
checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READWRITE);
} catch (SQLiteException e) {
// database does't exist yet.
}
if (checkDB != null) {
checkDB.close();
}
return checkDB != null ? true : false;
}
Although this is tedious it keeps your database future proof and the query is called at run time. This covers both your needs.
I hope this helps :)

Related

Set Image URL based on if condtion on ASPX page

As of now this code always works on my local and doesnt acts weird. But when we deploy on server even though if IsEnabled value is set to true it will load isfalse.gif and therafter few days it will start to load correct image based on IsEnabled value.
IsEnabled is an simple property defined in codebehind.
protected bool IsEnabled
{
get { return Utility.GetValue("TestKey"); }
}
Utility class pseudo:
public static class Utility
{
public static bool GetValue(string keyName)
{
bool kvalue = false;
// string value = string.Empty;
//the below cache is at global level defined below snippet is just pseudo how the data been present
Dictionary<string, string> dicCacheDictionary = new Dictionary<string, string>();
if (dicCacheDictionary.TryGetValue(keyName, out string value))
{
if (bool.TryParse(value, out bool result))
return result;
}
else
{
//GET FROM DATABASE AND add value to cache
//for now just for pseudo have hardcoded value
dicCacheDictionary.Add(keyName, "true");
}
//get from DB is not in cache
return kvalue;
}
}
ASPX Page :
<asp:Image ID="imgWebcast" ImageUrl='<%#(IsEnabled) ? "../../images/istrue.gif" : "../../images/isfalse.gif" %>' />
I looked at below areas and all looks good :
Cache precompiled files are deleted prior to deployment
Cached is cleared
IIS is reset
I can easily set it in code behind and resolve the above , but i need to understand the approach i did above is valid or not. Is something i am doing wrong. Does it achievable from the above approach

How can you retrieve multiple values from Firebase database in cloud functions?

I have the following function that I did in Java, it solves my problem, however I want to play with javascript as well. So I had the following problem: I only found functions that retrieve unique values, and I wanted a function similar to dataSnapshot.getChildren() that has in Java only that for JavaScript, if not, what would be the alternative?
To understand better, I'll leave the Java code here that works perfectly.
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
float okk = Float.valueOf(ds.child("value").getValue(String.class))/100000000;
prov += ds.child("wallet").getValue(String.class)+", "+String.format(Locale.US,"%.8f", okk)+"\n";
ds.getRef().removeValue();
}
tx_array.setText(prov);
}
#Override
public void onCancelled(#NonNull DatabaseError databaseError) {
}
});
The output will have to look like this, the same is in java.
39Hs93m61zYCaiaNe8yzgrDcutVAz2Kgdc, 0.00151515
3QMTHAaYcQB8kJxF5nxxBwskyCFukCNH8t, 0.00151515
3AcNSeB9DX3ZKvGxMaec9uZ98rY2BJKuzW, 0.00153787
36SjF1MBm2DE6YimNYiy9T4ez6Z7UA4rpg, 0.001540903
AHr3GF12div1Kgf6DegeiHSGQYssvbmih, 0.00162121
19vR7xchAg1vUgGwATwBsz5NYrVWYKdSQ3, 0.00164545
3KmfDgW9RdWp7P2ns3tydXsiChR5U9XKdT, 0.00165757
1C8rxppQk8mRSWB8xPKZ5DsYVykJBLNhV3, 0.00166212
Database Struct
If you take this piece of Java code:
mRef.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot dataSnapshot) {
for (DataSnapshot ds : dataSnapshot.getChildren()) {
float okk = Float.valueOf(ds.child("value").getValue(String.class))/100000000;
prov += ds.child("wallet").getValue(String.class)+", "+String.format(Locale.US,"%.8f", okk)+"\n";
ds.getRef().removeValue();
The equivalent in JavaScript would be:
ref.once("value").then(function(snapshot) {
snapshot.forEach(function(ds) {
var okk = ds.child("value").val() / 100000000;
prov += ds.child("wallet").val()+ ", "...
ds.ref.remove();
});
});
If you run into this type of question more often, I highly recommend reading the Android documentation and Web documentation side by side. They both follow the exact same structure, so once you know how to do something in Android, you can easily map it to JavaScript.
Based on what I read and the user told me, I was able to solve my problem with the following code, which works perfectly as I wanted.
exports.showEvent = functions.https.onRequest((req, res) => {
let prov = "";
return admin.database().ref('requests').once('value', (snapshot) => {
snapshot.forEach(function(ds) {
var okk = ds.child("value").val() / 100000000;
prov += ds.child("wallet").val()+ ", " + parseFloat(okk).toFixed(8) + "\n";
ds.ref.remove();
});
res.send(prov);
});
});

How to reflect Firebase Event Listener changes to a DIV element inside a web page [duplicate]

I have a simple HTML page printed out inside a Servlet. Here I have setup firebase admin sdk and have set a value event listener for a path.
When the events fire, I wish to change a Div element and display the results there.
EDIT: The listener does work on further testing with logs.
But I still do not know how to reflect the changes inside the div element as the Listeners are Asynchronous. That's most likely why the script isn't working.
Can someone please guide me as to what I should do. The code is as follows:
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseCredentials;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
#WebServlet("/WebWaitlistViewServelet")
public class WebWaitlistViewServelet extends HttpServlet {
private static final long serialVersionUID = 1L;
public WebWaitlistViewServelet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
try {
String cityName=request.getParameter("city");
String restId = request.getParameter("restid");
String userId = request.getParameter("userid");
if(cityName == null || restId == null || userId == null){
System.out.println("Error getting values");
return;
}else{
System.out.println(cityName+" "+restId+" "+userId);
}
pw.println("<HTML>");
pw.println("<HEAD>");
pw.println("<script>");
pw.println("function changePosition(position){ document.getElementById(\"positionInList\").innerHTML = position };");
pw.println("function changeTimeTillTurn(timetillturn){ document.getElementById(\"timeTillTurn\").innerHTML = timetillturn };");
pw.println("function showTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"visible\" };");
pw.println("function hideTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"hidden\" };");
pw.println("</script>");
pw.println("</HEAD>");
pw.println("<BODY>");
pw.println("<DIV align=\"center\">");
pw.println("<B>Your position in the waitlist is:</B>");
pw.println("</DIV><br/>");
pw.println("<DIV id=\"positionInList\" align=\"center\" style=\"color:blue\">");
pw.println("Loading...");
pw.println("</DIV><br/>");
pw.println("<DIV id=\"timeDiv\" align=\"center\">");
pw.println("<B>Approximate time till your turn is: </B><span id=\"timeTillTurn\" style=\"color:blue\">Loading...</span>");
pw.println("</DIV>");
pw.println("<BODY>");
pw.println("</HTML>");
pw.flush();
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/firebaseauth/firebase_admin_sdk_key.json");
// Initialize the app with a service account, granting admin privileges
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(is))
.setDatabaseUrl("https://restaurantrepo.firebaseio.com")
.build();
try {
FirebaseApp.initializeApp(options);
} catch (Exception e) {
//
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
DatabaseReference waitlistRef = FirebaseDatabase.getInstance().getReference().child(cityName).child(restId).child("waitlist");
Comparator<WaitlistedPerson> sortComparator = new Comparator<WaitlistedPerson>() {
#Override
public int compare(WaitlistedPerson lhs, WaitlistedPerson rhs) {
//sort ascending... the bigger the time entered, the later the person has joined... thus the higher the time entered the lower the position
//on waitlist
if(lhs.getTimeentered()<rhs.getTimeentered()){
//if time entered is lower, keep the person higher in the list
return -1;
}else if(lhs.getTimeentered()==rhs.getTimeentered()){
//if the time entered is the same, there are two cases possible
//1.. one person is remotely entered and one has entered at the resto POS... in this case, give priority to POS entered user
//2.. both people have remotely entered ... in this case, give preference to the person with lowest userid (he/she started using our app earlier)
//
//cases that will never happen are
//1.. two people with same userid entered remotely at same time .. can't happen as a second entry simply overwrites the old entry
//2.. two people with same time entered at POS ... can't happen as the resto host can only enter one party at a time..
if(!lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
//Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
//Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
return -1;
}else if(lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
//return the lowest user id
//userid is of format Uxx ... so get the xx part begining from index 1 of the string and get the number
int lhsuserid = Integer.parseInt(lhs.getUserid().substring(1));
int rhsuserid = Integer.parseInt(rhs.getUserid().substring(1));
//Log.d("FragmentCreate"," The userids are lhsuserid "+lhsuserid+" rhsuserid"+rhsuserid);
//Do not get tempted to use String compareto function as this will give wrong results
// U11 will get priority over U4 in string compareto due to 1 being lexicographically smaller
//Thus never use lexicographical sorting ever.
//The user ids can never be equal as two remotely entered users will never have two entries (can't... it's impossible due to firebase)
if(lhsuserid<rhsuserid){
return -1;
}else if(lhsuserid==rhsuserid){
//can never happen in real life... two remotely entered users can never have same id ever... just made for safeguard
return 0;
}else{
return 1;
}
}else if(!lhs.isRemotelyEntered() && !rhs.isRemotelyEntered()){
//both entered at POS and have same time
//can never happen in real life...
//made this just for testing scenarios in case i screw up and give wrong inputs
return 0;
}else{
//Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
//Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
return 1;
}
}else{
return 1;
}
}
};
ArrayList<WaitlistedPerson> listOfPeople = new ArrayList<>();
ValueEventListener eventListener = new ValueEventListener(){
#Override
public void onCancelled(DatabaseError error) {
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('Sorry, some error occured');</script>");
System.out.println("Sorry. some error occured");
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int positionCounter=0;
if(dataSnapshot.getChildrenCount()==1 || dataSnapshot.getChildrenCount() == 0 ){
//Log.d("FragmentCreate","This indicates that the restaurant probably closed down and removed all customers from the list");
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
System.out.println("You are no longer in the waitlist");
}else{
if(dataSnapshot.hasChild(userId)){
double averageWaitTime=0.0d;
long timeEnteredInMillis=0;
listOfPeople.clear();
Iterable<DataSnapshot> peopleInList = dataSnapshot.getChildren();
for(DataSnapshot currentPerson : peopleInList){
if(currentPerson.getKey().equals("dummy")){
continue;
}
if(currentPerson.getKey().equals(userId)){
//This is our node.... break the loop and enjoy using the counter
averageWaitTime = currentPerson.child("averagewaittimeperparty").getValue(Double.class);
timeEnteredInMillis = currentPerson.child("timeentered").getValue(Long.class);
listOfPeople.add(new WaitlistedPerson(currentPerson));
}else{
listOfPeople.add(new WaitlistedPerson(currentPerson));
}
}
//sort the list using our custom comparator and the get the index
Collections.sort(listOfPeople,sortComparator);
//find the position of the user now
for(WaitlistedPerson person : listOfPeople){
++positionCounter;
if(person.getUserid().equals(userId)){
break;
}
}
double timetillturn = Math.round(averageWaitTime * ((double)positionCounter));
long timeShouldComeAt = timeEnteredInMillis + (long)(timetillturn*60000);
Date timeWhenTurnArrives = new Date(timeShouldComeAt);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
pw.println("<script>showTimeTillTurn();</script>");
pw.println("<script>changePosition('"+positionCounter+"');</script>");
pw.println("<script>changeTimeTillTurn('"+sdf.format(timeWhenTurnArrives)+"');</script>");
System.out.println(positionCounter+" "+sdf.format(timeWhenTurnArrives));
}else{
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
System.out.println("You are no longer in the waitlist");
}
}
}
};
waitlistRef.addValueEventListener(eventListener);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
pw.close();
} catch (Exception e) {
//do nothing here
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
With servlets, your clients won't see any page updates until they send a new request to your application server. What you can do is get your ValueEventListener to update the state of an in-memory object. Then your servlet can read the latest state of that object whenever constructing the HTML output.
So i managed to solve this using a JSP instead of a Servelet.
In either case, the solution was to tranfer all the logic to a JavaScript function. Then calling the said function on body load.
onload=callthefunction()
The firebase listeners were converted from java to the JavaScript version:
on()
off()
This way there is need to call ajax or anything and the elements that need to be changed can be directly altered from JavaScript

change Dom element based on firebase admin value events

I have a simple HTML page printed out inside a Servlet. Here I have setup firebase admin sdk and have set a value event listener for a path.
When the events fire, I wish to change a Div element and display the results there.
EDIT: The listener does work on further testing with logs.
But I still do not know how to reflect the changes inside the div element as the Listeners are Asynchronous. That's most likely why the script isn't working.
Can someone please guide me as to what I should do. The code is as follows:
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.google.firebase.auth.FirebaseCredentials;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.DatabaseError;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;
import com.google.firebase.database.ValueEventListener;
#WebServlet("/WebWaitlistViewServelet")
public class WebWaitlistViewServelet extends HttpServlet {
private static final long serialVersionUID = 1L;
public WebWaitlistViewServelet() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
try {
String cityName=request.getParameter("city");
String restId = request.getParameter("restid");
String userId = request.getParameter("userid");
if(cityName == null || restId == null || userId == null){
System.out.println("Error getting values");
return;
}else{
System.out.println(cityName+" "+restId+" "+userId);
}
pw.println("<HTML>");
pw.println("<HEAD>");
pw.println("<script>");
pw.println("function changePosition(position){ document.getElementById(\"positionInList\").innerHTML = position };");
pw.println("function changeTimeTillTurn(timetillturn){ document.getElementById(\"timeTillTurn\").innerHTML = timetillturn };");
pw.println("function showTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"visible\" };");
pw.println("function hideTimeTillTurn(){ document.getElementById(\"timeDiv\").style.display = \"hidden\" };");
pw.println("</script>");
pw.println("</HEAD>");
pw.println("<BODY>");
pw.println("<DIV align=\"center\">");
pw.println("<B>Your position in the waitlist is:</B>");
pw.println("</DIV><br/>");
pw.println("<DIV id=\"positionInList\" align=\"center\" style=\"color:blue\">");
pw.println("Loading...");
pw.println("</DIV><br/>");
pw.println("<DIV id=\"timeDiv\" align=\"center\">");
pw.println("<B>Approximate time till your turn is: </B><span id=\"timeTillTurn\" style=\"color:blue\">Loading...</span>");
pw.println("</DIV>");
pw.println("<BODY>");
pw.println("</HTML>");
pw.flush();
InputStream is = getServletContext().getResourceAsStream("/WEB-INF/firebaseauth/firebase_admin_sdk_key.json");
// Initialize the app with a service account, granting admin privileges
FirebaseOptions options = new FirebaseOptions.Builder()
.setCredential(FirebaseCredentials.fromCertificate(is))
.setDatabaseUrl("https://restaurantrepo.firebaseio.com")
.build();
try {
FirebaseApp.initializeApp(options);
} catch (Exception e) {
//
}
// As an admin, the app has access to read and write all data, regardless of Security Rules
DatabaseReference waitlistRef = FirebaseDatabase.getInstance().getReference().child(cityName).child(restId).child("waitlist");
Comparator<WaitlistedPerson> sortComparator = new Comparator<WaitlistedPerson>() {
#Override
public int compare(WaitlistedPerson lhs, WaitlistedPerson rhs) {
//sort ascending... the bigger the time entered, the later the person has joined... thus the higher the time entered the lower the position
//on waitlist
if(lhs.getTimeentered()<rhs.getTimeentered()){
//if time entered is lower, keep the person higher in the list
return -1;
}else if(lhs.getTimeentered()==rhs.getTimeentered()){
//if the time entered is the same, there are two cases possible
//1.. one person is remotely entered and one has entered at the resto POS... in this case, give priority to POS entered user
//2.. both people have remotely entered ... in this case, give preference to the person with lowest userid (he/she started using our app earlier)
//
//cases that will never happen are
//1.. two people with same userid entered remotely at same time .. can't happen as a second entry simply overwrites the old entry
//2.. two people with same time entered at POS ... can't happen as the resto host can only enter one party at a time..
if(!lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
//Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
//Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
return -1;
}else if(lhs.isRemotelyEntered() && rhs.isRemotelyEntered()){
//return the lowest user id
//userid is of format Uxx ... so get the xx part begining from index 1 of the string and get the number
int lhsuserid = Integer.parseInt(lhs.getUserid().substring(1));
int rhsuserid = Integer.parseInt(rhs.getUserid().substring(1));
//Log.d("FragmentCreate"," The userids are lhsuserid "+lhsuserid+" rhsuserid"+rhsuserid);
//Do not get tempted to use String compareto function as this will give wrong results
// U11 will get priority over U4 in string compareto due to 1 being lexicographically smaller
//Thus never use lexicographical sorting ever.
//The user ids can never be equal as two remotely entered users will never have two entries (can't... it's impossible due to firebase)
if(lhsuserid<rhsuserid){
return -1;
}else if(lhsuserid==rhsuserid){
//can never happen in real life... two remotely entered users can never have same id ever... just made for safeguard
return 0;
}else{
return 1;
}
}else if(!lhs.isRemotelyEntered() && !rhs.isRemotelyEntered()){
//both entered at POS and have same time
//can never happen in real life...
//made this just for testing scenarios in case i screw up and give wrong inputs
return 0;
}else{
//Log.d("FragmentCreate","lhs userid "+lhs.getUserid()+" lhs remotelyentered "+lhs.isRemotelyEntered());
//Log.d("FragmentCreate","rhs userid "+rhs.getUserid()+" rhs remotelyentered "+rhs.isRemotelyEntered());
return 1;
}
}else{
return 1;
}
}
};
ArrayList<WaitlistedPerson> listOfPeople = new ArrayList<>();
ValueEventListener eventListener = new ValueEventListener(){
#Override
public void onCancelled(DatabaseError error) {
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('Sorry, some error occured');</script>");
System.out.println("Sorry. some error occured");
}
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
int positionCounter=0;
if(dataSnapshot.getChildrenCount()==1 || dataSnapshot.getChildrenCount() == 0 ){
//Log.d("FragmentCreate","This indicates that the restaurant probably closed down and removed all customers from the list");
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
System.out.println("You are no longer in the waitlist");
}else{
if(dataSnapshot.hasChild(userId)){
double averageWaitTime=0.0d;
long timeEnteredInMillis=0;
listOfPeople.clear();
Iterable<DataSnapshot> peopleInList = dataSnapshot.getChildren();
for(DataSnapshot currentPerson : peopleInList){
if(currentPerson.getKey().equals("dummy")){
continue;
}
if(currentPerson.getKey().equals(userId)){
//This is our node.... break the loop and enjoy using the counter
averageWaitTime = currentPerson.child("averagewaittimeperparty").getValue(Double.class);
timeEnteredInMillis = currentPerson.child("timeentered").getValue(Long.class);
listOfPeople.add(new WaitlistedPerson(currentPerson));
}else{
listOfPeople.add(new WaitlistedPerson(currentPerson));
}
}
//sort the list using our custom comparator and the get the index
Collections.sort(listOfPeople,sortComparator);
//find the position of the user now
for(WaitlistedPerson person : listOfPeople){
++positionCounter;
if(person.getUserid().equals(userId)){
break;
}
}
double timetillturn = Math.round(averageWaitTime * ((double)positionCounter));
long timeShouldComeAt = timeEnteredInMillis + (long)(timetillturn*60000);
Date timeWhenTurnArrives = new Date(timeShouldComeAt);
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
pw.println("<script>showTimeTillTurn();</script>");
pw.println("<script>changePosition('"+positionCounter+"');</script>");
pw.println("<script>changeTimeTillTurn('"+sdf.format(timeWhenTurnArrives)+"');</script>");
System.out.println(positionCounter+" "+sdf.format(timeWhenTurnArrives));
}else{
pw.println("<script>hideTimeTillTurn();</script>");
pw.println("<script>changePosition('You are no longer in the waitlist');</script>");
System.out.println("You are no longer in the waitlist");
}
}
}
};
waitlistRef.addValueEventListener(eventListener);
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
pw.close();
} catch (Exception e) {
//do nothing here
}
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
With servlets, your clients won't see any page updates until they send a new request to your application server. What you can do is get your ValueEventListener to update the state of an in-memory object. Then your servlet can read the latest state of that object whenever constructing the HTML output.
So i managed to solve this using a JSP instead of a Servelet.
In either case, the solution was to tranfer all the logic to a JavaScript function. Then calling the said function on body load.
onload=callthefunction()
The firebase listeners were converted from java to the JavaScript version:
on()
off()
This way there is need to call ajax or anything and the elements that need to be changed can be directly altered from JavaScript

Implementing pagination with Java servlets, MySQL, and Javascript for the front end

I'm having some trouble going through and visualizing how I accomplish pagination over a large dataset with a MySQL database, Java servlets, and using javascript to display the results.
I was working on a personal project with a small dataset to try and learn Java servlets / MySQL / JavaScript. I have a movie database with some movie names and other attributes in MySQL:
CREATE TABLE `movies` (
`id` int(11) NOT NULL AUTO INCREMENT,
`title` varchar(100) NOT NULL DEFAULT '',
`year` int(4) NOT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I then have a Movie java bean:
// Movie bean
import java.io.Serializable;
public class Movie implements Serializable {
// Instance variables
private Long id;
private String title;
private int year;
public Movie() {}
// Setters
public void setId (long id) { this.id = id; }
public void setTitle (String title) { this.title = title; }
public void setYear (int year) { this.year = year; }
// Getters
public long getId() { return id; }
public String getTitle() { return title; }
public int getYear() { return year; }
}
A MovieDAO which accesses the database and retrieves a list of all movies (below is an excerpt, assume I already connect to the database):
public class MovieDAO {
private List<Movie> movies;
private static ResultSet queryMovies(String st) throws SQLException {
ResultSet res = null;
try {
PreparedStatement ps = dbcon.prepareStatement(st);
res = ps.executeQuery();
} catch(SQLException e) {
System.out.println("Error with movieDAO query");
e.printStackTrace();
}
return res;
}
public List<Movie> listMovies() throws SQLException {
movies = new ArrayList<Movie>();
ResultSet res = queryMovies("SELECT * FROM movies");
while(res.next()) {
Movie mov = new Movie();
mov.setId(res.getLong("id"));
mov.setTitle(res.getString("title"));
mov.setYear(res.getInt("year"));
movies.add(mov);
}
return movies;
}
}
And finally my MovieServlet class which just displays all the information as a JSP variable that is a list:
#WebServlet("/movies")
public class MovieServlet extends HttpServlet {
private MovieDAO movieDAO;
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
movieDAO = new MovieDAO();
try {
List<Movie> movies = movieDAO.listMovies();
request.setAttribute("movies", movies); // JSP variable: ${movies}
request.getRequestDispatcher("movies.jsp").forward(request, response);
} catch (SQLException e) {
throw new ServletException("Could not retrieve movies from the database",e);
}
movieDAO.closeMovieDAO();
}
}
For the front end side of things I have a table which is populated through jsp and javascript. I originally just had a list of page numbers that were generated like so:
function showPageNumber() {
var html = '';
for(i = num_of_pages; i > 0; i--) { html += "<li class='page'><a>" + i + "</a></li>"; }
$('.page').click(function() {
result_min = ($(this).text() - 1) * results_per_page;
result_max = $(this).text() * results_per_page;
show(result_min,result_max);
});
}
function show(min,max) {
var $rows = $('#result_table');
$rows.hide().slice(min, max).show();
}
Inside each row of the table with the id of result_table, I had the jsp variables. I also had a sort function so when the user clicked on each header of the table, it would sort by that header (ie. clicking id would sort by ascending id). This worked great with even a few thousand records of movies and was actually relatively quick.
I then inserted about 80,000 more records into the database. Much to no ones surprise, loading all of that data takes ages. Sorting it takes even longer.
To deal with this, I only want to let the user access a next button, the first ten page number buttons, and a last button which goes to the last page. I figured limiting the number of possible movies helps display the data faster.
My problem is now how can I sort every record and display everything correctly? For example, if the user sorts by id they will get a list of ascending id's like so:
1 - movie1 - 1990
2 - movie2 - 1996
3 - movie3 - 1934
And if they click the same header the order will reverse like so:
3 - movie3 - 1934
2 - movie2 - 1996
1 - movie1 - 1990
But if I limit the amount of data retrieved, but I have a range of id's from 1 - 80,000 , how can I re-sort through all that data and retrieve the id values in reverse order now.. without having to call SELECT again?

Categories

Resources