0

I wrote a SQL parser, the code works fine and I can see proper output at the end of parsing. Now I am trying to display the parsed output in a JSP. In order to do that, I have setup the project on IntelliJ as show in the image below.

enter image description here

The parser I have written earlier has its main method inside getTableColumn which is marked in RED box in the image. It looks like this.

public class getTableColumn {
    ..
    ..
    public static void main(String args[]) throws SQLException {
        ReadQueries rq = new ReadQueries("query");
        String output  = rq.getData();
        ....
        ....
        ....
        ....
    }
 }

ReadQueries is the class where I declared all the custom methods to parse the SQL. The method getData returns the parsed output and it is present in the String output. I am trying to display the value of output in a jsp.

I renamed the main method in getTableColumn to processQuery so that I can call it from other classes as well. Based on a drop down in the JSP, I am trying to pass a string value into getTableColumn's processQuery as below.

import com.query.data.ReadQueries;
import com.table.modules.TableModules;
import com.where.WhereData;
import gudusoft.gsqlparser.EDbVendor;
import gudusoft.gsqlparser.IMetaDatabase;
import save.querydata.InsertColumns;

import java.io.File;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

class sampleMetaDB implements IMetaDatabase {
    String columns[][] = { {"server", "db", "schema", "TBL_BBGPOS_REP", "M_TP_PFOLIO"
            }, { "server", "db", "schema", "A_FXPOSITIONDEL_REP", "M_FXDELTA"}, 
               {"server", "db", "schema", "A_FXPOSITIONDEL_REP", "M_CLOSING_E" }, 
               {"server", "db", "schema", "A_FXPOSITIONDEL_REP", "M_FXDELTA_Z"}
    };

    public boolean checkColumn(String server, String database, String schema, String table, String column) {
        boolean bServer, bDatabase, bSchema, bTable, bColumn, bRet = false;
        for (int i = 0; i < columns.length; i++) {
            if ((server == null) || (server.length() == 0)) {
                bServer = true;
            } else {
                bServer = columns[i][0].equalsIgnoreCase(server);
            }
            if (!bServer) continue;
            if ((database == null) || (database.length() == 0)) {
                bDatabase = true;
            } else {
                bDatabase = columns[i][1].equalsIgnoreCase(database);
            }
            if (!bDatabase) continue;
            if ((schema == null) || (schema.length() == 0)) {
                bSchema = true;
            } else {
                bSchema = columns[i][2].equalsIgnoreCase(schema);
            }
            if (!bSchema) continue;
            bTable = columns[i][3].equalsIgnoreCase(table);
            if (!bTable) continue;
            bColumn = columns[i][4].equalsIgnoreCase(column);
            if (!bColumn) continue;
            bRet = true;
            break;
        }
        return bRet;
    }
}

public class getTableColumn {
    private static File[] listFiles(File sqlFiles) {
        List<File> children = new ArrayList<File>();
        if (sqlFiles != null)
            listFiles(sqlFiles, children);
        return children.toArray(new File[0]);
    }

    private static void listFiles(File rootFile, List<File> children) {
        if (rootFile.isFile())
            children.add(rootFile);
        else {
            File[] files = rootFile.listFiles();
            for (int i = 0; i < files.length; i++) {
                listFiles(files[i], children);
            }
        }
    }

    public String processQuery(String category) throws SQLException {

        EDbVendor vendor = EDbVendor.dbvmysql;
        System.out.println("Processing " + vendor.toString() + "...");
        TGetTableColumn getTableColumn = new TGetTableColumn(vendor);
        getTableColumn.showDetail = false;
        getTableColumn.showSummary = true;
        getTableColumn.showTreeStructure = false;
        getTableColumn.showBySQLClause = false;
        getTableColumn.showJoin = false;
        getTableColumn.showColumnLocation = true;
        getTableColumn.linkOrphanColumnToFirstTable = false;
        getTableColumn.showIndex = false;
        getTableColumn.showDatatype = true;
        getTableColumn.listStarColumn = true;
        getTableColumn.setMetaDatabase(new sampleMetaDB());
        String sqlQuery = queryDetails[1];
        getTableColumn.run(sqlQuery, false);

        String issue = category;
        ReadQueries rq = new ReadQueries(issue);
        String outputQuery = rq.getQueries();
        long t = System.currentTimeMillis();
        EDbVendor vendor = EDbVendor.dbvmysql;

        return outputQuery();
    }

    private static void displayInitInformation() {
        System.out.println("Usage: java getTableColumn [/f <path_to_sql_file>] [/d <path_to_directory_includes_sql_files>] [/t <database type>] [/<show option>]");
        System.out.println("/f: specify the sql file path to analyze.");
        System.out.println("/t: option, set the database type. Support oracle, mysql, mssql, db2, netezza, teradata, informix, sybase, postgresql, hive, greenplum and redshift, the default type is oracle");
        System.out.println("/showSummary: default show option, display the summary information.");
        System.out.println("/showDetail: show option, display the detail information.");
        System.out.println("/showTreeStructure: show option, display the information as a tree structure.");
        System.out.println("/showBySQLClause: show option, display the information group by sql clause type.");
        System.out.println("/showJoin: show option, display the join table and column.");
    }
}

The problem I see is that I am unable to create an object of getTableColumn in my servlet class.

package com.servlets;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/getdata.do")
public class DataServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String issue        = request.getParameter("reportSelection");
        getTableColumn gt   = new getTableColumn();
        if ("Latency".equals(issue)) {
            getTableColumn gt   = new getTableColumn();
            System.out.println("Latency");
        } else if ("DataQuality".equals(issue)) {
            System.out.println("Data quality");
        } else if ("Outage".equals(issue)) {

        }
    }
}

The line: getTableColumn gt = new getTableColumn(); says Cannot resolve symbol 'getTableColumn'. I tried to write import statement of that class but it didn't work either. I don't understand how to fix this problem. Could anyone let me know how can I fix it ?

Bentaye
  • 9,403
  • 5
  • 32
  • 45
Metadata
  • 2,127
  • 9
  • 56
  • 127
  • *I tried to write import statement of that class but it didn't work either*: that's what you need to do: import the class, the same way as you import all the other classes you use. If it "didn't work", then post the code you tried, and tell us precisely what the problem was. Note that classes conventionally start with an uppercase letter in Java, and use a noun, not a verb. – JB Nizet Dec 13 '19 at 09:28
  • Can you post the full 'getTableColumn.java' file? – Wesley De Keirsmaeker Dec 13 '19 at 09:28
  • You should _definitely_ have a look at the various Java code conventions out there. They differ in a number of ways but one common thing is class and method naming: _never_ call a class `getTableColumn` etc. - that _will_ cause bugs in the end because `getTableColumn()` looks like a simple getter call when it actually is a constructor and that will confuse devs (imagine yourself revisiting that code after months of not using it). Do yourself a favor and work on naming a little - at least rename the class to `GetTableColumn`. – Thomas Dec 13 '19 at 09:29
  • Also note that `getTableColumn gt = new getTableColumn();` in that `if("Latency"...)` branch won't compile - you're redefining the variable here. If need be (and that doesn't seem to the case) just do `gt = new getTableColumn();`. – Thomas Dec 13 '19 at 09:32
  • if the class is getTableColumn then what will the bean be? simply work on your naming. – Odwori Dec 13 '19 at 09:37
  • I added full contents inside the file getTableColumn.java file. Please take a look at it. – Metadata Dec 13 '19 at 09:39
  • @JBNizet, I understand that the naming convention of the class is not correct. I tried to see if the code works so that I can standardize it step by step once I display the values on a web page. – Metadata Dec 13 '19 at 09:41
  • You still haven't done the important part: post the code you tried, and tell us precisely what the problem was. An import is necessary. – JB Nizet Dec 13 '19 at 09:42
  • I posted the main part of code after making changes. I just changed the same project to a webProject, added a JSP and a servlet: DataServlet, changed the main method to processQuery and made it return a String and then try to call it from the servlet. If I run the code removing all the JSP, Servlets and making processQuery main() method, it works. I hope I made it clear atleast now. – Metadata Dec 13 '19 at 09:52
  • @Thomas, "imagine yourself revisiting that code after months of not using it" I agree with you on this. I was just testing the project and made it work. I will standardize the code once I reach a check point. – Metadata Dec 13 '19 at 09:54
  • 1
    And just saying: read about java naming conventions. Class names should go UpperCamelCase. They never start lowercase in java. "Verbs" are also more for *method* names, so rather go TableColumnsService", and that thing has "get this" "get that" methods on it. – GhostCat Dec 13 '19 at 09:56
  • The posted code still doesn't import the class you want to use. So, add that import, and tell us what the problem is once the import has been added. – JB Nizet Dec 13 '19 at 09:56

1 Answers1

1

I think you are having issues because your getTableColumn class is not in a package (or rather it is in the default package), and you can't import a class from the default package. So:

  • Move your getTableColumn class into a package, for example tablecolumn
  • Then in DataServlet, add: import tablecolumn.getTableColumn with the other imports

And please make the first letter Upper case for your classes: getTableColumn en tableRelationAnalyze are not valid names

Bentaye
  • 9,403
  • 5
  • 32
  • 45
  • This helped. Stupid of me not realising that. I simply imported the classes from parser and hence they have with first letter in lower case. Will make the necessary changes. – Metadata Dec 13 '19 at 11:55
  • We all do silly mistakes, and myself more than the others – Bentaye Dec 13 '19 at 12:06