специфичный для платформы libGdx код

1

Мне нужно создать специальный код для доступа к Derby DB и парсеру SQL FoundationDB из проекта на основе libGdx с другой реализацией между настольным компьютером и версией WebGL приложения. Приложение Desktop может обращаться к парсеру SQL и может подключаться к БД локально, а другая версия WebGL использует службу RPC GWT для доступа к данным через механизм клиент-сервер. Можно ли каким-то образом реализовать этот тип функциональности? Я хотел бы также обсудить реализацию игрушечного кода, если это возможно :)

Здесь текущий (не работающий над проектом WebGL) код QueryManager, хранящийся в основной папке проекта:

/**
 * 
 */
package it.viscioletti.sqlapprentice.sql;

import it.viscioletti.sqlapprentice.data.FieldDescription;
import it.viscioletti.sqlapprentice.data.FieldType;
import it.viscioletti.sqlapprentice.data.Row;
import it.viscioletti.sqlapprentice.data.TableDescription;
import it.viscioletti.sqlapprentice.gui.table.TableGui;
import it.viscioletti.sqlapprentice.utils.Constants;

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.sql.Types;
import java.util.Vector;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Application.ApplicationType;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.foundationdb.sql.StandardException;
import com.foundationdb.sql.parser.SQLParser;
import com.foundationdb.sql.parser.StatementNode;

/**
 * @author Federico
 *
 */
public class QueryManager {

    /* Member Variables: */
    private float tablesAreaW, tablesAreaH, textAreaH;
    private Connection conn;
    private ResultSet rs;
    private Statement stmt;
    private String sql;
    private TableGui resultTable;


    /* Constructors: */
    /** @throws SQLException */
    public QueryManager(String sql) {
        // stores the SQL String
        this.sql = sql.trim();

        // sets sizes used by the QueryManager
        float w = Gdx.graphics.getWidth(), h = Gdx.graphics.getHeight();
        tablesAreaW = (w / 10) * 7;
        tablesAreaH = (h / 10) * 6;
        textAreaH = h - (h / 10) - tablesAreaH;
    }

    /* Methods: */
    /** Checks the query sintax using Derby DBMS
     * @throws SQLException */
    public void checkSintax() throws SQLException {
        // connects to the DB
        connect();

        /* tries to execute the query. 
         * If is all fine, this method doesn't return anything,
         * otherwise it will throws a SQLException to the calling class */
        String[] sqlArray = sql.split(" ");
        // checks if is an INSERT INTO query type and then executes
        if(sqlArray[0].toUpperCase().equals("INSERT")) {
            System.out.println("Eseguo la INSERT (QM)"); // TODO remove later
            stmt.executeUpdate(sql); //TODO remove later
        } else
            stmt.executeQuery(sql);
    }

    /** Connects to the DB
     * @throws SQLException */
    private void connect() throws SQLException {
        // gets the connection to Derby DB
        conn = DriverManager.getConnection( Constants.CONNECTION_URL );
        // creates the statement for the connection
        stmt = conn.createStatement();
    }

    /** Executes the query and returns a TableGui object
     * @return The TableGui object result of the query
     * @throws SQLException */
    public TableGui getResultTable() throws SQLException {
        // connects to the DB
        connect();

        // gets the result set object of the executed query
        rs = stmt.executeQuery(sql);
        ResultSetMetaData rsmd = rs.getMetaData();

        Vector<FieldDescription> fieldDescriptions = new Vector<FieldDescription>();
        // stores each column name of the table
        String[] fieldNames = new String[rsmd.getColumnCount()];
        FieldType[] fieldTypes = new FieldType[rsmd.getColumnCount()];

        int idPos = -1;

        // the column numeration into the ResultsSetMetaData goes from 1 to column number
        for (int i = 1; i <= rsmd.getColumnCount(); i++) {

            // stores the position of SQLAPPRENTICEID, only if exists
            if(rsmd.getColumnName(i).trim().equals(Constants.TABLE_ID)) 
                idPos = i - 1;

            // gets the field name and adds it to the field names array
            fieldNames[i-1] = rsmd.getColumnName(i).trim();

            FieldType ft;

            // gets the column type and adds it to the field types array
            switch(rsmd.getColumnType(i)) {
                case Types.CHAR:
                case Types.VARCHAR:
                    ft = FieldType.CHAR;
                    break;
                case Types.INTEGER:
                    ft = FieldType.INTEGER;
                    break;
                default:
                    ft = null;
                    assert false;
            } 

            // adds the field type to the array
            fieldTypes[i - 1] = ft;

            // if its not a SQLAPPRENTICETABLEID
            if(!rsmd.getColumnName(i).trim().equals(Constants.TABLE_ID)) {
                // creates a new FieldDescription with appropriates column names and field types
                FieldDescription fd = new FieldDescription(fieldNames[i-1], ft);
                // adds it to the vector
                fieldDescriptions.add(fd);
            }
        }       

        // creates the TableDescription for the given table
        TableDescription td = new TableDescription(rsmd.getTableName(1), fieldDescriptions);

        TextureAtlas atlas = new TextureAtlas("ui/atlas.pack");
        Skin skin = new Skin(Gdx.files.internal("ui/applicationScreenSkin.json"), atlas);

        resultTable = new TableGui(skin, td);

        // sets bounds of the new table created
        resultTable.setBounds(tablesAreaW / 2, tablesAreaH, tablesAreaW, tablesAreaH);
        // draws debug lines
        resultTable.debug(); //TODO remove later

        resultTable.addTableHeader();

        // size of values array
        int valSize = (idPos == -1) ? fieldNames.length : fieldNames.length - 1;

        // stores the values of each table row
        Object[] values = new Object[valSize];

        // retrieves automatically the result set content
        while (rs.next()) {
            // uses a second index for values array because if the 
            // resultset has the id field in it, it bigger than values
            int j = 0, 
            // initialize id variable on every iteration
                id = 0;

            for (int i = 0; i < fieldNames.length; i++) {

                if(idPos != i) {
                    switch(fieldTypes[i]) {
                        case CHAR:
                            // trims the string returned because of the white spaces
                            values[j] = rs.getString(i + 1).trim();
                            break;
                        case INTEGER:
                            values[j] = rs.getInt(i + 1);
                            break;
                        default: assert false;
                    }
                    j++;
                } else 
                    id = rs.getInt(i + 1);
            }
            resultTable.addRow(new Row(id, td, values));
        }
        resultTable.setBounds((tablesAreaW / 2) - (resultTable.getTableWidth() / 2), 
                textAreaH + (tablesAreaH / 2) - (resultTable.getTableHeight() / 2), 
                resultTable.getTableWidth(), resultTable.getTableHeight());

        return resultTable;
    }

    /** Checks if the device ha 
     * Parses the query and returns its description
     * @return the QueryDescription */
    public QueryDescription dispatchParse() {
        if(Gdx.app.getType() == ApplicationType.Desktop) {
            System.out.println();
            try {
                return localParse();
            } catch (StandardException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } else if(Gdx.app.getType() == ApplicationType.WebGL) {
            System.out.println();
        }
        return null;
    }

    /** Parses locally the query and returns its description
     * @return the QueryDescription
     * @throws StandardException */
    public QueryDescription localParse() throws StandardException {

        // creates a new SQL parser to parse the query
        SQLParser parser = new SQLParser();

        // parses the query
        StatementNode stmt = parser.parseStatement(sql);

        // using the visitor design pattern to explore the query tree
        QueryVisitor qv = new QueryVisitor();

        stmt.accept(qv);

        // creates the query description
        return qv.createDescription();
    }

    /** Parses the query server-side and returns its description
     * @return the QueryDescription */
    public QueryDescription serverParse() {
        return null;
    }
}
  • 0
    что ты уже испробовал? Пожалуйста, прочитайте Как мне задать хороший вопрос? ,
  • 0
    Я попробовал этот учебник: github.com/libgdx/libgdx/wiki/… но у меня есть проблема, чтобы полностью отделить код Desktop и WebGL, потому что и объекты соединения Derby DB, и объект синтаксического анализатора SQL несовместимы с Проект на основе GWT и не может быть скомпилирован.
Показать ещё 2 комментария
Теги:
libgdx
gwt

1 ответ

0
Лучший ответ

Возможно, я нашел решение проблемы. В моем случае лучшим вариантом является создание кукольного класса в корневом проекте, а затем переписывание создания одного и того же класса в одном пакете в проекты, ориентированные на платформу, с внедрением различного поведения внутри. Как пример:

/* The puppet class into the root project: */
public class DBManager implements DBManagerInterface {
    public DBManager() {
    }

    @Override
    public void executeQuery(String sql) {
    }
}


/* the desktop project: */
public class DBManager implements DBManagerInterface {
    public DBManager() {
    }

    @Override
    public void executeQuery(String sql) {
        /* insert here the code to execute a query 
           locally on the desktop application */
    }
}

/* the WebGL project: */
public class DBManager implements DBManagerInterface {
    public DBManager() {
    }

    @Override
    public void executeQuery(String sql) {
        /* insert here the code to execute a query 
           using a client-server interaction via GWT RPC */
    }
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню