Android SQLite Database - Not reading decimal part of float from database - java

This is my first SQLite database with a float. I can't figure out why I am unable to store/retrieve the decimal parts of a float.
The database is defined as:
#Override
public void onCreate(SQLiteDatabase db){
// Create a string that contains the SQL statement to create the Nbmc device table
String SQL_CREATE_NBMC_TEMP_DATA_TABLE = "CREATE TABLE " + NbmcContract.NmbcTempData.TABLE_NAME + " ("
+ NbmcContract.NmbcTempData._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ NbmcContract.NmbcTempData.COLUMN_TIMESTAMP + " TEXT NOT NULL, "
+ NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT + " REAL) ";
db.execSQL(SQL_CREATE_NBMC_TEMP_DATA_TABLE);
}
I store floating point data in it from a service activity:
private static double lastSensorTempReading;
// ============ TEMP ==================
else if (UUID_SENSOR_FFF2.equals(characteristic.getUuid())) {
rxSensorDataType = FFF2_TEMP_CONST;
descStringBuilder.append("Elapsed Time: " + timeFormat.format(timeDiff) + "\n");
// temp comes in two bytes: newData[MSB], newData[LSB]
// temp = MSB + (0.1 * LSB)
int iTempMsb_i = (int) newData[0] & 0xff ;
int iTempLsb_i = (int) newData[1] & 0xff;
lastSensorTempReading = (float)iTempMsb_i + (0.10 * (float)iTempLsb_i);
Log.v("broadcastUpdate","Temp = " + lastSensorTempReading);
// Add this data to the temp Db
tempValues.put(NbmcContract.NmbcTempData.COLUMN_TIMESTAMP, estimatedTime);
tempValues.put(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT, lastSensorTempReading);
newRowId = db_temp.insert(NbmcContract.NmbcTempData.TABLE_NAME, null, tempValues);
}
And, when I use the Log.v to dump the value I think I am storing it looks correct (and it looks correct when I send it to the Main Activity via an intent).
V/broadcastUpdate: Temp = 33.3
However, when I read it back from the SQLite database in my MainActivity, I'm losing the part of the float/double that follows the decimal point but I'm not getting errors reported in the Logcat.
sb.append(" ------------------- Temperature Data -------------------------\n");
nbmcTempDbHelper = new NbmcTempDataDbHelper( this.getApplicationContext());
SQLiteDatabase tmpDb = nbmcTempDbHelper.getReadableDatabase();
c = tmpDb.rawQuery(" SELECT " + NbmcContract.NmbcTempData._ID + ", "
+ NbmcContract.NmbcTempData.COLUMN_TIMESTAMP + ", "
+ NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT +
" FROM " + NbmcContract.NmbcTempData.TABLE_NAME +
" LIMIT " + MAX_RESULTS_RETRIEVED + " OFFSET " + 0, null);
try {
if (c != null) {
if (c.moveToFirst()) {
do {
String tempRowId = c.getString(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData._ID));
String tempTimeString = c.getString(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_TIMESTAMP));
double tempDataDbl = c.getInt(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT));
Log.v("getEmailText", "Temp reading = " + tempDataDbl);
sb.append(tempRowId);
sb.append(DELIMITER);
sb.append(tempTimeString);
sb.append(DELIMITER);
sb.append(tempDataDbl);
sb.append(NEW_LINE);
} while (c.moveToNext());
}
}
} finally {
c.close();
tmpDb.close();
}
V/getEmailText: Temp reading = 30.0
V/getEmailText: Temp reading = 30.0
V/getEmailText: Temp reading = 30.0
V/getEmailText: Temp reading = 30.0

The problem is in this line
double tempDataDbl = c.getInt(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT));
While you are saving a Double you are retrieving an Integer. Just change the line to
double tempDataDbl = c.getDouble(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT));
Unfortunately AFAIK there is no way to get type mismatch. If you read through Data Types in SQLite it says :
In SQLite, the datatype of a value is associated with the value itself, not with its container. The dynamic type system of SQLite is backwards compatible with the more common static type systems of other database engines in the sense that SQL statements that work on statically typed databases should work the same way in SQLite. However, the dynamic typing in SQLite allows it to do things which are not possible in traditional rigidly typed databases.
Since any container e.g. INTEGER or REAL in your case can hold any and all kinds of data types and not even the database knows which type it is reading.

yes, dear
issue is at fetch time You having some problem with your code.
double tempDataDbl = c.getInt(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT));
change it to
double tempDataDbl = c.getDouble(c.getColumnIndexOrThrow(NbmcContract.NmbcTempData.COLUMN_DATA_FLOAT));

Related

Hbase loading .opv and .ope give hexadecimal output

I'm using Oracle Big Data Spatial & Graph v.2.5 and following the official guide to load through Java a Graph on HBase.
This is my code:
public class Main {
public static void main(String[] arg) throws Exception {
org.apache.log4j.BasicConfigurator.configure();
OraclePropertyGraphDataLoader opgdl = OraclePropertyGraphDataLoader.getInstance();
String vfile = "/root/oracle_property_files/connections.opv";
String efile = "/root/oracle_property_files/connections.ope";
PgHbaseGraphConfig cfg = GraphConfigBuilder.forPropertyGraphHbase()
.setName("config").setZkQuorum("zk01node,zk02node,zk03node").build();
OraclePropertyGraph opg = OraclePropertyGraph.getInstance(cfg);
opgdl.loadData(opg, vfile, efile, 48);
}
}
Using this libraries:
This is my .opv file:
1,name,1,Alice,,
1,age,2,,31,
2,name,1,Bob,,
2,age,2,,27,
And this is my .ope file:
1,1,2,knows,type,1,friends,,
My code creates on HBase the tables: configEI.
configGE.
configIT.
configVI.
configVT.
The problem is that if I launch the command scan 'configVT.' The output is mixed in hexadecimal and ASCII values:
hbase(main):003:0> scan 'configVT.'
ROW COLUMN+CELL
3v\x93ur|\xD7\xD3\x00\x00\x00\x00\x00\x00\x00\x02 column=v:i\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x01, timestamp=1624009988902, value=knows
3v\x93ur|\xD7\xD3\x00\x00\x00\x00\x00\x00\x00\x02 column=v:kage, timestamp=1624009989001, value=\x00\x00\x00\x1B\x02
3v\x93ur|\xD7\xD3\x00\x00\x00\x00\x00\x00\x00\x02 column=v:kname, timestamp=1624009989001, value=Bob\x01
\xCB\xFC%\xA7qt\x02\x84\x00\x00\x00\x00\x00\x00\x00 column=v:kage, timestamp=1624009988909, value=\x00\x00\x00\x1F\x02
\x01
\xCB\xFC%\xA7qt\x02\x84\x00\x00\x00\x00\x00\x00\x00 column=v:kname, timestamp=1624009988909, value=Alice\x01
\x01
\xCB\xFC%\xA7qt\x02\x84\x00\x00\x00\x00\x00\x00\x00 column=v:o\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x01, timestamp=1624009988909, value=knows
\x01
2 row(s) in 0.0490 seconds
I would like to have a more readable result.
Edit: It seems that String and Date types are stored correctly (but with some HEX escape character as Alice\x01). Instead the integers are totally converted to theirs HEX values.
I figured it out. Using the scan command, i read the tables as simply hbase tables, but they aren't, they are Oracle Big Data Spatial & Graph tables stored in hbase. So my configVT. table is only one of the five tables created with the java method opgdl.loadData and reading just it is not enough.
In order to get readable result, I should read it has edges or vertex:
opg.getVertices().forEach( e -> {
System.out.println("id vertex: " + e.getId());
e.getPropertyKeys().forEach(p -> {
System.out.println("property: " + p);
System.out.println("value: " + e.getProperty(p));
});
});
opg.getEdges().forEach( e -> {
System.out.println("label: " + e.getLabel());
System.out.println("id edge: " + e.getId());
Vertex vIn = e.getVertex(Direction.IN);
Vertex vOut = e.getVertex(Direction.OUT);
System.out.println("edge from: " + vOut.getId());
System.out.println("edge to: " + vIn.getId());
e.getPropertyKeys().forEach(p -> {
System.out.println("property: " + p);
System.out.println("value: " + e.getProperty(p));
});
});

How can i return multiple getters from my method?

I have made a method that is requesting a column from my MySQL database. Fortunately this is working, but i am trying to acces the return value. Because i want to acces the getters and setters for Voedingsmiddel. A new Voedingsmiddel is created inside the method and later returned. The values of the database are assigned as the attributes of the voedingsmiddel. This method is created in my Database class and i am trying to acces it within another class.
If i am trying to acces voedingsmiddel outside of the method, it is nog giving me an object, instead it is giving me the datalocation Voedingsmiddel#6f7fd0e6.
I was able to get some of the result i am trying to get. I achieved it by changing public Voedingsmiddel getVoedingsmiddelBijId to public double getVoedingsmiddelBijId. I also changed return voedingsmiddel; into voedingsmiddel.getCalorieen; So i was able to get 1 of the getters.
By calling the method Database.getVoedingsmiddelBijId(int).getCalorieen();
Intellij is telling me the following (Result of'Voedingsmiddel.getCalorieen()' is ignored).
public Voedingsmiddel getVoedingsmiddelBijId(int idVoedingsmiddel) {
Voedingsmiddel voedingsmiddel = new Voedingsmiddel("", 0, 0,0,0,0);
try {
String query = "select * from voedingsmiddel where idVoedingsmiddel = ?";
PreparedStatement preparedStatement = myCon.prepareStatement(query);
preparedStatement.setInt(1, idVoedingsmiddel);
myRes = preparedStatement.executeQuery();
while (myRes.next()) {
int idvoedingsmiddel = myRes.getInt("idVoedingsmiddel");
String naam = myRes.getString("naam");
int gram = myRes.getInt("gram");
double calorieen = myRes.getDouble("calorieën");
double koolhydraten = myRes.getDouble("koolhydraten");
double eiwitten = myRes.getDouble("eiwitten");
double vetten = myRes.getDouble("vetten");
voedingsmiddel = new Voedingsmiddel(naam, gram, calorieen, koolhydraten, eiwitten, vetten);
System.out.println("idVoedingsmiddel " + idvoedingsmiddel + " naam " + naam + " gram " + gram + " calorieën " + calorieen + " koolhydraten " + koolhydraten + " eiwitten " + eiwitten + " vetten " + vetten);
}
} catch (Exception exc) {
exc.printStackTrace();
System.out.println("Error: " + exc);
}
return voedingsmiddel;
}
First of all, i would really appreciate it, if someone could explain me what i am doing wrong. Also a solution to the problem would be more then welcome!
The expected result is that the return value of the method would be an object instead of what i think is a datalocation. So i can call the getters and setters for that object.
I have a history of posting too much code and not enough information. So i hope this is better, if not feel free to correct me.

java result set only writing one line instead of all selected into .csv

I have a java function that is meant to take strings from jlist called "readyList" and pulling data from mysql workbench tables with the intent to write a line for each string in a .csv file. With the current code it sucessfully pulls the data one at a time like i intended but it only writes the last line instead of all the lines. I want to have all the lines written in the .csv file. Please help!
int[] selectedIx = readyList.getSelectedIndices();
for (int i = 0; i < selectedIx.length; i++) {
// while (i < selectedIx.length) {
Object sel = readyList.getModel().getElementAt(selectedIx[i]);
Statement s1 = DBConnect.connection.createStatement();
String selTable01 = "SELECT Sku As s, Qty As q, Orig_Retail As prce, Orig_Sku As orgsk, Store As strcd "
+ "FROM completed_lines WHERE Form_Name = '" + sel + "' AND Warranty = 'true'";
s1.execute(selTable01);
try (ResultSet rs01 = s1.getResultSet()) {
fWriter = new FileWriter("Exports/Transfers/" + /* frmNm.replace(":", "_") */"EBW_" + GtDates.fdate + ".csv", false);
writer = new BufferedWriter(fWriter);
String header = "slip_number,slip_type,out_store,in_store,item_number,quantity,price,comment,to_num";
writer.write(header);
writer.newLine();
while (rs01.next()) {
String strcode = rs01.getString("strcd");
String sku = rs01.getString("s");
String qty = rs01.getString("q");
String price = rs01.getString("prce");
String orgsku = rs01.getString("orgsk");
//System.out.println(frmNm.split("_")[1] + qty + "," + sku + "," + vendor + "," + desc1 + "," + reas + "," + descdmg + "," + orgR + "," + nwsku + "," + desc2 + "," + qtyI);
String line = ""+","+"out"+","+strcode+","+"RTV"+","+sku+","+qty+","+price+","+"EBW"+","+orgsku;
writer.write(line);
writer.newLine();
}
}
// JOptionPane.showMessageDialog(frame, "All Data from Selected Forms has been Exported");
}
// FormCompelted();
writer.close();
}
}
A few issues with this code. The reason you're only getting the last result is because of this line:
fWriter = new FileWriter("Exports/Transfers/" + /* frmNm.replace(":", "_") */"EBW_" + GtDates.fdate + ".csv", false);
This line is inside your loop. The false as the last parameter tells FileWriter not to append. In other words, a false means overwrite the file if it exists. Since this is in your loop, each result overwrites the file that the last result created. You should create the FileWriter outside of your loop, probably in a try with resources. That will allow you to remove your writer.close() call, which should have been in a finally block anyway.
Not related to your original question but something you should be aware of: You're creating a new Statement with each loop iteration. This can be an expensive operation. You should use a PreparedStatement instead. Create it outside your loop and then just set the parameter and execute it inside the loop. It also implements AutoCloseable, so you can create it in a try with resources too, probably the same one you create your FileWriter in.

Input decimal or double numbers in JAVA

How can I input a decimal or double number as it is? I want if I input .56 it saves in the database as .56 not 1 because its rounding up and I want to ignore the rounding...
This is servlet, well I have beans and its also set to double; I also tried DecimalFormat but still not working or maybe I just don't know how to use it.
neutrophils = rs.getInt("neutrophils");
monocytes = rs.getInt("monocytes");
eosinophils = rs.getInt("eosinophils");
basophils = rs.getInt("basophils");
lymphocytes = rs.getInt("lymphocytes");
total= (neutrophils + monocytes + eosinophils + eosinophils + basophils + lymphocytes);
I made it like this, I changed the value of datatype to VARCHAR but the error is java.lang.NullPointerException; why is that?
neutrophils = Double.parseDouble(rs.getString("neutrophils"));
monocytes = Double.parseDouble(rs.getString("monocytes"));
eosinophils = Double.parseDouble(rs.getString("eosinophils"));
basophils = Double.parseDouble(rs.getString("basophils"));
lymphocytes = Double.parseDouble(rs.getString("lymphocytes"));
bands = (neutrophils + monocytes + eosinophils + eosinophils + basophils + lymphocytes);
If rs is ResultSet you can simply use rs.getDouble. If for some reason you don't want to use it, get the result as a String and then convert
Double.parseDouble(rs.getString(ColumnLabel));

After extracting data from html using a for loop, how do I insert one by one into a database?

I have extracted multiple data from an HTML using Jsoup and now I am trying to insert one by one into a derby db using JDBC on netbeans.
Here is my code:
public String nameOf() {
String nameStr = null;
String nameResults = "";
for(int j=100;j<=110;j++) {
refNum = j;
//System.out.println("Reference Number: " + refNum);
try {
//crawl and parse HTML from definition and causes page
Document docDandC = Jsoup.connect("http://www.abcd.edu/encylopedia/article/000" + refNum + ".htm").get();
// scrape name data
Elements name = docDandC.select("title");
nameStr = name.get(0).text();
//System.out.println(nameStr);
nameResults += nameStr + " ";
} catch (Exception e) {
//System.out.println("Reference number " + refNum + " does not exist.");
}
}
return nameResults;
So this method takes the names of diseases from 10 different HTMLs. What I am trying to do is to insert one name at a time to a derby db that I have created using JDBC. I have everything set up and all I have left to do is to insert each name in the corresponding name field of a table named DISEASE (which has fields: id, name, etc).
nameResults += nameStr + " ";
This part worries me as well since some diseases can have multiple words. Maybe I should use a list of some sort?
Please help! Thanks in advance.
Something like:
public List<String> nameOf() {
...
List<String> nameResults = new ArrayList<String>();
...
nameResults.add(nameStr);
...
return nameResults;

Categories