Fix to SF bug #1827521 - recent submissions not showing sub-community submissions.

- adds communities2item table maintenance back into browse, includes new SQL to query the community hierarchy more efficiently than the Item/Community API
- by extension, fixes a problem where items in an upgraded database can't be deleted due to their existence in communities2item
- also, changes Harvest to use communities2item instead of community2item, so RSS feeds will work on the same basis of recent submissions, and include the sub-community content

git-svn-id: http://scm.dspace.org/svn/repo/branches/dspace-1_5_x@2447 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Graham Triggs
2007-12-16 22:41:40 +00:00
parent 1b2178a688
commit 3b4e9a778e
8 changed files with 395 additions and 101 deletions

View File

@@ -79,6 +79,9 @@ public interface BrowseCreateDAO
* @throws BrowseException * @throws BrowseException
*/ */
public void deleteByItemID(String table, int itemID) throws BrowseException; public void deleteByItemID(String table, int itemID) throws BrowseException;
public void deleteCommunityMappings(int itemID) throws BrowseException;
public void insertCommunityMappings(int itemID) throws BrowseException;
/** /**
* Insert an index record into the given table for the given item id. The Map should contain * Insert an index record into the given table for the given item id. The Map should contain

View File

@@ -132,9 +132,9 @@ public class BrowseCreateDAOOracle implements BrowseCreateDAO
try try
{ {
String createComView = "CREATE VIEW " + view + " AS " + String createComView = "CREATE VIEW " + view + " AS " +
"SELECT Community2Item.community_id, " + table + ".* " + "SELECT Communities2Item.community_id, " + table + ".* " +
"FROM " + table + ", Community2Item " + "FROM " + table + ", Communities2Item " +
"WHERE " + table + ".item_id = Community2Item.item_id"; "WHERE " + table + ".item_id = Communities2Item.item_id";
if (execute) if (execute)
{ {
@@ -371,6 +371,25 @@ public class BrowseCreateDAOOracle implements BrowseCreateDAO
} }
/* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#deleteCommunityMappings(java.lang.String, int)
*/
public void deleteCommunityMappings(int itemID)
throws BrowseException
{
try
{
Object[] params = { new Integer(itemID) };
String dquery = "DELETE FROM Communities2Item WHERE item_id = ?";
DatabaseManager.updateQuery(context, dquery, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new BrowseException(e);
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#dropIndexAndRelated(java.lang.String, boolean) * @see org.dspace.browse.BrowseCreateDAO#dropIndexAndRelated(java.lang.String, boolean)
*/ */
@@ -495,6 +514,30 @@ public class BrowseCreateDAOOracle implements BrowseCreateDAO
} }
} }
/* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#insertCommunityMappings(java.lang.String, java.lang.String, java.lang.String)
*/
public void insertCommunityMappings(int itemID) throws BrowseException
{
try
{
int[] commID = getAllCommunityIDs(itemID);
for (int i = 0; i < commID.length; i++)
{
TableRow row = DatabaseManager.create(context, "Communities2Item");
row.setColumn("item_id", itemID);
row.setColumn("community_id", commID[i]);
DatabaseManager.update(context, row);
}
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new BrowseException(e);
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#insertDistinctRecord(java.lang.String, java.lang.String, java.lang.String) * @see org.dspace.browse.BrowseCreateDAO#insertDistinctRecord(java.lang.String, java.lang.String, java.lang.String)
*/ */
@@ -751,4 +794,89 @@ public class BrowseCreateDAOOracle implements BrowseCreateDAO
return false; return false;
} }
/**
* perform a database query to get all the communities that this item belongs to,
* including all mapped communities, and ancestors
*
* this is done here instead of using the Item api, because for reindexing we may
* not have Item objects, and in any case this is *much* faster
*
* @param itemId
* @return
* @throws SQLException
*/
private int[] getAllCommunityIDs(int itemId) throws SQLException
{
List<Integer> commIdList = new ArrayList<Integer>();
TableRowIterator tri = null;
try
{
tri = DatabaseManager.queryTable(context, "Community2Item",
"SELECT * FROM Community2Item WHERE item_id=?", itemId);
while (tri.hasNext())
{
TableRow row = tri.next();
int commId = row.getIntColumn("community_id");
commIdList.add(commId);
// Get the parent community, and continue to get all ancestors
Integer parentId = getParentCommunityID(commId);
while (parentId != null)
{
commIdList.add(parentId);
parentId = getParentCommunityID(parentId);
}
}
}
finally
{
if (tri != null)
tri.close();
}
// Need to iterate the array as toArray will produce an array Integers,
// not ints as we need.
int[] cIds = new int[commIdList.size()];
for (int i = 0; i < commIdList.size(); i++)
{
cIds[i] = commIdList.get(i);
}
return cIds;
}
/**
* Get the id of the parent community. Returns Integer, as null is used to
* signify that there are no parents (ie. top-level).
*
* @param commId
* @return
* @throws SQLException
*/
private Integer getParentCommunityID(int commId) throws SQLException
{
TableRowIterator tri = null;
try
{
tri = DatabaseManager.queryTable(context, "Community2Community",
"SELECT * FROM Community2Community WHERE child_comm_id=?", commId);
if (tri.hasNext())
{
return tri.next().getIntColumn("parent_comm_id");
}
}
finally
{
if (tri != null)
tri.close();
}
return null;
}
} }

View File

@@ -127,9 +127,9 @@ public class BrowseCreateDAOPostgres implements BrowseCreateDAO
try try
{ {
String createComView = "CREATE VIEW " + view + " as " + String createComView = "CREATE VIEW " + view + " as " +
"SELECT Community2Item.community_id, " + table + ".* " + "SELECT Communities2Item.community_id, " + table + ".* " +
"FROM " + table + ", Community2Item " + "FROM " + table + ", Communities2Item " +
"WHERE " + table + ".item_id = Community2Item.item_id;"; "WHERE " + table + ".item_id = Communities2Item.item_id;";
if (execute) if (execute)
{ {
@@ -375,6 +375,25 @@ public class BrowseCreateDAOPostgres implements BrowseCreateDAO
} }
} }
/* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#deleteCommunityMappings(java.lang.String, int)
*/
public void deleteCommunityMappings(int itemID)
throws BrowseException
{
try
{
Object[] params = { new Integer(itemID) };
String dquery = "DELETE FROM Communities2Item WHERE item_id = ?";
DatabaseManager.updateQuery(context, dquery, params);
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new BrowseException(e);
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#dropIndexAndRelated(java.lang.String, boolean) * @see org.dspace.browse.BrowseCreateDAO#dropIndexAndRelated(java.lang.String, boolean)
*/ */
@@ -496,7 +515,31 @@ public class BrowseCreateDAOPostgres implements BrowseCreateDAO
} }
} }
} }
/* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#insertCommunityMappings(java.lang.String, java.lang.String, java.lang.String)
*/
public void insertCommunityMappings(int itemID) throws BrowseException
{
try
{
int[] commID = getAllCommunityIDs(itemID);
for (int i = 0; i < commID.length; i++)
{
TableRow row = DatabaseManager.create(context, "Communities2Item");
row.setColumn("item_id", itemID);
row.setColumn("community_id", commID[i]);
DatabaseManager.update(context, row);
}
}
catch (SQLException e)
{
log.error("caught exception: ", e);
throw new BrowseException(e);
}
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.dspace.browse.BrowseCreateDAO#insertDistinctRecord(java.lang.String, java.lang.String, java.lang.String) * @see org.dspace.browse.BrowseCreateDAO#insertDistinctRecord(java.lang.String, java.lang.String, java.lang.String)
*/ */
@@ -704,4 +747,89 @@ public class BrowseCreateDAOPostgres implements BrowseCreateDAO
return " VARCHAR(" + size + ") "; return " VARCHAR(" + size + ") ";
} }
/**
* perform a database query to get all the communities that this item belongs to,
* including all mapped communities, and ancestors
*
* this is done here instead of using the Item api, because for reindexing we may
* not have Item objects, and in any case this is *much* faster
*
* @param itemId
* @return
* @throws SQLException
*/
private int[] getAllCommunityIDs(int itemId) throws SQLException
{
List<Integer> commIdList = new ArrayList<Integer>();
TableRowIterator tri = null;
try
{
tri = DatabaseManager.queryTable(context, "Community2Item",
"SELECT * FROM Community2Item WHERE item_id=?", itemId);
while (tri.hasNext())
{
TableRow row = tri.next();
int commId = row.getIntColumn("community_id");
commIdList.add(commId);
// Get the parent community, and continue to get all ancestors
Integer parentId = getParentCommunityID(commId);
while (parentId != null)
{
commIdList.add(parentId);
parentId = getParentCommunityID(parentId);
}
}
}
finally
{
if (tri != null)
tri.close();
}
// Need to iterate the array as toArray will produce an array Integers,
// not ints as we need.
int[] cIds = new int[commIdList.size()];
for (int i = 0; i < commIdList.size(); i++)
{
cIds[i] = commIdList.get(i);
}
return cIds;
}
/**
* Get the id of the parent community. Returns Integer, as null is used to
* signify that there are no parents (ie. top-level).
*
* @param commId
* @return
* @throws SQLException
*/
private Integer getParentCommunityID(int commId) throws SQLException
{
TableRowIterator tri = null;
try
{
tri = DatabaseManager.queryTable(context, "Community2Community",
"SELECT * FROM Community2Community WHERE child_comm_id=?", commId);
if (tri.hasNext())
{
return tri.next().getIntColumn("parent_comm_id");
}
}
finally
{
if (tri != null)
tri.close();
}
return null;
}
} }

View File

@@ -641,16 +641,12 @@ public class BrowseIndex
throws BrowseException throws BrowseException
{ {
BrowseIndex[] bis = getBrowseIndices(); BrowseIndex[] bis = getBrowseIndices();
String[] returnTables = new String[bis.length + 1]; String[] returnTables = new String[bis.length];
for (int i = 0; i < bis.length; i++) for (int i = 0; i < bis.length; i++)
{ {
returnTables[i] = bis[i].getTableName(); returnTables[i] = bis[i].getTableName();
} }
// FIXME: this complies with the old BrowseTables method, but I'm
// not really sure why it's here
returnTables[bis.length] = "Communities2Item";
return returnTables; return returnTables;
} }

View File

@@ -44,6 +44,7 @@ import org.dspace.content.Item;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class BrowseItemDAOOracle implements BrowseItemDAO public class BrowseItemDAOOracle implements BrowseItemDAO
{ {
@@ -87,61 +88,78 @@ public class BrowseItemDAOOracle implements BrowseItemDAO
public BrowseItem[] findAll() throws SQLException public BrowseItem[] findAll() throws SQLException
{ {
TableRowIterator tri = DatabaseManager.query(context, findAll); TableRowIterator tri = null;
ArrayList items = new ArrayList(); List<BrowseItem> items = new ArrayList<BrowseItem>();
while (tri.hasNext()) try
{ {
TableRow row = tri.next(); tri = DatabaseManager.query(context, findAll);
items.add(new BrowseItem(context, row.getIntColumn("item_id"), while (tri.hasNext())
row.getBooleanColumn("in_archive"), {
row.getBooleanColumn("withdrawn"))); TableRow row = tri.next();
items.add(new BrowseItem(context, row.getIntColumn("item_id"),
row.getBooleanColumn("in_archive"),
row.getBooleanColumn("withdrawn")));
}
}
finally
{
if (tri != null)
tri.close();
} }
BrowseItem[] bis = new BrowseItem[items.size()]; BrowseItem[] bis = new BrowseItem[items.size()];
return (BrowseItem[]) items.toArray((BrowseItem[]) bis); return items.toArray(bis);
} }
public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang) public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang)
throws SQLException throws SQLException
{ {
ArrayList values = new ArrayList(); List<DCValue> values = new ArrayList<DCValue>();
TableRowIterator tri; TableRowIterator tri = null;
if (qualifier == null) try
{ {
Object[] params = { new Integer(itemId), element, schema }; if (qualifier == null)
tri = DatabaseManager.query(context, getByMetadataElement, params); {
} Object[] params = { new Integer(itemId), element, schema };
else if (Item.ANY.equals(qualifier)) tri = DatabaseManager.query(context, getByMetadataElement, params);
{ }
Object[] params = { new Integer(itemId), element, schema }; else if (Item.ANY.equals(qualifier))
tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); {
} Object[] params = { new Integer(itemId), element, schema };
else tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params);
{ }
Object[] params = { new Integer(itemId), element, qualifier, schema }; else
tri = DatabaseManager.query(context, getByMetadata, params); {
} Object[] params = { new Integer(itemId), element, qualifier, schema };
tri = DatabaseManager.query(context, getByMetadata, params);
}
if (!tri.hasNext()) if (!tri.hasNext())
{ {
return null; return null;
} }
while (tri.hasNext()) while (tri.hasNext())
{ {
TableRow tr = tri.next(); TableRow tr = tri.next();
DCValue dcv = new DCValue(); DCValue dcv = new DCValue();
dcv.schema = schema; dcv.schema = schema;
dcv.element = tr.getStringColumn("element"); dcv.element = tr.getStringColumn("element");
dcv.qualifier = tr.getStringColumn("qualifier"); dcv.qualifier = tr.getStringColumn("qualifier");
dcv.language = tr.getStringColumn("text_lang"); dcv.language = tr.getStringColumn("text_lang");
dcv.value = tr.getStringColumn("text_value"); dcv.value = tr.getStringColumn("text_value");
values.add(dcv); values.add(dcv);
} }
}
finally
{
if (tri != null)
tri.close();
}
DCValue[] dcvs = new DCValue[values.size()]; DCValue[] dcvs = new DCValue[values.size()];
return (DCValue[]) values.toArray(dcvs); return values.toArray(dcvs);
} }
} }

View File

@@ -44,6 +44,7 @@ import org.dspace.content.Item;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
public class BrowseItemDAOPostgres implements BrowseItemDAO public class BrowseItemDAOPostgres implements BrowseItemDAO
{ {
@@ -87,61 +88,78 @@ public class BrowseItemDAOPostgres implements BrowseItemDAO
public BrowseItem[] findAll() throws SQLException public BrowseItem[] findAll() throws SQLException
{ {
TableRowIterator tri = DatabaseManager.query(context, findAll); TableRowIterator tri = null;
ArrayList items = new ArrayList(); List<BrowseItem> items = new ArrayList<BrowseItem>();
while (tri.hasNext()) try
{ {
TableRow row = tri.next(); tri = DatabaseManager.query(context, findAll);
items.add(new BrowseItem(context, row.getIntColumn("item_id"), while (tri.hasNext())
row.getBooleanColumn("in_archive"), {
row.getBooleanColumn("withdrawn"))); TableRow row = tri.next();
items.add(new BrowseItem(context, row.getIntColumn("item_id"),
row.getBooleanColumn("in_archive"),
row.getBooleanColumn("withdrawn")));
}
} }
finally
{
if (tri != null)
tri.close();
}
BrowseItem[] bis = new BrowseItem[items.size()]; BrowseItem[] bis = new BrowseItem[items.size()];
return (BrowseItem[]) items.toArray((BrowseItem[]) bis); return items.toArray(bis);
} }
public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang) public DCValue[] queryMetadata(int itemId, String schema, String element, String qualifier, String lang)
throws SQLException throws SQLException
{ {
ArrayList values = new ArrayList(); List<DCValue> values = new ArrayList<DCValue>();
TableRowIterator tri; TableRowIterator tri = null;
if (qualifier == null) try
{ {
Object[] params = { new Integer(itemId), element, schema }; if (qualifier == null)
tri = DatabaseManager.query(context, getByMetadataElement, params); {
} Object[] params = { new Integer(itemId), element, schema };
else if (Item.ANY.equals(qualifier)) tri = DatabaseManager.query(context, getByMetadataElement, params);
{ }
Object[] params = { new Integer(itemId), element, schema }; else if (Item.ANY.equals(qualifier))
tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params); {
} Object[] params = { new Integer(itemId), element, schema };
else tri = DatabaseManager.query(context, getByMetadataAnyQualifier, params);
{ }
Object[] params = { new Integer(itemId), element, qualifier, schema }; else
tri = DatabaseManager.query(context, getByMetadata, params); {
} Object[] params = { new Integer(itemId), element, qualifier, schema };
tri = DatabaseManager.query(context, getByMetadata, params);
}
if (!tri.hasNext()) if (!tri.hasNext())
{ {
return null; return null;
} }
while (tri.hasNext())
{
TableRow tr = tri.next();
DCValue dcv = new DCValue();
dcv.schema = schema;
dcv.element = tr.getStringColumn("element");
dcv.qualifier = tr.getStringColumn("qualifier");
dcv.language = tr.getStringColumn("text_lang");
dcv.value = tr.getStringColumn("text_value");
values.add(dcv);
}
while (tri.hasNext())
{
TableRow tr = tri.next();
DCValue dcv = new DCValue();
dcv.schema = schema;
dcv.element = tr.getStringColumn("element");
dcv.qualifier = tr.getStringColumn("qualifier");
dcv.language = tr.getStringColumn("text_lang");
dcv.value = tr.getStringColumn("text_value");
values.add(dcv);
}
}
finally
{
if (tri != null)
tri.close();
}
DCValue[] dcvs = new DCValue[values.size()]; DCValue[] dcvs = new DCValue[values.size()];
return (DCValue[]) values.toArray(dcvs); return values.toArray(dcvs);
} }
} }

View File

@@ -102,8 +102,8 @@ public class IndexBrowse
/** the DAO for write operations on the database */ /** the DAO for write operations on the database */
private BrowseCreateDAO dao; private BrowseCreateDAO dao;
/** the outputter class */ /** the outputter class */
private BrowseOutput output; private BrowseOutput output;
/** /**
@@ -392,12 +392,14 @@ public class IndexBrowse
// Remove from the item indexes (archive and withdrawn) // Remove from the item indexes (archive and withdrawn)
removeIndex(item.getID(), BrowseIndex.getItemBrowseIndex().getTableName()); removeIndex(item.getID(), BrowseIndex.getItemBrowseIndex().getTableName());
removeIndex(item.getID(), BrowseIndex.getWithdrawnBrowseIndex().getTableName()); removeIndex(item.getID(), BrowseIndex.getWithdrawnBrowseIndex().getTableName());
dao.deleteCommunityMappings(item.getID());
// Index any archived item that isn't withdrawn // Index any archived item that isn't withdrawn
if (item.isArchived() && !item.isWithdrawn()) if (item.isArchived() && !item.isWithdrawn())
{ {
Map<Integer, String> sortMap = getSortValues(item, itemMDMap); Map<Integer, String> sortMap = getSortValues(item, itemMDMap);
dao.insertIndex(BrowseIndex.getItemBrowseIndex().getTableName(), item.getID(), sortMap); dao.insertIndex(BrowseIndex.getItemBrowseIndex().getTableName(), item.getID(), sortMap);
dao.insertCommunityMappings(item.getID());
} }
else if (item.isWithdrawn()) else if (item.isWithdrawn())
{ {
@@ -557,6 +559,7 @@ public class IndexBrowse
// Remove from the item indexes (archive and withdrawn) // Remove from the item indexes (archive and withdrawn)
removeIndex(item.getID(), BrowseIndex.getItemBrowseIndex().getTableName()); removeIndex(item.getID(), BrowseIndex.getItemBrowseIndex().getTableName());
removeIndex(item.getID(), BrowseIndex.getWithdrawnBrowseIndex().getTableName()); removeIndex(item.getID(), BrowseIndex.getWithdrawnBrowseIndex().getTableName());
dao.deleteCommunityMappings(item.getID());
// Ensure that we remove any invalid entries // Ensure that we remove any invalid entries
pruneIndexes(); pruneIndexes();

View File

@@ -142,7 +142,7 @@ public class Harvest
} }
else if (scope.getType() == Constants.COMMUNITY) else if (scope.getType() == Constants.COMMUNITY)
{ {
query += ", community2item"; query += ", communities2item";
} }
} }
@@ -158,8 +158,8 @@ public class Harvest
} }
else if (scope.getType() == Constants.COMMUNITY) else if (scope.getType() == Constants.COMMUNITY)
{ {
query += " AND community2item.community_id= ? " + query += " AND communities2item.community_id= ? " +
" AND community2item.item_id=handle.resource_id"; " AND communities2item.item_id=handle.resource_id";
parameters.add(new Integer(scope.getID())); parameters.add(new Integer(scope.getID()));
} }
} }