Как получить все столбцы и таблицы независимо от псевдонима, используя jsqlparser?JAVA

Программисты JAVA общаются здесь
Ответить Пред. темаСлед. тема
Anonymous
 Как получить все столбцы и таблицы независимо от псевдонима, используя jsqlparser?

Сообщение Anonymous »

Я пытался получить все столбцы и таблицы независимо от используемого псевдонима, например, предположим этот запрос
SELECT e.name,
(SELECT COUNT(*) FROM projects AS p WHERE p.employee_id = e.employee_id) AS project_count,
(SELECT COUNT(*) FROM tasks AS p WHERE p.employee_id = e.employee_id) AS task_count
FROM employees AS e;

Учитывая, что имя псевдонима можно повторно использовать в разных областях, я не могу просто собрать такие данные, как столбец, таблица и псевдоним, и наконец выполнить работу. Как я могу это сделать, ниже представлена ​​моя попытка Если у вас есть какие-либо предложения или какой-либо другой алгоритм, пожалуйста, дайте мне знать, спасибо.
То, что я сейчас делаю, — это разрешение таблиц для заданного псевдонима в конце каждой области ниже, это код,
import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Supplier;

import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.select.Join;
import net.sf.jsqlparser.statement.select.LateralSubSelect;
import net.sf.jsqlparser.statement.select.ParenthesedFromItem;
import net.sf.jsqlparser.statement.select.ParenthesedSelect;
import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.Select;
import net.sf.jsqlparser.statement.select.SelectItem;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.WithItem;
import net.sf.jsqlparser.util.TablesNamesFinder;

class ScopedData implements Iterable {
protected final LinkedList scopes = new LinkedList();
private final Supplier creator;

public ScopedData(Supplier creator) {
this.creator = creator;
}

public void enterScope() {
scopes.push(creator.get());
}

public void exitScope() {
if (scopes.isEmpty()) {
throw new IllegalStateException("No scope to exit");
} else {
scopes.pop();
}
}

public List scopes() {
return Collections.unmodifiableList(scopes);
}

public T current() {
if (scopes.isEmpty()) {
throw new IllegalStateException("No scope to get");
} else {
return this.scopes.peek();
}
}

@Override
public Iterator iterator() {
return this.scopes.descendingIterator();
}
}

// I am using different class than TablesNamesFinder but it is almost same as that
class SqlTokenVisitor extends TablesNamesFinder {
// I have overridden this method because I have changed the order of visiting from in my class
@Override
public T visit(PlainSelect plainSelect, S context) {
List withItemsList = plainSelect.getWithItemsList();
if (withItemsList != null && !withItemsList.isEmpty()) {
for (WithItem withItem : withItemsList) {
withItem.accept((SelectVisitor) this, context);
}
}
if (plainSelect.getFromItem() != null) {
plainSelect.getFromItem().accept(this, context);
}
if (plainSelect.getJoins() != null) {
visitJoins(plainSelect.getJoins(), context);
}
if (plainSelect.getWhere() != null) {
plainSelect.getWhere().accept(this, context);
}
if (plainSelect.getHaving() != null) {
plainSelect.getHaving().accept(this, context);
}
if (plainSelect.getOracleHierarchical() != null) {
plainSelect.getOracleHierarchical().accept(this, context);
}
if (plainSelect.getSelectItems() != null) {
for (SelectItem item : plainSelect.getSelectItems()) {
item.accept(this, context);
}
}
return null;
}

private T visitJoins(List joins, S context) {
for (Join join : joins) {
join.getFromItem().accept(this, context);
join.getRightItem().accept(this, context);
for (Expression expression : join.getOnExpressions()) {
expression.accept(this, context);
}
}
return null;
}

public SqlTokenVisitor() {
this.init(true);
}
}

abstract class ScopedVisitor extends SqlTokenVisitor {
@Override
public T visit(LateralSubSelect lateralSubSelect, S context) {
this.enteringScope();
super.visit(lateralSubSelect, context);
this.exitingScope();
return null;
}

@Override
public T visit(ParenthesedSelect select, S context) {
this.enteringScope();
super.visit(select, context);
this.exitingScope();
return null;
}

@Override
public T visit(Select select, S context) {
this.enteringScope();
super.visit(select, context);
this.exitingScope();
return null;
}

@Override
public T visit(ParenthesedFromItem parenthesis, S context) {
this.enteringScope();
super.visit(parenthesis, context);
this.exitingScope();
return null;
}

public abstract void enteringScope();

public abstract void exitingScope();
}

class ColumnVisitor extends ScopedVisitor {
private void processScope(ScopeData scopeData) {
for (Column column : scopeData.columns) {
String resolvedTable = this.resolveAlias(column.getTable()).getName();
System.out.println(column.getColumnName() + " : " + resolvedTable);
}
}

private Table resolveAlias(Table alias) {
for (ScopeData data : scopedData) {
Table resolved = resolveAlias(data.tables, alias);
if (resolved != null) {
return resolved;
}
}
return alias;
}

public Table resolveAlias(List tables, Table alias) {
for (Table table : tables) {
if (table.getAlias() != null && table.getAlias().getName().equals(alias.getName())) {
return table;
}
}
return null;
}

@Override
public Void visit(LateralSubSelect lateralSubSelect, S context) {
if (lateralSubSelect.getAlias() != null) {
this.scopedData.current().otherTables.add(lateralSubSelect.getAlias().getName());
}
super.visit(lateralSubSelect, context);
return null;
}

@Override
public Void visit(WithItem withItem, S context) {
this.scopedData.current().otherTables.add(withItem.getAlias().getName());
super.visit(withItem, context);
return null;
}

@Override
public Void visit(ParenthesedSelect select, S context) {
if (select.getAlias() != null) {
this.scopedData.current().otherTables.add(select.getAlias().getName());
}
super.visit(select, context);
return null;
}

@Override
public Void visit(ParenthesedFromItem parenthesis, S context) {
if (parenthesis.getAlias() != null) {
this.scopedData.current().otherTables.add(parenthesis.getAlias().getName());
}
super.visit(parenthesis, context);
return null;
}

@Override
public Void visit(Column column, S context) {
super.visit(column, context);
if (column.getTable() != null) {
this.scopedData.current().columns.add(column);
}

return null;
}

@Override
public Void visit(Table table, S context) {
super.visit(table, context);
this.scopedData.current().tables.add(table);
return null;
}

@Override
public void enteringScope() {
this.scopedData.enterScope();
}

@Override
public void exitingScope() {
this.processScope(this.scopedData.current());
this.scopedData.exitScope();
}

private static class ScopeData {
public final List columns = new LinkedList();
public final List tables = new LinkedList();
public final List otherTables = new LinkedList();
}

private final ScopedData scopedData = new ScopedData(ScopeData::new);
}

public class Main {
public static void main(String[] args) throws JSQLParserException {
String query = "SELECT e.name, \n" + //
" (SELECT COUNT(*) FROM projects AS p WHERE p.employee_id = e.employee_id) AS project_count,\n" + //
" (SELECT COUNT(*) FROM tasks AS p WHERE p.employee_id = e.employee_id) AS task_count\n" + //
"FROM employees AS e;";
Statement stmt = CCJSqlParserUtil.parse(query);
stmt.accept(new ColumnVisitor());
}
}

Вывод
employee_id : projects
employee_id : employees
employee_id : tasks
employee_id : employees
name : employees


Подробнее здесь: https://stackoverflow.com/questions/791 ... jsqlparser
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «JAVA»