/* * #%L * model * %% * Copyright (C) 2012 - 2015 valdasraps * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Lesser Public License for more details. * * You should have received a copy of the GNU General Lesser Public * License along with this program. If not, see * <http://www.gnu.org/licenses/lgpl-3.0.html>. * #L% */ package lt.emasina.resthub.factory; import lt.emasina.resthub.parser.SqlParser; import com.google.inject.Inject; import java.io.Serializable; import java.io.StringReader; import java.sql.PreparedStatement; import java.sql.ResultSetMetaData; import java.util.ArrayList; import java.util.Collection; import java.util.List; import net.sf.jsqlparser.parser.CCJSqlParserManager; import net.sf.jsqlparser.statement.Statement; import net.sf.jsqlparser.statement.select.Select; import oracle.jdbc.OracleConnection; import lt.emasina.resthub.ConnectionFactory; import lt.emasina.resthub.exception.QueryException; import lt.emasina.resthub.model.MdColumn; import lt.emasina.resthub.model.MdParameter; import lt.emasina.resthub.model.MdType; import lt.emasina.resthub.util.NameUtil; public class TableBuilder implements Serializable { @Inject private CCJSqlParserManager pm; @Inject private ConnectionFactory cf; public void collectParameters(final String sql, Collection<MdParameter> parameters) throws Exception { SqlParser parser = new SqlParser(); Statement stmt = pm.parse(new StringReader(sql)); if (stmt instanceof Select) { ((Select) stmt).getSelectBody().accept(parser); } else { throw new Exception("Only SELECT statements allowed!"); } List<MdParameter> tempParameters = new ArrayList<>(); for (String name: parser.getParameterNames()) { MdParameter param = null; for (MdParameter p: parameters) { if (p.getName().equalsIgnoreCase(name)) { param = p; break; } } if (param == null) { param = new MdParameter(); param.setName(name); param.setType(MdType.STRING); param.setArray(Boolean.FALSE); } else { param.setName(name.toLowerCase()); } param.beforeSave(); tempParameters.add(param); } parameters.clear(); parameters.addAll(tempParameters); } public void collectColumns(final String connectionName, final String sql, List<MdColumn> columns) throws Exception { try (OracleConnection con = cf.getConnection(connectionName)) { try (PreparedStatement ps = con.prepareStatement(sql)) { List<String> columnNames = new ArrayList<>(); List<MdColumn> tempColumns = new ArrayList<>(); // Create missing columns ResultSetMetaData md = ps.getMetaData(); for (int i = 1; i <= md.getColumnCount(); i++) { String name = md.getColumnName(i); MdColumn col = null; for (MdColumn c: columns) { if (c.getName().equals(name)) { col = c; break; } } // Check repeating column names if (!NameUtil.isOraName(name)) { throw new QueryException("Complex column name defined! Please use alias for column '%s'", name); } if (columnNames.contains(name)) { throw new QueryException("Non unique column names defined! Please use alias for columns '%s'", name); } columnNames.add(name); if (col == null) { col = new MdColumn(); col.setName(name); col.setCName(NameUtil.getCName(name)); col.setJName(NameUtil.getJName(name)); } col.setNumber(i); col.setType(MdType.getMdType(md.getColumnType(i))); col.beforeSave(); tempColumns.add(col); } columns.clear(); columns.addAll(tempColumns); } } } }