I have below DBImporter class which is working fine and also inserting data correctly in database table. I am trying to fetch data from .CSV file and inserting into Oracle table.
Till now i was processing only one file in my directory and which is working fine. Now i want to process more than one file. So during run the first file process correctly and inserted data, in second file it started reading data and throw an error as :
java.lang.IllegalArgumentException: SQL array must not be empty
Below is my DBimporter class. I think the error is during final commit batch somewhere in line here but not sure
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
#Service
public class DBImporter {
private final static Logger log = LoggerFactory.getLogger(DBImporter.class);
private static final List<String> NULL_VALUES = Arrays.asList("", "N.A", "N.A", "UNKNOWN");
private static final List<String> COL_HEADERS = Arrays.asList("ID", "NM", "TYE", "SA");
private static final int BATCH_SIZE = 50;
private boolean eof = false;
private String tableName;
#Autowired
private JdbcTemplate jdbcTemplate;
public void setTableName(String tableName) {
this.tableName = tableName;
}
#Transactional(rollbackFor = IOException.class)
public void processFile(BufferedReader reader, String tableName) {
this.tableName = tableName;
List<String> sqlBatch = new ArrayList<String>(BATCH_SIZE);
log.info("Starte auslesen der Daten");
long t1 = System.currentTimeMillis();
log.info("Start time: " + t1);
jdbcTemplate.execute("DELETE FROM " + tableName);
while (!eof) {
try {
Map<String, ColumnData> dbColumns = getDBColumns();
// Get a list of db column data related to the column headers.
List<ColumnData> columnData = COL_HEADERS.stream().map(dbColumns::get).collect(toList());
// Get the next valid data row if its starts from "FRO" or "BO".
List<String> dataRow = findNextLineStartingWith(reader, "R", "T");
String query = createSql(columnData, dataRow);
sqlBatch.add(query);
// Process batch.
if (sqlBatch.size() >= BATCH_SIZE) {
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
}
} catch (IllegalStateException e) {
break;
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
// Commit the final batch.
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
long delta = System.currentTimeMillis() - t1;
log.info("Total runtime : " + delta / 1000 + " seconds");
}
/**
* Create a SQL insert query using the data row.
*
* #param tableName Name of the table.
* #param columnData Column data list.
* #param dataRow Data row to be inserted.
* #return Generated SQL query string.
*/
private String createSql(List<ColumnData> columnData, List<String> dataRow) {
List<String> values = new ArrayList<>(columnData.size());
for (int i = 0; i < columnData.size(); i++) {
if (NULL_VALUES.contains(dataRow.get(i))) {
values.add("NULL");
} else if (columnData.get(i).getType() >= Types.NUMERIC && columnData.get(i).getType() <= Types.DOUBLE) {
values.add(dataRow.get(i));
} else {
values.add("'" + dataRow.get(i).replace("'", "''") + "'");
}
}
return "INSERT INTO " + tableName + " (" +
columnData.stream().filter(Objects::nonNull).map(ColumnData::getName).collect(joining(", ")) +
", SYSTEM_INSERTED_AT) VALUES (" +
values.stream().collect(joining(", ")) +
", CURRENT_TIMESTAMP)";
}
/**
* Find the next line starting with the given string and split it into columns.
*
* #param reader BufferedReader object to be used.
* #param prefixes A list of prefixes to look for in the string.
* #return List of data objects.
* #throws IOException
*/
private List<String> findNextLineStartingWith(BufferedReader reader, String... prefixes) throws IOException {
while (true) {
String line = readLineOrThrow(reader);
for (String prefix : prefixes)
if (line.startsWith(prefix)) {
ArrayList<String> data = new ArrayList<>();
// Split the line using the delimiter.
data.addAll(Arrays.asList(line.split(";")));
// Build the row to be inserted.
List<String> row = Arrays.asList(data.get(1), data.get(2).trim(), "", "");
return row;
}
}
}
/**
* Read a single line in the file.
*
* #param reader BufferedReader object to be used.
* #return
* #throws IOException
*/
private String readLineOrThrow(BufferedReader reader) throws IOException {
String line = reader.readLine();
if (line == null) {
this.eof = true;
throw new IllegalStateException("Unexpected EOF");
}
return line.trim();
}
/**
* Read database column metadata.
*
* #param tableName Name of the table to process.
* #return A map containing column information.
*/
private Map<String, ColumnData> getDBColumns() {
Map<String, ColumnData> result = new HashMap<>();
try (Connection connection = jdbcTemplate.getDataSource().getConnection()) {
ResultSet rs = connection.getMetaData().getColumns(null, null, tableName, null);
while (rs.next()) {
String columnName = rs.getString(4).toUpperCase();
int type = rs.getInt(5);
result.put(columnName, new ColumnData(columnName, type));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Please try below changes:
// Commit the final batch.
if (sqlBatch.size() > 0){
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
}
And
#Transactional(rollbackFor = IOException.class)
public void processFile(BufferedReader reader, String tableName) {
eof = false;
...
But if you want a more clear and safe solution do changes in your code as below:
public class DBImporter {
private final static Logger log = LoggerFactory.getLogger(DBImporter.class);
private static final List<String> NULL_VALUES = Arrays.asList("", "N.A", "N.A", "UNKNOWN");
private static final List<String> COL_HEADERS = Arrays.asList("USER_ID", "NAME", "TYPE", "SRC_DATA");
private static final int BATCH_SIZE = 50;
#Autowired
private JdbcTemplate jdbcTemplate;
#Transactional(rollbackFor = IOException.class)
public void processFile(BufferedReader reader, String tableName) {
AtomicBoolean eof = new AtomicBoolean(false);
List<String> sqlBatch = new ArrayList<String>(BATCH_SIZE);
log.info("Starte auslesen der Daten");
long t1 = System.currentTimeMillis();
log.info("Start time: " + t1);
jdbcTemplate.execute("DELETE FROM " + tableName);
while (!eof.get()) {
try {
Map<String, ColumnData> dbColumns = getDBColumns(tableName);
// Get a list of db column data related to the column headers.
List<ColumnData> columnData = COL_HEADERS.stream().map(dbColumns::get).collect(toList());
// Get the next valid data row if its starts from "R" or "T".
List<String> dataRow = findNextLineStartingWith(reader, eof, "R", "T");
String query = createSql(tableName, columnData, dataRow);
sqlBatch.add(query);
// Process batch.
if (sqlBatch.size() >= BATCH_SIZE) {
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
}
} catch (IllegalStateException e) {
break;
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
// Commit the final batch.
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
long delta = System.currentTimeMillis() - t1;
log.info("Total runtime : " + delta / 1000 + " seconds");
}
/**
* Create a SQL insert query using the data row.
*
* #param tableName Name of the table.
* #param columnData Column data list.
* #param dataRow Data row to be inserted.
* #return Generated SQL query string.
*/
private String createSql(String tableName, List<ColumnData> columnData, List<String> dataRow) {
List<String> values = new ArrayList<>(columnData.size());
for (int i = 0; i < columnData.size(); i++) {
if (NULL_VALUES.contains(dataRow.get(i))) {
values.add("NULL");
} else if (columnData.get(i).getType() >= Types.NUMERIC && columnData.get(i).getType() <= Types.DOUBLE) {
values.add(dataRow.get(i));
} else {
values.add("'" + dataRow.get(i).replace("'", "''") + "'");
}
}
return "INSERT INTO " + tableName + " (" +
columnData.stream().filter(Objects::nonNull).map(ColumnData::getName).collect(joining(", ")) +
", SYSTEM_INSERTED_AT) VALUES (" +
values.stream().collect(joining(", ")) +
", CURRENT_TIMESTAMP)";
}
/**
* Find the next line starting with the given string and split it into columns.
*
* #param reader BufferedReader object to be used.
* #param prefixes A list of prefixes to look for in the string.
* #return List of data objects.
* #throws IOException
*/
private List<String> findNextLineStartingWith(BufferedReader reader, AtomicBoolean eof, String... prefixes) throws IOException {
while (true) {
String line = readLineOrThrow(reader, eof);
for (String prefix : prefixes)
if (line.startsWith(prefix)) {
ArrayList<String> data = new ArrayList<>();
// Split the line using the delimiter.
data.addAll(Arrays.asList(line.split(";")));
// Build the row to be inserted.
List<String> row = Arrays.asList(data.get(1), data.get(2).trim(), "", "");
// Insert type depending on the prefix.
if (prefix.equals("R"))
row.set(2, "USER");
else if (prefix.equals("T"))
row.set(2, "PERM");
row.set(3, String.join(";", row.subList(0, 3)));
return row;
}
}
}
/**
* Read a single line in the file.
*
* #param reader BufferedReader object to be used.
* #return
* #throws IOException
*/
private String readLineOrThrow(BufferedReader reader, AtomicBoolean eof) throws IOException {
String line = reader.readLine();
if (line == null) {
eof.set(true);
throw new IllegalStateException("Unexpected EOF");
}
return line.trim();
}
/**
* Read database column metadata.
*
* #param tableName Name of the table to process.
* #return A map containing column information.
*/
private Map<String, ColumnData> getDBColumns(String tableName) {
Map<String, ColumnData> result = new HashMap<>();
try (Connection connection = jdbcTemplate.getDataSource().getConnection()) {
ResultSet rs = connection.getMetaData().getColumns(null, null, tableName, null);
while (rs.next()) {
String columnName = rs.getString(4).toUpperCase();
int type = rs.getInt(5);
result.put(columnName, new ColumnData(columnName, type));
}
return result;
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
There is the possibility that your final batch is empty.
This is possible in case you just commited BATCH_SIZE entries and have cleared the sqlBatch. In case your while loop exits at this point of time,
there are no elements to commit.
You'll want to fix that by adding a size check, for example:
// Commit the final batch (only if there is something left)
if (sqlBatch.isEmpty() == false) {
jdbcTemplate.batchUpdate(sqlBatch.toArray(new String[sqlBatch.size()]));
sqlBatch.clear();
}
Edit:
As #Vasif pointed out you'll need to reset the eof between different calls of the method.
A simple solution (albeit somewhat hacky) would be
boolean eof = false
while (!eof) {
try {
} catch (IllegalStateException e) {
eof = true;
break;
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
}
A proper solution would be to refactor your code so that it does not rely on these exception being thrown.
Some tips:
Get rid of readLineOrThrow.
Remove the while(true) in findNextLineStartingWith and instead return an empty list if the next line is null.
Adjust the outside loop to handle this return value appropriately.
(Note: you might also need to break the loop if you get an IOException).
Related
I have a requirement to write Java program where I should read daily inventory feeds from suppliers, extract the data and add to the database. The feeds are different for each supplier and only in csv, txt or excel formats. Some suppliers may have extra columns in the feed, but they all guarantee to provide one column containing the product ID and one column containing the quantity (whose column indices can vary from supplier to supplier). Each product ID appears only once in a file. Part of the problem statement is dealing with data, sometimes placed in different positions within the feed for various suppliers.
I wrote below code assuming the columns are always named “product” and “quantity”. But any suggestions on how to handle this part of problem in a better way so that it is flexible to handle continued increase in the number of suppliers and their feeds in the future?
package com.file.handling;
import java.io.File;
import java.io.FileNotFoundException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Scanner;
public class Inventory {
private ArrayList<String> fileNames = new ArrayList<>();
public Inventory(ArrayList<String> fileNames) {
this.fileNames = fileNames;
}
/**
* This is the main method that initiates file read to get data
* #return Nothing.
* #exception FileNotFoundException On file not found.
* #see FileNotFoundException
*/
public void addItems(){
for (String filename: fileNames){
try{
URL url = getClass().getResource(filename);
File myObj = new File(url.getPath());
Scanner myReader = new Scanner(myObj);
ArrayList<String> lines = new ArrayList<>();
while (myReader.hasNextLine()){
lines.add(myReader.nextLine());
}
extractData(lines, myObj.getName());
myReader.close();
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
}
/**
* This is a private method which extracts productID, suppleirID and Quantity values from data passed
* #param lines arraylist of string data
* #param filename
* #return Nothing.
*/
private void extractData(ArrayList<String> lines, String filename) {
// Get fieldNames
String fieldNameString = lines.remove(0);
String[] fieldNames;
// Get supplierID and file type
String supplierID = filename.split("\\.")[0];
String fileType = filename.split("\\.")[1];
// Get index of fieldName product and quantity/inventory based on file type
int productIdx = -1;
int quantityIdx = -1;
if (fileType.equals("csv") || filename.equals("xlsb") || fileType.equals("xls") || fileType.equals("xlsx") || fileType.equals("xlsm")){
fieldNames = fieldNameString.split(",");
for (int i=0; i<fieldNames.length; i++){
String fieldName = fieldNames[i];
if (fieldName.toLowerCase().equals("product"))
productIdx = i;
else if (fieldName.toLowerCase().equals("inventory") || fieldName.toLowerCase().equals("quantity"))
quantityIdx = i;
}
// loop through remaining data to get productIDs and their quantities
for (String line: lines){
String productID = line.split(",")[productIdx];
int quantity = Integer.valueOf(line.split(",")[quantityIdx]);
System.out.println("ProductID: " + productID + " quantity: " + quantity + " SupplierID: " + supplierID);
// create SupplierProduct Object
SupplierProduct supplierProduct = new SupplierProduct(supplierID, productID, quantity);
// WriteToDB - use supplierProduct to write to database
}
} else if (fileType.equals("tsv") || fileType.equals("tab")) {
fieldNames = fieldNameString.split("\\s+");
for (int i=0; i<fieldNames.length; i++){
String fieldName = fieldNames[i];
if (fieldName.toLowerCase().equals("product"))
productIdx = i;
else if (fieldName.toLowerCase().equals("inventory") || fieldName.toLowerCase().equals("quantity"))
quantityIdx = i;
}
// loop through remaining data to get productIDs and their quantities
for (String line: lines){
String productID = line.split("\\s+")[productIdx];
int quantity = Integer.valueOf(line.split("\\s+")[quantityIdx]);
System.out.println("ProductID: " + productID + " Quantity: " + quantity + " SupplierID: " + supplierID);
// create SupplierProduct Object
SupplierProduct supplierProduct = new SupplierProduct(supplierID, productID, quantity);
// WriteToDB - use supplierProduct to write to database
}
}
}
}
class SupplierProduct {
private String supplierID;
private String productID;
private int quantity;
public SupplierProduct(String supplierID, String productID, int quantity) {
this.supplierID = supplierID;
this.productID = productID;
this.quantity = quantity;
}
}
I am trying to read an excel sheet
Added required Jars
Added poi jars within .classpath are below
<classpathentry kind="lib" path="External_Jars/poi/commons-codec-1.10.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/commons-logging-1.2.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/curvesapi-1.03.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/jsqlparser-0.8.0.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/poi-3.14-20160307.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/poi-excelant-3.14-20160307.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/poi-ooxml-3.14-20160307.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/poi-ooxml-schemas-3.14-20160307.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/poi-scratchpad-3.14-20160307.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/sqlsheet-6.5.jar"/>
<classpathentry kind="lib" path="External_Jars/poi/xmlbeans-2.6.0.jar"/>
Exception is -
java.lang.IllegalArgumentException: Cell index must be >= 0
at org.apache.poi.xssf.usermodel.XSSFRow.getCell(XSSFRow.java:237)
at org.apache.poi.xssf.usermodel.XSSFRow.getCell(XSSFRow.java:224)
at org.apache.poi.xssf.usermodel.XSSFRow.getCell(XSSFRow.java:44)
at com.hp.commercial.framework.common.JDBCExcel.updateTestCaseDoc(JDBCExcel.java:546)
at com.hp.commercial.framework.common.WebDriverListener1.afterInvocation(WebDriverListener1.java:262)
at org.testng.internal.invokers.InvokedMethodListenerInvoker$InvokeAfterInvocationWithoutContextStrategy.callMethod(InvokedMethodListenerInvoker.java:100)
at org.testng.internal.invokers.InvokedMethodListenerInvoker.invokeListener(InvokedMethodListenerInvoker.java:62)
at org.testng.internal.Invoker.runInvokedMethodListeners(Invoker.java:566)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:713)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:869)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1193)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:126)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Read excel sheet code
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.openqa.selenium.remote.RemoteWebDriver;
public class JDBCExcel{
private Connection con = null;
private ResultSet resultSet = null;
private Statement st = null;
private Workbook workBook = null;
private FileInputStream fileInputStream = null;
private String filePath = null;
/**
* WritingExcel method will be used with inline calling from method where
* needed to update excel sheet after updating by POI.
* #throws SQLException
*/
private void WritingExcel() throws SQLException {
try {
// closing connectiona and fileinput Stream for already oepened excel file
this.connectionClose();
// creating fileoutput Stream and writing
FileOutputStream fileOutput = new FileOutputStream(new File(filePath));
workBook.write(fileOutput);
// closing fileoutput Steram
fileOutput.close();
// Reloading excel file using fileinput Stream
this.loadExcel(filePath);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* load excel file from path. Based on its extension .xls or .xlsx, workbook
* using POI As well, formal declaration to get connection for driver
* manager using SqlSheet API
*
* #param path
*
*/
public void loadExcel(String path) {
try {
filePath = path;
fileInputStream = new FileInputStream(new File(filePath));
// check extension of file to determine workbook type
String fileExt = path.substring(path.indexOf(".")).toLowerCase();
// create workbook class based on file extension
if (fileExt.equals(".xls"))
workBook = new HSSFWorkbook(fileInputStream);
else if (fileExt.equals(".xlsx"))
workBook = new XSSFWorkbook(fileInputStream)
} catch (Throwable e) {
e.printStackTrace();
}
}
/**
* getRowId method to get particular row idneified by id value in ID column
* in Last-to-First manner. This will be handled by SqlSheet API
*
* #param sheet
* #param id
* #return
* #throws SQLException
*/
public Map<String, String> getRowbyID(String sheet, String id)
throws SQLException {
Map<String, String> map = new HashMap<>();
// TO DO.. how to execute Where in SQL Query in JAVA 8
String strQuery = "SELECT * FROM " + this.getSheetFormat(sheet); // + " WHERE ID= '" + id +
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
ResultSetMetaData rmd = resultSet.getMetaData();
while (resultSet.next()) {
//drawback to read cell again..so this is used.
String idCell = resultSet.getString("ID");
// Temporary solution until Where clause working in SQL Query
if (id.equalsIgnoreCase(idCell)) {
int columntCount = rmd.getColumnCount();
map.put(rmd.getColumnName(1), idCell);
for (int i = 2; i <= columntCount; i++) {
map.put(rmd.getColumnName(i), resultSet.getString(i));
}
break;
}
}
resultSet.close();
return map;
}
public String getValuebyParamName(String sheet, String paramName)
throws SQLException {
String strParamValue = "";
// TO DO.. how to execute Where in SQL Query in JAVA 8
String strQuery = "SELECT * FROM " + this.getSheetFormat(sheet); // + " where ParamName = " + paramName;
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
while (resultSet.next()) {
// Temporary solution until Where clause working in SQL Query
if (paramName.equalsIgnoreCase(resultSet.getString("ParamName"))) {
strParamValue = resultSet.getString("ParamValue");
strParamValue = (strParamValue == null) ? "" : strParamValue;
break;
}
}
resultSet.close();
return strParamValue;
}
public String getValueByAnyColumn(String sheet, String refColumn, String refKey, String targetCol)
throws SQLException {
String strValue = "";
String strQuery = "SELECT * FROM " + this.getSheetFormat(sheet);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
while (resultSet.next()) {
if (refKey.equalsIgnoreCase(resultSet.getString(refColumn))) {
strValue = resultSet.getString(targetCol);
strValue = (strValue.equalsIgnoreCase("$Null")) ? "" : strValue;
break;
}
}
resultSet.close();
return strValue;
}
public String getNextValueOfColumn(String sheet, String column, String refKey) throws SQLException {
String strValue = "";
String strQuery = "SELECT * FROM " + this.getSheetFormat(sheet);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
resultSet.last();
int resultSize = resultSet.getRow();
resultSet.beforeFirst();
while (resultSet.next()) {
if (refKey.equals(resultSet.getString(column))) {
if ((resultSize) == resultSet.getRow()) {
resultSet.first();
strValue = resultSet.getString(column);
strValue = (strValue.equalsIgnoreCase("$Null")) ? "" : strValue;
} else {
resultSet.next();
strValue = resultSet.getString(column);
strValue = (strValue.equalsIgnoreCase("$Null")) ? "" : strValue;
}
break;
}
}
resultSet.close();
return strValue;
}
public void updateParticularColumnValue(String sheetNm, String columnNm, String targetValue, String replaceValue, String... ParamName) throws Exception{
// Declaring Variables
String paramName = ParamName.length > 0 ? ParamName[0]: "";
Iterator<Row> rows = null;
ArrayList<String> columnNames = new ArrayList<String>();
// Opening spreadsheet
Sheet sheetName = workBook.getSheet(sheetNm);
// Collecting row Iterator
rows = sheetName.rowIterator();
// Reading first row of excel as column Titles
if (rows.hasNext()) { columnNames = this.getAllColumnTitles(rows.next().cellIterator()); }
boolean isForSingleRow = !paramName.isEmpty();
// Reading rest of rows as column values
while (rows.hasNext()) {
// getting next row
Row row = rows.next();
if(isForSingleRow) {
// not updating single row
break;
}
else {
if (row.getCell(columnNames.indexOf(columnNm.toLowerCase())).getStringCellValue().equalsIgnoreCase(targetValue)) {
//Else update each row turn by turn in loop
row.getCell(columnNames.indexOf(columnNm.toLowerCase())).setCellValue(replaceValue);
if (rows.hasNext()) {
row = rows.next();
row.getCell(columnNames.indexOf(columnNm.toLowerCase())).setCellValue(targetValue);
} else {
if (DriverScript.executionMode.equalsIgnoreCase("ITG")) {
CommonUtils.getExcel(Excel.Files.User).updateParticularColumnValue(Excel.User.Password.name(), "ITGStatus", "Old", "New");
} else {
CommonUtils.getExcel(Excel.Files.User).updateParticularColumnValue(Excel.User.Password.name(), "Status", "Old", "New");
}
}
break;
}
}
}
WritingExcel();
}
public List<ExecutionConfig> getModules() throws SQLException {
List<ExecutionConfig> listReturn = new ArrayList<ExecutionConfig>();
String Product = DriverScript.product;
String ProductExecutionconfig = Product + "ExecutionConfig";
// TO DO.. how to execute Where in SQL Query in JAVA 8
String strQuery = "SELECT * FROM " + this.getSheetFormat(ProductExecutionconfig); // +
// " WHERE SelectedToExecute='Yes' and Executed='No'";
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
Map<ExecutionConfig, Integer>unsortedExecutionConfigMap = new LinkedHashMap<>();
while (resultSet.next()) {
// Temporary solution until Where clause working in SQL Query
if ("Yes".equalsIgnoreCase(resultSet.getString("SelectedToExecute"))
&& "No".equalsIgnoreCase(resultSet.getString("Executed"))) {
ExecutionConfig obj = new ExecutionConfig(
resultSet.getString("ModuleName"),
resultSet.getString("TestCategory"),
resultSet.getString("RiskLevel"),
0); //No priority as it is decided in next block
unsortedExecutionConfigMap.put(obj, Integer.valueOf(resultSet.getString("ExecutionPriority").isEmpty() ? "0" : resultSet.getString("ExecutionPriority")));
}
}
resultSet.close();
Integer[] uniquePriorityNumbers = unsortedExecutionConfigMap.values().stream().sorted().distinct().toArray(Integer[]::new);
for(int currentPriority : uniquePriorityNumbers){
unsortedExecutionConfigMap.entrySet().forEach(e ->
{
if(e.getValue() == currentPriority){
ExecutionConfig eObj = e.getKey();
eObj.setModulePriority(listReturn.size());
listReturn.add(eObj);
}
});
}
return listReturn;
}
public List<TestCases> getActionList(ExecutionConfig selectedConfig)
throws SQLException {
String strModule = selectedConfig.strModuleName;
String strTestCategory = selectedConfig.strTestCat;
String strRiskLevel = selectedConfig.strRiskLevel;
List<TestCases> listReturn = new ArrayList<TestCases>();
// TO DO.. how to execute Where in SQL Query in JAVA 8
String strQuery = "SELECT * FROM " + this.getSheetFormat(strModule);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
while (resultSet.next()) {
String testCategory = resultSet.getString("TestCategory");
String riskLevel = resultSet.getString("RiskLevel");
if ("1".equalsIgnoreCase(String.valueOf(resultSet.getInt("Enabled"))) && "Automated".equalsIgnoreCase(resultSet.getString("TestExecution")) && strTestCategory.equalsIgnoreCase(testCategory) && strRiskLevel.equalsIgnoreCase(riskLevel)) {
TestCases obj = new TestCases(resultSet.getString("TCID"),
resultSet.getString("Action"),
testCategory,
riskLevel,
resultSet.getString("TestDescription"));
listReturn.add(obj);
}
}
resultSet.close();
return listReturn;
}
public void updateExecutionConfig(String strModuleName,
String strTestCategory) throws SQLException, IOException {
// Declaring Variables
String Product = getValuebyParamName(DriverScript.prodConfigSheetName,
"Product");
String ProductExecutionconfig = Product + "ExecutionConfig";
Iterator<Row> rows = null;
ArrayList<String> columnNames = new ArrayList<String>();
int updateRow = 0;
// Opening spreadsheet
Sheet sheetName = workBook.getSheet(ProductExecutionconfig);
// Collecting row Iterator
rows = sheetName.rowIterator();
// Reading first row of excel as column Titles
if (rows.hasNext()) {
columnNames = this.getAllColumnTitles(rows.next().cellIterator());
}
// Reading rest of rows as column values
while (rows.hasNext()) {
// getting next row
Row row = rows.next();
// converting cell type to String type to read cell value as string
row.getCell(columnNames.indexOf("modulename")).setCellType(
Cell.CELL_TYPE_STRING);
row.getCell(columnNames.indexOf("testcategory")).setCellType(
Cell.CELL_TYPE_STRING);
if ((String.valueOf(row.getCell(columnNames.indexOf("modulename")))
.equalsIgnoreCase(strModuleName))
&& (String.valueOf(row.getCell(columnNames
.indexOf("testcategory")))
.equalsIgnoreCase(strTestCategory))) {
{
// updating row
row.getCell(columnNames.indexOf("executed")).setCellValue(
"Yes");
updateRow++;
}
}
}
LocalLogManager.logf.info(Product + "ExecutionConfig for Module "
+ strModuleName + " has been updated for rows " + updateRow);
WritingExcel();
}
public void connectionClose() throws SQLException, IOException {
if (con != null){
con.close();
fileInputStream.close();}
}
public Connection getCon() {
return con;
}
public Statement getSt() {
return st;
}
public void closeStmt() throws SQLException {
if (st != null)
st.close();
}
public void updateTestCaseDoc(String sModuleName, String sActionName,
String sStatus) throws SQLException, ClassNotFoundException {
// Declaring Variables
Iterator<Row> rows = null;
ArrayList<String> columnNames = new ArrayList<String>();
String BrowserName = ((RemoteWebDriver)LocalDriverFactory.getDriver()).getCapabilities().getBrowserName();
BrowserName = BrowserName.equalsIgnoreCase("Internet Explorer") ? "IE": BrowserName;
System.out.println("BROWSER NAME IS XXXXXXXXXXXXXXXXXXXXXXXXXXXXX " + BrowserName);
// Opening spreadsheet
Sheet sheetName = workBook.getSheet(sModuleName);
// Collecting row Iterator
rows = sheetName.rowIterator();
// Reading first row of excel as column Titles
if (rows.hasNext()) {
columnNames = this.getAllColumnTitles(rows.next().cellIterator());
}
// Reading rest of rows as column values
while (rows.hasNext()) {
// getting next row
Row row = rows.next();
// converting cell type to String type to read cell value as string
row.getCell(columnNames.indexOf("action")).setCellType(
Cell.CELL_TYPE_STRING);
// checking if multiple cell has right value for paramiterziation to
// update row
if (String.valueOf(row.getCell(columnNames.indexOf("action")))
.equalsIgnoreCase(sActionName)) {
// updating row
row.getCell(columnNames.indexOf(BrowserName.toLowerCase() + "_passfail")).setCellValue(sStatus);
}
}
WritingExcel();
}
/**
* getMappedColValues method to retrieve map object including MappedFields
* type of object with first primary identifyable column name. This will be
* handled by SqlSheet API
*
* #param sheetname
* #return
* #throws Exception
*/
public Map<String, MappedFields> getMappedColValues(String sheetname)
throws Exception {
String strQuery = "SELECT * FROM " + this.getSheetFormat(sheetname);
Map<String, MappedFields> returnMap = new HashMap<String, MappedFields>();
st = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
resultSet = st.executeQuery(strQuery);
while (resultSet.next()) {
MappedFields mapFields = new MappedFields(resultSet.getString(2),
resultSet.getString(3), resultSet.getString(4));
returnMap.put(resultSet.getString(1), mapFields);
}
resultSet.close();
return returnMap;
}
/**
* getRowCount method to get total rows in sheet. This will be handled by
* SqlSheet API
*
* #param strSheetName
* #return
* #throws SQLException
*/
public int getRowCount(String strSheetName) throws SQLException {
int totalRow = 0;
String strQuery = "SELECT * FROM " + this.getSheetFormat(strSheetName);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
while (resultSet.next())
totalRow++;
resultSet.close();
return totalRow;
}
/**
* getRowCount method to get total rows in sheet. This will be handled by
* SqlSheet API
*
* #param strSheetName
* #return
* #throws SQLException
*/
public int getActiveTCRowCount(String groupName) throws SQLException {
String module, testCategory, riskLevel;
module = groupName.split("_")[0];
testCategory = groupName.split("_")[1];
riskLevel = groupName.split("_")[2];
String strQuery = "SELECT * FROM " + this.getSheetFormat(module);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
int rowIndex= 0;
while (resultSet.next()) {
if (testCategory.equalsIgnoreCase(resultSet.getString("TestCategory")) &&
riskLevel.equalsIgnoreCase(resultSet.getString("RiskLevel")) &&
"1".equalsIgnoreCase(resultSet.getString("Enabled"))){
rowIndex++;
}
}
return rowIndex;
}
/**
* getAllRowValue method to get all rows of parameterized sheet.
*
* #param strSheetName
* #return
* #throws SQLException
*/
public List<Map<String, String>> getAllRowValue(String strSheetName)
throws SQLException {
List<Map<String, String>> returnRowList = new ArrayList<Map<String, String>>();
String strQuery = "SELECT * FROM " + this.getSheetFormat(strSheetName);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()) {
int columntCount = resultSetMetaData.getColumnCount();
Map<String, String> map = new HashMap<String, String>();
for (int i = 1; i <= columntCount; i++) {
map.put(resultSetMetaData.getColumnName(i),
resultSet.getString(i));
}
returnRowList.add(map);
}
resultSet.close();
return returnRowList;
}
/**
* getPreDataSelectedModules method to get list of module. This will be
* handled by SqlSheet API
*
* #return
* #throws SQLException
*/
public List<String> getPreDataSelectedModules() throws SQLException {
List<String> listReturn = new ArrayList<String>();
String product = DriverScript.product;
String productExecutionconfig = product + "ExecutionConfig";
// TO DO.. how to execute Where in SQL Query in JAVA 8
String strQuery = "SELECT * FROM " + this.getSheetFormat(productExecutionconfig);
/* + " WHERE CreateAutomationPreData='Yes' ORDER BY Ranking"; */
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
while (resultSet.next()) {
// Temporary solution until Where clause working in SQL Query
if ("Yes".equalsIgnoreCase(resultSet
.getString("CreateAutomationPreData")))
listReturn.add(resultSet.getString("ModuleName"));
}
resultSet.close();
return listReturn;
}
/**
* getAllRowValueForModules method to get list of module columns based on
* provided strWhreCluase including module names. This will be handled by
* SqlSheet API
*
* #param strSheetName
* #param strWhereClause
* #return
* #throws SQLException
*/
public List<Map<String, String>> getAllRowValueForModules(
String strSheetName, String strWhereClause) throws SQLException {
// Fetching module name values from strWhereClause parameter.
List<String> moduleNames = new ArrayList<String>();
Matcher p = Pattern.compile("'(.*?)'").matcher(strWhereClause);
while (p.find()) {
moduleNames.add(p.group().replace("'", "").replace("%", "").toLowerCase());
}
List<Map<String, String>> returnRowList = new ArrayList<>();
String strQuery = "SELECT * FROM " + this.getSheetFormat(strSheetName);
/* + "WHERE " + strWhereClause; */
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
while (resultSet.next()) {
if (moduleNames.contains(resultSet.getString(2).toLowerCase())) {
int columntCount = resultSetMetaData.getColumnCount();
Map<String, String> map = new HashMap<>();
for (int i = 1; i < columntCount; i++) {
map.put(resultSetMetaData.getColumnName(i),
resultSet.getString(i));
}
returnRowList.add(map);
}
}
resultSet.close();
return returnRowList;
}
/**
* getAllColumnTitles method to provide all column names in
* ArrayList<String> object This will be used by methods where only POI
* worked.
*
* #param cells
* #return
*/
private ArrayList<String> getAllColumnTitles(Iterator<Cell> cells) {
// Temporary variable to send
ArrayList<String> columns = new ArrayList<String>();
// filling value of cells from parameter to arrayList<String>
while (cells.hasNext()) {
Cell cell = cells.next();
columns.add(cell.getStringCellValue().toLowerCase());
}
// returning list of columns
return columns;
}
private String getSheetFormat(String sheetName){
if (System.getProperty("java.version").contains("1.8"))
return sheetName;
else
return "[" + sheetName + "$]";
}
/** updateAnyColumnValue method to update any column value for single row or all rows
* #param sheetNm -> Name of Sheet
* #param columnNm -> Name of column to be updated with value
* #param ParamValue -> Value to be updated to for given column name
* #param ParamName -> Value of row identifier from frist column. If empty, assumed that all rows should be updated of given column with ParamValue
* #throws Exception
* #author Mitul Thesiya
*/
public void updateAnyColumnValue(String sheetNm, String columnNm, String ParamValue, String... ParamName) throws Exception{
// Declaring Variables
String paramName = ParamName.length > 0 ? ParamName[0]: "";
Iterator<Row> rows = null;
ArrayList<String> columnNames = new ArrayList<String>();
// Opening spreadsheet
Sheet sheetName = workBook.getSheet(sheetNm);
// Collecting row Iterator
rows = sheetName.rowIterator();
// Reading first row of excel as column Titles
if (rows.hasNext()) { columnNames = this.getAllColumnTitles(rows.next().cellIterator()); }
boolean isForSingleRow = !paramName.isEmpty();
// Reading rest of rows as column values
while (rows.hasNext()) {
// getting next row
Row row = rows.next();
//if ParamName parameter is found with row identifier value from first column by default
if(isForSingleRow) {
// converting cell type to String type to read cell value as string
row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
// checking if ParamName column title has same keyName of field as from parameter
if (String.valueOf(row.getCell(0)).equalsIgnoreCase(paramName)) {
// updating row
row.getCell(columnNames.indexOf(columnNm.toLowerCase())).setCellValue(ParamValue);
break;
}
}
else //Else update each row turn by turn in loop
row.getCell(columnNames.indexOf(columnNm.toLowerCase())).setCellValue(ParamValue);
}
WritingExcel();
}
public void updatedDataIncrementNumbers(String sheetNm, String ParamName, String ParamValue) throws Exception{
// Declaring Variables
Iterator<Row> rows = null;
ArrayList<String> columnNames = new ArrayList<String>();
// Opening spreadsheet
Sheet sheetName = workBook.getSheet(sheetNm);
// Collecting row Iterator
rows = sheetName.rowIterator();
// Reading first row of excel as column Titles
if (rows.hasNext()) { columnNames = this.getAllColumnTitles(rows.next().cellIterator()); }
// Reading rest of rows as column values
while (rows.hasNext()) {
// getting next row
Row row = rows.next();
// converting cell type to String type to read cell value as string
row.getCell(columnNames.indexOf("paramname")).setCellType(Cell.CELL_TYPE_STRING);
// checking if ParamName column title has same keyName of field as from parameter
if (String.valueOf(row.getCell(columnNames.indexOf("paramname"))).equalsIgnoreCase(ParamName)) {
// updating row
//if(ParamValue.length() != 0) {row.getCell(columnNames.indexOf("paramname")+1).setCellValue(ParamValue);}
row.getCell(columnNames.indexOf("paramname")+1).setCellValue(ParamValue);
break;
}
}
WritingExcel();
}
public int getPriorityOfTC(String actionName, String groupName) throws Exception{
String module, testCategory, riskLevel;
module = groupName.split("_")[0];
testCategory = groupName.split("_")[1];
riskLevel = groupName.split("_")[2];
int lastPriority = this.getMaxPriorityOfModule(module, testCategory, riskLevel);
String strQuery = "SELECT * FROM " + this.getSheetFormat(module);
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
Map<String, Integer> foundTestMethods = new LinkedHashMap();
try{
while (resultSet.next()) {
//if (resultSet.getString("Action").toLowerCase().equalsIgnoreCase(actionName.toLowerCase()) &&
if (testCategory.equalsIgnoreCase(resultSet.getString("TestCategory")) &&
riskLevel.equalsIgnoreCase(resultSet.getString("RiskLevel")) &&
"1".equalsIgnoreCase(resultSet.getString("Enabled"))){
foundTestMethods.put(resultSet.getString("Action"), resultSet.getString("ExecutionPriority").isEmpty() ? 0 : Integer.valueOf(resultSet.getString("ExecutionPriority")));
}
}
Integer[] uniquePriorityNumbers = foundTestMethods.values().stream().sorted().distinct().toArray(Integer[]::new);
int setPriroity = lastPriority;
for(int currentNumber : uniquePriorityNumbers){
if(currentNumber == foundTestMethods.get(actionName)){
for(Entry<String, Integer> keyValue : foundTestMethods.entrySet()){
if(keyValue.getValue() == currentNumber){
setPriroity++;
if(keyValue.getKey().equalsIgnoreCase(actionName)){
break;
}
}
}
break;
}
setPriroity += (int) foundTestMethods.values().stream().filter(e -> e.compareTo(currentNumber)== 0).count();
}
return setPriroity;
}
catch(Exception ex){
return lastPriority; //No matched row having same action name found
}
}
public int getMaxPriorityOfModule(String moduleName, String testCategory, String riskLevel) throws Exception{
int maxEligibleRowCount = 0;
int loopCount = Integer.valueOf(DriverScript.listModule.stream().filter(e -> moduleName.equalsIgnoreCase(e.getStrModuleName()) &&
testCategory.equalsIgnoreCase(e.getStrTestCat()) &&
riskLevel.equalsIgnoreCase(e.getStrRiskLevel())).findAny().get().getModulePriority());
for(int i=0; i<loopCount; i++){
String strQuery = "SELECT * FROM " + this.getSheetFormat(DriverScript.listModule.get(i).getStrModuleName());
st = con.createStatement();
resultSet = st.executeQuery(strQuery);
try{
while (resultSet.next()) {
if ("1".equalsIgnoreCase(resultSet.getString("Enabled"))){
maxEligibleRowCount++;
}
}
}
catch(Exception ex){
return maxEligibleRowCount; //No matched row having same action name found
}
}
return maxEligibleRowCount;
}
}
The column names are not as expected. The ArrayList columnNames does not contain either
columnNames.indexOf("action")
or
columnNames.indexOf(BrowserName.toLowerCase() + "_passfail")
so that indexOf returns -1. Hence the IllegalArgumentException in getCell. Correct the column names in your Excel file and think about error handling for such cases.
I need the output of my code to have columns of ID, NAME and CALORIES, but I'm not sure 'how'. I would like the id# to automatically populate itself, but when I had attempted what I had found on Oracle, it didn't work. And how do I go about having lines appear that separate everything?
This is my code:
package edu.umsl.java3816.foodItem;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class FoodItemTable {
Connection fit = null;
public static void main(String[] args) {
String createTableSQL = "create table FOOD_ITEM(ID INTEGER,NAME VARCHAR(256),CALORIES INTEGER)";
String insertTableSQL = "INSERT INTO FOOD_ITEM(ID,NAME,CALORIES) VALUES('1','hamburger','550')";
String selectSQLStatement = "SELECT * FROM FOOD_ITEM";
FoodItemTable fit = new FoodItemTable();
try {
fit.getConnection();
fit.createTable(createTableSQL);
fit.insertSQL(insertTableSQL);
fit.selectSQL(selectSQLStatement);
fit.shutdownDB();
} catch (Exception e) {
e.printStackTrace();
}
}
public void getConnection() throws Exception {
Class.forName("org.hsqldb.jdbcDriver");
fit = DriverManager.getConnection("jdbc:hsqldb:mem", "sa", // username
"");
}
public void createTable(String sqlStatement) {
Statement statement = null;
try {
statement = fit.createStatement();
int i = statement.executeUpdate(sqlStatement);
if (i == -1) {
System.out.println("Error: " + sqlStatement);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void insertSQL(String insertSQLStatement) {
Statement statement = null;
try {
statement = fit.createStatement();
int i = statement.executeUpdate(insertSQLStatement);
if (i == -1) {
System.out.println("Error: " + insertSQLStatement);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void selectSQL(String selectSQLStatement) {
Statement statement = null;
try {
statement = fit.createStatement();
ResultSet rs = statement.executeQuery(selectSQLStatement);
while (rs.next()) {
System.out.println(rs.getInt("ID"));
System.out.println(rs.getString("NAME"));
System.out.println(rs.getInt("CALORIES"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void shutdownDB() {
try {
fit.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
It looks like you want to show the results of your query within a console window but in a table style orderly fashion (at least to some extent).
You can do this with the use of a java method but first you will need to place your returned query result set into an two dimensional (2D) Array. Here is how you might accomplish this (utilizing your current selectSQL() method):
public void selectSQL(String selectSQLStatement) {
PreparedStatement statement;
int resultSetCount = 0;
String rowCountSQL = "SELECT COUNT(*) AS rCount FROM FOOD_ITEM;";
try {
//Get the number of records within that will be
//retrieved from your query...
statement = fit.prepareStatement(rowCountSQL);
ResultSet rs = statement.executeQuery();
while (rs.next()) { resultSetCount = rs.getInt("rCount"); }
// Are there records to display?
if (resultSetCount == 0) {
// No there isn't
System.out.println("There are NO Records to display!");
return;
}
// Yes there is so let's declare our 2D Object Array...
Object[][] queriedRecords = new Object[resultSetCount][3];
// And now fill the array...
statement = fit.prepareStatement(selectSQLStatement);
rs = statement.executeQuery();
int counter = 0;
while (rs.next()) {
queriedRecords[counter][0] = rs.getInt("ID");
queriedRecords[counter][1] = rs.getString("NAME");
queriedRecords[counter][2] = rs.getInt("CALORIES");
counter++;
}
// Display the retrieved records in Console window...
// The table header names to be used when printed
String[] tableHeader = { "ID", "NAME", "CALORIES" };
consolePrintTable(tableHeader, queriedRecords, 2, false, true);
} catch (SQLException e) { e.printStackTrace(); }
}
You will notice at the bottom of this method is a call to yet another method named consolePrintTable(). This method will display the retrieved data to the console. Read the JavaDoc I have supplied with this method. Here is the method code :
/**
* This method will take the supplied data and print a table to console in a particular
* spaced format.<br><br>
*
* <b>Example Usage:</b><pre>
*
* final Object[][] table = new Object[4][];
* table[0] = new Object[] { "foo", "bar", "baz", "bar2", "foo2", "baz2" };
* table[1] = new Object[] { "bar2", "foo2", "baz2", "bar2", "foo2", "baz2" };
* table[2] = new Object[] { "baz3", "bar3", "foo3", "bar2", "foo2", "baz2" };
* table[3] = new Object[] { "foo4", "bar4", "baz4", "bar2", "foo2", "baz2" };
*
* String[] h = {"Header 1", "Header 2", "Header 3", "Header 4", "Header 5", "Header 6"};
* consolePrintTable(h, table, 4, false, true);
*
* // Output will be:
*
* --------------------------------------------------------------------
* Header 1 Header 2 Header 3 Header 4 Header 5 Header 6
* --------------------------------------------------------------------
* foo bar baz bar2 foo2 baz2
* bar2 foo2 baz2 bar2 foo2 baz2
* baz3 bar3 foo3 bar2 foo2 baz2
* foo4 bar4 baz4 bar2 foo2 baz2</pre>
*
* #param headerData (1D String Array) Column (header) titles for the table.
* If no Header is desired then supply <b>null</b><br>
*
* #param tableData (2D Object Array) The table data to display.<br>
*
* #param spacesBetweenCells (Integer) The table that will be printed is always
* spaced apart from one another based on the widest cell detected within both
* supplied header data or the 2D Object Array data. This parameter allows you
* add additional spacing between each column.<br>
*
* #param options (optional - Boolean) ...<pre>
*
* rightAlignment - (Default is false) If boolean true is supplied
* theTable is displayed as right justified. Boolean
* false make the table display as left justified.
*
* applyHeaderLines - (Default is true) By default lines are applied to
* the table so as to separate the header from table
* data. If false is supplied then header lines are
* not displayed. This option only applies if a Header
* 1D String Array is supplied (not null).
*
* </pre><br>
*/
public static void consolePrintTable(String[] headerData, Object[][] tableData, int spacesBetweenCells, boolean... options) {
if (tableData.length == 0) { return; }
boolean alignRight = false; // Default is Left Alignment
boolean addHeaderLines = true;
if(options.length > 0) {
if (options.length >= 1) { alignRight = options[0]; }
if (options.length == 2) { addHeaderLines = options[1]; }
}
// Get the widest Cell needed so that all the
// table cells will be the same when printed.
int widestCell = 0;
for (Object[] tableData1 : tableData) {
for (int j = 0; j < tableData[0].length; j++) {
int l = tableData1[j].toString().length();
if (l > widestCell) { widestCell = l; }
}
}
//Now check for the widest in header (if any)
if (headerData != null && headerData.length > 0) {
for(int i = 0; i < headerData.length; i++) {
if (headerData[i].length() > widestCell) {
widestCell = headerData[i].length();
}
}
}
widestCell = (widestCell + spacesBetweenCells);
// -------------------------------------------
int columns = tableData[0].length;
String format = "", alignStrg = "-";
if (alignRight) { alignStrg = ""; }
for (int i = 1; i <= columns; i++) {
format+= "%" + alignStrg + String.valueOf(widestCell) + "s";
}
format+= "\n";
//Print The Header (if any)...
if (headerData != null && headerData.length > 0) {
int charCount = columns*widestCell;
if (!alignRight) { charCount = ((columns*widestCell) - spacesBetweenCells);}
String gridline = "\n" + String.join("", Collections.nCopies(charCount, "-"));
if (addHeaderLines) { System.out.println(gridline); }
for(int i = 0; i < headerData.length; i++) {
System.out.printf("%" + alignStrg + String.valueOf(widestCell) + "s", headerData[i]);
}
if (addHeaderLines) { System.out.println(gridline); }
else { System.out.println(""); }
}
// Display the Table data...
for (final Object[] row : tableData) {
System.out.format(format, row);
}
}
If you want to show the data of ID, calories, and name on the front-end (HTML), you can use tables. A simple example would be:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<table>
<tr>
<th>ID</th>
<th>NAME</th>
<th>Calories</th>
</tr>
<tr>
<td>You set the data here</td>
<td>..</td>
<td>..</td>
</tr>
<tr>
<td>..</td>
<td>..</td>
<td>..</td>
</tr>
</table>
</body>
</html>
Good Day
I have search the website but could not get anything to help me in my problem.
I`m a newby to android and started a project that I just can not complete.
using Android Studio 2.3
app name "Match Tracker"
Ok here it go's
example my app allows you to track a match "Rugby" now I would like the app to auto add points to the leader board if a team has 4 or more tries and that is where I get stuck!!
my FactDBAdaptor.class
EDITED*******
package za.co.sanrl.rugbyleague.database;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import za.co.sanrl.rugbyleague.main.MatchEvent;
import java.util.ArrayList;
/**
* Class that allows interaction with the Facts database such as insert, delete, update.
*
* #author Morne van Rooyen
*/
public class FactsDbAdapter {
public static final String KEY_MATCHID = "match_id";
public static final String KEY_TYPE = "type";
public static final String KEY_PLAYER1 = "player1";
public static final String KEY_PLAYER2 = "player2";
public static final String KEY_TEAM = "team";
public static final String KEY_TIME = "time";
private static final String DB_TABLE = "Facts";
private SQLiteDatabase db;
private BaseHelper dbHelper;
private Context context;
public FactsDbAdapter(Context context) {
this.context = context;
}
/**
* Open database so we can write to it.
*
* #return Open DB connection
* #throws SQLException
*/
public FactsDbAdapter open() throws SQLException {
dbHelper = new BaseHelper(context);
db = dbHelper.getWritableDatabase();
return this;
}
/**
* Close database.
*/
public void close() {
dbHelper.close();
}
/**
* Add a match fact to the database.
*
* #param match_id Match ID
* #param type Goal, penalty etc.
* #param player1 First player involved in event
* #param player2 Second player involved in event
* #param team The player(s) team
* #param time The time event took place
*/
public void addMatchFact(int match_id, String type, String player1, String player2, String team, String time) {
ContentValues values = new ContentValues();
values.put(KEY_MATCHID, match_id);
values.put(KEY_TYPE, type);
values.put(KEY_PLAYER1, player1);
values.put(KEY_PLAYER2, player2);
values.put(KEY_TEAM, team);
values.put(KEY_TIME, time);
//Insert into database.
try {
db.insert(DB_TABLE, null, values);
} catch (Exception e) {
Log.e("Database error when inserting match fact", e.toString());
e.printStackTrace();
}
}
/**
* Get the column values for a specific column provided.
*
* #param column - column you want to query.
* #param duplicates - if you want duplicate results.
* #return columnlist
*/
public ArrayList<String> getColumnValues(String column, boolean duplicates) {
Cursor cursor = null;
ArrayList<String> columnList = new ArrayList<>();
//Get column values.
try {
if (duplicates) {
cursor = db.rawQuery("SELECT " + column + " FROM " + DB_TABLE, null);
} else {
cursor = db.rawQuery("SELECT DISTINCT " + column + " FROM " + DB_TABLE, null);
}
} catch (Exception e) {
Log.e("Database error selecting facts", e.toString());
e.printStackTrace();
}
//Query result is not empty.
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndex(column);
do {
columnList.add(cursor.getString(columnIndex));
} while (cursor.moveToNext());
}
return columnList;
}
/**
* Count number of types with a given match_id.
*
* #param match_id Match ID
* #param type Event Type
* #param teamName Team Name
* #return count of types
*/
public int countTypesWithMatchID(int match_id, String type, String teamName) {
Cursor cursor = null;
ArrayList<String> columnList = new ArrayList<>();
//Get column values.
try {
cursor = db.rawQuery("SELECT " + KEY_TYPE + " FROM " + DB_TABLE +
" WHERE " + KEY_TYPE + "=? AND " + KEY_MATCHID + "=" + match_id +
" AND " + KEY_TEAM + "=?", new String[]{type, teamName});
} catch (Exception e) {
Log.e("Database error counting match events", e.toString());
e.printStackTrace();
}
//Query result is not empty.
if (cursor != null && cursor.moveToFirst()) {
int typeIndex = cursor.getColumnIndex(KEY_TYPE);
do {
columnList.add(cursor.getString(typeIndex));
} while (cursor.moveToNext());
}
return columnList.size();
}
/**Count 4 or more tries in a match begins**/
/**
* Count number of types with a given match_id.
*
* #param match_id Match ID
* #param type type is Tries
* #param teamName Team Name
* #return count of types
*/
public int countTriesWithMatchID(int match_id, String type, String teamName) {
Cursor cursor = null;
int result = 0;
//Get column values.
try {
cursor = db.rawQuery("SELECT COUNT(" + KEY_TYPE + ") FROM " + DB_TABLE +
" WHERE " + KEY_TYPE + "=Try AND " + KEY_MATCHID + "=" + match_id +
" AND " + KEY_TEAM + "=?", new String[]{type, teamName});
} catch (Exception e) {
Log.e("Database error counting match events", e.toString());
e.printStackTrace();
}
//Query result is not empty.
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getInt(0);
}
return result;
}
/**Count 4 or more tries in a match ends**/
/**
* Count the number a certain type with a certain player name comes up in db.
*
* #param type Event Type
* #param player Player involved in event
* #return count of types involving a specific player
*/
public int countTypesWithPlayer(String type, String player) {
Cursor cursor = null;
int result = 0;
//Get column values.
try {
cursor = db.rawQuery("SELECT COUNT(" + KEY_TYPE + ") FROM " + DB_TABLE +
" WHERE " + KEY_TYPE + "=? AND " + KEY_PLAYER1 + "=?", new String[]{type, player});
} catch (Exception e) {
Log.e("Db err counting type of events involving a player", e.toString());
e.printStackTrace();
}
//Query result is not empty.
if (cursor != null && cursor.moveToFirst()) {
result = cursor.getInt(0);
}
return result;
}
/**
* Get all match facts for a given match id.
*
* #param match_id Match ID
* #return All match facts
*/
public ArrayList<MatchEvent> getAllFactsForGivenMatchID(int match_id) {
Cursor cursor = null;
ArrayList<MatchEvent> result = new ArrayList<>();
//Get column values.
try {
cursor = db.rawQuery("SELECT * FROM " + DB_TABLE + " WHERE match_id=" + match_id, null);
} catch (Exception e) {
Log.e("Db err select * events", e.toString());
e.printStackTrace();
}
//Query result is not empty.
if (cursor != null && cursor.moveToFirst()) {
int typeIndex = cursor.getColumnIndex(FactsDbAdapter.KEY_TYPE);
int player1Index = cursor.getColumnIndex(FactsDbAdapter.KEY_PLAYER1);
int player2Index = cursor.getColumnIndex(FactsDbAdapter.KEY_PLAYER2);
int teamIndex = cursor.getColumnIndex(FactsDbAdapter.KEY_TEAM);
int timeIndex = cursor.getColumnIndex(FactsDbAdapter.KEY_TIME);
do {
String type = cursor.getString(typeIndex);
String player1 = cursor.getString(player1Index);
String player2 = cursor.getString(player2Index);
String team = cursor.getString(teamIndex);
String time = cursor.getString(timeIndex);
if (player2 != null) {
MatchEvent matchEvent = new MatchEvent(time, type, player1, player2, team);
result.add(matchEvent);
} else {
MatchEvent matchEvent = new MatchEvent(time, type, player1, team);
result.add(matchEvent);
}
} while (cursor.moveToNext());
}
return result;
}
}
now in my RugbyActivity.class the part that does not work is this
int bpts = factsDbAdapter.countTriesWithMatchID(factsDbAdapter.KEY_MATCHID, factsDbAdapter.KEY_TYPE, factsDbAdapter.KEY_TEAM);
if (bpts<3)
can anyone help me or steer me in the right direction please better discription of the code below
switch (status) {
case WIN: {// Team won the match.
int totalWins = teamAdapter.getColumnValueForTeamInt(teamAdapter.KEY_WINS, team);
int totalPoints = teamAdapter.getColumnValueForTeamInt(teamAdapter.KEY_TOTALPOINTS, team);
int totalBonusPoints = teamAdapter.getColumnValueForTeamInt(teamAdapter.KEY_BONUSPOINTS, team);
teamAdapter.updateSingleColumn(team, teamAdapter.KEY_WINS, totalWins + 1);
int bpts = factsDbAdapter.countTriesWithMatchID(factsDbAdapter.KEY_MATCHID, factsDbAdapter.KEY_TYPE, factsDbAdapter.KEY_TEAM);
if (bpts<3) {
teamAdapter.updateSingleColumn(team, teamAdapter.KEY_BONUSPOINTS, totalBonusPoints + 1);
teamAdapter.updateSingleColumn(team, teamAdapter.KEY_TOTALPOINTS, totalPoints + 5);
}
else
{
teamAdapter.updateSingleColumn(team, teamAdapter.KEY_TOTALPOINTS, totalPoints + 4);
}
break;
}
Thank you in advance
You have a method defined as:
public int countTriesWithMatchID(int match_id, String type, String teamName)
And you are calling it with:
factsDbAdapter.countTriesWithMatchID(factsDbAdapter.KEY_MATCHID, factsDbAdapter.KEY_TYPE, factsDbAdapter.KEY_TEAM)
If you replace the constants you are using, the call becomes:
factsDbAdapter.countTriesWithMatchID("match_id", "type", "team")
However, this will not work because they are all of type String, while your countTriesWithMatchID expects an int, a String and another String.
So, the problem is that you need an int for first parameter, the id of the match. A call like this would work, but you need the right id number:
factsDbAdapter.countTriesWithMatchID(1, "type", "team")
I hope this helps.
i have attached screen shot of the resultant CSV file
I am trying to write the result of the dql queries into a separate CSV file using dfc coding. but the result of the first record is printing twice in the resultant sheet.
public class ChkGroupExistence {
/**
* #param args
*/
private static Properties queryProp;
//private static Properties configProp;
IDfSession sess = null;
public ChkGroupExistence() {
System.out.println("Loading Properties..");
LoadProps loadProp = LoadProps.getInstance();
queryProp = loadProp.getQueryProp();
//configProp = loadProp.getConfigProp();
List<String> proj_list = new ArrayList<String>();
List<String> grp_list = new ArrayList<String>();
List<String> acl_list = new ArrayList<String>();
HashMap<String, String> projList_Map = new HashMap<String, String>();
IDfCollection projId_coll = null;
IDfCollection grp_coll = null;
//IDfCollection chk_coll = null;
//IDfCollection acl_coll = null;
String grpqry = null;
String chkqry = null;
//String getACLQuery = null;
int j=0;
CreateSession ifcDocsDfSession = new CreateSession();
try {
sess = ifcDocsDfSession.getSession();
DfLogger.info(this, "Session Created ::" + sess.getSessionId(),
null, null);
} catch (DfException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String qry = queryProp
.getProperty(IdocsConstants.PROJECT_ID);
try {
CSVWriter csvwriter=new CSVWriter(new FileWriter(new File("C:\\WBG\\IFCTools\\cs_log.csv")));
projId_coll = Util.executeQuery(sess, qry, IDfQuery.READ_QUERY);
while (projId_coll.next()) {
proj_list.add(projId_coll.getString("project_id"));
}
System.out.println("List of Project ::"+proj_list.size());
String tempQuery=queryProp.getProperty(IdocsConstants.P_GROUP_EXIST);
//String tempQuery1=queryProp.getProperty(IdocsConstants.P_GROUP_VERIFY);
//String tempQuery2 = queryProp.getProperty(IdocsConstants.P_GETACL);
List<String[]> csvList=new ArrayList<String[]>();
List<String[]> titleList = new ArrayList<String[]>();
String[] projList;
String[] titleString;
titleString = new String[3];
titleString[0]="ProjectId/Institutionnbr";
titleString[1]="GroupName";
titleString[2]="ACL Name";
titleList.add(titleString);
csvwriter.writeAll(titleList);
for(int i = 0; i <proj_list.size();i++ ) {
//grpqry = tempQuery+proj_list.get(i) + "_ed_off_grp'" ;
grpqry = MessageFormat.format(tempQuery,proj_list.get(i));
//chkqry = queryProp.getProperty(IdocsConstants.P_GROUP_VERIFY);
//System.out.println(grpqry);
//getACLQuery = MessageFormat.format(tempQuery2, proj_list.get(i));
//System.out.println(getACLQuery);
//System.out.println("grp_coll query is executing....");
grp_coll = Util.executeQuery(sess, grpqry, IDfQuery.READ_QUERY);
//System.out.println("verification query is executing.....");
//chk_coll = Util.executeQuery(sess, chkqry, IDfQuery.READ_QUERY);
//acl_coll = Util.executeQuery(sess, getACLQuery, IDfQuery.READ_QUERY);
if (grp_coll!=null && grp_coll.next()) {
String grpName = grp_coll.getString("group_name");
grp_list.add(grpName);
System.out.println("Got group for "+proj_list.get(i)+" :: "+grpName);
projList=new String[3];
projList[0]=proj_list.get(i);
projList[1]=grpName;
//System.out.println(grpName);
projList_Map.put(proj_list.get(i),grp_list.get(j));
j++;
System.out.println(projList_Map.size());
if(chkqry == null){
//System.out.println("group names are adding to the list.....");
//grp_list.add(grpName);
String acl_name = queryProp.getProperty(IdocsConstants.P_GETACL);
acl_list.add(acl_name);
projList[2]=acl_name;
}
csvList.add(projList);
csvwriter.writeAll(csvList);
}
}
System.out.println("Project List is loading....");
Set<String> keySet = projList_Map.keySet();
System.out.println(grp_list);
System.out.println(acl_list);
for(String set : keySet) {
System.out.println(set + " : " +projList_Map.get(set));
}
csvwriter.close();
} catch (DfException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IndexOutOfBoundsException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[])
{
ChkGroupExistence chkexist = new ChkGroupExistence();
}
}
CSVWriter.java
public class CSVWriter {
/**
* Default Delimiter will be used if not given.
*/
private static final char DEF_DELIM = ',';
/**
* Default Quote Character will be used if not given.
*/
private static final char DEF_QUOTE_CHAR = '"';
/**
* Default End of Line Character.
*/
private static final char DEFAULT_EOL = '\n';
/**
* Contains the Delimtter.
*/
private char delimiter;
/**
* Contains the Quote character.
*/
private char quotechar;
/**
* String contains the End of the line character.
*/
private char cLineEnd;
/**
* Instance Variable to hold Write Object.
*/
private Writer rawWriter;
/**
* Instance variable to hold PrintWriter object
*/
private PrintWriter pw;
/**
* Constructor to take File Writer as Input.
*
* #param writer
* File Writer
*/
public CSVWriter(Writer writer) {
this(writer, DEF_DELIM);
}
/**
* Constructor to take File Writer and Delimiter as Input.
*
* #param writer
* File Writer
* #param delim
* Delimiter
*/
public CSVWriter(Writer writer, char delim) {
this(writer, delim, DEF_QUOTE_CHAR);
}
/**
* Constructor to take File Writer, Delimiter and Quote Character as Input.
*
* #param writer
* File Writer
* #param delim
* Delimiter
* #param quote
* Quote Character
*/
public CSVWriter(Writer writer, char delim, char quote) {
this(writer, delim, quote, DEFAULT_EOL);
}
/**
* Constructor to take File Writer, Delimiter, Quote Character and End of
* Line feed as Input.
*
* #param writer
* File Writer
* #param delim
* Delimiter
* #param quote
* #param sEOL
*/
public CSVWriter(Writer writer, char delim, char quote, char sEOL) {
rawWriter = writer;
pw = new PrintWriter(writer);
delimiter = delim;
quotechar = quote;
cLineEnd = sEOL;
}
/**
* Method takes List as input and writes values into the CSV file.
*
* #param list
* List of Cell values.
*/
public void writeAll(List list) {
String sRow[];
for (Iterator iter = list.iterator(); iter.hasNext(); writeNext(sRow)) {
sRow = (String[]) iter.next();
}
}
/**
* Method that takes String[] as input and writes each and every cell.
*
* #param sRow
* String[]
*/
private void writeNext(String sRow[]) {
StringBuffer stringbuffer = new StringBuffer();
for (int i = 0; i < sRow.length; i++) {
if (i != 0) {
stringbuffer.append(delimiter);
}
String s = sRow[i];
if (s == null) {
continue;
}
if (quotechar != 0) {
stringbuffer.append(quotechar);
}
for (int j = 0; j < s.length(); j++) {
char c = s.charAt(j);
if (c == quotechar) {
stringbuffer.append(DEF_QUOTE_CHAR).append(c);
continue;
}
if (c == DEF_QUOTE_CHAR) {
stringbuffer.append(DEF_QUOTE_CHAR).append(c);
} else {
stringbuffer.append(c);
}
}
if (quotechar != 0) {
stringbuffer.append(quotechar);
}
}
stringbuffer.append(cLineEnd);
pw.write(stringbuffer.toString());
}
/**
* Method that closed the Print Writer. Only when this method is called, the
* CSV file will be saved.
*
* #throws IOException
*/
public void close() throws IOException {
pw.flush();
pw.close();
rawWriter.close();
}
Probably because you're including a repeating attribute in your query.
Tip: I tend to include the object ID for reference and debugging when I do this.
You can also insert a "DISTINCT" keyword into your query when including these repeating attributes.
The reason they act like this is the nature of the data model: all repeating attributes are stored in the same table - so when one of these attributes contains multiple values a query could return multiple rows when querying another repeating attribute. In this case a SELECT DISTINCT would do the trick.
You can also play around with the DQL hint ENABLE(ROW_BASED) if you are joining repeating attribute with single value attributes.
Happy coding!