Package railo.runtime.db

Source Code of railo.runtime.db.HSQLDBHandler

package railo.runtime.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;

import railo.commons.db.DBUtil;
import railo.commons.lang.SerializableObject;
import railo.commons.lang.StringUtil;
import railo.runtime.PageContext;
import railo.runtime.config.ConfigImpl;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.PageException;
import railo.runtime.op.Caster;
import railo.runtime.op.date.DateCaster;
import railo.runtime.sql.SQLParserException;
import railo.runtime.sql.SelectParser;
import railo.runtime.sql.Selects;
import railo.runtime.sql.old.ParseException;
import railo.runtime.timer.Stopwatch;
import railo.runtime.type.Collection.Key;
import railo.runtime.type.Query;
import railo.runtime.type.QueryColumn;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.util.CollectionUtil;
import static railo.runtime.db.DatasourceManagerImpl.QOQ_DATASOURCE_NAME;

/**
* class to reexecute queries on the resultset object inside the cfml enviroment
*/
public final class HSQLDBHandler {

  private static final int STRING=0;
  private static final int INT=1;
  private static final int DOUBLE=2;
  private static final int DATE=3;
  private static final int TIME=4;
  private static final int TIMESTAMP=5;
  private static final int BINARY=6;
 
 
  Executer executer=new Executer();
  QoQ qoq=new QoQ();
  private static Object lock=new SerializableObject();

  /**
   * constructor of the class
   */
  public HSQLDBHandler() {

  }
 
  /**
   * adds a table to the memory database
   * @param conn
   * @param pc
   * @param name name of the new table
   * @param query data source for table
   * @throws SQLException
   * @throws PageException
   */
  private static void addTable(Connection conn, PageContext pc,String name,Query query, boolean doSimpleTypes,ArrayList<String> usedTables) throws SQLException, PageException {
      Statement stat;
    usedTables.add(name);
      stat = conn.createStatement();
      Key[] keys = CollectionUtil.keys(query);
      int[] types=query.getTypes();
      int[] innerTypes=toInnerTypes(types);
      // CREATE STATEMENT
        String comma="";
        StringBuffer create=new StringBuffer("CREATE TABLE "+name+" (");
        StringBuffer insert=new StringBuffer("INSERT INTO  "+name+" (");
        StringBuffer values=new StringBuffer("VALUES (");
        for(int i=0;i<keys.length;i++) {
          String key=keys[i].getString();
          String type=(doSimpleTypes)?"VARCHAR_IGNORECASE":toUsableType(types[i]);
         
         
          create.append(comma+key);
          create.append(" ");
          create.append(type);
          insert.append(comma+key);     
          values.append(comma+"?");         
          comma=",";
        }
        create.append(")");
        insert.append(")");
        values.append(")");
                stat.execute(create.toString());
        PreparedStatement prepStat = conn.prepareStatement(insert.toString()+values.toString());

      // INSERT STATEMENT
      //HashMap integerTypes=getIntegerTypes(types);
       
      int count=query.getRecordcount();
      QueryColumn[] columns=new QueryColumn[keys.length];
      for(int i=0;i<keys.length;i++) {
          columns[i]=query.getColumn(keys[i]);
      }
      for(int y=0;y<count;y++) {
        for(int i=0;i<keys.length;i++) {
          int type=innerTypes[i];
          Object value=columns[i].get(y+1,null);
         
          //print.out("*** "+type+":"+Caster.toString(value));
          if(doSimpleTypes) {
           
            prepStat.setObject(i+1,Caster.toString(value));
          }
          else {
            if(value==null)
              prepStat.setNull(i+1,types[i]);
            else if(type==BINARY)
              prepStat.setBytes(i+1,Caster.toBinary(value));
            else if(type==DATE) {
              //print.out(new java.util.Date(new Date(DateCaster.toDateAdvanced(value,pc.getTimeZone()).getTime()).getTime()));

              prepStat.setTimestamp(i+1,(value.equals(""))?null:new Timestamp(DateCaster.toDateAdvanced(query.getAt(keys[i],y+1),pc.getTimeZone()).getTime()));
              //prepStat.setObject(i+1,Caster.toDate(value,null));
              //prepStat.setDate(i+1,(value==null || value.equals(""))?null:new Date(DateCaster.toDateAdvanced(value,pc.getTimeZone()).getTime()));
            }
            else if(type==TIME)
              prepStat.setTime(i+1,(value.equals(""))?null:new Time(DateCaster.toDateAdvanced(query.getAt(keys[i],y+1),pc.getTimeZone()).getTime()));
            else if(type==TIMESTAMP)
              prepStat.setTimestamp(i+1,(value.equals(""))?null:new Timestamp(DateCaster.toDateAdvanced(query.getAt(keys[i],y+1),pc.getTimeZone()).getTime()));
            else if(type==DOUBLE)
              prepStat.setDouble(i+1,(value.equals(""))?0:Caster.toDoubleValue(query.getAt(keys[i],y+1)));
            else if(type==INT)
              prepStat.setLong(i+1,(value.equals(""))?0:Caster.toIntValue(query.getAt(keys[i],y+1)));
            else if(type==STRING)
              prepStat.setObject(i+1,Caster.toString(value));
          }
         
        }
        prepStat.execute();     
      }

  }
 
 
  private static int[] toInnerTypes(int[] types) {
    int[] innerTypes=new int[types.length];
    for(int i=0;i<types.length;i++) {
      int type=types[i];
     
      if(
          type==Types.BIGINT ||
          type==Types.BIT ||
          type==Types.INTEGER ||
          type==Types.SMALLINT ||
          type==Types.TINYINT)innerTypes[i]=INT;
      else if(
              type==Types.DECIMAL ||
              type==Types.DOUBLE ||
              type==Types.NUMERIC ||
              type==Types.REAL)innerTypes[i]=DOUBLE;
      else if(type==Types.DATE)innerTypes[i]=DATE;
      else if(type==Types.TIME)innerTypes[i]=TIME;
      else if(type==Types.TIMESTAMP)innerTypes[i]=TIMESTAMP;
      else if(
              type==Types.BINARY ||
              type==Types.LONGVARBINARY ||
              type==Types.VARBINARY)innerTypes[i]=BINARY;
      else
          innerTypes[i]=STRING;
     
     
    }
    return innerTypes;
  }
 
 
  private static String toUsableType(int type) {
    if(type==Types.NCHAR)return "CHAR";
    if(type==Types.NCLOB)return "CLOB";
    if(type==Types.NVARCHAR)return "VARCHAR_IGNORECASE";
    if(type==Types.VARCHAR)return "VARCHAR_IGNORECASE";
      if(type==Types.JAVA_OBJECT)return "VARCHAR_IGNORECASE";
     
     
     
    return QueryImpl.getColumTypeName(type);
   
  }
 
 
  /**
   * remove a table from the memory database
   * @param conn
   * @param name
   * @throws DatabaseException
   */
  private static void removeTable(Connection conn, String name) throws SQLException {
    name=name.replace('.','_');
    Statement stat = conn.createStatement();
    stat.execute("DROP TABLE "+name);
    DBUtil.commitEL(conn);
  }
   
  /**
   * remove all table inside the memory database
   * @param conn
   */
  private static void removeAll(Connection conn, ArrayList<String> usedTables) {
    int len=usedTables.size();
   
    for(int i=0;i<len;i++) {
     
      String tableName=usedTables.get(i).toString();
      //print.out("remove:"+tableName);
      try {
        removeTable(conn,tableName);
      } catch (Throwable t) {}
    }
  }
 
    /**
     * executes a query on the queries inside the cld fusion enviroment
     * @param pc Page Context
     * @param sql
     * @param maxrows
     * @return result as Query
     * @throws PageException
     * @throws PageException
     */
    public Query execute(PageContext pc, SQL sql, int maxrows, int fetchsize, int timeout) throws PageException {
        Stopwatch stopwatch=new Stopwatch(Stopwatch.UNIT_NANO);
    stopwatch.start();
    String prettySQL =null;
    Selects selects=null;
   
    // First Chance
        try {
          SelectParser parser=new SelectParser();
          selects = parser.parse(sql.getSQLString());
         
          Query q=qoq.execute(pc,sql,selects,maxrows);
          q.setExecutionTime(stopwatch.time());

          return q;
        }
        catch (SQLParserException spe) {
          //railo.print.printST(spe);
          //sp
          //railo.print.out("sql parser crash at:");
          //railo.print.out("--------------------------------");
          //railo.print.out(sql.getSQLString().trim());
          //railo.print.out("--------------------------------");
          //print.e("1:"+sql.getSQLString());
          prettySQL = SQLPrettyfier.prettyfie(sql.getSQLString());
          //print.e("2:"+prettySQL);
          try {
            Query query=executer.execute(pc,sql,prettySQL,maxrows);
            query.setExecutionTime(stopwatch.time());
            return query;
          } catch (PageException ex) {
            //railo.print.printST(ex);
            //railo.print.out("old executor/zql crash at:");
            //railo.print.out("--------------------------------");
            //railo.print.out(sql.getSQLString().trim());
            //railo.print.out("--------------------------------");
           
          }
         
        }
        catch (PageException e) {
          //throw e;
          //print.out("new executor crash at:");
          //print.out("--------------------------------");
          //print.out(sql.getSQLString().trim());
          //print.out("--------------------------------");
        }
        //if(true) throw new RuntimeException();
     
  // SECOND Chance with hsqldb
    try {
      boolean isUnion=false;
      Set<String> tables=null;
      if(selects!=null) {
        HSQLUtil2 hsql2=new HSQLUtil2(selects);
        isUnion=hsql2.isUnion();
        tables=hsql2.getInvokedTables();
      }
      else {
        if(prettySQL==null)prettySQL = SQLPrettyfier.prettyfie(sql.getSQLString());
        HSQLUtil hsql=new HSQLUtil(prettySQL);
          tables=hsql.getInvokedTables();
        isUnion=hsql.isUnion();
      }

      String strSQL=StringUtil.replace(sql.getSQLString(),"[","",false);
      strSQL=StringUtil.replace(strSQL,"]","",false);
      sql.setSQLString(strSQL);
      return _execute(pc, sql, maxrows, fetchsize, timeout,stopwatch,tables,isUnion);
     
    }
      catch(ParseException e) {
        throw  new DatabaseException(e.getMessage(),null,sql,null);
      }
   
    }
   
    private QueryImpl _execute(PageContext pc, SQL sql, int maxrows, int fetchsize, int timeout, Stopwatch stopwatch, Set<String> tables, boolean isUnion) throws PageException {
      try {
      return __execute(pc, SQLImpl.duplicate(sql), maxrows, fetchsize, timeout,stopwatch,tables,false);
    }
      catch(PageException pe) {
      if(isUnion || StringUtil.indexOf(pe.getMessage(), "NumberFormatException:")!=-1){
        return __execute(pc, sql, maxrows, fetchsize, timeout,stopwatch,tables,true);
      }
      throw pe;
    }
  }

  public static  QueryImpl __execute(PageContext pc, SQL sql, int maxrows, int fetchsize, int timeout,Stopwatch stopwatch,Set<String> tables, boolean doSimpleTypes) throws PageException {
    ArrayList<String> usedTables=new ArrayList<String>();
    synchronized(lock) {
         
      QueryImpl nqr=null;
      ConfigImpl config = (ConfigImpl)pc.getConfig();
      DatasourceConnectionPool pool = config.getDatasourceConnectionPool();
      DatasourceConnection dc=pool.getDatasourceConnection(pc,config.getDataSource(QOQ_DATASOURCE_NAME),"sa","");
        Connection conn = dc.getConnection();
        try {
          DBUtil.setAutoCommitEL(conn,false);

            //sql.setSQLString(HSQLUtil.sqlToZQL(sql.getSQLString(),false));
            try {
            Iterator<String> it = tables.iterator();
            //int len=tables.size();
                  while(it.hasNext()) {
              String tableName=it.next().toString();//tables.get(i).toString();
             
              String modTableName=tableName.replace('.','_');
                      String modSql=StringUtil.replace(sql.getSQLString(),tableName,modTableName,false);
              sql.setSQLString(modSql);
              addTable(conn,pc,modTableName,Caster.toQuery(pc.getVariable(tableName)),doSimpleTypes,usedTables);
            }
                  DBUtil.setReadOnlyEL(conn,true);
                  try {
                    nqr =new QueryImpl(pc,dc,sql,maxrows,fetchsize,timeout,"query",null,false,false);
                  }
                  finally {
            DBUtil.setReadOnlyEL(conn,false);
                    DBUtil.commitEL(conn);
                    DBUtil.setAutoCommitEL(conn,true);
                  }
           
        } 
              catch (SQLException e) {
                  DatabaseException de = new DatabaseException("there is a problem to execute sql statement on query",null,sql,null);
                  de.setDetail(e.getMessage());
                  throw de;
              }
 
        }
        finally {
          removeAll(conn,usedTables);
                DBUtil.setAutoCommitEL(conn,true);
          pool.releaseDatasourceConnection(dc);
         
          //manager.releaseConnection(dc);
        }
          nqr.setExecutionTime(stopwatch.time());
      return nqr;
    }
    }
}
TOP

Related Classes of railo.runtime.db.HSQLDBHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.