diff --git a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java index bbf9a3f839..b04b683492 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java +++ b/dspace-api/src/main/java/org/dspace/identifier/DOIIdentifierProvider.java @@ -51,6 +51,9 @@ public class DOIIdentifierProvider public static final String DOI_ELEMENT = "identifier"; public static final String DOI_QUALIFIER = null; + // How many times do we want to try to find a new unique DOI? + private static final int THRESHOLD_UNIQUE_DOI = 1000; + /** * Prefix of DOI namespace. Set in dspace.cfg. */ @@ -153,42 +156,53 @@ public class DOIIdentifierProvider { String doi = formatIdentifier(identifier); - // check if the DOI is already registered for this dso - if (connector.isDOIRegistered(context, dso, doi)) - return; + TableRow doiRow = null; - // check if DOI is registered for another object - if (connector.isDOIRegistered(context, doi)) - { - log.warn("Trying to register DOI {}, that is already registered.", doi); - throw new IdentifierException("Trying to register a DOI that is " - + "registered for another object."); - } - - // check if doi is reserved for this specific dso - if (!connector.isDOIReserved(context, dso, doi)) - { - // check if doi is already reserved for another dso - if (connector.isDOIReserved(context, doi)) - { - log.warn("Trying to register DOI {}, that is reserved for " - + "another dso.", doi); - throw new IdentifierException("Trying to register a DOI " + - "that is reserved for another object."); + String status; + + if (null != doi) { + try { + // get DOI object from Database + // remove DOI.SCHEME before searching in DB. + doiRow = DatabaseManager.findByUnique(context, "Doi", + "doi", doi.substring(DOI.SCHEME.length())); + + + if (null == doiRow) { + try { + createNewIdentifier(context, dso, doi); + } + catch (Exception e) + { + // TODO: better exception handling + throw new RuntimeException(e); + } + log.warn("Trying to register DOI {}, that not exist in DB.", doi); + + } else { + + if (doiRow.getIntColumn("resource_id") != dso.getID() + || doiRow.getIntColumn("resource_type_id") != dso.getType()) { + + throw new IdentifierException("Trying to reserve a DOI " + + "that is reserved for another object."); + } + + if ("isRegistered".equals(doiRow.getStringColumn("status"))) + { + return; + } + + doiRow.setColumn("status", "toBeRegistered"); + DatabaseManager.update(context, doiRow); + } + } catch (SQLException ex) { + log.error("Error while trying to change doi status " + + dso.getTypeText() + " with ID " + dso.getID() + "."); + throw new RuntimeException("Error while while trying to change doi status " + + "for a DOI " + dso.getTypeText() + + " with ID " + dso.getID() + ".", ex); } - - - if(!connector.reserveDOI(context, dso, doi)) - { - throw new IdentifierException("It was impossible to reserve the DOI " - + doi + ". Take a look into the logs for further details."); - } - } - - if (!connector.registerDOI(context, dso, doi)) - { - throw new IdentifierException("It was impossible to register the DOI " - + doi + ". Take a look into the logs for further details."); } try { @@ -231,40 +245,138 @@ public class DOIIdentifierProvider { String doi = formatIdentifier(identifier); + TableRow doiRow = null; + + // ensure that the DOI is in our DOI table and is not reserved online // for another object than dso try { createNewIdentifier(context, dso, doi); - } - catch (IllegalArgumentException ex) - { + + doiRow = DatabaseManager.findByUnique(context, "Doi", + "doi", doi.substring(DOI.SCHEME.length())); + + if (null == doiRow) { + log.warn("Trying to reserve DOI {}, that not exist in DB.", doi); + throw new IdentifierException("Trying to reserve a DOI " + + "that not exist in DB."); + } else { + + if (doiRow.getIntColumn("resource_id") != dso.getID() + || doiRow.getIntColumn("resource_type_id") != dso.getType()) { + + throw new IdentifierException("Trying to reserve a DOI " + + "that is reserved for another object."); + } + + if (!doiRow.isColumnNull("status")) { + return; + } + + doiRow.setColumn("status", "toBeReserved"); + DatabaseManager.update(context, doiRow); + + } + } catch (IllegalArgumentException ex) { throw new IdentifierException("DOI is reserved for another object."); - } - catch (SQLException ex) - { + } catch (SQLException ex) { throw new RuntimeException("Error in database connection: " + ex.getMessage()); } + + } + + public void reserveDOIOnline(Context context, DSpaceObject dso, String identifier) + throws IdentifierException, IllegalArgumentException, SQLException { + String doi = formatIdentifier(identifier); + // ensure that the DOI is in our DOI table and is not reserved online + // for another object than dso + try { + createNewIdentifier(context, dso, doi); + } catch (IllegalArgumentException ex) { + throw new IdentifierException("DOI is reserved for another object."); + } catch (SQLException ex) { + throw new RuntimeException("Error in database connection: " + ex.getMessage()); + } + // check if DOI is reserved at the registration agency for the specific dso - if (!connector.isDOIReserved(context, dso, doi)) + if (connector.isDOIReserved(context, dso, doi)) { + // TODO: Send metadata update anyway! + return; + } + + // check if doi is already reserved for another object + if (connector.isDOIReserved(context, doi)) { + log.warn("Trying to reserve a DOI {} that is reserved for " + + "another object.", doi); + throw new IdentifierException("Trying to reserve a DOI " + + "that is reserved for another object."); + } + + // try to reserve the doi + if (!connector.reserveDOI(context, dso, doi)) { + throw new IdentifierException("It was impossible to reserve the DOI " + + doi + ". Take a look into the logs for further details."); + } + else { - // check if doi is already reserved for another object - if (connector.isDOIReserved(context, doi)) - { - log.warn("Trying to reserve a DOI {} that is reserved for " - + "another object.", doi); - throw new IdentifierException("Trying to reserve a DOI " + - "that is reserved for another object."); + TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", + "doi", doi.substring(DOI.SCHEME.length())); + doiRow.setColumn("status", "isReserved"); + try { + DatabaseManager.update(context, doiRow); + } catch (SQLException se) { ///muss ich sehenn + System.err.println("Caught SQLException: " + se.getMessage()); + se.printStackTrace(System.err); + throw se; } - // try to reserve the doi - if(!connector.reserveDOI(context, dso, doi)) - { + } + } + + public void registeredDOIOnline(Context context, DSpaceObject dso, String identifier) + throws IdentifierException, IllegalArgumentException, SQLException { + String doi = formatIdentifier(identifier); + // check if the DOI is already registered for this dso + if (connector.isDOIRegistered(context, dso, doi)) + { + return; + } + + // check if DOI is registered for another object + if (connector.isDOIRegistered(context, doi)) { + log.warn("Trying to register DOI {}, that is already registered.", doi); + throw new IdentifierException("Trying to register a DOI that is " + + "registered for another object."); + } + + // check if doi is reserved for this specific dso + if (!connector.isDOIReserved(context, dso, doi)) { + // check if doi is already reserved for another dso + if (connector.isDOIReserved(context, doi)) { + log.warn("Trying to register DOI {}, that is reserved for " + + "another dso.", doi); + throw new IdentifierException("Trying to register a DOI " + + "that is reserved for another object."); + } + + if (!connector.reserveDOI(context, dso, doi)) { throw new IdentifierException("It was impossible to reserve the DOI " + doi + ". Take a look into the logs for further details."); } } + + if (!connector.registerDOI(context, dso, doi)) { + throw new IdentifierException("It was impossible to register the DOI " + + doi + ". Take a look into the logs for further details."); + } else { + TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", + "doi", doi.substring(DOI.SCHEME.length())); + doiRow.setColumn("status", "isRegistered"); + DatabaseManager.update(context, doiRow); + } + } - + @Override public String mint(Context context, DSpaceObject dso) throws IdentifierException @@ -479,9 +591,9 @@ public class DOIIdentifierProvider */ public static String formatIdentifier(String identifier) throws IdentifierException { - if (null == identifier) + if (null == identifier) throw new IllegalArgumentException("Identifier is null.", new NullPointerException()); - if (identifier.startsWith("doi:")) + if (identifier.startsWith("doi:")) return identifier; if (identifier.isEmpty()) throw new IllegalArgumentException("Cannot format an empty identifier."); @@ -616,14 +728,37 @@ public class DOIIdentifierProvider "that's not part of our Namespace!"); } else - doi = this.getPrefix() + "/" + this.getNamespaceSeparator() + + { + // We need to generate a new DOI. + // We can register a DOI that was not minted, so we can have DOIs + // that have not the suffix of the doi_id column. + // Generate a new doi_id and check if we already have a DOI with the + // same suffix. Try max. THRESHOLD_UNIQUE_DOI times. + int i = 0; + for ( ; i < THRESHOLD_UNIQUE_DOI ; ++i) + { + doi = this.getPrefix() + "/" + this.getNamespaceSeparator() + doiRow.getIntColumn("doi_id"); - + if (null == DatabaseManager.findByUnique(context, "Doi", "doi", doi)) + { + break; + } + doiRow = DatabaseManager.create(context, "Doi"); + } + if (null != DatabaseManager.findByUnique(context, "Doi", "doi", doi)) + { + // We were unable to find a new DOI that does noch already exist. + // TODO: throw usefull Exception + throw new RuntimeException(); + } + } + doiRow.setColumn("doi", doi); doiRow.setColumn("resource_type_id", dso.getType()); doiRow.setColumn("resource_id", dso.getID()); + doiRow.setColumnNull("status"); DatabaseManager.update(context, doiRow); - + return DOI.SCHEME + doi; } diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java new file mode 100644 index 0000000000..52e0f6af6f --- /dev/null +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DOIOrganiser.java @@ -0,0 +1,366 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +package org.dspace.identifier.doi; + +import java.sql.SQLException; +import java.util.logging.Level; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.Option; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; +import org.apache.log4j.Logger; +import org.dspace.authorize.AuthorizeException; +import org.dspace.content.DSpaceObject; +import org.dspace.core.Constants; +import org.dspace.core.Context; +import org.dspace.identifier.DOI; +import org.dspace.identifier.DOIIdentifierProvider; +import org.dspace.identifier.IdentifierException; +import org.dspace.storage.rdbms.DatabaseManager; +import org.dspace.storage.rdbms.TableRow; +import org.dspace.storage.rdbms.TableRowIterator; +import org.dspace.utils.DSpace; + +/** + * + * @author Marsa Haoua + */ +public class DOIOrganiser { + + private static final Logger LOG = Logger.getLogger(DOIOrganiser.class); + + /** + * DSpace Context object + */ + //private Context context; + + /** + * Blanked off constructor, this class should be used as a command line + * tool. + * + */ + private DOIOrganiser() + // throws SQLException + { + // context = new Context(); + } + + public static void main(String[] args) + { + LOG.info("Starting DOI organiser "); + + // set up command line and Command line parser + CommandLineParser parser = new PosixParser(); + CommandLine line = null; + + // create an options object + Options options = new Options(); + + // add option to options + + options.addOption("h", "help", false, "Help"); + options.addOption("l", "list", false, + "List all objects to be reserved or registered "); + options.addOption("r", "register", false, + "register all to be registered identifiers online."); + options.addOption("s", "reserve", false, + "Reserve all to be reserved identifiers online.\n"); + + Option registerDoi = OptionBuilder.withArgName("DOI identifier") + .hasArgs(1) + .withDescription("Register an identifier online. " + + "An DOI identifier is needed.").create('g'); + + options.addOption(registerDoi); + + Option reserveDoi = OptionBuilder.withArgName("DOI identifier") + .hasArgs(1) + .withDescription("Reserve an identifier online." + + " An DOI identifier is needed. ").create('v'); + + options.addOption(reserveDoi); + + Option registerByItemOrHandle = OptionBuilder.withArgName("ItemID or Handle") + .hasArgs(1) + .withDescription("Reserve an identifier for a given ItemID or Handle." + + " An ItemID or a Handle is needed. ").create('t'); + + options.addOption(registerByItemOrHandle); + + Option reserveByItemOrHandle = OptionBuilder.withArgName("ItemID or Handle") + .hasArgs(1) + .withDescription("Reserve an identifier for a given ItemID or Handle." + + " An ItemID or a Handle is needed. ").create('i'); + + options.addOption(reserveByItemOrHandle); + + Context context = null; + try { + context = new Context(); + } + catch (SQLException sqle) + { + System.err.println("Can't connect to database: " + sqle.getMessage()); + System.exit(-1); + } + // Started from commandline, don't use the authentication system. + context.turnOffAuthorisationSystem(); + + try + { + line = parser.parse(options, args); + } + catch (ParseException ex) + { + LOG.fatal(ex); + System.exit(1); + } + + // user asks for help + if (line.hasOption('h')) + { + printHelp(options); + } + + if (line.hasOption('l')) + { + listDoiTable(context); + } + + if (line.hasOption('s')) + { + doiRequest(context, "toBeReserved"); + } + + if (line.hasOption('r')) + { + doiRequest(context, "toBeRegistered"); + } + + if(line.hasOption('g')){ + String identifier = line.getOptionValue('g'); + if(null == identifier){ + LOG.info("A DOI identifier is needed"); + throw new IllegalArgumentException("Identifier is null.", new NullPointerException()); + }else{ + doiRequestByDOI(context, identifier,"toBeRegistered"); + } + } + if(line.hasOption('v')){ + String identifier = line.getOptionValue('v'); + if(null == identifier){ + LOG.info("A DOI identifier is needed"); + throw new IllegalArgumentException("Identifier is null.", new NullPointerException()); + } + else + { + doiRequestByDOI(context, identifier,"toBeReserved"); + } + } + if(line.hasOption('t')){ + String itemID_Hdl = line.getOptionValue('t'); + if(null == itemID_Hdl){ + LOG.info("A ItemID or a Handle is needed"); + throw new IllegalArgumentException("ItemID or Handle is null.", new NullPointerException()); + } + else + { + doiRequestByItemID_Handle(context, itemID_Hdl,"toBeRegistered"); + } + } + if(line.hasOption('i')){ + String itemID_Hdl = line.getOptionValue('i'); + if(null == itemID_Hdl){ + LOG.info("A ItemID or a Handle is needed"); + throw new IllegalArgumentException("ItemID or Handle is null.", new NullPointerException()); + } + else + { + doiRequestByItemID_Handle(context, itemID_Hdl,"toBeReserved"); + } + } + try { + context.complete(); + } catch (SQLException sqle) + { + System.err.println("Cannot save changes to database: " + sqle.getMessage()); + System.exit(-1); + } + + LOG.info("Ending Doi organiser"); + } + + /** + * Print the help options for the user + * + * @param options that are available for the user + */ + private static void printHelp(Options options) + { + HelpFormatter myhelp = new HelpFormatter(); + + myhelp.printHelp("DOI organiser\n", options); + } + + private static TableRowIterator listDoiTableByStatus(Context context, String status) + { + TableRowIterator doiIterator = null; + try + { + String sql = "Select * From Doi Where status = ?"; + + doiIterator = DatabaseManager.queryTable(context, "Doi", sql, status); + } + catch (SQLException ex) + { + LOG.error("Error while trying to get data from database", ex); + throw new RuntimeException("Error while trying to get data from database", ex); + } + return doiIterator; + } + + private static void listDoiTable(Context context) + { + try + { + String sql = "Select * From Doi Where status = ? or status = ? "; + + TableRowIterator doiIterator = DatabaseManager.queryTable(context, + "Doi", sql, "toBeReserved", "toBeRegistered"); + while (doiIterator.hasNext()) + { + TableRow doiRow = doiIterator.next(); + System.out.println(doiRow.toString()); + } + doiIterator.close(); + } + catch (SQLException ex) + { + LOG.error("Error while trying to get data from database", ex); + throw new RuntimeException("Error while trying to get data from database", ex); + } + } + + private static void doiRequest(Context context, String status) throws RuntimeException + { + try + { + TableRowIterator iterator = listDoiTableByStatus(context, status); + + while (iterator.hasNext()) + { + TableRow doiRow = iterator.next(); + runRequest(context, doiRow, status); + } + iterator.close(); + } + catch (SQLException ex) + { + LOG.error("Error while trying to get data from database", ex); + throw new RuntimeException("Error while trying to get data from database", ex); + } + } + + private static void runRequest(Context context, TableRow doiRow, String status){ + DOIIdentifierProvider doiIdentifierProvider = new DSpace().getSingletonService(DOIIdentifierProvider.class); + try { + DSpaceObject dso = DSpaceObject.find(context, + doiRow.getIntColumn("resource_type_id"), + doiRow.getIntColumn("resource_id")); + + if (status.equals("toBeRegistered")) + { + doiIdentifierProvider.registeredDOIOnline(context, + dso, + doiRow.getStringColumn("doi")); + } + else + { + doiIdentifierProvider.reserveDOIOnline(context, + dso, + doiRow.getStringColumn("doi")); + } + } catch (SQLException ex) { + LOG.error("Error while trying to get data from database", ex); + throw new RuntimeException("Error while trying to get data from database", ex); + } catch (IdentifierException ex) { + LOG.error(ex); + } catch (IllegalArgumentException ex) { + LOG.error(ex); + } + } + + private static void doiRequestByDOI(Context context, String identifier, String status){ + try { + DOIIdentifierProvider doiIdentifierProvider = new DSpace().getSingletonService(DOIIdentifierProvider.class); + String doi = doiIdentifierProvider.formatIdentifier(identifier); + TableRow doiRow = DatabaseManager.findByUnique(context, "Doi", "doi", doi.substring(DOI.SCHEME.length())); + if(null == doiRow) LOG.error("Identifier: "+ identifier + " is not fund. "); + runRequest(context, doiRow, status); + } catch (SQLException ex) { + LOG.error("It wasn't possible to connect to the Database",ex); + } catch (IdentifierException ex) { + LOG.error(ex); + } + } + + + private static void doiRequestByItemID_Handle(Context context, String itemID_Hdl, String status) { + TableRow row = null; + try + { + if (itemID_Hdl.matches("\\d*")) + { + Integer itemID = Integer.valueOf(itemID_Hdl); + row = DatabaseManager.findByUnique(context, "Item", "item_id", itemID); + + if (null == row) LOG.error("ItemID: " + itemID + " is not fund. "); + + runRequestByItemID_Handle(context, Constants.ITEM, itemID, status); + } + else + { + row = DatabaseManager.findByUnique(context, "Handle", "handle", itemID_Hdl); + + if (null == row) LOG.error("Handle: " + itemID_Hdl + " is not fund. "); + + runRequestByItemID_Handle(context, row.getIntColumn("resource_type_id"), row.getIntColumn("resource_id"), status); + } + } + catch (SQLException ex) + { + LOG.error("It wasn't possible to connect to the Database", ex); + } + } + + private static void runRequestByItemID_Handle(Context context,Integer resource_type_id,Integer resource_id, String status ){ + DSpaceObject dso = null; + DOIIdentifierProvider doiIdentifierProvider = new DSpace().getSingletonService(DOIIdentifierProvider.class); + try { + dso = DSpaceObject.find(context, resource_type_id, resource_id); + if (status.equals("toBeRegistered")) { + doiIdentifierProvider.register(context, dso); + } else { + String identifier = doiIdentifierProvider.mint(context, dso); + dso.update(); + doiIdentifierProvider.reserve(context, dso, identifier); + } + } catch (SQLException ex) { + LOG.error("It wasn't possible to connect to the Database", ex); + } catch (IdentifierException ex) { + LOG.error("It wasn't possible to reserved or to registered an Identifier for the objact", ex); + } catch (AuthorizeException ex) { + LOG.error("It wasn't possible to update the dspace objact", ex); + } + } +} diff --git a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java index 4d8427dc00..02cf3d4d01 100644 --- a/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java +++ b/dspace-api/src/main/java/org/dspace/identifier/doi/DataCiteConnector.java @@ -45,6 +45,7 @@ import org.dspace.services.ConfigurationService; import org.jdom.Document; import org.jdom.Element; import org.jdom.JDOMException; +import org.jdom.Namespace; import org.jdom.filter.ElementFilter; import org.jdom.input.SAXBuilder; import org.jdom.output.Format; @@ -624,7 +625,7 @@ implements DOIConnector // and we'll add it to the DSO after successful registration. root = addDOI(doi, root); } - else if (metadataDOI != doi) + else if (!metadataDOI.equals(doi.substring(DOI.SCHEME.length()))) { throw new IdentifierException("DSO with type " + dso.getTypeText() + " and id " + dso.getID() + " already has DOI " @@ -1122,7 +1123,7 @@ implements DOIConnector } private String extractDOI(Element root) { - Element doi = root.getChild("identifier"); + Element doi = root.getChild("identifier", root.getNamespace()); return (null == doi) ? null : doi.getTextTrim(); } diff --git a/dspace/config/crosswalks/DIM2DataCite.xsl b/dspace/config/crosswalks/DIM2DataCite.xsl index 6225295809..7656d25b43 100644 --- a/dspace/config/crosswalks/DIM2DataCite.xsl +++ b/dspace/config/crosswalks/DIM2DataCite.xsl @@ -188,7 +188,11 @@ - + + + + + @@ -196,9 +200,9 @@ - + - + @@ -315,7 +319,7 @@ - + Image diff --git a/dspace/config/launcher.xml b/dspace/config/launcher.xml index a84cca1af8..35a5585823 100644 --- a/dspace/config/launcher.xml +++ b/dspace/config/launcher.xml @@ -199,6 +199,14 @@ + + organiser + Run the DOI organiser + + org.dspace.identifier.doi.DOIOrganiser + + + packager Execute a packager diff --git a/dspace/config/spring/api/identifier-service.xml b/dspace/config/spring/api/identifier-service.xml index c6f12b112b..6d31865677 100644 --- a/dspace/config/spring/api/identifier-service.xml +++ b/dspace/config/spring/api/identifier-service.xml @@ -33,7 +33,8 @@ a DOIConnector that handle all API calls to your DOI registration agency. Please configure a DOIConnector as well!--> + @@ -42,7 +43,7 @@ - --> + @@ -61,6 +63,5 @@ - --> diff --git a/dspace/etc/h2/database_schema.sql b/dspace/etc/h2/database_schema.sql index 96437f156e..571787e3d9 100644 --- a/dspace/etc/h2/database_schema.sql +++ b/dspace/etc/h2/database_schema.sql @@ -501,7 +501,8 @@ CREATE TABLE Doi doi_id INTEGER PRIMARY KEY, doi VARCHAR(256), resource_type_id INTEGER, - resource_id INTEGER + resource_id INTEGER, + status VARCHAR(20) ); -- index by handle, commonly looked up diff --git a/dspace/etc/oracle/database_schema.sql b/dspace/etc/oracle/database_schema.sql index 7c9681cb7a..ac396b1d73 100644 --- a/dspace/etc/oracle/database_schema.sql +++ b/dspace/etc/oracle/database_schema.sql @@ -453,7 +453,8 @@ CREATE TABLE Doi doi_id INTEGER PRIMARY KEY, doi VARCHAR2(256) UNIQUE, resource_type_id INTEGER, - resource_id INTEGER + resource_id INTEGER, + status VARCHAR(20) ); -- index by resource id and resource type id diff --git a/dspace/etc/oracle/database_schema_30-31.sql b/dspace/etc/oracle/database_schema_30-31.sql new file mode 100644 index 0000000000..575bb2649b --- /dev/null +++ b/dspace/etc/oracle/database_schema_30-31.sql @@ -0,0 +1,59 @@ +-- +-- database_schema_18-3.sql +-- +-- Version: $Revision$ +-- +-- Date: $Date: 2012-05-29 +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + +-- +-- SQL commands to upgrade the database schema of a live DSpace 1.8 or 1.8.x +-- to the DSpace 3 database schema +-- +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- + +ALTER TABLE resourcepolicy + ADD ( + rpname VARCHAR2(30), + rptype VARCHAR2(30), + rpdescription VARCHAR2(100) + ); + + +ALTER TABLE item ADD discoverable NUMBER(1); + +CREATE TABLE versionhistory +( + versionhistory_id INTEGER NOT NULL PRIMARY KEY +); + +CREATE TABLE versionitem +( + versionitem_id INTEGER NOT NULL PRIMARY KEY, + item_id INTEGER REFERENCES Item(item_id), + version_number INTEGER, + eperson_id INTEGER REFERENCES EPerson(eperson_id), + version_date TIMESTAMP, + version_summary VARCHAR2(255), + versionhistory_id INTEGER REFERENCES VersionHistory(versionhistory_id) +); + +CREATE SEQUENCE versionitem_seq; +CREATE SEQUENCE versionhistory_seq; + + +------------------------------------------- +-- New columns and longer hash for salted password hashing DS-861 -- +------------------------------------------- +ALTER TABLE EPerson modify( password VARCHAR(128)); +ALTER TABLE EPerson ADD salt VARCHAR(32); +ALTER TABLE EPerson ADD digest_algorithm VARCHAR(16); diff --git a/dspace/etc/postgres/database_schema.sql b/dspace/etc/postgres/database_schema.sql index 09fed160f5..305e04c291 100644 --- a/dspace/etc/postgres/database_schema.sql +++ b/dspace/etc/postgres/database_schema.sql @@ -494,7 +494,8 @@ CREATE TABLE Doi doi_id INTEGER PRIMARY KEY, doi VARCHAR(256) UNIQUE, resource_type_id INTEGER, - resource_id INTEGER + resource_id INTEGER, + status VARCHAR(20) ); -- index by handle, commonly looked up diff --git a/dspace/etc/postgres/database_schema_30-31.sql b/dspace/etc/postgres/database_schema_30-31.sql new file mode 100644 index 0000000000..3244e6cb5b --- /dev/null +++ b/dspace/etc/postgres/database_schema_30-31.sql @@ -0,0 +1,28 @@ +-- +-- database_schema_30-31.sql +-- +-- Version: $Revision$ +-- +-- Date: $Date: 2013-07-13 +-- +-- The contents of this file are subject to the license and copyright +-- detailed in the LICENSE and NOTICE files at the root of the source +-- tree and available online at +-- +-- http://www.dspace.org/license/ +-- + +-- +-- SQL commands to upgrade the database schema of a live DSpace 3.0 or 3.1.x +-- to the DSpace 3 database schema +-- +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. DUMP YOUR DATABASE FIRST. +-- + +------------------------------------------- +-- New columns for Doi Table status -- +------------------------------------------- + +ALTER TABLE DOI ADD COLUMN status VARCHAR(20); \ No newline at end of file