On Tue, 2006-05-09 at 09:30 -0400, Andrus Adamchik wrote:
> I think you can select files in question and then do "Team -> Add to
> Version Control" and then do a diff.
Ah! It works.
I didn't think to try it since I've got read-only access to the
repository.
Attached is an example using the MSAccess adapter.
--
Øyvind Harboe
http://www.zylin.com
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/AutoAdapter.java
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/AutoAdapter.java (revision 405312)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/AutoAdapter.java (working copy)
@@ -77,6 +77,7 @@
import org.objectstyle.cayenne.dba.frontbase.FrontBaseSniffer;
import org.objectstyle.cayenne.dba.hsqldb.HSQLDBSniffer;
import org.objectstyle.cayenne.dba.ingres.IngresSniffer;
+import org.objectstyle.cayenne.dba.msaccess.MSAccessSniffer;
import org.objectstyle.cayenne.dba.mysql.MySQLSniffer;
import org.objectstyle.cayenne.dba.openbase.OpenBaseSniffer;
import org.objectstyle.cayenne.dba.oracle.OracleSniffer;
@@ -105,7 +106,8 @@
new MySQLSniffer(), new PostgresSniffer(), new OracleSniffer(),
new SQLServerSniffer(), new HSQLDBSniffer(), new DB2Sniffer(),
new SybaseSniffer(), new DerbySniffer(), new OpenBaseSniffer(),
- new FirebirdSniffer(), new FrontBaseSniffer(), new IngresSniffer()
+ new FirebirdSniffer(), new FrontBaseSniffer(), new IngresSniffer(),
+ new MSAccessSniffer()
};
/**
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessActionBuilder.java
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessActionBuilder.java (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessActionBuilder.java (revision 0)
@@ -0,0 +1,31 @@
+package org.objectstyle.cayenne.dba.msaccess;
+
+import org.objectstyle.cayenne.access.jdbc.BatchAction;
+import org.objectstyle.cayenne.dba.DbAdapter;
+import org.objectstyle.cayenne.dba.JdbcActionBuilder;
+import org.objectstyle.cayenne.map.EntityResolver;
+import org.objectstyle.cayenne.query.BatchQuery;
+import org.objectstyle.cayenne.query.SQLAction;
+
+public class MSAccessActionBuilder extends JdbcActionBuilder
+{
+
+ public MSAccessActionBuilder(DbAdapter adapter, EntityResolver resolver)
+ {
+ super(adapter, resolver);
+ }
+
+
+ public SQLAction batchAction(BatchQuery query) {
+ // check run strategy...
+
+ // optimistic locking is not supported in batches due to JDBC driver limitations
+ boolean useOptimisticLock = query.isUsingOptimisticLocking();
+
+ boolean runningAsBatch = !useOptimisticLock && adapter.supportsBatchUpdates();
+ BatchAction action = new MSAccessBatchAction(query, adapter, entityResolver);
+ action.setBatch(runningAsBatch);
+ return action;
+ }
+
+}
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessAdapter.java
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessAdapter.java (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessAdapter.java (revision 0)
@@ -0,0 +1,22 @@
+package org.objectstyle.cayenne.dba.msaccess;
+
+import org.objectstyle.cayenne.access.DataNode;
+import org.objectstyle.cayenne.dba.JdbcAdapter;
+import org.objectstyle.cayenne.query.Query;
+import org.objectstyle.cayenne.query.SQLAction;
+
+/**
+ **/
+public class MSAccessAdapter extends JdbcAdapter {
+
+
+ public MSAccessAdapter()
+ {
+ setSupportsGeneratedKeys(true);
+ }
+ public SQLAction getAction(Query query, DataNode node) {
+ return query.createSQLAction(new MSAccessActionBuilder(this, node
+ .getEntityResolver()));
+ }
+
+ }
\ No newline at end of file
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessBatchAction.java
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessBatchAction.java (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessBatchAction.java (revision 0)
@@ -0,0 +1,143 @@
+package org.objectstyle.cayenne.dba.msaccess;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.Collections;
+import java.util.Map;
+
+import org.objectstyle.cayenne.CayenneException;
+import org.objectstyle.cayenne.access.OperationObserver;
+import org.objectstyle.cayenne.access.OptimisticLockException;
+import org.objectstyle.cayenne.access.QueryLogger;
+import org.objectstyle.cayenne.access.ResultIterator;
+import org.objectstyle.cayenne.access.jdbc.BatchAction;
+import org.objectstyle.cayenne.access.jdbc.JDBCResultIterator;
+import org.objectstyle.cayenne.access.jdbc.RowDescriptor;
+import org.objectstyle.cayenne.access.trans.BatchQueryBuilder;
+import org.objectstyle.cayenne.dba.DbAdapter;
+import org.objectstyle.cayenne.map.EntityResolver;
+import org.objectstyle.cayenne.query.BatchQuery;
+import org.objectstyle.cayenne.query.DeleteBatchQuery;
+import org.objectstyle.cayenne.query.UpdateBatchQuery;
+
+/**
+ * Extracts generated primary key for MS Access databases. Note that only a single
+ * generated column is supported.
+ *
+ */
+public class MSAccessBatchAction extends BatchAction {
+
+ public MSAccessBatchAction(BatchQuery batchQuery, DbAdapter adapter,
+ EntityResolver entityResolver)
+ {
+ super(batchQuery, adapter, entityResolver);
+ }
+
+ protected void runAsIndividualQueries(Connection connection, BatchQueryBuilder queryBuilder, OperationObserver delegate, boolean generatesKeys) throws SQLException, Exception
+ {
+
+ boolean isLoggable = QueryLogger.isLoggable();
+ boolean useOptimisticLock = query.isUsingOptimisticLocking();
+
+ String queryStr = queryBuilder.createSqlString(query);
+
+ // log batch SQL execution
+ QueryLogger.logQuery(queryStr, Collections.EMPTY_LIST);
+
+ // run batch queries one by one
+ query.reset();
+
+ // here a bit of woodoo to support generated keys....
+ PreparedStatement statement = connection.prepareStatement(queryStr);
+ try {
+ while (query.next()) {
+ if (isLoggable) {
+ QueryLogger.logQueryParameters("bind", queryBuilder
+ .getParameterValues(query));
+ }
+
+ queryBuilder.bindParameters(statement, query);
+
+ int updated = statement.executeUpdate();
+ if (useOptimisticLock && updated != 1) {
+
+ Map snapshot = Collections.EMPTY_MAP;
+ if (query instanceof UpdateBatchQuery) {
+ snapshot = ((UpdateBatchQuery) query).getCurrentQualifier();
+ }
+ else if (query instanceof DeleteBatchQuery) {
+ snapshot = ((DeleteBatchQuery) query).getCurrentQualifier();
+ }
+
+ throw new OptimisticLockException(
+ query.getDbEntity(),
+ queryStr,
+ snapshot);
+ }
+
+ delegate.nextCount(query, updated);
+
+ if (generatesKeys)
+ {
+ String findPrimKey = "SELECT @@IDENTITY";
+ QueryLogger.logQuery(findPrimKey, Collections.EMPTY_LIST);
+
+ Statement fetchPrimKey = connection.createStatement();
+ try
+ {
+ fetchPrimKey.executeQuery(findPrimKey);
+ processGeneratedKeys(fetchPrimKey, delegate);
+ } finally
+ {
+ try
+ {
+ fetchPrimKey.close();
+ } catch (Throwable e)
+ {
+ }
+ }
+ }
+
+ if (isLoggable) {
+ QueryLogger.logUpdateCount(updated);
+ }
+ }
+ }
+ finally {
+ try {
+ statement.close();
+ }
+ catch (Exception e) {
+ }
+ }
+ }
+
+ /**
+ * Implements generated keys extraction supported by MS Access
+ *
+ */
+ protected void processGeneratedKeys(Statement statement, OperationObserver observer)
+ throws SQLException, CayenneException {
+
+ /*
+ * The only difference between JDBC 3.0 & MS Access extraction for this fn.
+ * is that we invoke getResultSet() here on the query that found the
+ * latest primary key insterted.
+ */
+ ResultSet keysRS = statement.getResultSet();
+ RowDescriptor descriptor = new RowDescriptor(keysRS, getAdapter()
+ .getExtendedTypes());
+ ResultIterator iterator = new JDBCResultIterator(
+ null,
+ null,
+ keysRS,
+ descriptor,
+ 0);
+
+ observer.nextGeneratedDataRows(query, iterator);
+ }
+
+}
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessSniffer.java
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessSniffer.java (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/MSAccessSniffer.java (revision 0)
@@ -0,0 +1,22 @@
+package org.objectstyle.cayenne.dba.msaccess;
+
+import java.sql.DatabaseMetaData;
+import java.sql.SQLException;
+
+import org.objectstyle.cayenne.dba.DbAdapter;
+import org.objectstyle.cayenne.dba.DbAdapterFactory;
+
+public class MSAccessSniffer implements DbAdapterFactory {
+
+ public DbAdapter createAdapter(DatabaseMetaData md) throws SQLException {
+ String dbName = md.getDatabaseProductName();
+ if (dbName == null || dbName.toUpperCase().indexOf("ACCESS") < 0) {
+ return null;
+ }
+
+ MSAccessAdapter adapter = new MSAccessAdapter();
+
+ adapter.setSupportsGeneratedKeys(true);
+ return adapter;
+ }
+}
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/package.html
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/package.html (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/package.html (revision 0)
@@ -0,0 +1,5 @@
+<html>
+<body>
+Microsoft Access DbAdapter.
+</body>
+</html>
\ No newline at end of file
Index: C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/types.xml
===================================================================
--- C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/types.xml (revision 0)
+++ C:/workspace/cayenne-java/src/cayenne/java/org/objectstyle/cayenne/dba/msaccess/types.xml (revision 0)
@@ -0,0 +1,78 @@
+<?xml version="1.0"?>
+
+<!-- MS SQL Server types mapping. -->
+
+<types>
+ <jdbc-type name="ARRAY"/>
+ <jdbc-type name="BIGINT">
+ <db-type name="int"/>
+ </jdbc-type>
+ <jdbc-type name="BINARY">
+ <db-type name="binary"/>
+ </jdbc-type>
+ <jdbc-type name="BIT">
+ <db-type name="bit"/>
+ </jdbc-type>
+ <jdbc-type name="BLOB">
+ <db-type name="image"/>
+ </jdbc-type>
+ <jdbc-type name="BOOLEAN">
+ <db-type name="bit"/>
+ </jdbc-type>
+ <jdbc-type name="CHAR">
+ <db-type name="char"/>
+ </jdbc-type>
+ <jdbc-type name="CLOB">
+ <db-type name="text"/>
+ </jdbc-type>
+ <jdbc-type name="DATALINK"/>
+ <jdbc-type name="DATE">
+ <db-type name="datetime"/>
+ </jdbc-type>
+ <jdbc-type name="DECIMAL">
+ <db-type name="decimal"/>
+ </jdbc-type>
+ <jdbc-type name="DOUBLE">
+ <db-type name="double precision"/>
+ </jdbc-type>
+ <jdbc-type name="FLOAT">
+ <db-type name="float"/>
+ </jdbc-type>
+ <jdbc-type name="INTEGER">
+ <db-type name="int"/>
+ </jdbc-type>
+ <jdbc-type name="JAVA_OBJECT"/>
+ <jdbc-type name="LONGVARBINARY">
+ <db-type name="image"/>
+ </jdbc-type>
+ <jdbc-type name="LONGVARCHAR">
+ <db-type name="text"/>
+ </jdbc-type>
+ <jdbc-type name="NUMERIC">
+ <db-type name="numeric"/>
+ </jdbc-type>
+ <jdbc-type name="OTHER"/>
+ <jdbc-type name="REAL">
+ <db-type name="real"/>
+ </jdbc-type>
+ <jdbc-type name="REF"/>
+ <jdbc-type name="SMALLINT">
+ <db-type name="smallint"/>
+ </jdbc-type>
+ <jdbc-type name="STRUCT"/>
+ <jdbc-type name="TIME">
+ <db-type name="datetime"/>
+ </jdbc-type>
+ <jdbc-type name="TIMESTAMP">
+ <db-type name="datetime"/>
+ </jdbc-type>
+ <jdbc-type name="TINYINT">
+ <db-type name="tinyint"/>
+ </jdbc-type>
+ <jdbc-type name="VARBINARY">
+ <db-type name="varbinary"/>
+ </jdbc-type>
+ <jdbc-type name="VARCHAR">
+ <db-type name="varchar"/>
+ </jdbc-type>
+</types>