modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
| 24 +-
modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
| 16 +
modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
| 23 +-
modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
| 22 +
modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
| 78 ++++++
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/ResourceGWTService.java
| 2
modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/ResourceGWTServiceImpl.java
| 9
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
| 41 +++
modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
| 112 ++++++++--
9 files changed, 280 insertions(+), 47 deletions(-)
New commits:
commit caa08cef46c679064040e6256fdaf24f2d402250
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Feb 25 13:02:29 2014 -0500
[1025918] Uninventoring resources is slow; should not take more than a second
As suggested by Elias Ross, convert our depth-restricted "recursive" join
queries with recursive queries leveraging native support in
Oracle and Postgres.
Also:
- remove unused coregui (GWT) service that depended on an old query.
diff --git
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
index b1fb366..6d5036d 100644
---
a/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
+++
b/modules/core/domain/src/main/java/org/rhq/core/domain/discovery/ResourceSyncInfo.java
@@ -71,6 +71,26 @@ public class ResourceSyncInfo implements Serializable {
* the top level server. note that we support up to 6 levels below platform but we
are starting one level down) */
public static final String QUERY_TOP_LEVEL_SERVER =
"ResourceSyncInfo.topLevelServer";
+ // Native Queries not supported by HQL
+ public static final String QUERY_NATIVE_QUERY_TOP_LEVEL_SERVER_ORACLE = ""
//
+ + " SELECT r.id, r.uuid, r.mtime, r.inventory_status " //
+ + " FROM rhq_resource r " //
+ + " START WITH r.id = :resourceId " //
+ + " CONNECT BY PRIOR r.id = r.parent_resource_id ";
+ public static final String QUERY_NATIVE_QUERY_TOP_LEVEL_SERVER_POSTGRES =
"" //
+ + " WITH RECURSIVE childResource AS " //
+ + " ( SELECT r.id, r.uuid, r.mtime, r.inventory_status " //
+ + " FROM rhq_resource AS r " //
+ + " WHERE r.id = :resourceId " // non-recursive term
+ + " UNION ALL " //
+ + " SELECT r.id, r.uuid, r.mtime, r.inventory_status " // recursive
term
+ + " FROM rhq_resource AS r " //
+ + " JOIN childResource AS cr " //
+ + " ON (r.parent_resource_id = cr.id) " //
+ + " ) " //
+ + " SELECT id, uuid, mtime, inventory_status " //
+ + " FROM childResource ";
+
/**
* Server-assigned id
*/
@@ -140,7 +160,7 @@ public class ResourceSyncInfo implements Serializable {
return true;
}
- protected ResourceSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus)
{
+ public ResourceSyncInfo(int id, String uuid, long mtime, InventoryStatus istatus) {
this.id = id;
this.uuid = uuid;
this.mtime = mtime;
diff --git a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
index cf6e69c..bb74bf3 100644
--- a/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
+++ b/modules/core/domain/src/main/java/org/rhq/core/domain/resource/Resource.java
@@ -698,8 +698,8 @@ import org.rhq.core.domain.util.Summary;
@NamedQuery(name = Resource.QUERY_FIND_DESCENDANTS_BY_TYPE_AND_NAME, query =
"" //
+ "SELECT r.id " //
+ " FROM Resource r " //
- + " WHERE ( r.resourceType.id = :resourceTypeId OR :resourceTypeId IS NULL )
" //
- + " AND ( UPPER(r.name) like :name OR :name IS NULL ) " //
+ + " WHERE ( r.resourceType.id = :resourceTypeId OR :resourceTypeId = 0 )
" //
+ + " AND ( UPPER(r.name) like :resourceName OR :resourceName =
'$$$null$$$' ) " //
+ " AND ( r.id = :resourceId " //
+ " OR r.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.id = :resourceId) "
+ " OR r.id IN (SELECT rr.id FROM Resource rr WHERE
rr.parentResource.parentResource.id = :resourceId) "
@@ -903,6 +903,80 @@ public class Resource implements Comparable<Resource>,
Serializable {
public static final String QUERY_RESOURCE_VERSION_AND_DRIFT_IN_COMPLIANCE =
"Resource.findResourceVersionDriftInCompliance";
public static final String QUERY_RESOURCE_VERSION_AND_DRIFT_OUT_OF_COMPLIANCE =
"Resource.findResourceVersionDriftOutOfCompliance";
+ // Native Queries not supported by HQL
+ public static final String QUERY_NATIVE_FIND_DESCENDANTS_ORACLE = "" //
+ + " SELECT r.id " //
+ + " FROM rhq_resource r " //
+ + " START WITH r.id = :resourceId " //
+ + " CONNECT BY PRIOR r.id = r.parent_resource_id ";
+ public static final String QUERY_NATIVE_FIND_DESCENDANTS_POSTGRES = "" //
+ + " WITH RECURSIVE childResource AS " //
+ + " ( SELECT r.id " //
+ + " FROM rhq_resource AS r " //
+ + " WHERE r.id = :resourceId " // non-recursive term
+ + " UNION ALL " //
+ + " SELECT r.id " // recursive term
+ + " FROM rhq_resource AS r " //
+ + " JOIN childResource AS cr " //
+ + " ON (r.parent_resource_id = cr.id) " //
+ + " ) " //
+ + " SELECT id " //
+ + " FROM childResource ";
+
+ /**
+ * Note, special parameter values to represent NULL, do not use NULL:<pre>
+ * :resourceTypeId = 0
+ * :resourceName = "$$$null$$$"</pre>
+ */
+ public static final String QUERY_NATIVE_FIND_DESCENDANTS_BY_TYPE_AND_NAME_ORACLE =
"" //
+ + " SELECT r.id " //
+ + " FROM rhq_resource r " //
+ + " WHERE ( r.resource_type_id = :resourceTypeId OR
:resourceTypeId = 0 ) " //
+ + " AND ( UPPER(r.name) LIKE :resourceName OR :resourceName =
'$$$null$$$' ) " //
+ + " START WITH r.id = :resourceId " //
+ + " CONNECT BY PRIOR r.id = r.parent_resource_id ";
+ /**
+ * Note, special parameter values to represent NULL, do not use NULL:<pre>
+ * :resourceTypeId = 0
+ * :resourceName = "$$$null$$$"</pre>
+ */
+ public static final String QUERY_NATIVE_FIND_DESCENDANTS_BY_TYPE_AND_NAME_POSTGRES =
"" //
+ + " WITH RECURSIVE childResource AS " //
+ + " ( SELECT r.id AS resourceId, r.name AS resourceName,
r.resource_type_id AS resourceTypeId " //
+ + " FROM rhq_resource AS r " //
+ + " WHERE r.id = :resourceId " //
+ + " UNION ALL " //
+ + " SELECT r.id AS resourceId, r.name AS resourceName,
r.resource_type_id AS resourceTypeId " //
+ + " FROM rhq_resource AS r " //
+ + " JOIN childResource AS cr " //
+ + " ON (r.parent_resource_id = cr.resourceId) " //
+ + " ) " //
+ + " SELECT cr.resourceId " //
+ + " FROM childResource AS cr " //
+ + " WHERE ( cr.resourceTypeId = :resourceTypeId OR :resourceTypeId = 0 )
" //
+ + " AND ( UPPER(cr.resourceName) LIKE :resourceName OR :resourceName =
'$$$null$$$' ) ";
+
+ public static final String QUERY_NATIVE_FIND_RESOURCE_PLATFORM_ORACLE = ""
//
+ + " SELECT r.id " //
+ + " FROM rhq_resource r " //
+ + " WHERE r.parent_resource_id IS NULL " //
+ + " START WITH r.id = :resourceId " //
+ + " CONNECT BY PRIOR r.parent_resource_id = r.id ";
+ public static final String QUERY_NATIVE_FIND_RESOURCE_PLATFORM_POSTGRES =
"" //
+ + " WITH RECURSIVE parentResource AS " //
+ + " ( SELECT r.id AS resourceId, r.parent_resource_id AS
parentResourceId " //
+ + " FROM rhq_resource AS r " //
+ + " WHERE r.id = :resourceId " //
+ + " UNION " //
+ + " SELECT r.id AS resourceId, r.parent_resource_id AS
parentResourceId " //
+ + " FROM rhq_resource AS r " //
+ + " JOIN parentResource AS pr " //
+ + " ON (r.id = pr.parentResourceId) " //
+ + " ) " //
+ + " SELECT pr.resourceId " //
+ + " FROM parentResource AS pr " //
+ + " WHERE ( pr.parentResourceId IS NULL ) ";
+
private static final int UUID_LENGTH = 36;
private static final long serialVersionUID = 1L;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/ResourceGWTService.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/ResourceGWTService.java
index d166dab..75e5b29 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/ResourceGWTService.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/client/gwt/ResourceGWTService.java
@@ -89,8 +89,6 @@ public interface ResourceGWTService extends RemoteService {
List<ResourceInstallCount> findResourceInstallCounts(boolean groupByVersions)
throws RuntimeException;
- Resource getPlatformForResource(int resourceId) throws RuntimeException;
-
PageList<Resource> getQueuedPlatforms(ArrayList<InventoryStatus>
statuses, PageControl pc)
throws RuntimeException;
diff --git
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/ResourceGWTServiceImpl.java
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/ResourceGWTServiceImpl.java
index f89f31a..ca4c595 100644
---
a/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/ResourceGWTServiceImpl.java
+++
b/modules/enterprise/gui/coregui/src/main/java/org/rhq/coregui/server/gwt/ResourceGWTServiceImpl.java
@@ -243,15 +243,6 @@ public class ResourceGWTServiceImpl extends AbstractGWTServiceImpl
implements Re
}
}
- public Resource getPlatformForResource(int resourceId) throws RuntimeException {
- try {
- return
SerialUtility.prepare(resourceManager.getRootResourceForResource(resourceId),
- "ResourceService.getPlatformForResource");
- } catch (Throwable t) {
- throw getExceptionToThrowToClient(t);
- }
- }
-
public List<RecentlyAddedResourceComposite> findRecentlyAddedResources(long
ctime, int maxItems)
throws RuntimeException {
try {
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
index 6c8548d..0cfbb01 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/discovery/DiscoveryBossBean.java
@@ -65,6 +65,8 @@ import org.rhq.core.clientapi.agent.upgrade.ResourceUpgradeResponse;
import org.rhq.core.clientapi.server.discovery.InvalidInventoryReportException;
import org.rhq.core.clientapi.server.discovery.InventoryReport;
import org.rhq.core.clientapi.server.discovery.StaleTypeException;
+import org.rhq.core.db.DatabaseType;
+import org.rhq.core.db.DatabaseTypeFactory;
import org.rhq.core.domain.auth.Subject;
import org.rhq.core.domain.authz.Permission;
import org.rhq.core.domain.configuration.Configuration;
@@ -334,14 +336,42 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
}
}
+ @SuppressWarnings("unchecked")
@Override
public Collection<ResourceSyncInfo> getResourceSyncInfo(int resourceId) {
// [PERF] this is an expensive query that can return a large collection. But
it's faster than the old way of
// letting hibernate grab the whole hierarchy via eager fetch of children...
- Query q =
entityManager.createNamedQuery(ResourceSyncInfo.QUERY_TOP_LEVEL_SERVER);
- q.setParameter("resourceId", resourceId);
+ Query query = null;
+ Collection<ResourceSyncInfo> result = null;
+ boolean isNative = true;
+
+ DatabaseType dbType = DatabaseTypeFactory.getDefaultDatabaseType();
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ query =
entityManager.createNativeQuery(ResourceSyncInfo.QUERY_NATIVE_QUERY_TOP_LEVEL_SERVER_ORACLE);
+
+ } else if (DatabaseTypeFactory.isPostgres(dbType)) {
+ query =
entityManager.createNativeQuery(ResourceSyncInfo.QUERY_NATIVE_QUERY_TOP_LEVEL_SERVER_POSTGRES);
+
+ } else {
+ isNative = false;
+ query =
entityManager.createNamedQuery(ResourceSyncInfo.QUERY_TOP_LEVEL_SERVER);
+ }
+
+ query.setParameter("resourceId", resourceId);
- Collection<ResourceSyncInfo> result = q.getResultList();
+ if ( isNative ) {
+ List<Object[]> rows = query.getResultList();
+ result = new ArrayList<ResourceSyncInfo>(rows.size());
+ for ( Object[] row : rows ) {
+ int id = dbType.getInteger(row[0]);
+ String uuid = (String)row[1];
+ long mtime = dbType.getLong(row[2]);
+ InventoryStatus status = InventoryStatus.valueOf((String)row[3]);
+ result.add(new ResourceSyncInfo(id, uuid, mtime, status));
+ }
+ } else {
+ result = query.getResultList();
+ }
return result;
}
@@ -634,7 +664,8 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
Resource existingResource = findExistingResource(resource, null);
if (existingResource != null) {
- mergeResourceResponse = new MergeResourceResponse(existingResource.getId(),
true);
+ mergeResourceResponse = new MergeResourceResponse(existingResource.getId(),
existingResource.getMtime(),
+ true);
} else {
Subject creator = this.subjectManager.getSubjectById(creatorSubjectId);
try {
@@ -658,7 +689,7 @@ public class DiscoveryBossBean implements DiscoveryBossLocal,
DiscoveryBossRemot
throw new IllegalStateException(e);
}
- mergeResourceResponse = new MergeResourceResponse(resource.getId(), false);
+ mergeResourceResponse = new MergeResourceResponse(resource.getId(),
resource.getCtime(), false);
}
return mergeResourceResponse;
diff --git
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
index c1a745b..6bb586e 100644
---
a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
+++
b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/resource/ResourceManagerBean.java
@@ -388,9 +388,7 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
// set agent references null
// foobar the resourceKeys
// update the inventory status to UNINVENTORY
- Query toBeDeletedQuery =
entityManager.createNamedQuery(Resource.QUERY_FIND_DESCENDANTS);
- toBeDeletedQuery.setParameter("resourceId", resourceId);
- List<Integer> toBeDeletedResourceIds =
toBeDeletedQuery.getResultList();
+ List<Integer> toBeDeletedResourceIds = getDescendents(resourceId);
int i = 0;
if (isDebugEnabled) {
@@ -490,15 +488,71 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
}
@SuppressWarnings("unchecked")
+ private List<Integer> getDescendents(int resourceId) {
+ List<Integer> result = null;
+ Query query = null;
+
+ DatabaseType dbType = DatabaseTypeFactory.getDefaultDatabaseType();
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_DESCENDANTS_ORACLE);
+
+ } else if (DatabaseTypeFactory.isPostgres(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_DESCENDANTS_POSTGRES);
+
+ } else {
+ query = entityManager.createNamedQuery(Resource.QUERY_FIND_DESCENDANTS);
+ }
+
+ query.setParameter("resourceId", resourceId);
+
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ List<?> rl = query.getResultList();
+ result = new ArrayList<Integer>(rl.size());
+ for (Object id : rl) {
+ result.add(dbType.getInteger(id));
+ }
+ } else {
+ // native Integer support
+ result = query.getResultList();
+ }
+
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
public List<Integer> getResourceDescendantsByTypeAndName(Subject user, int
resourceId, Integer resourceTypeId,
String name) {
- Query descendantQuery =
entityManager.createNamedQuery(Resource.QUERY_FIND_DESCENDANTS_BY_TYPE_AND_NAME);
- descendantQuery.setParameter("resourceId", resourceId);
- descendantQuery.setParameter("resourceTypeId", resourceTypeId);
+
+ List<Integer> result = null;
+ Query query = null;
+ DatabaseType dbType = DatabaseTypeFactory.getDefaultDatabaseType();
+
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_DESCENDANTS_BY_TYPE_AND_NAME_ORACLE);
+
+ } else if (DatabaseTypeFactory.isPostgres(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_DESCENDANTS_BY_TYPE_AND_NAME_POSTGRES);
+
+ } else {
+ query =
entityManager.createNamedQuery(Resource.QUERY_FIND_DESCENDANTS_BY_TYPE_AND_NAME);
+ }
+
+ query.setParameter("resourceId", resourceId);
+ query.setParameter("resourceTypeId", ((null != resourceTypeId) ?
resourceTypeId : 0));
name = QueryUtility.formatSearchParameter(name);
- descendantQuery.setParameter("name", name);
- List<Integer> descendants = descendantQuery.getResultList();
- return descendants;
+ query.setParameter("resourceName", ((null != name) ? name :
"$$$null$$$"));
+
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ List<?> rl = query.getResultList();
+ result = new ArrayList<Integer>(rl.size());
+ for (Object id : rl) {
+ result.add(dbType.getInteger(id));
+ }
+ } else {
+ // native Integer support
+ result = query.getResultList();
+ }
+ return result;
}
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
@@ -1120,12 +1174,37 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
return sb.toString();
}
+ // Used by Portal WAR only
+ @Deprecated
@NotNull
public Resource getRootResourceForResource(int resourceId) {
- Query q =
entityManager.createNamedQuery(Resource.QUERY_FIND_ROOT_PLATFORM_OF_RESOURCE);
- q.setParameter("resourceId", resourceId);
+ Query query = null;
+ Resource result = null;
+ DatabaseType dbType = DatabaseTypeFactory.getDefaultDatabaseType();
- return (Resource) q.getSingleResult();
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_RESOURCE_PLATFORM_ORACLE);
+
+ } else if (DatabaseTypeFactory.isPostgres(dbType)) {
+ query =
entityManager.createNativeQuery(Resource.QUERY_NATIVE_FIND_RESOURCE_PLATFORM_POSTGRES);
+
+ } else {
+ query =
entityManager.createNamedQuery(Resource.QUERY_FIND_ROOT_PLATFORM_OF_RESOURCE);
+ }
+
+ query.setParameter("resourceId", resourceId);
+
+ Integer platformId;
+ if (DatabaseTypeFactory.isOracle(dbType)) {
+ platformId = dbType.getInteger(query.getSingleResult());
+
+ } else {
+ // native Integer support
+ platformId = (Integer)query.getSingleResult();
+ }
+
+ result = entityManager.find(Resource.class, platformId);
+ return result;
}
@SuppressWarnings("unchecked")
@@ -2879,14 +2958,9 @@ public class ResourceManagerBean implements ResourceManagerLocal,
ResourceManage
}
private List<Integer> getFamily(Resource resource) {
+ List<Integer> result = getDescendents(resource.getId());
- // note - this query is good only to 6 levels deep
- Query query = entityManager.createNamedQuery(Resource.QUERY_FIND_DESCENDANTS);
- query.setParameter("resourceId", resource.getId());
-
- List<Integer> resourceIds = query.getResultList();
-
- return resourceIds;
+ return result;
}
@Override
commit 31301a1f167e289814f31e2af343834544edb641
Author: Jay Shaughnessy <jshaughn(a)redhat.com>
Date: Tue Feb 25 09:45:47 2014 -0500
Added getLong() to the interface since different vendors do it differently.
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
index 9e141a8..88f1405 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/DatabaseType.java
@@ -277,8 +277,8 @@ public abstract class DatabaseType {
* Get the Integer representation of the number type supplied by the db vendor for an
integer field value.
* The default implementation simply applies a cast to the passed in number and is
appropriate for DB types
* that support a native integer field type (like Postgres). Other db types should
override this method
- * (like Oracle).
- *
+ * (like Oracle).
+ *
* @param number
* @return
*/
@@ -287,6 +287,18 @@ public abstract class DatabaseType {
}
/**
+ * Get the Long representation of the number type supplied by the db vendor for a
long field value.
+ * The default implementation simply applies a cast to the passed in number and is
appropriate for DB types
+ * that support a native long field type. Other db types should override this method
(like Oracle).
+ *
+ * @param number
+ * @return
+ */
+ public Long getLong(Object number) {
+ return (Long) number;
+ }
+
+ /**
* Fill out a <code>PreparedStatement</code> correctly with a boolean.
*
* @param bool the boolean you want
@@ -310,7 +322,7 @@ public abstract class DatabaseType {
* the implementation determined the information WITHOUT generating an SQLException
(meaning the
* transaction has not been invalidated. Otherwise, throws an exception which should
be handled.
*
- * @throws IllegalStateException if the check generated an expected "table does
not exist SQLException (note, the
+ * @throws IllegalStateException if the check generated an expected "table does
not exist SQLException (note, the
* exception invalidates the transaction).
* @throws Exception if the table check failed for a reason other than a "table
does not exist" error.
*/
@@ -646,8 +658,8 @@ public abstract class DatabaseType {
* Provides the value to be used for the ESCAPE character in string literals. The
SQL standard is a single
* character, typically '\', but not every dbType conforms to the standard.
To override the db default set
* the rhq.server.database.escape-character system property.
- *
- * @return If set, the value of rhq.server.database.escape-character, otherwise the
db default.
+ *
+ * @return If set, the value of rhq.server.database.escape-character, otherwise the
db default.
*/
public String getEscapeCharacter() {
String result =
System.getProperty("rhq.server.database.escape-character");
@@ -658,7 +670,7 @@ public abstract class DatabaseType {
/**
* Most vendors support foreign keys to itself that in fact perform cascade delete.
But some do not and
* that currently affects our data model. (see rhq_config_property in
content-schema.xml).
- *
+ *
* @return true unless overriden to return false.
*/
public boolean supportsSelfReferringCascade() {
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
index 15ee0af..0e0fb2a 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/OracleDatabaseType.java
@@ -64,9 +64,9 @@ public abstract class OracleDatabaseType extends DatabaseType {
/* (non-Javadoc)
* @see org.rhq.core.db.DatabaseType#getInteger(java.lang.Object)
- *
+ *
* Oracle stores integer fields as Numbers and returns a BigDecimal. It is assumed
<code>number</code> is actually
- * an integer value, otherwise precision will be lost in this conversion.
+ * an integer value, otherwise precision will be lost in this conversion.
*/
@Override
public Integer getInteger(Object number) {
@@ -74,6 +74,18 @@ public abstract class OracleDatabaseType extends DatabaseType {
return intField.intValue();
}
+ /* (non-Javadoc)
+ * @see org.rhq.core.db.DatabaseType#getLong(java.lang.Object)
+ *
+ * Oracle stores long fields as Numbers and returns a BigDecimal. It is assumed
<code>number</code> is actually
+ * a long value, otherwise precision will be lost in this conversion.
+ */
+ @Override
+ public Long getLong(Object number) {
+ BigDecimal longField = (BigDecimal) number;
+ return longField.longValue();
+ }
+
/**
* For Oracle databases, the boolean parameter will actually be of type
"int" with a value of 0 or 1.
*
diff --git
a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
index 4d376f3..a1594dc 100644
--- a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
+++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java
@@ -18,6 +18,7 @@
*/
package org.rhq.core.db;
+import java.math.BigInteger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
@@ -42,10 +43,12 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
*
* @see DatabaseType#getVendor()
*/
+ @Override
public String getVendor() {
return VENDOR_NAME;
}
+ @Override
public String getHibernateDialect() {
return "org.hibernate.dialect.PostgreSQLDialect";
}
@@ -53,6 +56,7 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
/**
* @see DatabaseType#isTableNotFoundException(SQLException)
*/
+ @Override
public boolean isTableNotFoundException(SQLException e) {
return (e.getSQLState().toUpperCase().equals("42P01"));
}
@@ -63,6 +67,7 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
*
* @see DatabaseType#getSequenceValue(Connection, String, String)
*/
+ @Override
public int getSequenceValue(Connection conn, String table, String key) throws
SQLException {
String query = "SELECT currval('" + table + "_" + key +
"_seq')";
PreparedStatement selectPS = null;
@@ -86,6 +91,7 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
/**
* @see DatabaseType#getNextSequenceValue(Connection, String, String)
*/
+ @Override
public int getNextSequenceValue(Connection conn, String table, String key) throws
SQLException {
String query = "SELECT nextval('" + table + "_" + key +
"_seq'::text)";
@@ -110,6 +116,7 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
/**
* @see DatabaseType#alterColumn(Connection, String, String, String, String, String,
Boolean, Boolean)
*/
+ @Override
public void alterColumn(Connection conn, String table, String column, String
generic_column_type,
String default_value, String precision, Boolean nullable, Boolean reindex) throws
SQLException {
String db_column_type = null;
@@ -150,6 +157,7 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
/**
* @see DatabaseType#reindexTable(Connection, String)
*/
+ @Override
public void reindexTable(Connection conn, String table) throws SQLException {
executeSql(conn, "REINDEX TABLE " + table);
}
@@ -162,13 +170,26 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
* Note 1: The default behavior may change in a future version of postgres given
that
* the standard_conforming_strings setting may change from 'off' to
'on' out of the box.
* Note 2: Also related,
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674 for more.
- *
+ *
* @see DatabaseType#getEscapeCharacter()
*/
+ @Override
public String getEscapeCharacter() {
String result =
System.getProperty("rhq.server.database.escape-character");
return (null == result) ? "\\\\" : result;
}
+ /* (non-Javadoc)
+ * @see org.rhq.core.db.DatabaseType#getLong(java.lang.Object)
+ *
+ * Postgres stores long fields as BigInteger and returns a BigInteger. It is assumed
<code>number</code> is actually
+ * a long value, otherwise precision will be lost in this conversion.
+ */
+ @Override
+ public Long getLong(Object number) {
+ BigInteger longField = (BigInteger) number;
+ return longField.longValue();
+ }
+
}
\ No newline at end of file