haul 2002/08/11 10:47:55 Modified: src/scratchpad/src/org/apache/cocoon/acting/modular Tag: cocoon_2_0_3_branch DatabaseAction.java DatabaseUpdateAction.java DatabaseSelectAction.java DatabaseDeleteAction.java DatabaseAddAction.java TestAction.java Added: src/scratchpad/src/org/apache/cocoon/acting/modular Tag: cocoon_2_0_3_branch DatabaseQueryAction.java Log: <action dev="CH" type="update"> Sync modules and related components with HEAD. </action> Revision Changes Path No revision No revision 1.1.2.2 +320 -357 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseAction.java Index: DatabaseAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseAction.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DatabaseAction.java 28 Apr 2002 19:59:52 -0000 1.1.2.1 +++ DatabaseAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.2 @@ -77,6 +77,7 @@ import org.apache.avalon.framework.activity.Disposable; import org.apache.avalon.framework.component.Component; import org.apache.avalon.framework.component.ComponentException; +import org.apache.avalon.framework.component.ComponentManager; import org.apache.avalon.framework.component.ComponentSelector; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; @@ -92,20 +93,19 @@ import org.apache.avalon.excalibur.component.DefaultRoleManager; import org.apache.avalon.excalibur.datasource.DataSourceComponent; + import org.apache.cocoon.Constants; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.components.classloader.RepositoryClassLoader; -import org.apache.cocoon.components.url.URLFactory; -import org.apache.cocoon.environment.ObjectModelHelper; -import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.generation.ImageDirectoryGenerator; import org.apache.cocoon.util.ClassUtils; import org.apache.cocoon.util.HashMap; +import org.apache.cocoon.util.JDBCTypeConversions; import org.apache.cocoon.selection.Selector; -import org.apache.cocoon.acting.AbstractDatabaseAction; +import org.apache.cocoon.acting.AbstractComplementaryConfigurableAction; import org.apache.cocoon.components.modules.database.AutoIncrementModule; import org.apache.cocoon.components.modules.input.InputModule; import org.apache.cocoon.components.modules.output.OutputModule; @@ -117,8 +117,7 @@ * and writing parameters. In addition the descriptor format has * changed to accomodate the new features. * - * <p>This action is heavily based upon the original DatabaseAddAction - * and relies on the AbstractDatabaseAction.</p> + * <p>This action is heavily based upon the original DatabaseAddActions.</p> * * <p>Modes have to be configured in cocoon.xconf. Mode names from * descriptor.xml file are looked up in the component service. Default @@ -143,12 +142,11 @@ * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ - * @see org.apache.cocoon.modules.input - * @see org.apache.cocoon.modules.output - * @see org.apache.cocoon.modules.database + * @see org.apache.cocoon.components.modules.input + * @see org.apache.cocoon.components.modules.output + * @see org.apache.cocoon.components.modules.database */ -public abstract class DatabaseAction extends AbstractDatabaseAction { - +public abstract class DatabaseAction extends AbstractComplementaryConfigurableAction implements Configurable, Disposable { // ======================================================================== // constants @@ -174,7 +172,8 @@ // instance vars // ======================================================================== - protected HashMap defaultModeNames = new HashMap( 3 ); + protected ComponentSelector dbselector; + protected Map defaultModeNames = new HashMap( 3 ); protected final HashMap cachedQueryData = new HashMap(); @@ -244,7 +243,7 @@ - // set up default modes + // set up default modes // <input/> // <output/> // <autoincrement/> @@ -261,20 +260,41 @@ } // ======================================================================== + // Avalon methods + // ======================================================================== + + /** + * Compose the Actions so that we can select our databases. + */ + public void compose(ComponentManager manager) throws ComponentException { + this.dbselector = (ComponentSelector) manager.lookup(DataSourceComponent.ROLE + "Selector"); + + super.compose(manager); + } + + + /** + * dispose + */ + public void dispose() { + this.manager.release(dbselector); + } + + + // ======================================================================== // protected utility methods // ======================================================================== /** - * override super's method since we prefer to get the datasource - * from defaults first or from sitemap parameters rather than from - * descriptor file. + * Get the Datasource we need. */ protected DataSourceComponent getDataSource( Configuration conf, Parameters parameters ) throws ComponentException { String sourceName = parameters.getParameter( "connection", (String) settings.get( "connection" ) ); if ( sourceName == null ) { - return getDataSource( conf ); + Configuration dsn = conf.getChild("connection"); + return (DataSourceComponent) this.dbselector.select(dsn.getValue("")); } else { if (getLogger().isDebugEnabled()) getLogger().debug("Using datasource: "+sourceName); @@ -282,25 +302,31 @@ } } + /** + * Return whether a type is a Large Object (BLOB/CLOB). + */ + protected final boolean isLargeObject (String type) { + if ("ascii".equals(type)) return true; + if ("binary".equals(type)) return true; + if ("image".equals(type)) return true; + + return false; + } /** - * Store a key/value pair in the request attributes. We prefix the key + * Store a key/value pair in the output attributes. We prefix the key * with the name of this class to prevent potential name collisions. - * This method overrides super class' method to allow an OutputModule - * to take care of what to do with the values. */ - protected void setRequestAttribute(Request request, String key, Object value) { + protected void setOutputAttribute(Map objectModel, String outputMode, String key, Object value) { ComponentSelector outputSelector = null; OutputModule output = null; - String outputMode = null; try { - outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); - outputMode = (String) request.getAttribute(ATTRIBUTE_KEY); + outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){ output = (OutputModule) outputSelector.select(outputMode); } - output.setAttribute( null, request, key, value ); + output.setAttribute( null, objectModel, key, value ); } catch (Exception e) { if (getLogger().isWarnEnabled()) getLogger() @@ -309,7 +335,7 @@ + ":" + e.getMessage() ); } finally { if (outputSelector != null) { - if (output != null) + if (output != null) outputSelector.release(output); this.manager.release(outputSelector); } @@ -317,238 +343,6 @@ } - /** - * Retrieve a value from the request attributes. - * This method overrides super class' method to allow an OutputModule - * to take care of where to get the values. - */ - // FIXME: OutputModule doesn't provide getAttribute anymore - protected Object getRequestAttribute(Request request, String key) { - - if (getLogger().isErrorEnabled()) - getLogger() - .error("getRequestAttribute not supported"); - return null; - } - - - // ======================================================================== - // main method - // ======================================================================== - - - /** - * Add a record to the database. This action assumes that - * the file referenced by the "descriptor" parameter conforms - * to the AbstractDatabaseAction specifications. - */ - public Map act( Redirector redirector, SourceResolver resolver, Map objectModel, - String source, Parameters param ) throws Exception { - - DataSourceComponent datasource = null; - Connection conn = null; - Map results = new HashMap(); - int rows = 0; - - // read global parameter settings - boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT; - Request request = ObjectModelHelper.getRequest(objectModel); - - // call specific default modes apart from output mode are not supported - // set request attribute - String outputMode = param.getParameter("output", (String) defaultModeNames.get(MODE_OUTPUT)); - request.setAttribute(ATTRIBUTE_KEY, outputMode); - - if (this.settings.containsKey("reloadable")) - reloadable = Boolean.getBoolean((String) this.settings.get("reloadable")); - - // read local parameter settings - try { - Configuration conf = - this.getConfiguration(param.getParameter("descriptor", (String) this.settings.get("descriptor")), - resolver, - param.getParameterAsBoolean("reloadable",reloadable)); - - // get database connection and try to turn off autocommit - datasource = this.getDataSource(conf, param); - conn = datasource.getConnection(); - if (conn.getAutoCommit() == true) { - try { - conn.setAutoCommit(false); - } catch (Exception ex) { - String tmp = param.getParameter("use-transactions",(String) this.settings.get("use-transactions",null)); - if (tmp != null && (tmp.equalsIgnoreCase("no") || tmp.equalsIgnoreCase("false") || tmp.equalsIgnoreCase("0"))) { - if (getLogger().isErrorEnabled()) - getLogger().error("This DB connection does not support transactions. If you want to risk your data's integrity by continuing nonetheless set parameter \"use-transactions\" to \"no\"."); - throw ex; - } - } - } - - // find tables to work with - Configuration[] tables = conf.getChildren("table"); - String tablesetname = param.getParameter("table-set", (String) this.settings.get("table-set")); - Map set_tables = null; // default to old behaviour - - HashMap modeTypes = null; - - if (tablesetname != null) { - // new set based behaviour - Configuration[] tablesets = conf.getChildren("table-set"); - String setname = null; - boolean found = false; - - // find tables contained in tableset - int j = 0; - for (j=0; j<tablesets.length; j++) { - setname = tablesets[j].getAttribute ("name", ""); - if (tablesetname.trim().equals (setname.trim ())) { - found = true; - break; - } - } - if (!found) { - throw new IOException(" given set " + tablesetname + " does not exists in a description file."); - } - - Configuration[] set = tablesets[j].getChildren("table"); - - // construct a Map that contains the names of the tables - // contained in the requested tableset - set_tables = new HashMap(set.length); - for (int i=0; i<set.length; i++) { - // look for alternative mode types - modeTypes = new HashMap(2); - modeTypes.put( MODE_AUTOINCR, set[i].getAttribute( "autoincr-mode", "autoincr" ) ); - modeTypes.put( MODE_OTHERS, set[i].getAttribute( "others-mode", "others" ) ); - set_tables.put(set[i].getAttribute("name",""), modeTypes); - } - } else { - modeTypes = new HashMap(2); - modeTypes.put( MODE_AUTOINCR, "autoincr" ); - modeTypes.put( MODE_OTHERS, "others" ); - }; - - for (int i=0; i<tables.length; i++) { - if (set_tables == null || - set_tables.containsKey( tables[i].getAttribute( "name" ) ) || - ( tables[i].getAttribute( "alias", null ) != null && set_tables.containsKey( tables[i].getAttribute( "alias" ) ) ) - ) { - if (tablesetname != null) { - if (tables[i].getAttribute("alias", null) != null && set_tables.containsKey(tables[i].getAttribute("alias"))){ - modeTypes = (HashMap) set_tables.get(tables[i].getAttribute("alias")); - set_tables.remove(tables[i].getAttribute("alias")); - } else { - modeTypes = (HashMap) set_tables.get(tables[i].getAttribute("name")); - set_tables.remove(tables[i].getAttribute("name")); - } - } - rows += processTable( tables[i], conn, request, results, modeTypes ); - } - } - - if (conn.getAutoCommit()==false) - conn.commit(); - - // obtain output mode module and rollback output - ComponentSelector outputSelector = null; - OutputModule output = null; - try { - outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); - if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){ - output = (OutputModule) outputSelector.select(outputMode); - } - output.commit( null, request ); - } catch (Exception e) { - if (getLogger().isWarnEnabled()) - getLogger() - .warn( "Could not select output mode " - + (String) outputMode - + ":" + e.getMessage() ); - } finally { - if (outputSelector != null) { - if (output != null) - outputSelector.release(output); - this.manager.release(outputSelector); - } - } - - } catch (Exception e) { - if ( conn != null ) { - try { - if (getLogger().isDebugEnabled()) - getLogger().debug( "Rolling back transaction. Caused by " + e.getMessage() ); - conn.rollback(); - results = null; - - // obtain output mode module and commit output - ComponentSelector outputSelector = null; - OutputModule output = null; - try { - outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); - if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){ - output = (OutputModule) outputSelector.select(outputMode); - } - output.rollback( null, request, e); - } catch (Exception e2) { - if (getLogger().isWarnEnabled()) - getLogger() - .warn( "Could not select output mode " - + (String) outputMode - + ":" + e2.getMessage() ); - } finally { - if (outputSelector != null) { - if (output != null) - outputSelector.release(output); - this.manager.release(outputSelector); - } - } - - } catch (SQLException se) { - if (getLogger().isDebugEnabled()) - getLogger().debug("There was an error rolling back the transaction", se); - } - } - - //throw new ProcessingException("Could not add record :position = " + currentIndex, e); - - // don't throw an exception, an error has been signalled, that should suffice - - String throwException = (String) this.settings.get( "throw-exception", - param.getParameter( "throw-exception", null ) ); - if ( throwException != null && - ( throwException.equalsIgnoreCase( "true" ) || throwException.equalsIgnoreCase( "yes" ) ) ) { - throw new ProcessingException("Could not add record",e); - } - } finally { - if (conn != null) { - try { - conn.close(); - } catch (SQLException sqe) { - getLogger().warn("There was an error closing the datasource", sqe); - } - } - - if (datasource != null) - this.dbselector.release(datasource); - } - if (results != null) { - if (rows>0) { - results.put("row-count",new Integer(rows)); - } else { - results = null; - } - } else { - if (rows>0) { - results = new HashMap(1); - results.put("row-count",new Integer(rows)); - } - } - - return (results == null? results : Collections.unmodifiableMap(results)); - } - - /** * Inserts a row or a set of rows into the given table based on the @@ -556,10 +350,10 @@ * * @param table the table's configuration * @param conn the database connection - * @param request the request + * @param objectModel the objectModel */ - protected int processTable( Configuration table, Connection conn, Request request, - Map results, HashMap modeTypes ) + protected int processTable( Configuration table, Connection conn, Map objectModel, + Map results, Map modeTypes ) throws SQLException, ConfigurationException, Exception { PreparedStatement statement = null; @@ -567,8 +361,9 @@ try { LookUpKey luk = new LookUpKey(table, modeTypes); CacheHelper queryData = null; - - getLogger().debug("modeTypes : "+ modeTypes); + + if (getLogger().isDebugEnabled()) + getLogger().debug("modeTypes : "+ modeTypes); // get cached data // synchronize complete block since we don't want 100s of threads @@ -586,7 +381,7 @@ getLogger().debug("query: "+queryData.queryString); statement = conn.prepareStatement(queryData.queryString); - Object[][] columnValues = this.getColumnValues( table, queryData, request ); + Object[][] columnValues = this.getColumnValues( table, queryData, objectModel ); int setLength = 1; if ( queryData.isSet ) { @@ -600,7 +395,7 @@ for ( int rowIndex = 0; rowIndex < setLength; rowIndex++ ) { if (getLogger().isDebugEnabled()) getLogger().debug( "====> row no. " + rowIndex ); - rows += processRow( request, conn, statement, table, queryData, columnValues, rowIndex, results ); + rows += processRow( objectModel, conn, statement, (String) modeTypes.get(MODE_OUTPUT), table, queryData, columnValues, rowIndex, results ); } } finally { @@ -647,8 +442,7 @@ /** * compose name for output a long the lines of "table.column" */ - protected String getOutputName ( Configuration tableConf, Configuration columnConf ) - throws ConfigurationException { + protected String getOutputName ( Configuration tableConf, Configuration columnConf ) { return getOutputName( tableConf, columnConf, -1 ); } @@ -658,11 +452,10 @@ * compose name for output a long the lines of "table.column[row]" or * "table.column" if rowIndex is -1. */ - protected String getOutputName ( Configuration tableConf, Configuration columnConf, int rowIndex ) - throws ConfigurationException { + protected String getOutputName ( Configuration tableConf, Configuration columnConf, int rowIndex ) { - return ( tableConf.getAttribute("alias", tableConf.getAttribute("name") ) - + "." + columnConf.getAttribute("name") + return ( tableConf.getAttribute("alias", tableConf.getAttribute("name", null) ) + + "." + columnConf.getAttribute("name",null) + ( rowIndex == -1 ? "" : "[" + rowIndex + "]" ) ); } @@ -676,7 +469,7 @@ * a set. * */ - protected Object[] getColumnValue( Configuration tableConf, Column column, Request request ) + protected Object[] getColumnValue( Configuration tableConf, Column column, Map objectModel ) throws ConfigurationException, ComponentException { if ( column.isAutoIncrement ) { @@ -684,25 +477,25 @@ } else { Object[] values; String cname = getOutputName( tableConf, column.columnConf ); - + // obtain input module and read values ComponentSelector inputSelector = null; InputModule input = null; try { - inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); + inputSelector=(ComponentSelector) this.manager.lookup(INPUT_MODULE_SELECTOR); if (column.mode != null && inputSelector != null && inputSelector.hasComponent(column.mode)){ input = (InputModule) inputSelector.select(column.mode); } if ( column.isSet ){ if (getLogger().isDebugEnabled()) - getLogger().debug( "Trying to set column " + cname +" using getAttributeValues method"); - values = input.getAttributeValues( cname, column.modeConf, request ); + getLogger().debug( "Trying to set column " + cname +" from "+column.mode+" using getAttributeValues method"); + values = input.getAttributeValues( cname, column.modeConf, objectModel ); } else { if (getLogger().isDebugEnabled()) - getLogger().debug( "Trying to set column " + cname +" using getAttribute method"); + getLogger().debug( "Trying to set column " + cname +" from "+column.mode+" using getAttribute method"); values = new Object[1]; - values[0] = input.getAttribute( cname, column.modeConf, request ); + values[0] = input.getAttribute( cname, column.modeConf, objectModel ); } if ( values != null ) { @@ -714,12 +507,12 @@ } finally { if (inputSelector != null) { - if (input != null) + if (input != null) inputSelector.release(input); this.manager.release(inputSelector); } } - + return values; } } @@ -728,8 +521,8 @@ /** * Setup parsed attribute configuration object */ - protected void fillModes ( Configuration[] conf, boolean isKey, HashMap defaultModeNames, - HashMap modeTypes, CacheHelper set ) + protected void fillModes ( Configuration[] conf, boolean isKey, Map defaultModeNames, + Map modeTypes, CacheHelper set ) throws ConfigurationException { String setMode = null; @@ -773,98 +566,268 @@ } } + /** + * create a unique name using the getOutputName method and write + * the value to the output module and the results map if present. + * + */ + protected void setOutput( Map objectModel, String outputMode, Map results, + Configuration table, Configuration column, int rowIndex, Object value ) { + String param = this.getOutputName( table, column, rowIndex ); + if (getLogger().isDebugEnabled()) + getLogger().debug( "Setting column " + param + " to " + value ); + this.setOutputAttribute(objectModel, outputMode, param, value); + if (results != null) + results.put( param, String.valueOf( value ) ); + } /** - * Put key values into request attributes. + * set a column in a statement using the appropriate JDBC setXXX method. + * */ - protected void storeKeyValue( Configuration tableConf, Column key, int rowIndex, Connection conn, - Statement statement, Request request, Map results ) - throws SQLException, ConfigurationException, ComponentException { - - ComponentSelector autoincrSelector = null; - AutoIncrementModule autoincr = null; - try { - autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR); - if (key.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(key.mode)){ - autoincr = (AutoIncrementModule) autoincrSelector.select(key.mode); - } - - if (!autoincr.includeAsValue()) { - String keyname = getOutputName( tableConf, key.columnConf, rowIndex ); - Object value = autoincr.getPostValue( tableConf, key.columnConf, key.modeConf, conn, statement, request ); - if (getLogger().isDebugEnabled()) - getLogger().debug( "Retrieving autoincrement for " + keyname + "as " + value ); - setRequestAttribute( request, keyname, value ); - results.put( keyname, String.valueOf( value ) ); - } + protected void setColumn ( PreparedStatement statement, int position, Configuration entry, Object value ) throws Exception { - } finally { - if (autoincrSelector != null) { - if (autoincr != null) - autoincrSelector.release(autoincr); - this.manager.release(autoincrSelector); - } - } - + JDBCTypeConversions.setColumn(statement, position, value, (Integer) JDBCTypeConversions.typeConstants.get(entry.getAttribute("type"))); } /** - * Sets the key value on the prepared statement for an autoincrement type. + * set a column in a statement using the appropriate JDBC setXXX + * method and propagate the value to the output module and results + * map if present. Effectively combines calls to setColumn and + * setOutput. * - * @param table the table's configuration object - * @param column the key's configuration object - * @param currentIndex the position of the key column - * @param rowIndex the position in the current row set - * @param conn the database connection - * @param statement the insert statement - * @param request the request object - * @param result sitemap result object - * @return the number of columns by which to increment the currentIndex - */ - protected int setKeyAuto ( Configuration table, Column column, int currentIndex, int rowIndex, - Connection conn, PreparedStatement statement, Request request, Map results ) - throws ConfigurationException, SQLException, ComponentException, Exception { - - int columnCount = 0; - - - ComponentSelector autoincrSelector = null; - AutoIncrementModule autoincr = null; + */ + protected void setColumn ( Map objectModel, String outputMode, Map results, + Configuration table, Configuration column, int rowIndex, + Object value, PreparedStatement statement, int position ) throws Exception { + + if (results!=null) this.setOutput( objectModel, outputMode, results, table, column, rowIndex, value ); + this.setColumn( statement, position, column, value ); + } + + + // ======================================================================== + // main method + // ======================================================================== + + + /** + * Add a record to the database. This action assumes that + * the file referenced by the "descriptor" parameter conforms + * to the AbstractDatabaseAction specifications. + */ + public Map act( Redirector redirector, SourceResolver resolver, Map objectModel, + String source, Parameters param ) throws Exception { + + DataSourceComponent datasource = null; + Connection conn = null; + Map results = new HashMap(); + int rows = 0; + + // read global parameter settings + boolean reloadable = Constants.DESCRIPTOR_RELOADABLE_DEFAULT; + + // call specific default modes apart from output mode are not supported + // set request attribute + String outputMode = param.getParameter("output", (String) defaultModeNames.get(MODE_OUTPUT)); + + if (this.settings.containsKey("reloadable")) + reloadable = Boolean.getBoolean((String) this.settings.get("reloadable")); + + // read local parameter settings try { - autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR); - if (column.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(column.mode)){ - autoincr = (AutoIncrementModule) autoincrSelector.select(column.mode); + Configuration conf = + this.getConfiguration(param.getParameter("descriptor", (String) this.settings.get("descriptor")), + resolver, + param.getParameterAsBoolean("reloadable",reloadable)); + + // get database connection and try to turn off autocommit + datasource = this.getDataSource(conf, param); + conn = datasource.getConnection(); + if (conn.getAutoCommit() == true) { + try { + conn.setAutoCommit(false); + } catch (Exception ex) { + String tmp = param.getParameter("use-transactions",(String) this.settings.get("use-transactions",null)); + if (tmp != null && (tmp.equalsIgnoreCase("no") || tmp.equalsIgnoreCase("false") || tmp.equalsIgnoreCase("0"))) { + if (getLogger().isErrorEnabled()) + getLogger().error("This DB connection does not support transactions. If you want to risk your data's integrity by continuing nonetheless set parameter \"use-transactions\" to \"no\"."); + throw ex; + } + } } - if ( autoincr.includeInQuery() ) { - if ( autoincr.includeAsValue() ) { - Object value = autoincr.getPreValue( table, column.columnConf, column.modeConf, conn, request ); - String keyname = this.getOutputName( table, column.columnConf, rowIndex ); - if (getLogger().isDebugEnabled()) - getLogger().debug( "Setting key " + keyname + " to " + value ); - statement.setObject( currentIndex, value ); - setRequestAttribute( request, keyname, value ); - results.put( keyname, String.valueOf( value ) ); - columnCount = 1; + // find tables to work with + Configuration[] tables = conf.getChildren("table"); + String tablesetname = param.getParameter("table-set", (String) this.settings.get("table-set")); + Map set_tables = null; // default to old behaviour + + Map modeTypes = null; + + if (tablesetname == null) { + modeTypes = new HashMap(6); + modeTypes.put( MODE_AUTOINCR, "autoincr" ); + modeTypes.put( MODE_OTHERS, "others" ); + modeTypes.put( MODE_OUTPUT, outputMode ); + for (int i=0; i<tables.length; i++) { + rows += processTable( tables[i], conn, objectModel, results, modeTypes ); } } else { - if (getLogger().isDebugEnabled()) - getLogger().debug( "Automatically setting key" ); + // new set based behaviour + + // create index for table names / aliases + Map tableIndex = new HashMap(2*tables.length); + String tableName = null; + Object result = null; + for (int i=0; i<tables.length; i++) { + tableName = tables[i].getAttribute("alias",tables[i].getAttribute("name","")); + result = tableIndex.put(tableName,new Integer(i)); + if (result != null) { + throw new IOException("Duplicate table entry for "+tableName+" at positions "+result+" and "+i); + } + } + + Configuration[] tablesets = conf.getChildren("table-set"); + String setname = null; + boolean found = false; + + // find tables contained in tableset + int j = 0; + for (j=0; j<tablesets.length; j++) { + setname = tablesets[j].getAttribute ("name", ""); + if (tablesetname.trim().equals (setname.trim ())) { + found = true; + break; + } + } + if (!found) { + throw new IOException(" given set " + tablesetname + " does not exists in a description file."); + } + + Configuration[] set = tablesets[j].getChildren("table"); + + for (int i=0; i<set.length; i++) { + // look for alternative mode types + modeTypes = new HashMap(6); + modeTypes.put( MODE_AUTOINCR, set[i].getAttribute( "autoincr-mode", "autoincr" ) ); + modeTypes.put( MODE_OTHERS, set[i].getAttribute( "others-mode", "others" ) ); + modeTypes.put( MODE_OUTPUT, outputMode ); + tableName=set[i].getAttribute("name",""); + if (tableIndex.containsKey(tableName)) { + j = ((Integer)tableIndex.get(tableName)).intValue(); + rows += processTable( tables[j], conn, objectModel, results, modeTypes ); + } else { + throw new IOException(" given table " + tableName + " does not exists in a description file."); + } + } + } + + if (conn.getAutoCommit()==false) + conn.commit(); + + // obtain output mode module and rollback output + ComponentSelector outputSelector = null; + OutputModule output = null; + try { + outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); + if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){ + output = (OutputModule) outputSelector.select(outputMode); + } + output.commit( null, objectModel ); + } catch (Exception e) { + if (getLogger().isWarnEnabled()) + getLogger() + .warn( "Could not select output mode " + + (String) outputMode + + ":" + e.getMessage() ); + } finally { + if (outputSelector != null) { + if (output != null) + outputSelector.release(output); + this.manager.release(outputSelector); + } + } + + } catch (Exception e) { + if ( conn != null ) { + try { + if (getLogger().isDebugEnabled()) { + getLogger().debug( "Rolling back transaction. Caused by " + e.getMessage() ); + } + conn.rollback(); + results = null; + + // obtain output mode module and commit output + ComponentSelector outputSelector = null; + OutputModule output = null; + try { + outputSelector=(ComponentSelector) this.manager.lookup(OUTPUT_MODULE_SELECTOR); + if (outputMode != null && outputSelector != null && outputSelector.hasComponent(outputMode)){ + output = (OutputModule) outputSelector.select(outputMode); + } + output.rollback( null, objectModel, e); + } catch (Exception e2) { + if (getLogger().isWarnEnabled()) + getLogger() + .warn( "Could not select output mode " + + (String) outputMode + + ":" + e2.getMessage() ); + } finally { + if (outputSelector != null) { + if (output != null) + outputSelector.release(output); + this.manager.release(outputSelector); + } + } + + } catch (SQLException se) { + if (getLogger().isDebugEnabled()) + getLogger().debug("There was an error rolling back the transaction", se); + } } + //throw new ProcessingException("Could not add record :position = " + currentIndex, e); + + // don't throw an exception, an error has been signalled, that should suffice + + String throwException = (String) this.settings.get( "throw-exception", + param.getParameter( "throw-exception", null ) ); + if ( throwException != null && + ( throwException.equalsIgnoreCase( "true" ) || throwException.equalsIgnoreCase( "yes" ) ) ) { + throw new ProcessingException("Could not add record",e); + } } finally { - if (autoincrSelector != null) { - if (autoincr != null) - autoincrSelector.release(autoincr); - this.manager.release(autoincrSelector); + if (conn != null) { + try { + conn.close(); + } catch (SQLException sqe) { + getLogger().warn("There was an error closing the datasource", sqe); + } } - } - return columnCount; + if (datasource != null) + this.dbselector.release(datasource); + } + if (results != null) { + if (rows>0) { + results.put("row-count",new Integer(rows)); + } else { + results = null; + } + } else { + if (rows>0) { + results = new HashMap(1); + results.put("row-count",new Integer(rows)); + } + } + + return (results == null? results : Collections.unmodifiableMap(results)); } + + // ======================================================================== // abstract methods // ======================================================================== @@ -877,7 +840,7 @@ * This method is intended to be overridden by classes that * implement other operations e.g. delete */ - protected abstract int processRow( Request request, Connection conn, PreparedStatement statement, + protected abstract int processRow( Map objectModel, Connection conn, PreparedStatement statement, String outputMode, Configuration table, CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results ) throws SQLException, ConfigurationException, Exception; @@ -888,7 +851,7 @@ * This method is intended to be overridden by classes that * implement other operations e.g. delete */ - protected abstract String selectMode( boolean isAutoIncrement, HashMap modes ); + protected abstract String selectMode( boolean isAutoIncrement, Map modes ); /** @@ -908,7 +871,7 @@ * This method is intended to be overridden by classes that * implement other operations e.g. delete */ - abstract Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request ) + abstract Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel ) throws ConfigurationException, ComponentException; /** @@ -922,7 +885,7 @@ * @param table the table's configuration object * @return the insert query as a string */ - protected abstract CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames ) + protected abstract CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames ) throws ConfigurationException, ComponentException; } 1.1.2.2 +15 -22 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseUpdateAction.java Index: DatabaseUpdateAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseUpdateAction.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DatabaseUpdateAction.java 28 Apr 2002 19:59:52 -0000 1.1.2.1 +++ DatabaseUpdateAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.2 @@ -61,13 +61,9 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.cocoon.environment.Request; - /** * Updates a record in a database. The action can update one or more - * tables, and can update more than one row to a table at a time. The - * form descriptor semantics for this are still in a bit of a state of - * flux. + * tables, and can update more than one row to a table at a time. * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ @@ -79,7 +75,7 @@ * here: UPDATE * highly specific to operation INSERT / UPDATE / DELETE / SELECT */ - protected String selectMode ( boolean isAutoIncrement, HashMap modes ) { + protected String selectMode ( boolean isAutoIncrement, Map modes ) { return (String) modes.get( MODE_OTHERS ); } @@ -96,12 +92,12 @@ * Fetch all values for all columns that are needed to do the * database operation. */ - protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request ) + protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel ) throws ConfigurationException, ComponentException { Object[][] columnValues = new Object[ queryData.columns.length ][]; for ( int i = 0; i < queryData.columns.length; i++ ){ - columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request ); + columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel ); } return columnValues; } @@ -115,7 +111,7 @@ * @param table the table's configuration object * @return the insert query as a string */ - protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames ) + protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames ) throws ConfigurationException, ComponentException { LookUpKey lookUpKey = new LookUpKey( table, modeTypes ); @@ -171,8 +167,9 @@ /** * set all necessary ?s and execute the query */ - protected int processRow ( Request request, Connection conn, PreparedStatement statement, Configuration table, - CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results ) + protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode, + Configuration table, CacheHelper queryData, Object[][] columnValues, + int rowIndex, Map results ) throws SQLException, ConfigurationException, Exception { @@ -182,25 +179,21 @@ for (int i = 0; i < queryData.columns.length; i++) { Column col = queryData.columns[i]; if ( !col.isKey ) { - this.setColumn( statement, currentIndex, request, col.columnConf, - getOutputName( table, col.columnConf, rowIndex ), - columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], - rowIndex); + this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex ); currentIndex++; } } for (int i = 0; i < queryData.columns.length; i++) { Column col = queryData.columns[i]; if ( col.isKey ) { - this.setColumn( statement, currentIndex, request, col.columnConf, - getOutputName( table, col.columnConf, rowIndex ), - columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], - rowIndex); + this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex ); currentIndex++; } } - int rowCount = statement.executeUpdate(); - return rowCount; + int rowCount = statement.executeUpdate(); + return rowCount; } } 1.1.2.2 +15 -103 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseSelectAction.java Index: DatabaseSelectAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseSelectAction.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DatabaseSelectAction.java 28 Apr 2002 19:59:52 -0000 1.1.2.1 +++ DatabaseSelectAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.2 @@ -69,15 +69,12 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.cocoon.environment.Request; - -import org.apache.cocoon.acting.AbstractDatabaseAction; +import org.apache.cocoon.util.JDBCTypeConversions; /** * Selects a record from a database. The action can select one or more * tables, and can select from more than one row of a table at a - * time. The form descriptor semantics for this are still in a bit of - * a state of flux. + * time. * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ @@ -89,7 +86,7 @@ * here: SELECT * highly specific to operation INSERT / UPDATE / DELETE / SELECT */ - protected String selectMode ( boolean isAutoIncrement, HashMap modes ) { + protected String selectMode ( boolean isAutoIncrement, Map modes ) { return (String) modes.get( MODE_OTHERS ); } @@ -110,7 +107,7 @@ * @param table the table's configuration object * @return the insert query as a string */ - protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames ) + protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames ) throws ConfigurationException, ComponentException { LookUpKey lookUpKey = new LookUpKey( table, modeTypes ); @@ -168,13 +165,13 @@ * Fetch all values for all key columns that are needed to do the * database operation. */ - protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request ) + protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel ) throws ConfigurationException, ComponentException { Object[][] columnValues = new Object[ queryData.columns.length ][]; for ( int i = 0; i < queryData.columns.length; i++ ){ if ( queryData.columns[i].isKey ) { - columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request ); + columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel ); } else { // columnValues[i] = new Object[1]; // this should not be needed } @@ -186,8 +183,9 @@ /** * set all necessary ?s and execute the query */ - protected int processRow ( Request request, Connection conn, PreparedStatement statement, Configuration table, - CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results ) + protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode, + Configuration table, CacheHelper queryData, Object[][] columnValues, + int rowIndex, Map results ) throws SQLException, ConfigurationException, Exception { int currentIndex = 1; @@ -196,10 +194,8 @@ for (int i = 0; i < queryData.columns.length; i++) { Column col = queryData.columns[i]; if ( col.isKey ) { - this.setColumn( statement, currentIndex, request, col.columnConf, - getOutputName( table, col.columnConf, rowIndex ), - columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], - rowIndex); + this.setColumn(objectModel, outputMode, null, table, col.columnConf, rowIndex, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], statement, currentIndex ); currentIndex++; } } @@ -208,99 +204,15 @@ ResultSet resultset = statement.getResultSet(); rowIndex = 0; while ( resultset.next() ){ - //if ( ! ( rowIndex == -1 && resultset.isLast() ) ) { - rowIndex++; - //} for (int i = 0; i < queryData.columns.length; i++) { if ( !queryData.columns[i].isKey ) { - Object value = this.getColumn( resultset, queryData.columns[i].columnConf ); - String param = getOutputName( table, queryData.columns[i].columnConf, rowIndex ); - this.setRequestAttribute( request, param, value ); - results.put(param,value); + Object value = JDBCTypeConversions.getColumn( resultset, queryData.columns[i].columnConf ); + this.setOutput(objectModel, outputMode, results, table, queryData.columns[i].columnConf, rowIndex, value); } } + rowIndex++; } return rowIndex; - } - - - /** - * Get the Statement column so that the results are mapped correctly. - * (this has been copied from AbstractDatabaseAction and modified slightly) - */ - protected Object getColumn(ResultSet set, Configuration column ) throws Exception { - - Integer type = (Integer) AbstractDatabaseAction.typeConstants.get(column.getAttribute("type")); - String dbcol = column.getAttribute("name"); - Object value = null; - - switch (type.intValue()) { - case Types.CLOB: - Clob dbClob = set.getClob(dbcol); - int length = (int) dbClob.length(); - InputStream asciiStream = new BufferedInputStream(dbClob.getAsciiStream()); - byte[] buffer = new byte[length]; - asciiStream.read(buffer); - String str = new String(buffer); - asciiStream.close(); - value = str; - break; - case Types.BIGINT: - value = set.getBigDecimal(dbcol); - break; - case Types.TINYINT: - value = new Byte(set.getByte(dbcol)); - break; - case Types.VARCHAR: - value = set.getString(dbcol); - break; - case Types.DATE: - value = set.getDate(dbcol); - break; - case Types.DOUBLE: - value = new Double(set.getDouble(dbcol)); - break; - case Types.FLOAT: - value = new Float(set.getFloat(dbcol)); - break; - case Types.INTEGER: - value = new Integer(set.getInt(dbcol)); - break; - case Types.NUMERIC: - value = new Long(set.getLong(dbcol)); - break; - case Types.SMALLINT: - value = new Short(set.getShort(dbcol)); - break; - case Types.TIME: - value = set.getTime(dbcol); - break; - case Types.TIMESTAMP: - value = set.getTimestamp(dbcol); - break; - case Types.ARRAY: - value = set.getArray(dbcol); // new Integer(set.getInt(dbcol)); - break; - case Types.BIT: - value = new Integer(set.getInt(dbcol)); - break; - case Types.CHAR: - value = new Integer(set.getInt(dbcol)); - break; - case Types.STRUCT: - value = (Struct) set.getObject(dbcol); - break; - case Types.OTHER: - value = set.getObject(dbcol); - break; - - default: - // The blob types have to be requested separately, via a Reader. - value = ""; - break; - } - - return value; } 1.1.2.2 +10 -15 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseDeleteAction.java Index: DatabaseDeleteAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseDeleteAction.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DatabaseDeleteAction.java 28 Apr 2002 19:59:52 -0000 1.1.2.1 +++ DatabaseDeleteAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.2 @@ -61,13 +61,9 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.cocoon.environment.Request; - /** * Updates a record in a database. The action can update one or more - * tables, and can update more than one row to a table at a time. The - * form descriptor semantics for this are still in a bit of a state of - * flux. + * tables, and can update more than one row to a table at a time. * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ @@ -79,7 +75,7 @@ * here: DELETE * highly specific to operation INSERT / UPDATE / DELETE / SELECT */ - protected String selectMode ( boolean isAutoIncrement, HashMap modes ) { + protected String selectMode ( boolean isAutoIncrement, Map modes ) { return (String) modes.get( MODE_OTHERS ); } @@ -96,13 +92,13 @@ * Fetch all values for all key columns that are needed to do the * database operation. */ - protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Request request ) + protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, Map objectModel ) throws ConfigurationException, ComponentException { Object[][] columnValues = new Object[ queryData.columns.length ][]; for ( int i = 0; i < queryData.columns.length; i++ ){ if ( queryData.columns[i].isKey ) { - columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request ); + columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel ); } else { // columnValues[i] = new Object[1]; // this should not be needed } @@ -120,7 +116,7 @@ * @param table the table's configuration object * @return the insert query as a string */ - protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames ) + protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames ) throws ConfigurationException, ComponentException { LookUpKey lookUpKey = new LookUpKey( table, modeTypes ); @@ -158,7 +154,7 @@ /** * set all necessary ?s and execute the query */ - protected int processRow ( Request request, Connection conn, PreparedStatement statement, + protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode, Configuration table, CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results ) throws SQLException, ConfigurationException, Exception { @@ -169,10 +165,9 @@ for (int i = 0; i < queryData.columns.length; i++) { Column col = queryData.columns[i]; if ( col.isKey ) { - this.setColumn( statement, currentIndex, request, col.columnConf, - getOutputName( table, col.columnConf, rowIndex ), - columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], - rowIndex); + this.setColumn( objectModel, outputMode, results, table, col.columnConf, rowIndex, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], + statement, currentIndex ); currentIndex++; } } 1.1.2.2 +98 -15 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseAddAction.java Index: DatabaseAddAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseAddAction.java,v retrieving revision 1.1.2.1 retrieving revision 1.1.2.2 diff -u -r1.1.2.1 -r1.1.2.2 --- DatabaseAddAction.java 28 Apr 2002 19:59:52 -0000 1.1.2.1 +++ DatabaseAddAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.2 @@ -53,6 +53,7 @@ import java.util.Map; import java.sql.Connection; +import java.sql.Statement; import java.sql.PreparedStatement; import java.sql.SQLException; import org.apache.cocoon.util.HashMap; @@ -62,14 +63,12 @@ import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.cocoon.environment.Request; - import org.apache.cocoon.components.modules.database.AutoIncrementModule; /** * Adds record in a database. The action can update one or more * tables, and can add more than one row to a table at a time. See - * {@see DatabaseAction} for details. + * {@link DatabaseAction} for details. * * @author <a href="mailto:[EMAIL PROTECTED]">Christian Haul</a> * @version CVS $Id$ @@ -80,7 +79,7 @@ /** * set all necessary ?s and execute the query */ - protected int processRow ( Request request, Connection conn, PreparedStatement statement, + protected int processRow ( Map objectModel, Connection conn, PreparedStatement statement, String outputMode, Configuration table, CacheHelper queryData, Object[][] columnValues, int rowIndex, Map results ) throws SQLException, ConfigurationException, Exception { @@ -90,12 +89,12 @@ Column col = queryData.columns[i]; if ( col.isAutoIncrement && col.isKey ) { currentIndex += setKeyAuto( table, col, currentIndex, rowIndex, - conn, statement, request, results ); + conn, statement, objectModel, outputMode, results ); } else { - this.setColumn( statement, currentIndex, request, col.columnConf, - getOutputName( table, col.columnConf, rowIndex ), - columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ], - rowIndex); + this.setOutput( objectModel, outputMode, results, table, col.columnConf, rowIndex, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]); + this.setColumn( statement, currentIndex, col.columnConf, + columnValues[ i ][ ( col.isSet ? rowIndex : 0 ) ]); currentIndex++; } } @@ -104,7 +103,7 @@ for (int i = 0; i < queryData.columns.length; i++) { if ( queryData.columns[i].isAutoIncrement && queryData.columns[i].isKey ) { storeKeyValue( table, queryData.columns[i], rowIndex, - conn, statement, request, results ); + conn, statement, objectModel, outputMode, results ); } } return rowCount; @@ -112,11 +111,95 @@ /** + * Sets the key value on the prepared statement for an autoincrement type. + * + * @param table the table's configuration object + * @param column the key's configuration object + * @param currentIndex the position of the key column + * @param rowIndex the position in the current row set + * @param conn the database connection + * @param statement the insert statement + * @param objectModel the objectModel object + * @param outputMode name of the requested output module + * @param result sitemap result object + * @return the number of columns by which to increment the currentIndex + */ + protected int setKeyAuto ( Configuration table, Column column, int currentIndex, int rowIndex, + Connection conn, PreparedStatement statement, Map objectModel, String outputMode, Map results ) + throws ConfigurationException, SQLException, ComponentException, Exception { + + int columnCount = 0; + ComponentSelector autoincrSelector = null; + AutoIncrementModule autoincr = null; + try { + autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR); + if (column.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(column.mode)){ + autoincr = (AutoIncrementModule) autoincrSelector.select(column.mode); + } + + if ( autoincr.includeInQuery() ) { + if ( autoincr.includeAsValue() ) { + Object value = autoincr.getPreValue( table, column.columnConf, column.modeConf, conn, objectModel ); + this.setColumn(objectModel, outputMode, results, table, column.columnConf, rowIndex, value, statement, currentIndex); + columnCount = 1; + } + } else { + if (getLogger().isDebugEnabled()) + getLogger().debug( "Automatically setting key" ); + } + + } finally { + if (autoincrSelector != null) { + if (autoincr != null) + autoincrSelector.release(autoincr); + this.manager.release(autoincrSelector); + } + } + + return columnCount; + } + + + + /** + * Put key values into request attributes. Checks whether the + * value needs to be retrieved from the database module first. + * + */ + protected void storeKeyValue( Configuration tableConf, Column key, int rowIndex, Connection conn, + Statement statement, Map objectModel, String outputMode, Map results ) + throws SQLException, ConfigurationException, ComponentException { + + ComponentSelector autoincrSelector = null; + AutoIncrementModule autoincr = null; + try { + autoincrSelector=(ComponentSelector) this.manager.lookup(DATABASE_MODULE_SELECTOR); + if (key.mode != null && autoincrSelector != null && autoincrSelector.hasComponent(key.mode)){ + autoincr = (AutoIncrementModule) autoincrSelector.select(key.mode); + } + + if (!autoincr.includeAsValue()) { + Object value = autoincr.getPostValue( tableConf, key.columnConf, key.modeConf, conn, statement, objectModel ); + this.setOutput(objectModel, outputMode, results, tableConf, key.columnConf, rowIndex, value); + } + + } finally { + if (autoincrSelector != null) { + if (autoincr != null) + autoincrSelector.release(autoincr); + this.manager.release(autoincrSelector); + } + } + + } + + + /** * determine which mode to use as default mode * here: INSERT * highly specific to operation INSERT / UPDATE / DELETE / SELECT */ - protected String selectMode ( boolean isAutoIncrement, HashMap modes ) { + protected String selectMode ( boolean isAutoIncrement, Map modes ) { if ( isAutoIncrement ) return (String) modes.get( MODE_AUTOINCR ); @@ -137,12 +220,12 @@ * database operation. */ protected Object[][] getColumnValues( Configuration tableConf, CacheHelper queryData, - Request request ) + Map objectModel ) throws ConfigurationException, ComponentException { Object[][] columnValues = new Object[ queryData.columns.length ][]; for ( int i = 0; i < queryData.columns.length; i++ ){ - columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], request ); + columnValues[i] = this.getColumnValue( tableConf, queryData.columns[i], objectModel ); } return columnValues; } @@ -155,7 +238,7 @@ * @param table the table's configuration object * @return the insert query as a string */ - protected CacheHelper getQuery( Configuration table, HashMap modeTypes, HashMap defaultModeNames ) + protected CacheHelper getQuery( Configuration table, Map modeTypes, Map defaultModeNames ) throws ConfigurationException, ComponentException { LookUpKey lookUpKey = new LookUpKey( table, modeTypes ); 1.1.2.3 +19 -19 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/TestAction.java Index: TestAction.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/TestAction.java,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -r1.1.2.2 -r1.1.2.3 --- TestAction.java 11 Jun 2002 23:54:53 -0000 1.1.2.2 +++ TestAction.java 11 Aug 2002 17:47:55 -0000 1.1.2.3 @@ -51,23 +51,28 @@ package org.apache.cocoon.acting.modular; -import org.apache.avalon.framework.component.ComponentSelector; +import org.apache.avalon.framework.activity.Initializable; import org.apache.avalon.framework.configuration.Configurable; import org.apache.avalon.framework.configuration.Configuration; import org.apache.avalon.framework.configuration.ConfigurationException; +import org.apache.avalon.framework.parameters.ParameterException; import org.apache.avalon.framework.parameters.Parameters; import org.apache.avalon.framework.thread.ThreadSafe; +import org.apache.avalon.framework.component.ComponentSelector; +import org.apache.cocoon.Constants; import org.apache.cocoon.acting.ComposerAction; -import org.apache.cocoon.components.modules.input.InputModule; -import org.apache.cocoon.components.modules.output.OutputModule; -import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Redirector; import org.apache.cocoon.environment.Request; +import org.apache.cocoon.environment.Session; import org.apache.cocoon.environment.SourceResolver; +import org.apache.cocoon.components.modules.input.InputModule; +import org.apache.cocoon.components.modules.output.OutputModule; + import java.util.Enumeration; import java.util.Map; +import java.util.HashMap; /** Demo action that uses componentized input / output layer. In order * to stop combinatorial explosion of actions, matchers, and selectors @@ -103,9 +108,9 @@ public void configure(Configuration config) throws ConfigurationException { this.inputConf = config.getChild("input-module"); - this.inputName = this.inputConf.getAttribute("name"); + this.inputName = this.inputConf.getAttribute("name", this.inputHint); this.outputConf = config.getChild("output-module"); - this.outputName = this.outputConf.getAttribute("name"); + this.outputName = this.outputConf.getAttribute("name", this.outputHint); this.defaultParameterName = config.getChild("parameter-name").getValue(null); this.useGetValues = config.getChild("use-getValues").getValueAsBoolean(this.useGetValues); } @@ -116,11 +121,6 @@ String source, Parameters param ) throws Exception { // general setup - Request request = ObjectModelHelper.getRequest(objectModel); - if (request == null) { - getLogger().error("no request object!"); - return(null); - } String parameterName = param.getParameter("parameter-name",this.defaultParameterName); boolean useGetValues = param.getParameterAsBoolean("use-getValues",this.useGetValues); InputModule input = null; @@ -149,11 +149,11 @@ if (getLogger().isDebugEnabled()) getLogger().debug("reading all parameter values"); // for a test, read all parameters from input and write them to outout // get names first, then (one) value per name - Enumeration enum = input.getAttributeNames(this.inputConf,request); + Enumeration enum = input.getAttributeNames(this.inputConf,objectModel); while (enum.hasMoreElements()) { parameterName = (String) enum.nextElement(); - Object value = input.getAttribute(parameterName, this.inputConf, request); - output.setAttribute(this.outputConf, request, parameterName, value); + Object value = input.getAttribute(parameterName, this.inputConf, objectModel); + output.setAttribute(this.outputConf, objectModel, parameterName, value); if (getLogger().isDebugEnabled()) getLogger().debug("["+parameterName+"] = ["+value+"]"); @@ -163,8 +163,8 @@ if (useGetValues) { // get all existing values - Object[] value = input.getAttributeValues(parameterName, this.inputConf, request); - output.setAttribute(this.outputConf, request, parameterName, value); + Object[] value = input.getAttributeValues(parameterName, this.inputConf, objectModel); + output.setAttribute(this.outputConf, objectModel, parameterName, value); if (getLogger().isDebugEnabled()) for (int i=0; i<value.length; i++) @@ -176,14 +176,14 @@ if (getLogger().isDebugEnabled()) getLogger().debug("reading parameter values for "+parameterName); - Object value = input.getAttribute(parameterName, this.inputConf, request); - output.setAttribute(this.outputConf, request, parameterName, value); + Object value = input.getAttribute(parameterName, this.inputConf, objectModel); + output.setAttribute(this.outputConf, objectModel, parameterName, value); if (getLogger().isDebugEnabled()) getLogger().debug("["+parameterName+"] = ["+value+"]"); // ------------------------------------------------------------------------ } } - output.commit(this.outputConf,request); + output.commit(this.outputConf,objectModel); if (getLogger().isDebugEnabled()) getLogger().debug("done commit"); // done } No revision No revision 1.1.2.1 +235 -0 xml-cocoon2/src/scratchpad/src/org/apache/cocoon/acting/modular/Attic/DatabaseQueryAction.java
---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]