Author: aadamchik
Date: Fri Sep 1 02:31:20 2006
New Revision: 439249
URL: http://svn.apache.org/viewvc?rev=439249&view=rev
Log:
* adding DB auto-generation function to the provider
* fixing non-selecting native query
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManager.java
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManagerFactory.java
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaEntityManager.java
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaNativeQuery.java
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaPersistenceProvider.java
incubator/cayenne/main/trunk/core/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/MockJpaEntityManager.java
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManager.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManager.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManager.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManager.java
Fri Sep 1 02:31:20 2006
@@ -28,6 +28,7 @@
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import javax.persistence.TransactionRequiredException;
+import javax.persistence.spi.PersistenceUnitInfo;
import javax.persistence.spi.PersistenceUnitTransactionType;
/**
@@ -57,6 +58,10 @@
this.open = true;
}
+ protected PersistenceUnitInfo getPersistenceUnitInfo() {
+ return factory.getPersistenceUnitInfo();
+ }
+
/**
* Set the lock mode for an entity object contained in the persistence
context.
*/
@@ -303,12 +308,7 @@
* @param sqlString a native SQL query string
* @return the new query instance
*/
- public Query createNativeQuery(String sqlString) {
- checkClosed();
-
- // TODO: Andrus, 2/10/2006 - implement
- throw new UnsupportedOperationException("TODO");
- }
+ public abstract Query createNativeQuery(String sqlString);
/**
* Create an instance of Query for executing a native SQL query.
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManagerFactory.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManagerFactory.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManagerFactory.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/JpaEntityManagerFactory.java
Fri Sep 1 02:31:20 2006
@@ -41,6 +41,10 @@
this.unitInfo = unitInfo;
this.open = true;
}
+
+ protected PersistenceUnitInfo getPersistenceUnitInfo() {
+ return unitInfo;
+ }
/**
* Indicates whether the factory is open. Returns true until the factory
has been
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaEntityManager.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaEntityManager.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaEntityManager.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaEntityManager.java
Fri Sep 1 02:31:20 2006
@@ -114,6 +114,14 @@
}
@Override
+ public Query createNativeQuery(String sqlString) {
+ checkClosed();
+
+ return new CjpaNativeQuery(context, sqlString, getPersistenceUnitInfo()
+ .getPersistenceUnitName());
+ }
+
+ @Override
public void joinTransaction() {
// TODO: andrus, 7/24/2006 - noop
}
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaNativeQuery.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaNativeQuery.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaNativeQuery.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaNativeQuery.java
Fri Sep 1 02:31:20 2006
@@ -17,12 +17,12 @@
* under the License.
****************************************************************/
-
package org.apache.cayenne.jpa.cspi;
import javax.persistence.Query;
import org.apache.cayenne.access.DataContext;
+import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.query.SQLTemplate;
public class CjpaNativeQuery extends CjpaQuery {
@@ -31,6 +31,16 @@
public CjpaNativeQuery(DataContext ctxt, String sqlString, Class
resultClass) {
super(ctxt);
+ setQuery(new SQLTemplate(resultClass, processSQLString(sqlString)));
+ }
+
+ public CjpaNativeQuery(DataContext ctxt, String sqlString, String
dataMapName) {
+ super(ctxt);
+ DataMap map = ctxt.getEntityResolver().getDataMap(dataMapName);
+ setQuery(new SQLTemplate(map, processSQLString(sqlString)));
+ }
+
+ protected String processSQLString(String sqlString) {
// named parameters are like ":parametername" and positional parameters
// are like "?123". SQLTemplate support "$parametername"
@@ -42,22 +52,22 @@
// handle positional parameters like named
if (sqlString.indexOf('?') >= 0) {
// convert "?123" to "$positional_123"
- sqlString = sqlString.replaceAll("\\?([0-9]+)", "\\$" +
POSITIONAL_PARAM_PREFIX + "$1");
+ sqlString = sqlString.replaceAll("\\?([0-9]+)", "\\$"
+ + POSITIONAL_PARAM_PREFIX
+ + "$1");
}
- setQuery(new SQLTemplate(resultClass, sqlString));
+ return sqlString;
}
-
/**
* Bind an argument to a positional parameter.
*
* @param position
* @param value
* @return the same query instance
- * @throws IllegalArgumentException
- * if position does not correspond to positional parameter of
- * query or argument is of incorrect type
+ * @throws IllegalArgumentException if position does not correspond to
positional
+ * parameter of query or argument is of incorrect type
*/
public Query setParameter(int position, Object value) {
@@ -66,9 +76,11 @@
String name = POSITIONAL_PARAM_PREFIX + Integer.toString(position);
try {
return setParameter(name, value);
- } catch (IllegalArgumentException e) {
- throw new IllegalArgumentException("Invalid positional parameter:
" + position, e);
+ }
+ catch (IllegalArgumentException e) {
+ throw new IllegalArgumentException("Invalid positional parameter: "
+ + position, e);
}
}
-
+
}
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaPersistenceProvider.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaPersistenceProvider.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaPersistenceProvider.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/main/java/org/apache/cayenne/jpa/cspi/CjpaPersistenceProvider.java
Fri Sep 1 02:31:20 2006
@@ -22,7 +22,9 @@
import java.io.InputStream;
import java.io.PrintWriter;
import java.sql.Connection;
+import java.sql.ResultSet;
import java.sql.SQLException;
+import java.util.Collection;
import java.util.Map;
import javax.persistence.EntityManagerFactory;
@@ -30,6 +32,13 @@
import javax.persistence.spi.PersistenceUnitTransactionType;
import javax.sql.DataSource;
+import org.apache.cayenne.access.DataDomain;
+import org.apache.cayenne.access.DataNode;
+import org.apache.cayenne.access.DbGenerator;
+import org.apache.cayenne.conf.Configuration;
+import org.apache.cayenne.conf.ConnectionProperties;
+import org.apache.cayenne.dba.AutoAdapter;
+import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.jpa.bridge.DataMapConverter;
import org.apache.cayenne.jpa.conf.EntityMapLoader;
import org.apache.cayenne.jpa.conf.EntityMapLoaderContext;
@@ -37,19 +46,14 @@
import org.apache.cayenne.jpa.enhancer.UnitClassTranformer;
import org.apache.cayenne.jpa.map.JpaClassDescriptor;
import org.apache.cayenne.jpa.spi.JpaPersistenceProvider;
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.cayenne.access.DataDomain;
-import org.apache.cayenne.access.DataNode;
-import org.apache.cayenne.conf.Configuration;
-import org.apache.cayenne.conf.ConnectionProperties;
-import org.apache.cayenne.dba.AutoAdapter;
-import org.apache.cayenne.dba.DbAdapter;
import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.util.ResourceLocator;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.validation.SimpleValidationFailure;
import org.apache.cayenne.validation.ValidationResult;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* A PersistenceProvider implementation based on Cayenne stack. Wraps a Cayenne
@@ -59,6 +63,8 @@
*/
public class CjpaPersistenceProvider extends JpaPersistenceProvider {
+ public static final String CREATE_SCHEMA_PROPERTY =
"cayenne.schema.create";
+
protected Configuration configuration;
protected Log logger;
@@ -151,6 +157,11 @@
domain.addNode(node);
+ if ("true".equalsIgnoreCase(info.getProperties().getProperty(
+ CREATE_SCHEMA_PROPERTY))) {
+ loadSchema(dataSource, adapter, cayenneMap);
+ }
+
long t1 = System.currentTimeMillis();
// report conflicts...
@@ -173,6 +184,74 @@
CjpaEntityManagerFactory factory = new
CjpaEntityManagerFactory(domain, info);
factory.setDelegate(this);
return factory;
+ }
+
+ /**
+ * Loads database schema if it doesn't yet exist.
+ */
+ protected void loadSchema(DataSource dataSource, DbAdapter adapter,
DataMap map) {
+
+ Collection tables = map.getDbEntities();
+ if (tables.isEmpty()) {
+ return;
+ }
+
+ // sniff a first table precense
+
+ // TODO: andrus 9/1/2006 - should we make this check a part of
DbGenerator (and
+ // query - a part of DbAdapter)?
+ DbEntity table = (DbEntity) tables.iterator().next();
+
+ try {
+ Connection c = dataSource.getConnection();
+ try {
+
+ String tableName = table.getName().toLowerCase();
+
+ // select all tables to avoid case sensitivity issues.
+ ResultSet rs = c.getMetaData().getTables(
+ table.getCatalog(),
+ table.getSchema(),
+ null,
+ null);
+
+ try {
+ while (rs.next()) {
+ String sqlName = rs.getString("TABLE_NAME");
+ if (tableName.equals(sqlName.toLowerCase())) {
+ logger.debug("table "
+ + table.getFullyQualifiedName()
+ + " is present; will skip schema
generation.");
+ return;
+ }
+ }
+ }
+ finally {
+ rs.close();
+ }
+ }
+ finally {
+ c.close();
+ }
+ }
+ catch (SQLException e1) {
+ // db exists
+ logger.debug("error generating schema, assuming schema exists.");
+ return;
+ }
+
+ logger.debug("table "
+ + table.getFullyQualifiedName()
+ + " is absent; will continue with schema generation.");
+
+ // run generator
+ DbGenerator generator = new DbGenerator(adapter, map);
+ try {
+ generator.runGenerator(dataSource);
+ }
+ catch (Exception e) {
+
+ }
}
protected DbAdapter createCustomAdapter(
Modified:
incubator/cayenne/main/trunk/core/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/MockJpaEntityManager.java
URL:
http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/core/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/MockJpaEntityManager.java?rev=439249&r1=439248&r2=439249&view=diff
==============================================================================
---
incubator/cayenne/main/trunk/core/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/MockJpaEntityManager.java
(original)
+++
incubator/cayenne/main/trunk/core/cayenne-jpa/src/test/java/org/apache/cayenne/jpa/MockJpaEntityManager.java
Fri Sep 1 02:31:20 2006
@@ -17,7 +17,6 @@
* under the License.
****************************************************************/
-
package org.apache.cayenne.jpa;
import javax.persistence.EntityTransaction;
@@ -29,11 +28,11 @@
public MockJpaEntityManager(JpaEntityManagerFactory factory) {
super(factory);
}
-
+
@Override
public void lock(Object entity, LockModeType lockMode) {
}
-
+
@Override
protected EntityTransaction createResourceLocalTransaction() {
return null;
@@ -81,6 +80,12 @@
public Query createNamedQuery(String name) {
checkClosed();
+ return null;
+ }
+
+ @Override
+ public Query createNativeQuery(String sqlString) {
+ checkClosed();
return null;
}