Clarify my doubts in testng extend report - selenium

#Test(priority = 0)
public void verify_Templete_BG(){
logger =report.startTest("Verify TempleteBG");
String expectedBG = "White";
for(int pageNo = 1; pageNo<=3 ; pageNo++){
Assert.assertTrue(expectedBG.equals("White"));
}
System.out.println("TC1 Pass");
logger.log(LogStatus.PASS, "TC1 Pass");
}
In this above sample program, I have some doubts.
If loop 2 fails(loop 1 and loop 3 pass) what will be output. Whether this testcase pass or fail.
If loop 3 fails(loop 1 and loop 2 pass) what will be output. Whether this testcase pass or fail.
Or else, how to know which loop got fails.

If any assert fails, the test case will fail immediately.
You can add a little code and test out the different outcomes for yourself. Adjust the actualBG values for the different loops to be whatever you want. The code below is set up for Case 1, to fail on loop 2.
#Test(priority = 0)
public void verify_Templete_BG()
{
logger = report.startTest("Verify TempleteBG");
String expectedBG = "White";
String actualBG = "";
for (int pageNo = 1; pageNo <= 3; pageNo++)
{
switch (pageNo)
{
case 1:
actualBG = "White";
break;
case 2:
actualBG = "Black";
break;
case 3:
actualBG = "White";
break;
default:
break;
}
Assert.assertTrue(expectedBG.equals(actualBG));
}
System.out.println("TC1 Pass");
logger.log(LogStatus.PASS, "TC1 Pass");
}

Assuming yours is an Extent Reports. Extent reports actually prints step wise results for each Test cases. So you could actually modify it to like the below.
#Test(priority = 0)
public void verify_Templete_BG(){
logger =report.startTest("Verify TempleteBG");
String expectedBG = "White";
for(int pageNo = 1; pageNo<=3 ; pageNo++){
if(Assert.assertTrue(expectedBG.equals("White")))
logger.log(LogStatus.PASS, pageNo +" Loop Passed");
else
logger.log(LogStatus.Fail, pageNo +" Loop Failed");
}
report.endTest(logger);
report.flush();
}
assertTrue will return true or false based on the condition you are passing in. When it is true, you will print PageNo - Loop is passed. Else you will print it as failed.

Related

how do i get out of this Infinite loop

I am trying to get this loop to ask the question again what the user inputs not a 1 or a 2 but it puts me in a infinite loop how do i get out?
package vga;
import java.util.Scanner;
public class FPS_Info {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean placeHolder;
String gameList[] = new String[2];
gameList[0] = ("Battlefield 1");
gameList[1] = ("Call Of Duty WWII");
System.out.printf("Please slect from theses games %s or %s.%nType 1 for %s and type 2 for %s.%n",
gameList[0], gameList[1], gameList[0], gameList[1]);
int gameSelection = scanner.nextInt();
if (gameSelection == 1 || gameSelection ==2) {
placeHolder = true;
}
while (placeHolder = true) {
if (gameSelection == 1) {
System.out.println("Battlefield 1, good choice.");
break;
} else if (gameSelection == 2) {
System.out.println("Call Of Duty WWII, good selection.");
break;
} else {
System.out.println("Please enter one of the options.");
placeHolder = false;
}
}
}
}
If you restructure your code, you don't need the placeholder.
import java.util.Scanner;
public class FPS_Info {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
boolean placeHolder;
String gameList[] = new String[2];
gameList[0] = ("Battlefield 1");
gameList[1] = ("Call Of Duty WWII");
System.out.printf("Please slect from theses games %s or %s.%nType 1 for %s and type 2 for %s.%n",
gameList[0], gameList[1], gameList[0], gameList[1]);
int gameSelection = scanner.nextInt();
while (gameSelection != 1 && gameSelection != 2) { // or while (gameSelection > 0 && gameSelection <= gameList.length)
System.out.println("Please enter one of the options.");
gameSelection = scanner.nextInt();
}
if (gameSelection == 1) {
System.out.println("Battlefield 1, good choice.");
}
else if (gameSelection == 2) {
System.out.println("Call Of Duty WWII, good selection.");
}
}
}
Your code includes:
while (placeHolder = true)
You probably meant placeHolder == true. The = assigns true rather than checks against it, so it's not doing the loop like you probably meant.
That said, there's no reason to == true in the first place. You can just
while (placeHolder)

How to display #Test Result in TestNG Report when it is called from another #Test method. Please suggest an answer

I am using ITestListener, Extent Manager for Generating Extent Report. It is working fine.
I'm calling 5 #Test methods from another method. The Reports (TestNG & Extent Report) usually showing only 1 output for the executed test.
Please suggest any other way to get the #Test Output when they called from another method.
I want to control execution of my methods through from excel instead of creating long XML files.
Please Check my sample Code: Suggest any other way to acheive the Report
My TestNG XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="logixexpress" parallel="false">
<listeners>
<listener class-name="common.CommonITestNGListener"></listener>
</listeners>
<parameter name = "Browser" value = "Chrome"></parameter>
<parameter name = "DataFile" value = "\\TestData\\Express.xlsx"></parameter>
<parameter name = "AppRepoFile" value = "\\OR\\AppRepo.properties"></parameter>
<test name="Express Test Execution">
<classes>
<class name="logixexpress.Driver">
</class>
</classes>
</test>
</suite>
My Driver Script:
public class Driver extends commonhelper{
public static int Drvrownum = 3;
#Test
public void ExecuteDriver() throws Exception {
for (int i = Drvrownum; i < (ExcelWS.getLastRowNum() + Drvrownum); i++) {
String mname = GetDatafromCell("Global", Drvrownum, "ActionName");
String EF = GetDatafromCell("Global", Drvrownum, "ExecutionFlag");
if (EF.equalsIgnoreCase("false")) {
Drvrownum = Drvrownum + 1;
continue;
}
else {
switch (mname) {
case "WorkQueue":
WorkQueue wq = new WorkQueue();
wq.RunWQcases();
Drvrownum = Drvrownum + 1;
break;
case "XXX":
System.out.println("All Iterations Completed");
Drvrownum = Drvrownum + 1;
return;
default:
break;
}
}
}
}
}
And my test Script:
public class WorkQueue extends commonhelper{
public static int WQrownum = 2;
public static String EXLFilePath = scrpath + "\\TestData\\Express.xlsx";
#Test
public void RunWQcases() throws Exception {
setExcelFile(EXLFilePath, "WorkQueue");
for (int i = WQrownum; i < (ExcelWS.getLastRowNum() + WQrownum); i++) {
String WQMname = GetDatafromCell(WQrownum, "ActionName");
String AEF = GetDatafromCell(WQrownum, "ExecutionFlag");
if (AEF.equalsIgnoreCase("false")) {
WQrownum = WQrownum + 1;
continue;
}
else {
switch (WQMname) {
case "ExecuteWQ":
ExecuteWQ();
WQrownum = WQrownum + 1;
break;
case "openchart":
openchart();
WQrownum = WQrownum + 1;
break;
case "XXX":
System.out.println("Sub Class Iterations Completed");
WQrownum = WQrownum + 1;
return;
}
}
}
}
#Test
public void ExecuteWQ() throws Exception {
driver.findElement(By.linkText("Work Queue")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Coding WQ")));
driver.findElement(By.linkText("Coding WQ")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//table[#class='main']")));
}
#Test
public void openchart() throws Exception {
WebElement wqtable = driver.findElement(By.xpath("//table[#class='main']"));
List<WebElement> trow = wqtable.findElements(By.tagName("tr"));
for (int i = 0; i < trow.size(); i++) {
boolean getrow = false;
List<WebElement> tcol = trow.get(i).findElements(By.tagName("th"));
System.out.println("Number of Columns = " + tcol.size());
for (int j = 0; j < tcol.size(); j++) {
if (tcol.get(j).getText().equalsIgnoreCase("Action")) {
driver.findElement(By.className("grid-edit")).click();
getrow = true;
break;
}
}
if (getrow) {
break;
}
}
Thread.sleep(2000);
}
}
If I correctly understand the question the problem is that the TestNG report does not give any information about the test methods which are being called from another methods. The question includes extent report but for now, I will answer only for the TesNG part,
No.
Inside your #Test method, if you call another #Test method, and you have included only the calling function in your xml file, TestNG will execute both methods but count only 1 as executed tests. For example, if you write something like:
#Test
public void test1()
{
test2()
test3()
}
#Test
public void test2()
{
}
#Test
public void test3()
{
}
And you have included only test1 method in your xml file, TestNG will consider only ONE test method is executed and will prepare the reports accordingly.
Additionally, it is a bad practice to design your tests in such a way. Individual tests should be completely independent to each other in all ideal cases. You should probably club both of your tests if it is a single flow. If it is not and you have to use output of one test to another, you can see this .
Yes, this is right.
I want to control the method's execution based on an excel file.
Any solution to get rid of my Report Issue?
I had written my code as follows:
I am executing Class "Driver" from TestNG XML file. My Common Helper contains #Before, #After & Listener class contain all implemented methods of ITestListener.
Yes, this is right.
I want to control the method's execution based on an excel file.
Any solution to get rid of my Report Issue?
I had written my code as follows:
I am executing Class "Driver" from TestNG XML file. My Common Helper contains #Before, #After & Listener class contain all implemented methods of ITestListener.
public class Driver extends commonhelper{
public static int Drvrownum = 3;
#Test
public void ExecuteDriver() throws Exception {
for (int i = Drvrownum; i < (ExcelWS.getLastRowNum() + Drvrownum); i++) {
String mname = GetDatafromCell("Global", Drvrownum, "ActionName");
String EF = GetDatafromCell("Global", Drvrownum, "ExecutionFlag");
if (EF.equalsIgnoreCase("false")) {
Drvrownum = Drvrownum + 1;
continue;
}
else {
switch (mname) {
case "WorkQueue":
WorkQueue wq = new WorkQueue();
wq.RunWQcases();
Drvrownum = Drvrownum + 1;
break;
case "XXX":
System.out.println("All Iterations Completed");
Drvrownum = Drvrownum + 1;
return;
default:
break;
}
}
}
}
}
public class WorkQueue extends commonhelper{
public static int WQrownum = 2;
public static String EXLFilePath = scrpath + "\\TestData\\Express.xlsx";
#Test
public void RunWQcases() throws Exception {
setExcelFile(EXLFilePath, "WorkQueue");
for (int i = WQrownum; i < (ExcelWS.getLastRowNum() + WQrownum); i++) {
String WQMname = GetDatafromCell(WQrownum, "ActionName");
String AEF = GetDatafromCell(WQrownum, "ExecutionFlag");
if (AEF.equalsIgnoreCase("false")) {
WQrownum = WQrownum + 1;
continue;
}
else {
switch (WQMname) {
case "ExecuteWQ":
ExecuteWQ();
WQrownum = WQrownum + 1;
break;
case "openchart":
openchart();
WQrownum = WQrownum + 1;
break;
case "XXX":
System.out.println("Sub Class Iterations Completed");
WQrownum = WQrownum + 1;
return;
}
}
}
}
#Test
public void ExecuteWQ() throws Exception {
driver.findElement(By.linkText("Work Queue")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("Coding WQ")));
driver.findElement(By.linkText("Coding WQ")).click();
wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//table[#class='main']")));
}
#Test
public void openchart() throws Exception {
WebElement wqtable = driver.findElement(By.xpath("//table[#class='main']"));
List<WebElement> trow = wqtable.findElements(By.tagName("tr"));
for (int i = 0; i < trow.size(); i++) {
boolean getrow = false;
List<WebElement> tcol = trow.get(i).findElements(By.tagName("th"));
System.out.println("Number of Columns = " + tcol.size());
for (int j = 0; j < tcol.size(); j++) {
if (tcol.get(j).getText().equalsIgnoreCase("Action")) {
driver.findElement(By.className("grid-edit")).click();
getrow = true;
break;
}
}
if (getrow) {
break;
}
}
Thread.sleep(2000);
}
}

get and set methods from an ArrayList in another class

/*
* Notes here
*/
package billboardsign;
/**
*
* #author John Parada
*/
import java.util.ArrayList;
public class Billboard
{
private String text;
private ArrayList<String> messages = new ArrayList<String>();
public Billboard()
{
messages.add("Happy New Year");
messages.add("Happy Holidays");
messages.add("Team Pizza");
messages.add("Game On");
messages.add("Let's Go Team");
}
public ArrayList<String> getMessages()
{
return messages;
}
public void setMessages(String msg)
{
messages.add(msg);
}
public boolean isEmpty()
{
return text == null || text.isEmpty();
}
public String substring(int begin, int end)
{
if (begin >= 0 && end < text.length())
{
return text.substring(begin, end);
}
else
return null;
}
//add the method Reverse here
// THIS CODE IS NO GOOD!for (int count = text.length() - 1; count >= 0; count-- )
//FOLLOW UP LINE System.out.printf( "%s ", text.charAt( count ) );
public String reverse()
{
if (isEmpty())
return null;
else
{
char[] chars = text.toCharArray();
//create antoher arrayList
char[] reverse = new char[chars.length];
for (int i = chars.length - 1, j = 0; i < 0; i--, j++)
{
reverse[j] = chars[i];
}
return new String(reverse);
}
}
//add the method Replace string here
public String replace(char oldChar, char newChar)
{
return text.replace(oldChar, newChar);
}
//add the method displayInfo here
public void displayInfo()
{
System.out.printf("\n%s\nMessage", messages);
}
}
/*
* Notes on the Billboard Project
*/
package billboardsign;
/**
*
* #author John Parada
*/
import java.util.Scanner;
public class BillboardSign
{
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
Billboard newBillboard = new Billboard(); //default constructor
//Menu
int choose_again = 1;
int choiceNumber;
Scanner newInput = new Scanner(System.in);
while (choose_again > 0 )
{
//list options to user
System.out.println ("\nPlease choose a number between 1 and 6 to choose an\n"
+ "option for the Messages Board to display: "
+ "\n1) Display Default Message 1"
+ "\n2) Display Default Message 2"
+ "\n3) Display Default Message 3"
+ "\n4) Display Default Message 4"
+ "\n5) Display Default Message 5"
+ "\n6) Enter a New Message"
+ "\n7) Reverse a Message"
+ "\n8) Replace a Message - Substring"
+ "\n9) Exit Program");
//get the user to input a selection
System.out.print ("\nPlease Enter Your Selection: ");
choiceNumber = newInput.nextInt();
//use switch statement to help with thieir choice input
switch (choiceNumber)
{
case 1:
//execute get() and displayInfo() method for default Message 1
//newBillboard = Billboard();
messages.get(0);
displayInfo();
break;
case 2:
//execute get() and displayInfo() method for default Message 2
newBillboard = Billboard();
Billboard = displayInfo();
break;
case 3:
//execute get() and displayInfo() method for default Message 3
newBillboard = Billboard();
Billboard = displayInfo();
break;
case 4:
//execute get() and displayInfo() method for default Message 4
newBillboard = Billboard();
Billboard = displayInfo();
break;
case 5:
displayInfo();
break;
case 6:
//execute set() and displayInfo() methods to create a new message
break;
case 7:
//execute reverse message method
break;
case 8:
//execute Replace message - Substring method
case 9:
//Dispaly to the user that they have chose to exit
System.out.print ("\nYou have chosen to cancel and exit. \n");
System.exit(0);
}
//prompt user for antother selection? (Contiune=1 and Exit= -1)
System.out.println();
System.out.print ("\nIf you would like to select another animal enter 1 or if your are done enter -1: ");
choose_again = newInput.nextInt();
}
}
private static void displayInfo() {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
In short, when the user selects 1, he or she is supposed to get the first element of the ArrayList(0). When he or she selects 2, they will get the second element in the ArrayList(1). I need to invoke the get method, and use the displayInfo of the Billboard.
Thank you in advance for any and all help.
Regards,
John Parada
do something likewise,
case 1:
newBillboard.getMessages().get(0);
...
case 1:
newBillboard.getMessages().get(1);
....
And so on.
your getMessages() method is returning an arraylist so either you should have in an arraylist variable in your main class like this
ArrayList<String> messages = newBillboard.getMessages();
and then call it like this
case 1:
//execute get() and displayInfo() method for default Message 1
//newBillboard = Billboard();
System.out.println (messages.get(0));
//displayInfo();
break;
or you can simply call it like this
newBillboard.getMessages.get(0);//here 0 is for first element
and there is no need to get an object of your class in every case
and what is the need of displayInfo is unclear so if you tell why have you added that i might see to it.

Using Matchers for Objects

So I am trying to create a "TestClass" that basically holds onto my Matcher, actual results, error message, and test label.
However, I am slowly starting to realize this might not be possible but I feel like it should be.
Perhaps someone here can help.
Here is what I am trying to do:
public void runTest(){
Assert.assertThat(testLabel + " " + errorMessage, actualResult, testToRun);
}
or, since I am doing Selenium Tests, something like this:
public void runTestAsWebElement(String attributeToCheck){
Object tempActualResult;
switch (attributeToCheck.toLowerCase()){
case "isdisplayed()":
case "isdisplayed":
tempActualResult = ((WebElement) actualResult).isDisplayed();
break;
case "isselected":
case "isselected()":
tempActualResult = ((WebElement) actualResult).isSelected();
break;
case "isenabled":
case "isenabled()":
tempActualResult = ((WebElement) actualResult).isEnabled();
break;
case "text":
tempActualResult = ((WebElement) actualResult).getText();
break;
default:
tempActualResult = ((WebElement) actualResult).getAttribute(attributeToCheck);
}
Assert.assertThat(testLabel + " " + errorMessage, tempActualResult, testToRun);
}
However, I am wondering, will the matchers be able to figure out that the Actual Result is a String or Boolean? Or will it always fail since both objects are being compared as Objects, rather than strings (not sure how the underlying code would be executed).
Any advice on how to properly handle this situation would be much appreciated!
Just to give some context - I am currently writing code like this:
Switch(whatToTest){
case "eye portfolio tests":
customCheckErrorMessages.add("The Eye Portfolio header doesn't match expected user's value");
customCheckActualResults.add(eyePortfolioPage.eyePortfolioAccountHeader);
customCheckExpectedResults.add(holder);
customCheckTests.add(containsString(holder));
customTestAttributeToTest.add("text");
break;
//just showing what my step looks like
}
String actualResult = "";
for(int x = 0; x < customCheckErrorMessages.size(); x++){
try{
switch (customTestAttributeToTest.get(x)){
case "text":
actualResult = customCheckActualResults.get(x).getText();
break;
default:
actualResult = customCheckActualResults.get(x).getAttribute(customTestAttributeToTest.get(x));
break;
}
}catch (IndexOutOfBoundsException e){
//Assuming this field wasn't actually entered. Defaulting to getText
actualResult = customCheckActualResults.get(x).getText();
}
System.out.println("Additional Test #" + (x+1));
Assert.assertThat(customCheckErrorMessages.get(x) + " Expected: \"" + customCheckExpectedResults.get(x)
+ "\", Actual: \"" + customCheckActualResults.get(x).getText().trim(),
actualResult.trim(),
customCheckTests.get(x));
}
I would like to write code like this:
switch(whatIWantToTest){
case "transaction tests":
customTests.add(new TestClass("There should be at least one transaction appearing on the page", //error Message
"Looking For Transactions:", //Test Label
myOrdersPage.transactions.size(), //Actual Result
greaterThanOrEqualTo(1))); //Test to run (should contain expected result)
//Just showing what my step looks like
}
for (TestClass test : customTests){
test.runTest();
}
Here is the code I decided to use. If anyone has a better suggestion I would love to hear it :)
private String testType;
public String errorMessage, testAttribute;
public WebElement actualResult;
public List<WebElement> actualResults;
public String providedStringValue = null;
public Boolean providedBooleanValue = null;
public Matcher testToRun;
public int attempts = 1;
//Empty Constructor
public TestCase() {
errorMessage = "";
testType = "";
actualResult = null;
actualResults = null;
testToRun = null;
providedStringValue = null;
providedBooleanValue = null;
}
//Run Test as a String check
public TestCase(String errorMessage, String providedResult, Matcher testToRun){
this.errorMessage = errorMessage;
providedStringValue = providedResult;
testType = "String";
this.testToRun = testToRun;
}
//Run Test as a Boolean check
public TestCase(String errorMessage, Boolean providedResult, Matcher testToRun){
this.errorMessage = errorMessage;
providedBooleanValue = providedResult;
testType = "Boolean";
this.testToRun = testToRun;
}
//Run Test on a WebElement
public TestCase(String errorMessage, String testAttribute, WebElement actualResult, Matcher testToRun) {
this.errorMessage = errorMessage;
testType = "WebElement";
this.testAttribute = testAttribute;
this.actualResult = actualResult;
this.testToRun = testToRun;
}
//Run Test on a List<WebElement>
public TestCase(String errorMessage, String testAttribute, List<WebElement> actualResults, Matcher testToRun) {
this.errorMessage = errorMessage;
testType = "List";
this.testAttribute = testAttribute;
this.actualResults = actualResults;
this.testToRun = testToRun;
}
public void clearTest() {
errorMessage = "";
testType = "";
testAttribute = "";
actualResult = null;
actualResults = null;
testToRun = null;
providedStringValue = null;
providedBooleanValue = null;
}
public void runTest() {
try {
if (testType.equalsIgnoreCase("WebElement")) {
runTestAsWebElement(testAttribute);
} else if (testType.equalsIgnoreCase("List")) {
runTestAsList(testAttribute);
} else if(testType.equalsIgnoreCase("Boolean")){
runTestAsBooleanCheck();
} else if(testType.equalsIgnoreCase("String")){
runTestAsStringCheck();
} else {
Assert.fail("Don't know how to run this test type");
}
} catch (StaleElementReferenceException e) {
if (attempts < 5) {
System.out.println("StaleElementReferenceException - Running test again");
attempts++;
runTest();
return;
} else {
throw e;
}
}
attempts = 1;
}
private void runTestAsStringCheck(){
Assert.assertThat(errorMessage, providedStringValue, testToRun);
}
private void runTestAsBooleanCheck(){
Assert.assertThat(errorMessage, providedBooleanValue, testToRun);
}
//Sometimes the actualResult is a WebElement which means the value to check is wrapped within another value.
private void runTestAsWebElement(String attributeToCheck) {
Object actualResultHolder;
switch (attributeToCheck.toLowerCase()) {
case "exists":
case "present":
try{
actualResult.isDisplayed(); //Forcing WebElement to look for element. If throws exception, element not found
actualResultHolder = true;
} catch (NoSuchElementException e){
actualResultHolder = false;
}
break;
case"display":
case "displayed":
case "isdisplayed()":
case "isdisplayed":
try{
actualResultHolder = actualResult.isDisplayed();
} catch (NoSuchElementException e){
System.out.println("Element not found");
throw e;
//actualResultHolder = false;
}
break;
case "selected":
case "isselected":
case "isselected()":
actualResultHolder = actualResult.isSelected();
break;
case "enabled":
case "isenabled":
case "isenabled()":
actualResultHolder = actualResult.isEnabled();
break;
case "text":
actualResultHolder = actualResult.getText().trim();
break;
default:
if (attributeToCheck.contains("css: ")) {//In case we want to test the css attribute instead of the HTML attribute
attributeToCheck = attributeToCheck.split("css: ")[1];
actualResultHolder = actualResult.getCssValue(attributeToCheck);
} else {
actualResultHolder = actualResult.getAttribute(attributeToCheck);
}
}
Assert.assertThat(errorMessage + "\n Actual Result = \"" + actualResultHolder + "\" ", actualResultHolder, testToRun);
}
private void runTestAsList(String attributeToCheck) {
switch (attributeToCheck.toLowerCase()) {
case "size":
case "size()":
Assert.assertThat(errorMessage, actualResults.size(), testToRun);
break;
default:
//do nothing - Test has to do with the list of elements.
Assert.assertThat(errorMessage, actualResults, testToRun);
}
}
Then, if for whatever reason I need some other type of test I just add it to the class.

Extracting ResultSetMetaData from Spring JdbcTemplate

I am trying to fetch the resultsetmeta data using Spring jdbc template. It works fine if there is atleast one row returned.
The problem arises when there is no rows returned i.e. an empty resultSet.
I have tried a lot and still stuck up with the same. If there is any solution to this, please help me with this.
Also, I found ResultSetWrappingSqlRowSetMetaData class in spring. Is this of some use in my context?
Thanks for the help.
Finally I found the answer to my question. Below is the code:
template.query(builder.toString(),new ResultSetExtractor<Integer>() {
#Override
public Integer extractData(ResultSet rs) throws SQLException, DataAccessException {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
for(int i = 1 ; i <= columnCount ; i++){
SQLColumn column = new SQLColumn();
column.setName(rsmd.getColumnName(i));
column.setAutoIncrement(rsmd.isAutoIncrement(i));
column.setType(rsmd.getColumnTypeName(i));
column.setTypeCode(rsmd.getColumnType(i));
column.setTableName(sqlTable.getName().toUpperCase());
columns.add(column);
}
return columnCount;
}
});
For a detailed explanation you can visit here
You can also use JdbcUtils
#SuppressWarnings("unchecked")
public static List<TableColumnTypeMap> getTableColumns(DataSource dataSource,
String tableName) {
try {
return (List<TableColumnTypeMap>) JdbcUtils.extractDatabaseMetaData(dataSource,
new DatabaseMetaDataCallback() {
#Override
public Object processMetaData(DatabaseMetaData dbmd)
throws SQLException, MetaDataAccessException {
ResultSet rs = dbmd
.getColumns("", "%", tableName + "%", null);
List<TableColumnTypeMap> list = new ArrayList();
while (rs.next()) {
String tableCat = rs.getString("TABLE_CAT");
String tableSchem = rs.getString("TABLE_SCHEM");
String tableName = rs.getString("TABLE_NAME");
String columnName = rs.getString("COLUMN_NAME");
String typeName = rs.getString("TYPE_NAME");
String columnSize = rs.getString("COLUMN_SIZE");
String nullable = rs.getString("NULLABLE");
String remarks = rs.getString("REMARKS");
int dataType = rs.getInt("DATA_TYPE");
System.out.println(tableName);
TableColumnTypeMap tableColumnTypeMap = new TableColumnTypeMap()
.setColumnName(columnName)
.setColumnType(typeName)
.setJavaClassName(getColumnCLassName(dataType))
.setRemarks(remarks);
list.add(tableColumnTypeMap);
}
return list;
}
});
} catch (MetaDataAccessException ex) {
throw new RuntimeException("get table list failed", ex);
}
}
for java class map:
private static String getColumnCLassName(int sqlType) {
String className = String.class.getName();
switch (sqlType) {
case Types.NUMERIC:
case Types.DECIMAL:
className = java.math.BigDecimal.class.getName();
break;
case Types.BIT:
className = java.lang.Boolean.class.getName();
break;
case Types.TINYINT:
className = java.lang.Byte.class.getName();
break;
case Types.SMALLINT:
className = java.lang.Short.class.getName();
break;
case Types.INTEGER:
className = java.lang.Integer.class.getName();
break;
case Types.BIGINT:
className = java.lang.Long.class.getName();
break;
case Types.REAL:
className = java.lang.Float.class.getName();
break;
case Types.FLOAT:
case Types.DOUBLE:
className = java.lang.Double.class.getName();
break;
case Types.BINARY:
case Types.VARBINARY:
case Types.LONGVARBINARY:
className = "byte[]";
break;
case Types.DATE:
className = java.sql.Date.class.getName();
break;
case Types.TIME:
className = java.sql.Time.class.getName();
break;
case Types.TIMESTAMP:
className = java.sql.Timestamp.class.getName();
break;
case Types.BLOB:
className = java.sql.Blob.class.getName();
break;
case Types.CLOB:
className = java.sql.Clob.class.getName();
break;
default:
break;
}
return className;
}
for result class
/**
* #author ryan
* #date 19-7-15 下午6:05
*/
#Data
#Accessors(chain = true)
public class TableColumnTypeMap {
private String columnName;
private String columnType;
private String javaClassName;
private String remarks;
}