hammant     01/11/18 06:18:02

  Modified:    apps/db/src/java/org/apache/avalon/db/basic/actions
                        BasicCreateIndex.java BasicCreateQueryable.java
                        BasicCreateTable.java BasicCreateView.java
                        BasicInsertRows.java
               apps/db/src/java/org/apache/avalon/db/basic/data
                        BasicRow.java BasicView.java
               apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql
                        BasicLXSQLCreateIndexHandler.java
                        BasicLXSQLCreateTableHandler.java
                        BasicLXSQLCreateViewHandler.java
                        BasicLXSQLInsertRowsHandler.java
               apps/db/src/java/org/apache/avalon/db/data RowListener.java
               apps/db/src/java/org/apache/avalon/db/data/impl
                        AbstractQueryable.java AbstractTableRow.java
               apps/db/src/java/org/apache/avalon/db/persistence/store
                        StorePersistence.java
               apps/db/src/java/org/apache/avalon/db/test Tester.java
  Added:       apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql
                        BasicLXSQLQueryableHandler.java
  Log:
  refactor handler logic.  XML moves to handlers from actions.
  
  Revision  Changes    Path
  1.7       +4 -29     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateIndex.java
  
  Index: BasicCreateIndex.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateIndex.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- BasicCreateIndex.java     2001/11/16 06:36:59     1.6
  +++ BasicCreateIndex.java     2001/11/18 14:18:01     1.7
  @@ -12,11 +12,9 @@
   import org.apache.avalon.db.actions.ActionException;
   import org.apache.avalon.db.data.impl.AbstractQueryable;
   import org.apache.avalon.db.data.Index;
  +import org.apache.avalon.db.data.Column;
   import org.apache.avalon.db.basic.data.BasicIndex;
   import org.apache.avalon.db.services.DatabasePersistor;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Node;
   
   import java.util.Vector;
   
  @@ -26,43 +24,22 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.6 $
  + * @version $Revision: 1.7 $
    */
   public class BasicCreateIndex extends BasicCreateQueryable implements 
CreateIndex {
   
       private String mIndexName;
       private String mTableName;
  -    private Document mLxsql;
   
  -    public BasicCreateIndex(String indexName, String tableName, Document 
lxsql) {
  +    public BasicCreateIndex(String indexName, String tableName) { // todo 
pass in keys
  +        super(null); // no columns?
           mIndexName = indexName;
           mTableName = tableName;
  -        mLxsql = lxsql;
  -
       }
   
       public void initialize() throws ActionException {
  -
  -        NodeList subRootNodes = mLxsql.getChildNodes();
  -        for (int i = 0; i < subRootNodes.getLength(); i++) {
  -            if (subRootNodes.item(i).getNodeName().equals("columns")) {
  -                processColumns(subRootNodes.item(i));
  -            }
  -        }
  -
       }
   
  -    private void processColumns(Node columnsNode) throws ActionException {
  -        NodeList subRootNodes = mLxsql.getChildNodes();
  -        Vector cols = new Vector();
  -        for (int i = 0; i < subRootNodes.getLength(); i++) {
  -            Node node = subRootNodes.item(i);
  -            if (node.getNodeName().equals("column")) {
  -                
cols.add(node.getAttributes().getNamedItem("name").getNodeName());
  -            }
  -        }
  -    }
  -
   
       protected void checkNodeType(String nodeName) throws ActionException {
           // TODO never called?
  @@ -78,8 +55,6 @@
       public void execute() throws ActionException {
   
           System.out.println("ci execute");
  -
  -        NodeList subRootNodes = mLxsql.getChildNodes();
   
           AbstractQueryable tableOrView = null; //TODO
   
  
  
  
  1.9       +3 -70     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateQueryable.java
  
  Index: BasicCreateQueryable.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateQueryable.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- BasicCreateQueryable.java 2001/11/14 21:18:43     1.8
  +++ BasicCreateQueryable.java 2001/11/18 14:18:01     1.9
  @@ -25,9 +25,6 @@
   import org.apache.avalon.db.data.impl.DecimalColumn;
   import org.apache.avalon.db.basic.data.BasicTable;
   import org.apache.avalon.db.services.DatabasePersistor;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Node;
   
   import java.util.Vector;
   
  @@ -37,77 +34,13 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.8 $
  + * @version $Revision: 1.9 $
    */
   public abstract class BasicCreateQueryable extends AbstractAction implements 
CreateTable {
   
       protected Column[] mColumns;
   
  -
  -    /**
  -     * Method getColumns
  -     *
  -     *
  -     */
  -    protected Column[] getColumns(Element lxsql) throws ActionException {
  -
  -        NodeList subRootNodes = lxsql.getChildNodes();
  -
  -        Vector columns = new Vector();
  -
  -        for (int f = 0 ; f < subRootNodes.getLength(); f++) {
  -            String nodeName = subRootNodes.item(f).getNodeName();
  -            if (nodeName.equals("columns")) {
  -                NodeList subColumnsNodes = 
subRootNodes.item(f).getChildNodes();
  -                for (int x = 0 ; x < subColumnsNodes.getLength(); x++) {
  -                    if 
(subColumnsNodes.item(x).getNodeName().equals("column")) {
  -                        columns.add(createColumn(subColumnsNodes.item(x), 
x));
  -                    } else {
  -
  -                        throw new ActionException("Only 'column' allowed as 
a node under 'columns' node");
  -                    }
  -                }
  -            } else {
  -
  -            }
  -        }
  -
  -        Column[] columnsAry = new Column[columns.size()];
  -        columns.toArray(columnsAry);
  -
  -        return columnsAry;
  -
  -    }
  -
  -    protected abstract void checkNodeType(String nodeName) throws 
ActionException;
  -
  -    protected Column createColumn(Node columnNode, int ix) throws 
ActionException {
  -        String sqlFieldType = 
columnNode.getAttributes().getNamedItem("type").getNodeValue();
  -        String fieldName = 
columnNode.getAttributes().getNamedItem("name").getNodeValue();
  -        Column column = null;
  -        if (sqlFieldType.equals("varchar")) {
  -            int maxLength = 
Integer.parseInt(columnNode.getAttributes().getNamedItem("max").getNodeValue());
  -            column= new VarCharColumn(fieldName, maxLength);
  -        } else if (sqlFieldType.equals("integer")) {
  -            column= new IntegerColumn(fieldName);
  -        } else if (sqlFieldType.equals("date")) {
  -            column= new DateColumn(fieldName);
  -        } else if (sqlFieldType.equals("time")) {
  -            column= new TimeColumn(fieldName);
  -        } else if (sqlFieldType.equals("timestamp")) {
  -            column= new TimestampColumn(fieldName);
  -        } else if (sqlFieldType.equals("smallint")) {
  -            column= new SmallIntColumn(fieldName);
  -        } else if (sqlFieldType.equals("real")) {
  -            column= new RealColumn(fieldName);
  -        } else if (sqlFieldType.equals("bigint")) {
  -            column= new BigIntColumn(fieldName);
  -        } else if (sqlFieldType.equals("decimal")) {
  -            column= new DecimalColumn(fieldName);
  -        } else {
  -            throw new ActionException("Column type " + sqlFieldType + " not 
recognised");
  -        }
  -        column.setIndex(ix);
  -        return column;
  +    public BasicCreateQueryable(Column[] columns) {
  +        this.mColumns = columns;
       }
   }
  
  
  
  1.11      +2 -9      
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateTable.java
  
  Index: BasicCreateTable.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateTable.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- BasicCreateTable.java     2001/11/14 21:18:43     1.10
  +++ BasicCreateTable.java     2001/11/18 14:18:01     1.11
  @@ -16,9 +16,6 @@
   import org.apache.avalon.db.data.impl.AbstractColumn;
   import org.apache.avalon.db.basic.data.BasicTable;
   import org.apache.avalon.db.services.DatabasePersistor;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Node;
   
   import java.util.Vector;
   
  @@ -35,11 +32,10 @@
       private String mTableName;
   
       private int mRecordCount;
  -    private Element mLxsql;
   
  -    public BasicCreateTable(String tableName, Element lxsql) {
  +    public BasicCreateTable(String tableName, Column[] columns) {
  +        super(columns);
           mTableName = tableName;
  -        mLxsql = lxsql;
       }
   
       public void initialize() throws ActionException {
  @@ -57,9 +53,6 @@
       public void execute() throws ActionException {
   
           System.out.println("ct execute");
  -
  -        NodeList subRootNodes = mLxsql.getChildNodes();
  -        mColumns = getColumns(mLxsql);
   
   
           /*
  
  
  
  1.11      +9 -28     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateView.java
  
  Index: BasicCreateView.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicCreateView.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- BasicCreateView.java      2001/11/14 21:18:43     1.10
  +++ BasicCreateView.java      2001/11/18 14:18:01     1.11
  @@ -17,9 +17,6 @@
   import org.apache.avalon.db.basic.data.BasicTable;
   import org.apache.avalon.db.basic.data.BasicView;
   import org.apache.avalon.db.services.DatabasePersistor;
  -import org.w3c.dom.Document;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Element;
   
   import java.util.Vector;
   
  @@ -29,30 +26,21 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.10 $
  + * @version $Revision: 1.11 $
    */
   public class BasicCreateView extends BasicCreateQueryable implements 
CreateView {
   
  -    private String mViewName;
  -    private BasicSelect mBasicSelect;
  -    private Element mRootElement;
  +    private String mViewName, mOnName;
  +    private SimpleWhereClause mSimpleWhereClause;
   
  -    public BasicCreateView(String viewName, Element rootElement) {
  +    public BasicCreateView(String viewName, String onName, Column[] columns 
,SimpleWhereClause simpleWhereClause) {
  +        super(columns);
           mViewName = viewName;
  -        mRootElement = rootElement;
  +        mOnName = onName;
  +        mSimpleWhereClause = simpleWhereClause;
       }
   
       public void initialize() throws ActionException {
  -        NodeList subRootNodes = mRootElement.getChildNodes();
  -        for (int i = 0; i < subRootNodes.getLength(); i++) {
  -            System.out.println(">>>"+subRootNodes.item(i).getNodeName());
  -            if (subRootNodes.item(i).getNodeName().equals("simple-select")) {
  -                mBasicSelect = new BasicSelect((Element) 
subRootNodes.item(i));
  -            } else if (subRootNodes.item(i).getNodeName().equals("columns")) 
{
  -            }
  -        }
  -        mColumns = getColumns(mRootElement);
  -        mBasicSelect.initialize();
       }
   
       protected void checkNodeType(String nodeName) throws ActionException {
  @@ -70,21 +58,14 @@
   
           System.out.println("cv execute");
   
  -        View view = new BasicView(mViewName, mColumns, mBasicSelect);
  +        View view = new BasicView(mViewName, mColumns, mSimpleWhereClause);
           mDatabasePersistor.addQueryable(mViewName, view);
   
  -        if (mBasicSelect != null) {
  -            mBasicSelect.execute();
  -        }
  -
  -
       }
   
       public void setDatabasePersistor(DatabasePersistor databasePersistor) {
           super.setDatabasePersistor(databasePersistor);
  -        if (mBasicSelect != null) {
  -            mBasicSelect.setDatabasePersistor(databasePersistor);
  -        }
  +
       }
   
       public int getRecordCount() {
  
  
  
  1.3       +6 -58     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicInsertRows.java
  
  Index: BasicInsertRows.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/actions/BasicInsertRows.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicInsertRows.java      2001/11/17 10:12:08     1.2
  +++ BasicInsertRows.java      2001/11/18 14:18:01     1.3
  @@ -17,15 +17,11 @@
   import org.apache.avalon.db.data.ValidationException;
   import org.apache.avalon.db.data.WritableColumn;
   
  -
   import org.apache.avalon.framework.logger.LogEnabled;
   
  -import org.w3c.dom.Document;
  -import org.w3c.dom.Element;
  -import org.w3c.dom.NodeList;
  -import org.w3c.dom.Node;
   
   import java.util.Vector;
  +import java.util.Collection;
   
   
   /**
  @@ -33,13 +29,13 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class BasicInsertRows extends AbstractAction implements 
InsertRows,LogEnabled {
   
  -    private Document mDocument;
       private BasicTable mTable;
       private int mRecordCount;
  +    private Collection mRows;
   
       /**
        * Constructor BasicInsertRows
  @@ -49,9 +45,9 @@
        * @param document
        *
        */
  -    public BasicInsertRows(BasicTable table, Document document) {
  +    public BasicInsertRows(BasicTable table, Collection rows) {
           mTable = table;
  -        mDocument = document;
  +        mRows = rows;
       }
   
       public void initialize() throws ActionException {
  @@ -68,61 +64,13 @@
           System.out.println("insert execute");
   
           System.out.println("mTable=" + mTable);
  -        System.out.println("mDocument=" + mDocument);
  -
  -        Element rootElement = mDocument.getDocumentElement();
   
  -        NodeList subRootNodes = rootElement.getChildNodes();
  +        mTable.addRows(mRows);
   
  -        try {
   
  -            for (int f = 0 ; f < subRootNodes.getLength(); f++) {
  -                if (subRootNodes.item(f).getNodeName().equals("rows")) {
  -                    NodeList subRowsNodes = 
subRootNodes.item(f).getChildNodes();
  -                    processSubRowsNodes(subRowsNodes);
  -               } else {
  -                   throw new ActionException("Only 'rows' allowed as a node 
under root node");
  -                }
  -            }
  -        } catch (ValidationException ve) {
  -            throw new ActionException(ve.getMessage());
  -        }
       }
   
  -    private void processSubRowsNodes(NodeList subRowsNodes) throws 
ValidationException {
  -        Object[] values = new Object[mTable.getColumns().length];
  -        for (int x = 0 ; x < subRowsNodes.getLength(); x++) {
  -            if (subRowsNodes.item(x).getNodeName().equals("row")) {
  -                mRecordCount++;
  -                NodeList subValueNodes = 
subRowsNodes.item(x).getChildNodes();
  -                for (int y = 0 ; y < subValueNodes.getLength(); y++) {
  -                    if (subValueNodes.item(y).getNodeName().equals("value")) 
{
  -                        Element rowNode = (Element)subValueNodes.item(y);
  -                        String colName = rowNode.getAttribute("col");
  -                        String valueStr = 
rowNode.getFirstChild().getNodeValue();
  -                        int ix = mTable.getColumnIndex(colName);
  -                        Column col = mTable.getColumn(colName);
  -                        if (col instanceof WritableColumn) {
  -                            WritableColumn wCol = (WritableColumn) col;
  -                            values[ix] = wCol.convertFromObject(valueStr);
  -                        }
  -                    }
  -                }
  -                Vector pendingRow = new Vector();
  -                for (int q = 0; q < values.length; q ++) {
  -                    if (values[q] == null) {
  -                        pendingRow.add(BasicRow.NOVALUE);
  -                    } else {
  -                        pendingRow.add(values[q]);
  -                    }
  -                }
  -                mTable.addRow(new BasicRow(mTable,pendingRow));
  -            } else {
  -                // TODO
  -            }
  -        }
   
  -    }
   
   
       public int getRecordCount() {
  
  
  
  1.8       +2 -1      
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/data/BasicRow.java
  
  Index: BasicRow.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/data/BasicRow.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- BasicRow.java     2001/11/12 22:14:29     1.7
  +++ BasicRow.java     2001/11/18 14:18:01     1.8
  @@ -23,6 +23,7 @@
       protected Column[] mColumns;
   
       public BasicRow(BasicTable basicTable, Vector row) {
  +        super(basicTable);
           mColumns = basicTable.getColumns();
           mRow = row;
       }
  @@ -33,7 +34,7 @@
                   mRow.setElementAt(value,x);
               }
           }
  -        mAbstractQueryable.notifyRowListenersChanged(new Row[] { this });
  +        mAbstractQueryable.notifyRowListenersChanged(this);
       }
   
       public Object getValue(String columnName) {
  
  
  
  1.3       +5 -4      
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/data/BasicView.java
  
  Index: BasicView.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/data/BasicView.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicView.java    2001/11/09 12:43:48     1.2
  +++ BasicView.java    2001/11/18 14:18:01     1.3
  @@ -10,21 +10,22 @@
   import org.apache.avalon.db.data.impl.AbstractView;
   import org.apache.avalon.db.data.Column;
   import org.apache.avalon.db.basic.actions.BasicSelect;
  +import org.apache.avalon.db.basic.actions.SimpleWhereClause;
   
   /**
    * Class BasicView
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class BasicView extends AbstractView {
   
  -    private BasicSelect mBasicSelect;
  +    private SimpleWhereClause mWhereClause;
   
  -    public BasicView(String name, Column[] columns, BasicSelect basicSelect) 
{
  +    public BasicView(String name, Column[] columns, SimpleWhereClause 
whereClause) {
           super(name, columns);
  -        mBasicSelect = basicSelect;
  +        mWhereClause = whereClause;
       }
   
       public int getColumnIndex(String columnName) {
  
  
  
  1.4       +2 -2      
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateIndexHandler.java
  
  Index: BasicLXSQLCreateIndexHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateIndexHandler.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- BasicLXSQLCreateIndexHandler.java 2001/11/16 06:36:59     1.3
  +++ BasicLXSQLCreateIndexHandler.java 2001/11/18 14:18:02     1.4
  @@ -29,7 +29,7 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.3 $
  + * @version $Revision: 1.4 $
    */
   public class BasicLXSQLCreateIndexHandler extends BasicLXSQLHandler {
   
  @@ -68,7 +68,7 @@
           if (mDatabasePersistor.queryableExists(indexName)) {
               throw new ActionException("Table/View/Index exists already");
           } else {
  -            CreateIndex action = new BasicCreateIndex(indexName, tableName, 
doc);
  +            CreateIndex action = new BasicCreateIndex(indexName, tableName);
   
               mParser.initializeAction(action);
               action.execute();
  
  
  
  1.3       +15 -3     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateTableHandler.java
  
  Index: BasicLXSQLCreateTableHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateTableHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicLXSQLCreateTableHandler.java 2001/11/16 06:14:59     1.2
  +++ BasicLXSQLCreateTableHandler.java 2001/11/18 14:18:02     1.3
  @@ -19,9 +19,11 @@
   import org.apache.avalon.db.transport.UpdateReply;
   import org.apache.avalon.db.actions.ActionException;
   import org.apache.avalon.db.actions.CreateTable;
  +import org.apache.avalon.db.data.Column;
   
   import org.w3c.dom.Document;
   import org.w3c.dom.Element;
  +import org.w3c.dom.NodeList;
   
   
   /**
  @@ -29,9 +31,9 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
  -public class BasicLXSQLCreateTableHandler extends BasicLXSQLHandler {
  +public class BasicLXSQLCreateTableHandler extends BasicLXSQLQueryableHandler 
{
   
       /**
        * Constructor BasicLXSQLCreateTableHandler
  @@ -67,7 +69,17 @@
           if (mDatabasePersistor.queryableExists(tableName)) {
               throw new ActionException("Table/View/Index exists already");
           } else {
  -            CreateTable action = new BasicCreateTable(tableName, 
rootElement);
  +
  +            Column[] columns = null;
  +            NodeList subRootNodes = rootElement.getChildNodes();
  +            for (int i = 0; i < subRootNodes.getLength(); i++) {
  +                System.out.println(">>>"+subRootNodes.item(i).getNodeName());
  +                if (subRootNodes.item(i).getNodeName().equals("columns")) {
  +                    columns = getColumns((Element) subRootNodes.item(i));
  +                }
  +            }
  +            System.out.println(">>>-" + columns[0]);
  +            CreateTable action = new BasicCreateTable(tableName, columns);
   
               mParser.initializeAction(action);
               action.execute();
  
  
  
  1.3       +24 -5     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateViewHandler.java
  
  Index: BasicLXSQLCreateViewHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLCreateViewHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicLXSQLCreateViewHandler.java  2001/11/16 06:14:59     1.2
  +++ BasicLXSQLCreateViewHandler.java  2001/11/18 14:18:02     1.3
  @@ -12,6 +12,8 @@
   
   import org.apache.avalon.db.basic.parser.BasicLXSQLParser;
   import org.apache.avalon.db.basic.actions.BasicCreateView;
  +import org.apache.avalon.db.basic.actions.SimpleWhereClause;
  +import org.apache.avalon.db.basic.actions.BasicSelect;
   import org.apache.avalon.db.services.DatabasePersistor;
   import org.apache.avalon.db.transport.Reply;
   import org.apache.avalon.db.transport.Request;
  @@ -19,9 +21,11 @@
   import org.apache.avalon.db.transport.UpdateReply;
   import org.apache.avalon.db.actions.ActionException;
   import org.apache.avalon.db.actions.CreateView;
  +import org.apache.avalon.db.data.Column;
   
   import org.w3c.dom.Document;
   import org.w3c.dom.Element;
  +import org.w3c.dom.NodeList;
   
   
   /**
  @@ -29,9 +33,9 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
  -public class BasicLXSQLCreateViewHandler extends BasicLXSQLHandler {
  +public class BasicLXSQLCreateViewHandler extends BasicLXSQLQueryableHandler {
   
       /**
        * Constructor BasicLXSQLCreateViewHandler
  @@ -62,12 +66,27 @@
           CreateViewRequest cvr = (CreateViewRequest) request;
           Document doc = mParser.parseLXSQLString(cvr.getSql());
           Element rootElement = doc.getDocumentElement();
  -        String tableName = rootElement.getAttribute("name");
  +        String viewName = rootElement.getAttribute("name");
  +        String onName = rootElement.getAttribute("on");
   
  -        if (mDatabasePersistor.queryableExists(tableName)) {
  +        if (mDatabasePersistor.queryableExists(viewName)) {
               throw new ActionException("Table/View/Index exists already");
           } else {
  -            CreateView action = new BasicCreateView(tableName, rootElement);
  +
  +            Column[] columns = null;
  +            NodeList subRootNodes = rootElement.getChildNodes();
  +            for (int i = 0; i < subRootNodes.getLength(); i++) {
  +                System.out.println(">>>"+subRootNodes.item(i).getNodeName());
  +                if (subRootNodes.item(i).getNodeName().equals("columns")) {
  +                    columns = this.getColumns((Element) 
subRootNodes.item(i));
  +                }
  +            }
  +
  +            SimpleWhereClause swc = new SimpleWhereClause("TODO");
  +            swc.enableLogging(super.getLogger());
  +
  +
  +            CreateView action = new BasicCreateView(viewName, onName, 
columns ,swc);
   
               mParser.initializeAction(action);
               action.execute();
  
  
  
  1.3       +64 -2     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLInsertRowsHandler.java
  
  Index: BasicLXSQLInsertRowsHandler.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLInsertRowsHandler.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- BasicLXSQLInsertRowsHandler.java  2001/11/16 06:14:59     1.2
  +++ BasicLXSQLInsertRowsHandler.java  2001/11/18 14:18:02     1.3
  @@ -12,6 +12,7 @@
   
   import org.apache.avalon.db.basic.parser.BasicLXSQLParser;
   import org.apache.avalon.db.basic.data.BasicTable;
  +import org.apache.avalon.db.basic.data.BasicRow;
   import org.apache.avalon.db.basic.actions.BasicInsertRows;
   import org.apache.avalon.db.services.DatabasePersistor;
   import org.apache.avalon.db.transport.Reply;
  @@ -21,17 +22,24 @@
   import org.apache.avalon.db.actions.ActionException;
   import org.apache.avalon.db.actions.InsertRows;
   import org.apache.avalon.db.data.Queryable;
  +import org.apache.avalon.db.data.ValidationException;
  +import org.apache.avalon.db.data.Column;
  +import org.apache.avalon.db.data.WritableColumn;
   
   import org.w3c.dom.Document;
   import org.w3c.dom.Element;
  +import org.w3c.dom.NodeList;
   
  +import java.util.Vector;
  +import java.util.Collection;
   
  +
   /**
    * Class BasicLXSQLInsertRowsHandler
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.2 $
  + * @version $Revision: 1.3 $
    */
   public class BasicLXSQLInsertRowsHandler extends BasicLXSQLHandler {
   
  @@ -67,12 +75,66 @@
           String queryableStr = rootElement.getAttribute("table-name");
           Queryable queryable = (Queryable) 
mDatabasePersistor.getQueryable(queryableStr);
   
  +        NodeList subRootNodes = rootElement.getChildNodes();
  +
  +        Collection rows = null;
  +        try {
  +            for (int f = 0 ; f < subRootNodes.getLength(); f++) {
  +                if (subRootNodes.item(f).getNodeName().equals("rows")) {
  +                    NodeList subRowsNodes = 
subRootNodes.item(f).getChildNodes();
  +                    rows = processSubRowsNodes((BasicTable) queryable, 
subRowsNodes);
  +               } else {
  +                   throw new ActionException("Only 'rows' allowed as a node 
under root node");
  +                }
  +            }
  +        } catch (ValidationException ve) {
  +            throw new ActionException(ve.getMessage());
  +        }
  +
           //TOTO should be able to work with views and indexes.
  -        InsertRows action = new BasicInsertRows((BasicTable) queryable, doc);
  +        InsertRows action = new BasicInsertRows((BasicTable) queryable, 
rows);
   
           mParser.initializeAction(action);
           action.execute();
   
           return new UpdateReply(action.getRecordCount());
       }
  +
  +    private Vector processSubRowsNodes(BasicTable table, NodeList 
subRowsNodes) throws ValidationException {
  +        Vector rows = new Vector();
  +        Object[] values = new Object[table.getColumns().length];
  +        for (int x = 0 ; x < subRowsNodes.getLength(); x++) {
  +            if (subRowsNodes.item(x).getNodeName().equals("row")) {
  +                NodeList subValueNodes = 
subRowsNodes.item(x).getChildNodes();
  +                for (int y = 0 ; y < subValueNodes.getLength(); y++) {
  +                    if (subValueNodes.item(y).getNodeName().equals("value")) 
{
  +                        Element rowNode = (Element)subValueNodes.item(y);
  +                        String colName = rowNode.getAttribute("col");
  +                        String valueStr = 
rowNode.getFirstChild().getNodeValue();
  +                        int ix = table.getColumnIndex(colName);
  +                        Column col = table.getColumn(colName);
  +                        if (col instanceof WritableColumn) {
  +                            WritableColumn wCol = (WritableColumn) col;
  +                            values[ix] = wCol.convertFromObject(valueStr);
  +                        }
  +                    }
  +                }
  +                Vector pendingRow = new Vector();
  +                for (int q = 0; q < values.length; q ++) {
  +                    if (values[q] == null) {
  +                        pendingRow.add(BasicRow.NOVALUE);
  +                    } else {
  +                        pendingRow.add(values[q]);
  +                    }
  +                }
  +                rows.add(new BasicRow(table,pendingRow));
  +            } else {
  +                // TODO
  +            }
  +        }
  +        return rows;
  +    }
  +
  +
  +
   }
  
  
  
  1.1                  
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/basic/handlers/lxsql/BasicLXSQLQueryableHandler.java
  
  Index: BasicLXSQLQueryableHandler.java
  ===================================================================
  
  /*
   * Copyright (C) The Apache Software Foundation. All rights reserved.
   *
   * This software is published under the terms of the Apache Software License
   * version 1.1, a copy of which has been included with this distribution in
   * the LICENSE file.
   */
  package org.apache.avalon.db.basic.handlers.lxsql;
  
  import org.apache.avalon.db.basic.parser.BasicLXSQLParser;
  import org.apache.avalon.db.services.DatabasePersistor;
  import org.apache.avalon.db.data.Column;
  import org.apache.avalon.db.data.impl.VarCharColumn;
  import org.apache.avalon.db.data.impl.IntegerColumn;
  import org.apache.avalon.db.data.impl.DateColumn;
  import org.apache.avalon.db.data.impl.TimeColumn;
  import org.apache.avalon.db.data.impl.TimestampColumn;
  import org.apache.avalon.db.data.impl.SmallIntColumn;
  import org.apache.avalon.db.data.impl.RealColumn;
  import org.apache.avalon.db.data.impl.BigIntColumn;
  import org.apache.avalon.db.data.impl.DecimalColumn;
  import org.apache.avalon.db.actions.ActionException;
  import org.w3c.dom.Element;
  import org.w3c.dom.NodeList;
  import org.w3c.dom.Node;
  
  import java.util.Vector;
  
  
  /**
   * Class BasicLXSQLQueryableHandler
   *
   *
   * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
   * @author Gerhard Froehlich <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
   * @version $Revision: 1.1 $
   */
  public abstract class BasicLXSQLQueryableHandler extends BasicLXSQLHandler {
  
      /**
       * Constructor BasicLXSQLQueryableHandler
       *
       *
       * @param parser
       * @param databasePersistor
       *
       */
      public BasicLXSQLQueryableHandler(BasicLXSQLParser parser, 
DatabasePersistor databasePersistor) {
          super(parser,databasePersistor);
      }
  
      /**
       * Method getColumns
       *
       *
       */
      protected Column[] getColumns(Element columnsNode) throws ActionException 
{
  
          Vector columns = new Vector();
  
          NodeList subColumnsNodes = columnsNode.getChildNodes();
          for (int x = 0 ; x < subColumnsNodes.getLength(); x++) {
              if (subColumnsNodes.item(x).getNodeName().equals("column")) {
                  columns.add(createColumn(subColumnsNodes.item(x), x));
              } else {
  
                  throw new ActionException("Only 'column' allowed as a node 
under 'columns' node");
              }
          }
  
          Column[] columnsAry = new Column[columns.size()];
          columns.toArray(columnsAry);
  
          return columnsAry;
  
      }
  
  
      protected Column createColumn(Node columnNode, int ix) throws 
ActionException {
          String sqlFieldType = 
columnNode.getAttributes().getNamedItem("type").getNodeValue();
          String fieldName = 
columnNode.getAttributes().getNamedItem("name").getNodeValue();
          Column column = null;
          if (sqlFieldType.equals("varchar")) {
              int maxLength = 
Integer.parseInt(columnNode.getAttributes().getNamedItem("max").getNodeValue());
              column= new VarCharColumn(fieldName, maxLength);
          } else if (sqlFieldType.equals("integer")) {
              column= new IntegerColumn(fieldName);
          } else if (sqlFieldType.equals("date")) {
              column= new DateColumn(fieldName);
          } else if (sqlFieldType.equals("time")) {
              column= new TimeColumn(fieldName);
          } else if (sqlFieldType.equals("timestamp")) {
              column= new TimestampColumn(fieldName);
          } else if (sqlFieldType.equals("smallint")) {
              column= new SmallIntColumn(fieldName);
          } else if (sqlFieldType.equals("real")) {
              column= new RealColumn(fieldName);
          } else if (sqlFieldType.equals("bigint")) {
              column= new BigIntColumn(fieldName);
          } else if (sqlFieldType.equals("decimal")) {
              column= new DecimalColumn(fieldName);
          } else {
              throw new ActionException("Column type " + sqlFieldType + " not 
recognised");
          }
          column.setIndex(ix);
          return column;
      }
  
  }
  
  
  
  1.3       +10 -4     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/RowListener.java
  
  Index: RowListener.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/RowListener.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- RowListener.java  2001/11/12 15:09:04     1.2
  +++ RowListener.java  2001/11/18 14:18:02     1.3
  @@ -8,18 +8,24 @@
    */
   package org.apache.avalon.db.data;
   
  +import java.util.Collection;
  +
   /**
    * Interface RowListener
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version * $Revision: 1.2 $
  + * @version * $Revision: 1.3 $
    */
   public interface RowListener {
  +
  +    void rowsAdded(Queryable queryable, Row row);
  +    void rowsDeleted(Queryable queryable, Row row);
  +    void rowsChanged(Queryable queryable, Row row);
   
  -    void rowsAdded(Queryable queryable, Row[] rows);
  -    void rowsDeleted(Queryable queryable, Row[] rows);
  -    void rowsChanged(Queryable queryable, Row[] rows);
  +    void rowsAdded(Queryable queryable, Collection rows);
  +    void rowsDeleted(Queryable queryable, Collection rows);
  +    void rowsChanged(Queryable queryable, Collection rows);
   
   
   }
  
  
  
  1.6       +50 -11    
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/impl/AbstractQueryable.java
  
  Index: AbstractQueryable.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/impl/AbstractQueryable.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractQueryable.java    2001/11/17 17:04:27     1.5
  +++ AbstractQueryable.java    2001/11/18 14:18:02     1.6
  @@ -26,7 +26,7 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.5 $
  + * @version $Revision: 1.6 $
    */
   public abstract class AbstractQueryable extends AbstractNameable implements 
Queryable {
   
  @@ -81,21 +81,22 @@
        *
        */
       public void addRow(Row row) {
  -        AbstractTableRow atr = (AbstractTableRow) row;
  -        mRows.add(atr);
  -        atr.setAbstractQueryable(this);
  -        this.notifyRowListenersAdded(new Row[] {row});
  +        mRows.add(row);
  +        this.notifyRowListenersAdded(row);
  +    }
  +    public void addRows(Collection rows) {
  +        mRows.addAll(rows);
  +        this.notifyRowListenersAdded(rows);
       }
   
       public void deleteRow(Row row) {
           AbstractTableRow atr = (AbstractTableRow) row;
           mRows.remove(atr);
  -        this.notifyRowListenersDeleted(new Row[] {row});
  -        atr.setAbstractQueryable(null);
  +        this.notifyRowListenersDeleted(row);
       }
   
       public void rowChanged(Row row) {
  -        this.notifyRowListenersChanged(new Row[] {row});
  +        this.notifyRowListenersChanged(row);
       }
   
   
  @@ -114,7 +115,7 @@
           }
       }
   
  -    public void notifyRowListenersAdded(Row[] rows) {
  +    public void notifyRowListenersAdded(Collection rows) {
           Iterator it = mListeners.iterator();
           while (it.hasNext()) {
               WeakReference ref = (WeakReference) it.next();
  @@ -126,8 +127,22 @@
               }
           }
       }
  +    public void notifyRowListenersAdded(Row row) {
  +        Iterator it = mListeners.iterator();
  +        while (it.hasNext()) {
  +            WeakReference ref = (WeakReference) it.next();
  +            RowListener listener = (RowListener) ref.get();
  +            if (listener == null) {
  +                it.remove();
  +            } else {
  +                listener.rowsAdded(this, row);
  +            }
  +        }
  +    }
  +
   
  -    public void notifyRowListenersChanged(Row[] rows) {
  +
  +    public void notifyRowListenersChanged(Collection rows) {
           Iterator it = mListeners.iterator();
           while (it.hasNext()) {
               WeakReference ref = (WeakReference) it.next();
  @@ -139,8 +154,20 @@
               }
           }
       }
  +    public void notifyRowListenersChanged(Row row) {
  +        Iterator it = mListeners.iterator();
  +        while (it.hasNext()) {
  +            WeakReference ref = (WeakReference) it.next();
  +            RowListener listener = (RowListener) ref.get();
  +            if (listener == null) {
  +                it.remove();
  +            } else {
  +                listener.rowsChanged(this, row);
  +            }
  +        }
  +    }
   
  -    public void notifyRowListenersDeleted(Row[] rows) {
  +    public void notifyRowListenersDeleted(Collection rows) {
           Iterator it = mListeners.iterator();
           while (it.hasNext()) {
               WeakReference ref = (WeakReference) it.next();
  @@ -149,6 +176,18 @@
                   it.remove();
               } else {
                   listener.rowsDeleted(this, rows);
  +            }
  +        }
  +    }
  +    public void notifyRowListenersDeleted(Row row) {
  +        Iterator it = mListeners.iterator();
  +        while (it.hasNext()) {
  +            WeakReference ref = (WeakReference) it.next();
  +            RowListener listener = (RowListener) ref.get();
  +            if (listener == null) {
  +                it.remove();
  +            } else {
  +                listener.rowsDeleted(this, row);
               }
           }
       }
  
  
  
  1.4       +3 -3      
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/impl/AbstractTableRow.java
  
  Index: AbstractTableRow.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/data/impl/AbstractTableRow.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- AbstractTableRow.java     2001/11/12 22:14:29     1.3
  +++ AbstractTableRow.java     2001/11/18 14:18:02     1.4
  @@ -19,14 +19,14 @@
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.3 $
  + * @version $Revision: 1.4 $
    */
   public abstract class AbstractTableRow implements Row {
   
       protected AbstractQueryable mAbstractQueryable;
   
  -    public void setAbstractQueryable(AbstractQueryable absQueryable) {
  -        mAbstractQueryable = absQueryable;
  +    public AbstractTableRow(AbstractQueryable abstractQueryable) {
  +        mAbstractQueryable = abstractQueryable;
       }
   
       /**
  
  
  
  1.11      +18 -5     
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/persistence/store/StorePersistence.java
  
  Index: StorePersistence.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/persistence/store/StorePersistence.java,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- StorePersistence.java     2001/11/12 21:46:25     1.10
  +++ StorePersistence.java     2001/11/18 14:18:02     1.11
  @@ -20,13 +20,15 @@
   import org.apache.avalon.cornerstone.services.store.Store;
   import org.apache.avalon.cornerstone.services.store.ObjectRepository;
   
  +import java.util.Collection;
   
  +
   /**
    * Class StorePersistence
    *
    *
    * @author Paul Hammant <a href="mailto:[EMAIL PROTECTED]">[EMAIL 
PROTECTED]</a>
  - * @version $Revision: 1.10 $
  + * @version $Revision: 1.11 $
    */
   public class StorePersistence extends NoPersistence implements RowListener {
   
  @@ -76,17 +78,28 @@
               queryable.addRowListener(this);
           }
       }
  +
  +    public void rowsAdded(Queryable queryable, Collection rows) {
  +        persist(queryable);
  +    }
  +
  +    public void rowsDeleted(Queryable queryable, Collection rows) {
  +        persist(queryable);
  +    }
  +
  +    public void rowsChanged(Queryable queryable, Collection rows) {
  +        persist(queryable);
  +    }
   
  -    public void rowsAdded(Queryable queryable, Row[] rows) {
  -        System.out.println("qqqqqq");
  +    public void rowsAdded(Queryable queryable, Row row) {
           persist(queryable);
       }
   
  -    public void rowsDeleted(Queryable queryable, Row[] rows) {
  +    public void rowsDeleted(Queryable queryable, Row row) {
           persist(queryable);
       }
   
  -    public void rowsChanged(Queryable queryable, Row[] rows) {
  +    public void rowsChanged(Queryable queryable, Row row) {
           persist(queryable);
       }
   
  
  
  
  1.23      +10 -17    
jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/test/Tester.java
  
  Index: Tester.java
  ===================================================================
  RCS file: 
/home/cvs/jakarta-avalon-cornerstone/apps/db/src/java/org/apache/avalon/db/test/Tester.java,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- Tester.java       2001/11/17 17:32:50     1.22
  +++ Tester.java       2001/11/18 14:18:02     1.23
  @@ -90,25 +90,18 @@
   
           System.err.println("VIEW 1");
           st = mCon.createStatement();
  -        String view = "<create-view name=\"FlintstonesView\">" +
  +        String view = "<create-view name=\"FlintstonesView\" 
on=\"Flintstones\">" +
                            "<columns>" +
  -                            "<column name=\"forename\" type=\"varchar\" 
max=\"20\"/>" +
  -                            "<column name=\"surname\" type=\"varchar\" 
max=\"20\"/>" +
  -                            "<column name=\"age\" type=\"integer\"/>" +
  +                             "<column name=\"forename\" type=\"varchar\" 
max=\"20\"/>" +
  +                             "<column name=\"surname\" type=\"varchar\" 
max=\"20\"/>" +
  +                             "<column name=\"age\" type=\"integer\"/>" +
                            "</columns>" +
  -                         "<simple-select>" +
  -                            "<columns>" +
  -                               "<column name=\"forename\"/>" +
  -                               "<column name=\"surname\"/>" +
  -                            "</columns>" +
  -                            "<from><table name=\"Flintstones\"/></from>" +
  -                            "<where>" +
  -                               "<and>" +
  -                                  "<condition expr=\"forename=Wilma\"/>" +
  -                                  "<condition expr=\"surname=Flintstone\"/>" 
+
  -                               "</and>" +
  -                            "</where>" +
  -                         "</simple-select>" +
  +                         "<where>" +
  +                             "<and>" +
  +                                 "<condition expr=\"forename=Wilma\"/>" +
  +                                 "<condition expr=\"surname=Flintstone\"/>" +
  +                             "</and>" +
  +                         "</where>" +
                         "</create-view>";
   
           st.execute(view);
  
  
  

--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to