[DS-968] XML configurable workflow

git-svn-id: http://scm.dspace.org/svn/repo/dspace/trunk@6526 9c30dcfa-912a-0410-8fc2-9e0234be79fd
This commit is contained in:
Ben Bosman
2011-08-04 15:58:31 +00:00
parent 818c01c24e
commit 65f5786e9e
94 changed files with 10642 additions and 928 deletions

View File

@@ -0,0 +1,3 @@
#Selection of workflow framework that will be used in DSpace
workflow.framework=originalworkflow
#workflow.framework=xmlworkflow

View File

@@ -0,0 +1,23 @@
<dspace-dc-types>
<dspace-header>
<title>DSpace Submission Workflow Types Registry</title>
<contributor.author>Bram De Schouwer</contributor.author>
<contributor.author>Kevin Van de Velde</contributor.author>
<contributor.author>Ben Bosman</contributor.author>
<contributor.author>Mark Diggory</contributor.author>
</dspace-header>
<dc-schema>
<name>workflow</name>
<namespace>http://www.dspace.org/workflow</namespace>
</dc-schema>
<dc-type>
<schema>workflow</schema>
<element>score</element>
<scope_note>Metadata field used for the score review</scope_note>
</dc-type>
</dspace-dc-types>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<bean id="claimaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.userassignment.ClaimAction" scope="singleton"/>
<bean id="reviewaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.ReviewAction" scope="singleton"/>
<bean id="editaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.AcceptEditRejectAction" scope="singleton"/>
<bean id="finaleditaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.FinalEditAction" scope="singleton"/>
<bean id="selectrevieweraction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.SelectReviewerAction" scope="singleton"/>
<bean id="singleuserreviewaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.SingleUserReviewAction" scope="singleton"/>
<bean id="scorereviewaction_xmlui" class="org.dspace.app.xmlui.aspect.xmlworkflow.actions.processingaction.ScoreReviewAction" scope="singleton"/>
</beans>

View File

@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd">
<bean id="claimactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.ClaimAction" scope="prototype"/>
<bean id="reviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ReviewAction" scope="prototype"/>
<bean id="editactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.AcceptEditRejectAction" scope="prototype"/>
<bean id="finaleditactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.FinalEditAction" scope="prototype"/>
<bean id="singleuserreviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SingleUserReviewAction" scope="prototype"/>
<bean id="selectrevieweractionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.SelectReviewerAction" scope="prototype">
<property name="roleId" value="reviewer"/>
</bean>
<bean id="scorereviewactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreReviewAction" scope="prototype"/>
<bean id="evaluationactionAPI" class="org.dspace.xmlworkflow.state.actions.processingaction.ScoreEvaluationAction" scope="prototype">
<property name="minimumAcceptanceScore" value="50" />
</bean>
<bean id="autoassignactionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AutoAssignAction" scope="prototype"/>
<bean id="noUserSelectionActionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.NoUserSelectionAction" scope="prototype"/>
<bean id="assignoriginalsubmitteractionAPI" class="org.dspace.xmlworkflow.state.actions.userassignment.AssignOriginalSubmitterAction" scope="prototype"/>
<bean id="reviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="reviewaction"/>
<property name="processingAction" ref="reviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="editaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="editaction"/>
<property name="processingAction" ref="editactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="finaleditaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="finaleditaction"/>
<property name="processingAction" ref="finaleditactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<!--Action for the select single reviewer workflow -->
<bean id="selectrevieweraction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="selectrevieweraction"/>
<property name="processingAction" ref="selectrevieweractionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="singleuserreviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="singleuserreviewaction"/>
<property name="processingAction" ref="singleuserreviewactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="scorereviewaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="scorereviewaction"/>
<property name="processingAction" ref="scorereviewactionAPI" />
<property name="requiresUI" value="true"/>
</bean>
<!--Autmatic step that evaluates scores (workflow.score) and checks if they match the configured minimum for archiving -->
<bean id="evaluationaction" class="org.dspace.xmlworkflow.state.actions.WorkflowActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="evaluationaction"/>
<property name="processingAction" ref="evaluationactionAPI" />
<property name="requiresUI" value="false"/>
</bean>
<!--User selection actions-->
<bean id="claimaction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="claimaction"/>
<property name="processingAction" ref="claimactionAPI"/>
<property name="requiresUI" value="true"/>
</bean>
<bean id="autoassignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="autoassignAction"/>
<property name="processingAction" ref="autoassignactionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="noUserSelectionAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value="noUserSelectionAction"/>
<property name="processingAction" ref="noUserSelectionActionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
<bean id="originalSubmitterAssignAction" class="org.dspace.xmlworkflow.state.actions.UserSelectionActionConfig" scope="prototype">
<constructor-arg type="java.lang.String" value=""/>
<property name="processingAction" ref="assignoriginalsubmitteractionAPI"/>
<property name="requiresUI" value="false"/>
</bean>
</beans>

View File

@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<wf-config>
<workflow-map>
<name-map collection="default" workflow="default"/>
<!--<name-map collection="123456789/4" workflow="selectSingleReviewer"/>-->
<!--<name-map collection="123456789/5" workflow="scoreReview"/>-->
</workflow-map>
<!--Standard workflow step-->
<workflow start="reviewstep" id="default">
<roles>
<role id="reviewer" name="Reviewer" description="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them." />
<role id="editor" name="Editor" description="The people responsible for this step are able to edit the metadata of incoming submissions, and then accept or reject them."/>
<role id="finaleditor" name="Final Editor" description="The people responsible for this step are able to edit the metadata of incoming submissions, but will not be able to reject them."/>
</roles>
<step id="reviewstep" role="reviewer" userSelectionMethod="claimaction">
<outcomes>
<step status="0">editstep</step>
</outcomes>
<actions>
<action id="reviewaction"/>
</actions>
</step>
<step id="editstep" role="editor" userSelectionMethod="claimaction">
<outcomes>
<step status="0">finaleditstep</step>
</outcomes>
<actions>
<action id="editaction"/>
</actions>
</step>
<step id="finaleditstep" role="finaleditor" userSelectionMethod="claimaction">
<actions>
<action id="finaleditaction"/>
</actions>
</step>
</workflow>
<!--Workflow where a reviewManager can select a single review who will then either accept/reject the item-->
<workflow id="selectSingleReviewer" start="selectReviewerStep">
<roles>
<role id="reviewer" name="Reviewer" scope="item" />
<role id="reviewmanagers" name="ReviewManagers" scope="repository"/>
</roles>
<step id="selectReviewerStep" role="reviewmanagers" userSelectionMethod="claimaction">
<outcomes>
<step status="0">singleUserReviewStep</step>
</outcomes>
<actions>
<action id="selectrevieweraction"/>
</actions>
</step>
<step id="singleUserReviewStep" role="reviewer" userSelectionMethod="autoassignAction">
<outcomes>
<step status="1">selectReviewerStep</step>
</outcomes>
<actions>
<action id="singleuserreviewaction"/>
</actions>
</step>
</workflow>
<!--Workflow where a number of users will perform reviews on an item and depending on the scores the item will be archived/rejected-->
<workflow id="scoreReview" start="scoreReviewStep">
<roles>
<role id="scoreReviewers" name="ScoreReviewers" scope="collection" description="The people responsible to select a single reviewer for the submission"/>
</roles>
<step id="scoreReviewStep" role="scoreReviewers" userSelectionMethod="claimaction" requiredUsers="2">
<outcomes>
<step status="0">evaluationStep</step>
</outcomes>
<actions>
<action id="scorereviewaction"/>
</actions>
</step>
<step id="evaluationStep" userSelectionMethod="noUserSelectionAction">
<actions>
<action id="evaluationaction"/>
</actions>
</step>
</workflow>
</wf-config>

View File

@@ -71,6 +71,8 @@
<aspect name="E-Person" path="resource://aspects/EPerson/" />
<aspect name="Submission and Workflow" path="resource://aspects/Submission/" />
<aspect name="Statistics" path="resource://aspects/Statistics/" />
<aspect name="Original Workflow" path="resource://aspects/Workflow/" />
<!--<aspect name="XMLWorkflow" path="resource://aspects/XMLWorkflow/" />-->
<!--
To enable Discovery, uncomment this Aspect that will enable it
within your existing XMLUI
@@ -129,4 +131,4 @@
<!-- <theme name="Table Theme" regex=".*" path="TableTheme/" /> -->
</themes>
</xmlui>
</xmlui>

View File

@@ -0,0 +1,331 @@
-- Convert workflow groups:
-- TODO: is 'to_number' ok? do not forget to change role_id values
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'reviewer' AS role_id,
eperson_group_id AS group_id,
to_number(replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_1', '')) AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_1';
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'editor' AS role_id,
eperson_group_id AS group_id,
to_number(replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_2', '')) AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_2';
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'finaleditor' AS role_id,
eperson_group_id AS group_id,
to_number(replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_3', '')) AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_3';
-- Migrate workflow items
INSERT INTO xmlwf_workflowitem (workflowitem_id, item_id, collection_id, multiple_titles, published_before, multiple_files)
SELECT
workflow_id AS workflowitem_id,
item_id,
collection_id,
multiple_titles,
published_before,
multiple_files
FROM workflowitem;
-- Migrate claimed tasks
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'reviewstep' AS step_id,
'reviewaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 2;
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'editstep' AS step_id,
'editaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 4;
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'finaleditstep' AS step_id,
'finaleditaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 6;
-- Migrate pooled tasks
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'reviewstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 1 AND xmlwf_collectionrole.role_id = 'reviewer';
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'editstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 3 AND xmlwf_collectionrole.role_id = 'editor';
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'finaleditstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 5 AND xmlwf_collectionrole.role_id = 'finaleditor';
-- Create policies for claimtasks
-- public static final int BITSTREAM = 0;
-- public static final int BUNDLE = 1;
-- public static final int ITEM = 2;
-- public static final int READ = 0;
-- public static final int WRITE = 1;
-- public static final int DELETE = 2;
-- public static final int ADD = 3;
-- public static final int REMOVE = 4;
-- Item
-- TODO: getnextID == SELECT sequence.nextval FROM DUAL!!
-- Create a temporarty table with action ID's
CREATE TABLE temptable(
action_id INTEGER PRIMARY KEY
)
INSERT ALL
INTO temptable (action_id) VALUES (0)
INTO temptable (action_id) VALUES (1)
INTO temptable (action_id) VALUES (2)
INTO temptable (action_id) VALUES (3)
INTO temptable (action_id) VALUES (4)
SELECT * FROM DUAL;
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM (xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id),
temptable;
-- Bundles
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM
(
(xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
), temptable;
-- Bitstreams
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM
(
((xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
), temptable;
-- Create policies for pooled tasks
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM (xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id),
temptable;
-- Bundles
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM
(
(xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
), temptable;
-- Bitstreams
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM
(
((xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
), temptable;
-- Drop the temporary table with the action ID's
DROP TABLE temptable;
-- Create policies for submitter
-- TODO: only add if unique
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM (xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id);
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM ((xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
);
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
resourcepolicy_seq.nextval AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM (((xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
);
-- TODO: not tested yet
INSERT INTO xmlwf_in_progress_user (in_progress_user_id, workflowitem_id, step_id, user_id, finished)
SELECT
xmlwf_in_progress_user_seq.nextval AS in_progress_user_id,
xmlwf_workflowitem.item_id AS workflowitem_id,
xmlwf_claimtask.owner_id AS user_id
0 as finished
FROM
(xmlwf_claimtask INNER JOIN xmlwf_workflowitem ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id);
-- TODO: improve this, important is NVL(curr, 1)!! without this function, empty tables (max = [null]) will only result in sequence deletion
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(workflowitem_id) INTO curr FROM xmlwf_workflowitem;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_workflowitem_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_workflowitem_seq START WITH ' || NVL(curr, 1);
END;
/
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(collectionrole_id) INTO curr FROM xmlwf_collectionrole;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_collectionrole_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_collectionrole_seq START WITH ' || NVL(curr, 1);
END;
/
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(workflowitemrole_id) INTO curr FROM xmlwf_workflowitemrole;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_workflowitemrole_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_workflowitemrole_seq START WITH ' || NVL(curr, 1);
END;
/
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(pooltask_id) INTO curr FROM xmlwf_pooltask;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_pooltask_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_pooltask_seq START WITH ' || NVL(curr, 1);
END;
/
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(claimtask_id) INTO curr FROM xmlwf_claimtask;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_claimtask_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_claimtask_seq START WITH ' || NVL(curr, 1);
END;
/
DECLARE
curr NUMBER := 0;
BEGIN
SELECT max(in_progress_user_id) INTO curr FROM xmlwf_in_progress_user;
curr := curr + 1;
EXECUTE IMMEDIATE 'DROP SEQUENCE xmlwf_in_progress_user_seq';
EXECUTE IMMEDIATE 'CREATE SEQUENCE xmlwf_in_progress_user_seq START WITH ' || NVL(curr, 1);
END;
/

View File

@@ -0,0 +1,107 @@
CREATE SEQUENCE xmlwf_workflowitem_seq;
CREATE SEQUENCE xmlwf_collectionrole_seq;
CREATE SEQUENCE xmlwf_workflowitemrole_seq;
CREATE SEQUENCE xmlwf_claimtask_seq;
CREATE SEQUENCE xmlwf_in_progress_user_seq;
CREATE SEQUENCE xmlwf_pooltask_seq;
CREATE TABLE xmlwf_workflowitem
(
workflowitem_id INTEGER PRIMARY KEY,
item_id INTEGER REFERENCES item(item_id) UNIQUE,
collection_id INTEGER REFERENCES collection(collection_id),
-- Answers to questions on first page of submit UI
multiple_titles NUMBER(1),
published_before NUMBER(1),
multiple_files NUMBER(1)
-- Note: stage reached not applicable here - people involved in workflow
-- can always jump around submission UI
);
-- TODO: it seems like this index is already created by the 'unique' constraint in the table creation
-- CREATE INDEX xmlwf_wf_item_fk_idx ON xmlwf_workflowitem(item_id);
CREATE INDEX xmlwf_wf_coll_fk_idx ON xmlwf_workflowitem(collection_id);
CREATE TABLE xmlwf_collectionrole (
collectionrole_id INTEGER PRIMARY KEY,
role_id VARCHAR2(256),
collection_id integer REFERENCES collection(collection_id),
group_id integer REFERENCES epersongroup(eperson_group_id)
);
ALTER TABLE xmlwf_collectionrole ADD CONSTRAINT xmlwf_collectionrole_unique UNIQUE (role_id, collection_id, group_id);
CREATE INDEX xmlwf_cr_coll_role_fk_idx ON xmlwf_collectionrole(collection_id,role_id);
CREATE INDEX xmlwf_cr_coll_fk_idx ON xmlwf_collectionrole(collection_id);
CREATE TABLE xmlwf_workflowitemrole (
workflowitemrole_id INTEGER PRIMARY KEY,
role_id VARCHAR2(256),
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
eperson_id integer REFERENCES eperson(eperson_id),
group_id integer REFERENCES epersongroup(eperson_group_id)
);
ALTER TABLE xmlwf_workflowitemrole
ADD CONSTRAINT xmlwf_workflowitemrole_unique UNIQUE (role_id, workflowitem_id, eperson_id);
CREATE INDEX xmlwf_wfir_item_role_fk_idx ON xmlwf_workflowitemrole(workflowitem_id,role_id);
CREATE INDEX xmlwf_wfir_item_fk_idx ON xmlwf_workflowitemrole(workflowitem_id);
CREATE TABLE xmlwf_pooltask (
pooltask_id INTEGER PRIMARY KEY,
workflowitem_id INTEGER REFERENCES xmlwf_workflowitem(workflowitem_id),
workflow_id VARCHAR2(256),
step_id VARCHAR2(256),
action_id VARCHAR2(256),
eperson_id INTEGER REFERENCES EPerson(eperson_id),
group_id INTEGER REFERENCES epersongroup(eperson_group_id)
);
CREATE INDEX xmlwf_pt_epers_fk_idx ON xmlwf_pooltask(eperson_id);
CREATE INDEX xmlwf_pt_wf_fk_idx ON xmlwf_pooltask(workflowitem_id);
CREATE INDEX xmlwf_pt_wf_epers_fk_idx ON xmlwf_pooltask(eperson_id,workflowitem_id);
CREATE TABLE xmlwf_claimtask (
claimtask_id INTEGER PRIMARY KEY,
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
workflow_id VARCHAR2(256),
step_id VARCHAR2(256),
action_id VARCHAR2(256),
owner_id integer REFERENCES eperson(eperson_id)
);
ALTER TABLE xmlwf_claimtask
ADD CONSTRAINT xmlwf_claimtask_unique UNIQUE (step_id, workflowitem_id, workflow_id, owner_id, action_id);
CREATE INDEX xmlwf_ct_wf_fk_idx ON xmlwf_claimtask(workflowitem_id);
CREATE INDEX xmlwf_ct_wf_epers_fk_idx ON xmlwf_claimtask(workflowitem_id,owner_id);
CREATE INDEX xmlwf_ct_epers_fk_idx ON xmlwf_claimtask(owner_id);
CREATE INDEX xmlwf_ct_wf_step_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id);
CREATE INDEX xmlwf_ct_wf_step_act_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id,action_id);
CREATE INDEX xmlwf_ct_wf_st_ac_ep_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id,action_id,owner_id);
CREATE TABLE xmlwf_in_progress_user (
in_progress_user_id INTEGER PRIMARY KEY,
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
user_id integer REFERENCES eperson(eperson_id),
finished NUMBER(1)
);
ALTER TABLE xmlwf_in_progress_user
ADD CONSTRAINT xmlwf_in_progress_user_unique UNIQUE (workflowitem_id, user_id);
CREATE INDEX xmlwf_ipu_wf_fk_idx ON xmlwf_in_progress_user(workflowitem_id);
CREATE INDEX xmlwf_ipu_epers_fk_idx ON xmlwf_in_progress_user(user_id);
-- TODO: it seems like this index is already created by the 'unique' constraint in the table creation
-- CREATE INDEX xmlwf_ipu_wf_epers_fk_idx ON xmlwf_in_progress_user(workflowitem_id,user_id);

View File

@@ -0,0 +1,243 @@
-- Convert workflow groups:
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'reviewer' AS role_id,
eperson_group_id AS group_id,
replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_1', '')::INTEGER AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_1';
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'editor' AS role_id,
eperson_group_id AS group_id,
replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_2', '')::INTEGER AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_2';
INSERT INTO xmlwf_collectionrole (role_id, group_id, collection_id)
SELECT
'finaleditor' AS role_id,
eperson_group_id AS group_id,
replace(replace(name, 'COLLECTION_', ''), '_WORKFLOW_STEP_3', '')::INTEGER AS collection_id
FROM epersongroup
WHERE name LIKE 'COLLECTION_%_WORKFLOW_STEP_3';
-- Migrate workflow items
INSERT INTO xmlwf_workflowitem (workflowitem_id, item_id, collection_id, multiple_titles, published_before, multiple_files)
SELECT
workflow_id AS workflowitem_id,
item_id,
collection_id,
multiple_titles,
published_before,
multiple_files
FROM workflowitem;
-- Migrate claimed tasks
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'reviewstep' AS step_id,
'reviewaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 2;
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'editstep' AS step_id,
'editaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 4;
INSERT INTO xmlwf_claimtask (workflowitem_id, workflow_id, step_id, action_id, owner_id)
SELECT
workflow_id AS workflowitem_id,
'default' AS workflow_id,
'finaleditstep' AS step_id,
'finaleditaction' AS action_id,
owner AS owner_id
FROM workflowitem WHERE owner IS NOT NULL AND state = 6;
-- Migrate pooled tasks
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'reviewstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 1 AND xmlwf_collectionrole.role_id = 'reviewer';
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'editstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 3 AND xmlwf_collectionrole.role_id = 'editor';
INSERT INTO xmlwf_pooltask (workflowitem_id, workflow_id, step_id, action_id, group_id)
SELECT
workflowitem.workflow_id AS workflowitem_id,
'default' AS workflow_id,
'finaleditstep' AS step_id,
'claimaction' AS action_id,
xmlwf_collectionrole.group_id AS group_id
FROM workflowitem INNER JOIN xmlwf_collectionrole ON workflowitem.collection_id = xmlwf_collectionrole.collection_id
WHERE workflowitem.owner IS NULL AND workflowitem.state = 5 AND xmlwf_collectionrole.role_id = 'finaleditor';
-- Create policies for claimtasks
-- public static final int BITSTREAM = 0;
-- public static final int BUNDLE = 1;
-- public static final int ITEM = 2;
-- public static final int READ = 0;
-- public static final int WRITE = 1;
-- public static final int DELETE = 2;
-- public static final int ADD = 3;
-- public static final int REMOVE = 4;
-- Item
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM (xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id),
(VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Bundles
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM
(
(xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
), (VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Bitstreams
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_claimtask.owner_id AS eperson_id
FROM
(
((xmlwf_workflowitem INNER JOIN xmlwf_claimtask ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
), (VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Create policies for pooled tasks
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM (xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id),
(VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Bundles
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM
(
(xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
), (VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Bitstreams
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, epersongroup_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
temptable.action_id AS action_id,
xmlwf_pooltask.group_id AS epersongroup_id
FROM
(
((xmlwf_workflowitem INNER JOIN xmlwf_pooltask ON xmlwf_workflowitem.workflowitem_id = xmlwf_pooltask.workflowitem_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
), (VALUES (0), (1), (2), (3), (4)) AS temptable(action_id);
-- Create policies for submitter
-- TODO: only add if unique
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
2 AS resource_type_id,
xmlwf_workflowitem.item_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM (xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id);
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
1 AS resource_type_id,
item2bundle.bundle_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM ((xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id
);
INSERT INTO resourcepolicy (policy_id, resource_type_id, resource_id, action_id, eperson_id)
SELECT
getnextid('resourcepolicy') AS policy_id,
0 AS resource_type_id,
bundle2bitstream.bitstream_id AS resource_id,
0 AS action_id,
item.submitter_id AS eperson_id
FROM (((xmlwf_workflowitem INNER JOIN item ON xmlwf_workflowitem.item_id = item.item_id)
INNER JOIN item2bundle ON xmlwf_workflowitem.item_id = item2bundle.item_id)
INNER JOIN bundle2bitstream ON item2bundle.bundle_id = bundle2bitstream.bundle_id
);
INSERT INTO xmlwf_in_progress_user (in_progress_user_id, workflowitem_id, user_id, finished)
SELECT
getnextid('xmlwf_in_progress_user') AS in_progress_user_id,
xmlwf_workflowitem.item_id AS workflowitem_id,
xmlwf_claimtask.owner_id AS user_id,
BOOL(0) as finished
FROM
(xmlwf_claimtask INNER JOIN xmlwf_workflowitem ON xmlwf_workflowitem.workflowitem_id = xmlwf_claimtask.workflowitem_id);
-- Update the sequences
SELECT setval('xmlwf_workflowitem_seq', max(workflowitem_id)) FROM xmlwf_workflowitem;
SELECT setval('xmlwf_collectionrole_seq', max(collectionrole_id)) FROM xmlwf_collectionrole;
SELECT setval('xmlwf_workflowitemrole_seq', max(workflowitemrole_id)) FROM xmlwf_workflowitemrole;
SELECT setval('xmlwf_pooltask_seq', max(pooltask_id)) FROM xmlwf_pooltask;
SELECT setval('xmlwf_claimtask_seq', max(claimtask_id)) FROM xmlwf_claimtask;
SELECT setval('xmlwf_in_progress_user_seq', max(in_progress_user_id)) FROM xmlwf_in_progress_user;

View File

@@ -0,0 +1,103 @@
CREATE SEQUENCE xmlwf_workflowitem_seq;
CREATE SEQUENCE xmlwf_collectionrole_seq;
CREATE SEQUENCE xmlwf_workflowitemrole_seq;
CREATE SEQUENCE xmlwf_pooltask_seq;
CREATE SEQUENCE xmlwf_claimtask_seq;
CREATE SEQUENCE xmlwf_in_progress_user_seq;
CREATE TABLE xmlwf_workflowitem
(
workflowitem_id integer DEFAULT nextval('xmlwf_workflowitem_seq') PRIMARY KEY,
item_id INTEGER REFERENCES item(item_id) UNIQUE,
collection_id INTEGER REFERENCES collection(collection_id),
-- Answers to questions on first page of submit UI
multiple_titles BOOL,
published_before BOOL,
multiple_files BOOL
-- Note: stage reached not applicable here - people involved in workflow
-- can always jump around submission UI
);
CREATE INDEX xmlwf_workflowitem_item_fk_idx ON xmlwf_workflowitem(item_id);
CREATE INDEX xmlwf_workflowitem_coll_fk_idx ON xmlwf_workflowitem(collection_id);
CREATE TABLE xmlwf_collectionrole (
collectionrole_id integer DEFAULT nextval('xmlwf_collectionrole_seq') PRIMARY KEY,
role_id Text,
collection_id integer REFERENCES collection(collection_id),
group_id integer REFERENCES epersongroup(eperson_group_id)
);
ALTER TABLE ONLY xmlwf_collectionrole
ADD CONSTRAINT xmlwf_collectionrole_unique UNIQUE (role_id, collection_id, group_id);
CREATE INDEX xmlwf_collectionrole_coll_role_fk_idx ON xmlwf_collectionrole(collection_id,role_id);
CREATE INDEX xmlwf_collectionrole_coll_fk_idx ON xmlwf_collectionrole(collection_id);
CREATE TABLE xmlwf_workflowitemrole (
workflowitemrole_id integer DEFAULT nextval('xmlwf_workflowitemrole_seq') PRIMARY KEY,
role_id Text,
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
eperson_id integer REFERENCES eperson(eperson_id),
group_id integer REFERENCES epersongroup(eperson_group_id)
);
ALTER TABLE ONLY xmlwf_workflowitemrole
ADD CONSTRAINT xmlwf_workflowitemrole_unique UNIQUE (role_id, workflowitem_id, eperson_id);
CREATE INDEX xmlwf_workflowitemrole_item_role_fk_idx ON xmlwf_workflowitemrole(workflowitem_id,role_id);
CREATE INDEX xmlwf_workflowitemrole_item_fk_idx ON xmlwf_workflowitemrole(workflowitem_id);
CREATE TABLE xmlwf_pooltask (
pooltask_id INTEGER DEFAULT nextval('xmlwf_pooltask_seq') PRIMARY KEY,
workflowitem_id INTEGER REFERENCES xmlwf_workflowitem(workflowitem_id),
workflow_id TEXT,
step_id TEXT,
action_id TEXT,
eperson_id INTEGER REFERENCES EPerson(eperson_id),
group_id INTEGER REFERENCES epersongroup(eperson_group_id)
);
CREATE INDEX xmlwf_pooltask_eperson_fk_idx ON xmlwf_pooltask(eperson_id);
CREATE INDEX xmlwf_pooltask_workflow_fk_idx ON xmlwf_pooltask(workflowitem_id);
CREATE INDEX xmlwf_pooltask_workflow_eperson_fk_idx ON xmlwf_pooltask(eperson_id,workflowitem_id);
CREATE TABLE xmlwf_claimtask (
claimtask_id integer DEFAULT nextval('xmlwf_claimtask_seq') PRIMARY KEY,
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
workflow_id Text,
step_id Text,
action_id Text,
owner_id integer REFERENCES eperson(eperson_id)
);
ALTER TABLE ONLY xmlwf_claimtask
ADD CONSTRAINT xmlwf_claimtask_unique UNIQUE (step_id, workflowitem_id, workflow_id, owner_id, action_id);
CREATE INDEX xmlwf_claimtask_workflow_fk_idx ON xmlwf_claimtask(workflowitem_id);
CREATE INDEX xmlwf_claimtask_workflow_eperson_fk_idx ON xmlwf_claimtask(workflowitem_id,owner_id);
CREATE INDEX xmlwf_claimtask_eperson_fk_idx ON xmlwf_claimtask(owner_id);
CREATE INDEX xmlwf_claimtask_workflow_step_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id);
CREATE INDEX xmlwf_claimtask_workflow_step_action_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id,action_id);
CREATE INDEX xmlwf_claimtask_workflow_step_action_eperson_fk_idx ON xmlwf_claimtask(workflowitem_id,step_id,action_id,owner_id);
CREATE TABLE xmlwf_in_progress_user (
in_progress_user_id integer DEFAULT nextval('xmlwf_in_progress_user_seq') PRIMARY KEY,
workflowitem_id integer REFERENCES xmlwf_workflowitem(workflowitem_id),
user_id integer REFERENCES eperson(eperson_id),
finished BOOL
);
ALTER TABLE ONLY xmlwf_in_progress_user
ADD CONSTRAINT xmlwf_in_progress_user_unique UNIQUE (workflowitem_id, user_id);
CREATE INDEX xmlwf_in_progress_user_workflow_fk_idx ON xmlwf_in_progress_user(workflowitem_id);
CREATE INDEX xmlwf_in_progress_user_eperson_fk_idx ON xmlwf_in_progress_user(user_id);
CREATE INDEX xmlwf_in_progress_user_workflow_eperson_fk_idx ON xmlwf_in_progress_user(workflowitem_id,user_id);