Package railo.runtime.tag

Source Code of railo.runtime.tag.Update

package railo.runtime.tag;

import java.sql.DatabaseMetaData;
import java.sql.SQLException;
import java.util.ArrayList;

import railo.commons.lang.ExceptionUtil;
import railo.commons.lang.StringUtil;
import railo.runtime.config.ConfigImpl;
import railo.runtime.db.DataSource;
import railo.runtime.db.DataSourceManager;
import railo.runtime.db.DatasourceConnection;
import railo.runtime.db.SQL;
import railo.runtime.db.SQLImpl;
import railo.runtime.db.SQLItem;
import railo.runtime.db.SQLItemImpl;
import railo.runtime.debug.DebuggerPro;
import railo.runtime.debug.DebuggerUtil;
import railo.runtime.exp.DatabaseException;
import railo.runtime.exp.PageException;
import railo.runtime.ext.tag.TagImpl;
import railo.runtime.op.Caster;
import railo.runtime.type.QueryImpl;
import railo.runtime.type.Struct;
import railo.runtime.type.StructImpl;
import railo.runtime.type.scope.Form;
import railo.runtime.type.util.ArrayUtil;
import railo.runtime.type.util.CollectionUtil;
import railo.runtime.type.util.ListUtil;

/**
* Updates existing records in data sources.
*
*
*
**/
public final class Update extends TagImpl {

  /** If specified, password overrides the password value specified in the ODBC setup. */
  private String password;

  /** Name of the data source that contains a table. */
  private String datasource;

  /** If specified, username overrides the username value specified in the ODBC setup. */
  private String username;

  /** A comma-separated list of form fields to update. If this attribute is not specified, all fields
  **     in the form are included in the operation. */
  private String formfields;

  /** For data sources that support table ownership, for example, SQL Server, Oracle, and Sybase
  **     SQL Anywhere, use this field to specify the owner of the table. */
  private String tableowner;

  /** Name of the table you want to update. */
  private String tablename;

  /** For data sources that support table qualifiers, use this field to specify the qualifier for the
  **     table. The purpose of table qualifiers varies across drivers. For SQL Server and Oracle, the qualifier
  **     refers to the name of the database that contains the table. For the Intersolv dBase driver, the
  **     qualifier refers to the directory where the DBF files are located. */
  private String tablequalifier;

  @Override
  public void release()  {
    super.release();
    password=null;
    username=null;
    formfields=null;
    tableowner=null;
    tablequalifier=null;
    datasource=null;
  }

  /** set the value password
  *  If specified, password overrides the password value specified in the ODBC setup.
  * @param password value to set
  **/
  public void setPassword(String password)  {
    this.password=password;
  }

  /** set the value datasource
  *  Name of the data source that contains a table.
  * @param datasource value to set
  **/
  public void setDatasource(String datasource)  {
    this.datasource=datasource;
  }

  /** set the value username
  *  If specified, username overrides the username value specified in the ODBC setup.
  * @param username value to set
  **/
  public void setUsername(String username)  {
    this.username=username;
  }

  /** set the value formfields
  *  A comma-separated list of form fields to update. If this attribute is not specified, all fields
  *     in the form are included in the operation.
  * @param formfields value to set
  **/
  public void setFormfields(String formfields)  {
    this.formfields=formfields;
  }

  /** set the value tableowner
  *  For data sources that support table ownership, for example, SQL Server, Oracle, and Sybase
  *     SQL Anywhere, use this field to specify the owner of the table.
  * @param tableowner value to set
  **/
  public void setTableowner(String tableowner)  {
    this.tableowner=tableowner;
  }

  /** set the value tablename
  *  Name of the table you want to update.
  * @param tablename value to set
  **/
  public void setTablename(String tablename)  {
    this.tablename=tablename;
  }

  /** set the value tablequalifier
  *  For data sources that support table qualifiers, use this field to specify the qualifier for the
  *     table. The purpose of table qualifiers varies across drivers. For SQL Server and Oracle, the qualifier
  *     refers to the name of the database that contains the table. For the Intersolv dBase driver, the
  *     qualifier refers to the directory where the DBF files are located.
  * @param tablequalifier value to set
  **/
  public void setTablequalifier(String tablequalifier)  {
    this.tablequalifier=tablequalifier;
  }


  @Override
  public int doStartTag()  {
    return SKIP_BODY;
  }

  @Override
  public int doEndTag() throws PageException  {

    Object ds=Insert.getDatasource(pageContext,datasource);
   
    DataSourceManager manager = pageContext.getDataSourceManager();
      DatasourceConnection dc=ds instanceof DataSource?
          manager.getConnection(pageContext,(DataSource)ds,username,password):
          manager.getConnection(pageContext,Caster.toString(ds),username,password);
    try {
     
      Struct meta =null;
        try {
          meta=Insert.getMeta(dc,tablequalifier,tableowner,tablename);
        }
        catch(SQLException se){
          meta=new StructImpl();
        }
     
        String[] pKeys=getPrimaryKeys(dc);
      SQL sql=createSQL(dc,pKeys,meta);
      if(sql!=null) {
        railo.runtime.type.Query query = new QueryImpl(pageContext,dc,sql,-1,-1,-1,"query");
       
        if(pageContext.getConfig().debug()) {
          String dsn=ds instanceof DataSource?((DataSource)ds).getName():Caster.toString(ds);
          boolean logdb=((ConfigImpl)pageContext.getConfig()).hasDebugOptions(ConfigImpl.DEBUG_DATABASE);
          if(logdb){
            boolean debugUsage=DebuggerUtil.debugQueryUsage(pageContext,query);
            ((DebuggerPro)pageContext.getDebugger()).addQuery(debugUsage?query:null,dsn,"",sql,query.getRecordcount(),pageContext.getCurrentPageSource(),query.getExecutionTime());
          }
        }
      }
      return EVAL_PAGE;
    }
    finally {
      manager.releaseConnection(pageContext,dc);
    }
  }

    private String[] getPrimaryKeys(DatasourceConnection dc) throws PageException {
      railo.runtime.type.Query query = getPrimaryKeysAsQuery(dc);
    int recCount=query.getRecordcount();
        String[] pKeys=new String[recCount];
   
        if(recCount==0) throw new DatabaseException("can't find primary keys of table ["+tablename+"]",null,null,dc);
       
        for(int row=1;row<=recCount;row++) {
            pKeys[row-1]=Caster.toString(query.getAt("column_name",row));
        }

    return pKeys;
    }
   
    private railo.runtime.type.Query getPrimaryKeysAsQuery(DatasourceConnection dc) throws PageException {

        // Read Meta Data
        DatabaseMetaData meta;
        try {
            meta = dc.getConnection().getMetaData();
        }
        catch (SQLException e) {
            throw new DatabaseException(e,dc);
        }
       
        try {
            return new QueryImpl(meta.getPrimaryKeys(tablequalifier, tableowner, tablename),-1,"query",pageContext.getTimeZone());
        }
    catch (SQLException e) {
        try {
            return new QueryImpl(meta.getBestRowIdentifier(tablequalifier, tableowner, tablename, 0, false),-1,"query",pageContext.getTimeZone());
            }
        catch (SQLException sqle) {
                throw new DatabaseException("can't find primary keys of table ["+tablename+"] ("+ExceptionUtil.getMessage(sqle)+")",null,null,dc);
            }
        }
    }

    /**
     * @param keys primary Keys
     * @return return SQL String for update
     * @throws PageException
     */
    private SQL createSQL(DatasourceConnection dc,String[] keys, Struct meta) throws PageException {
        String[] fields=null;
        Form form = pageContext.formScope();
        if(formfields!=null) fields=ListUtil.toStringArray(ListUtil.listToArrayRemoveEmpty(formfields,','));
        else fields=CollectionUtil.keysAsString(pageContext.formScope());
       
        StringBuffer set=new StringBuffer();
        StringBuffer where=new StringBuffer();
        ArrayList setItems=new ArrayList();
        ArrayList whereItems=new ArrayList();
        String field;
        for(int i=0;i<fields.length;i++) {
            field = StringUtil.trim(fields[i],null);
            if(StringUtil.startsWithIgnoreCase(field, "form."))
              field=field.substring(5);
           
            if(!field.equalsIgnoreCase("fieldnames")) {
                if(ArrayUtil.indexOfIgnoreCase(keys,field)==-1) {
                  if(set.length()==0) set.append(" set ");
                  else set.append(",");
                  set.append(field);
                  set.append("=?");
                  ColumnInfo ci=(ColumnInfo) meta.get(field);
                  if(ci!=null)setItems.add(new SQLItemImpl(form.get(field,null),ci.getType()));
                  else setItems.add(new SQLItemImpl(form.get(field,null)));
                }
                else {
                  if(where.length()==0) where.append(" where ");
                  else where.append(" and ");
                  where.append(field);
                  where.append("=?");
                  whereItems.add(new SQLItemImpl(form.get(field,null)));
                }
            }
        }
        if((setItems.size()+whereItems.size())==0) return null;
       
        if(whereItems.size()==0)throw new DatabaseException("can't find primary keys ["+ListUtil.arrayToList(keys,",")+"] of table ["+tablename+"] in form scope",null,null,dc);
       
        StringBuffer sql=new StringBuffer();
        sql.append("update ");
        if(tablequalifier!=null && tablequalifier.length()>0) {
            sql.append(tablequalifier);
            sql.append('.');
        }
        if(tableowner!=null && tableowner.length()>0) {
            sql.append(tableowner);
            sql.append('.');
        }
        sql.append(tablename);
        sql.append(set);
        sql.append(where);
       
        return new SQLImpl(sql.toString(),arrayMerge(setItems,whereItems));
    }

    private SQLItem[] arrayMerge(ArrayList setItems, ArrayList whereItems) {
        SQLItem[] items=new SQLItem[setItems.size()+whereItems.size()];

        int index=0;
        // Item
        int size=setItems.size();
        for(int i=0;i<size;i++) {
            items[index++]=(SQLItem) setItems.get(i);
        }
        // Where
        size=whereItems.size();
        for(int i=0;i<size;i++) {
            items[index++]=(SQLItem) whereItems.get(i);
        }
        return items;
    }
}















TOP

Related Classes of railo.runtime.tag.Update

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.