⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adoworkflowstore.cs

📁 基于DotNet的工作流引擎实现
💻 CS
📖 第 1 页 / 共 3 页
字号:
using System;
using System.Collections;
using System.Data;
using System.Text;
using DotNetTools.Data;
using DotNetTools.PropertySet;
using DotNetTools.Workflow.Query;
using log4net;
/*
* Copyright (c) 2002-2003 by OpenSymphony
* All rights reserved.
*/

namespace DotNetTools.Workflow.Spi.Ado
{
	/// <summary> ado.net implementation.
	/// <p>
	/// *
	/// The following properties are all <b>required</b>:
	/// <ul>
	/// <li><b>connectionString</b> - the connectionString for the DataSource that is to be used.</li>
	/// <li><b>entry.sequence</b> - SQL query that returns the next ID for a workflow entry</li>
	/// <li><b>entry.table</b> - table name for workflow entry</li>
	/// <li><b>entry.id</b> - column name for workflow entry ID field</li>
	/// <li><b>entry.name</b> - column name for workflow entry name field</li>
	/// <li><b>entry.state</b> - column name for workflow entry state field</li>
	/// <li><b>step.sequence</b> - SQL query that returns the next ID for a workflow step</li>
	/// <li><b>history.table</b> - table name for steps in history</li>
	/// <li><b>current.table</b> - table name for current steps</li>
	/// <li><b>step.id</b> - column name for step ID field</li>
	/// <li><b>step.entryId</b> - column name for workflow entry ID field (foreign key relationship to [entry.table].[entry.id])</li>
	/// <li><b>step.stepId</b> - column name for step workflow definition step field</li>
	/// <li><b>step.actionId</b> - column name for step action field</li>
	/// <li><b>step.owner</b> - column name for step owner field</li>
	/// <li><b>step.caller</b> - column name for step caller field</li>
	/// <li><b>step.startDate</b> - column name for step start date field</li>
	/// <li><b>step.dueDate</b> - column name for optional step due date field</li>
	/// <li><b>step.finishDate</b> - column name for step finish date field</li>
	/// <li><b>step.status</b> - column name for step status field</li>
	/// <li><b>currentPrev.table</b> - table name for the previous IDs for current steps</li>
	/// <li><b>historyPrev.table</b> - table name for the previous IDs for history steps</li>
	/// <li><b>step.previousId</b> - column name for step ID field (foreign key relation to [history.table].[step.id] or [current.table].[step.id])</li>
	/// </ul>
	/// *
	/// </summary>
	/// <author>  
	/// <a href="mailto:plightbo@hotmail.com">Pat Lightbody</a>
	/// </author>
	/// <author>jjx (.net)</author>
	public abstract class AdoWorkflowStore : IWorkflowStore
	{
		public AdoWorkflowStore(){
			
		}
		public AdoWorkflowStore(IDictionary props)
		{
			Init(props);
		}
		protected abstract IDbConnection Connection
		{
			get;
			
		}

		//~ Static fields/initializers /////////////////////////////////////////////

		protected static readonly ILog log;

		//~ Instance fields ////////////////////////////////////////////////////////

		protected internal String currentPrevTable;
		protected internal String currentTable;
		protected internal String entryId;
		protected internal String entryName;
		protected internal String entrySequence;
		protected internal String entryState;
		protected internal String entryTable;
		protected internal String historyPrevTable;
		protected internal String historyTable;
		protected internal String stepActionId;
		protected internal String stepCaller;
		protected internal String stepDueDate;
		protected internal String stepEntryId;
		protected internal String stepFinishDate;
		protected internal String stepId;
		protected internal String stepOwner;
		protected internal String stepPreviousId;
		protected internal String stepSequence;
		protected internal String stepStartDate;
		protected internal String stepStatus;
		protected internal String stepStepId;
		protected internal bool closeConnWhenDone = false;
		protected internal String connectionString = String.Empty;

		protected abstract String getParameterName(String parameterName);
		
		protected abstract IDbCommand createDbCommand(IDbConnection connection, String sql);
	
		protected abstract IDataParameter createDataParameter(String name, Object value);
		

		//~ Methods ////////////////////////////////////////////////////////////////

		public virtual void SetEntryState(long id, int state)
		{
			IDbCommand ps = null;

			try
			{
				String sql = "UPDATE " + entryTable + " SET " + entryState +
					" = " + getParameterName("entryState") + "  WHERE " + entryId + " = " +
					getParameterName("entryId");

				ps = createDbCommand(Connection, sql);
				ps.Parameters.Add(createDataParameter("entryState", state));
				ps.Parameters.Add(createDataParameter("entryId", id));


				ps.ExecuteNonQuery();
			}
			catch (Exception e)
			{
				throw new StoreException("Unable to update state for workflow instance #" + id + " to " + state, e);
			}
			finally
			{
				cleanup(ps.Connection, ps, null);
			}
		}

		public virtual IPropertySet GetPropertySet(long entryId)
		{
			IDictionary args = new Hashtable(1);
			args.Add("globalKey", "osff_" + entryId);

			return PropertySetManager.GetInstance("ado", args);
		}

		public virtual IStep CreateCurrentStep(long entryId, int wfStepId, String owner, DateTime startDate, DateTime dueDate, String status, long[] previousIds)
		{
			IDbConnection conn = null;

			try
			{
				conn = Connection;

				long id = createCurrentStep(conn, entryId, wfStepId, owner, startDate, dueDate, status);
				addPreviousSteps(conn, id, previousIds);

				return new SimpleStep(id, entryId, wfStepId, 0, owner, startDate, dueDate, DateTime.MaxValue, status, previousIds, null);
			}
			catch (Exception e)
			{
				throw new StoreException("Unable to create current step for workflow instance #" + entryId, e);
			}
			finally
			{
				cleanup(conn, null, null);
			}
		}

		public virtual IWorkflowEntry CreateEntry(String workflowName)
		{
			IDbConnection conn = null;
			IDbCommand stmt = null;

			try
			{
				conn = Connection;

				String sql = "INSERT INTO " + entryTable + " (" + entryId + ", " + entryName + ", " + entryState + ") VALUES (" +
					getParameterName(entryId) + "," + getParameterName(entryName) + "," +
					getParameterName(entryState) + ")";
				
			
				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql);
				}

				stmt = createDbCommand(conn, sql);
				long id = getNextEntrySequence(conn);
				
				stmt.Parameters.Add(createDataParameter(entryId, id));
				

				stmt.Parameters.Add(createDataParameter(entryName, workflowName));
				stmt.Parameters.Add(createDataParameter(entryState, SimpleWorkflowEntry.CREATED));
				stmt.ExecuteNonQuery();
					return new SimpleWorkflowEntry(id, workflowName, SimpleWorkflowEntry.CREATED);
			}
			catch (Exception e)
			{
				throw new StoreException("Error creating new workflow instance", e);
			}
			finally
			{
				cleanup(conn, stmt, null);
			}
		}

		public virtual IList FindCurrentSteps(long entryId)
		{
			IDbConnection conn = null;
			IDbCommand stmt = null;

			SafeDataReader rset = null;
			IDbCommand stmt2 = null;

			try
			{
				conn = Connection;

				String sql = "SELECT " + this.stepId + ", " + stepStepId + ", " + 
						stepActionId + ", " + stepOwner + ", " + stepStartDate + ", " + 
					stepDueDate + ", " + stepFinishDate + ", " + stepStatus + ", " + 
					stepCaller + " FROM " + currentTable + " WHERE " + 
					stepEntryId + " = " + getParameterName(stepEntryId);
				String sql2 = "SELECT " + stepPreviousId + " FROM " + currentPrevTable +
					" WHERE " + this.stepId + " = " + getParameterName(stepId)+" order by "+this.stepId+" desc";

				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql);
				}

				stmt = createDbCommand(conn, sql);


				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql2);
				}


				stmt2 = createDbCommand(conn, sql2);
				stmt.Parameters.Add(createDataParameter(stepEntryId, entryId));


				rset =new SafeDataReader( stmt.ExecuteReader());

				ArrayList currentSteps = new ArrayList();

				IList stepIds=new ArrayList();
				while (rset.Read())
				{
					long id = rset.GetInt32(this.stepId);
				//	entryId=rset.GetInt32(this.stepEntryId);
					
					int _stepId = rset.GetInt32(this.stepStepId);
					stepIds.Add(id);
					int actionId = rset.GetInt32(this.stepActionId);
					String owner = rset.GetString(this.stepOwner);
					DateTime startDate = rset.GetDateTime(this.stepStartDate);
					DateTime dueDate = rset.GetDateTime(this.stepDueDate);
					DateTime finishDate = rset.GetDateTime(this.stepFinishDate);
					String status = rset.GetString(this.stepStatus);
					String caller = rset.GetString(this.stepCaller);
					SimpleStep step = new SimpleStep(id, entryId, _stepId, actionId, owner, startDate, dueDate, finishDate, status, null, caller);
					currentSteps.Add(step);
				}
				rset.Close();
				for(int i=0;i<stepIds.Count;i++)
				{
					long id=(long)stepIds[i];

					ArrayList prevIdsList = new ArrayList();
					stmt2.Parameters.Clear();
					stmt2.Parameters.Add(createDataParameter(stepId, id));
					SafeDataReader rs = new SafeDataReader(stmt2.ExecuteReader());

					while (rs.Read())
					{
						long prevId = rs.GetInt32(this.stepPreviousId);
						prevIdsList.Add(prevId);
					}

					rs.Close();
					long[] prevIds = new long[prevIdsList.Count];

					prevIdsList.CopyTo(prevIds,0);
										
					(currentSteps[i] as SimpleStep).PreviousStepIds=prevIds;
					

				}

				return currentSteps;
			}
			catch (Exception e)
			{
				throw new StoreException("Unable to locate current steps for workflow instance #" + entryId, e);
			}
			finally
			{
				cleanup(null, stmt2, null);
				cleanup(conn, stmt, rset);
			}
		}

		public virtual IWorkflowEntry FindEntry(long theEntryId)
		{
			IDbConnection conn = null;
			IDbCommand stmt = null;

			SafeDataReader rset = null;

			try
			{
				conn = Connection;

				String sql = "SELECT " + entryName + ", " + entryState + " FROM " + 
					entryTable + " WHERE " + entryId + " = " + getParameterName(entryId);

				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql);
				}

				stmt = createDbCommand(conn, sql);

				stmt.Parameters.Add(createDataParameter(entryId, theEntryId));

				rset =new SafeDataReader( stmt.ExecuteReader());
				rset.Read();

				String workflowName =rset.GetString(this.entryName);
				int state = rset.GetInt32(this.entryState);

				return new SimpleWorkflowEntry(theEntryId, workflowName, state);
			}
			catch (Exception)
			{
				throw new StoreException("Error finding workflow instance #" + entryId);
			}
			finally
			{
				cleanup(conn, stmt, rset);
			}
		}

		public virtual IList FindHistorySteps(long entryId)
		{
			IDbConnection conn = null;
			IDbCommand stmt = null;
			IDbCommand stmt2 = null;

			SafeDataReader rset = null;

			try
			{
				conn = Connection;

				String sql = "SELECT " + this.stepId + ", " + stepStepId + ", " + stepActionId +
					", " + stepOwner + ", " + stepStartDate + ", " + 
					stepDueDate + ", " + stepFinishDate + ", " + 
					stepStatus + ", " + stepCaller + " FROM " + 
					historyTable + " WHERE " + stepEntryId + " = " + 
					getParameterName(stepEntryId) + " ORDER BY " + this.stepId + " DESC";
				String sql2 = "SELECT " + stepPreviousId + " FROM " + historyPrevTable + 
				" WHERE " + this.stepId + " = " + getParameterName(stepId);

				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql);
				}

				stmt = createDbCommand(conn, sql);

				if (log.IsDebugEnabled)
				{
					log.Debug("Executing SQL statement: " + sql2);
				}


				stmt2 = createDbCommand(conn, sql2);
				stmt.Parameters.Add(createDataParameter(stepEntryId, entryId));


				rset = new SafeDataReader(stmt.ExecuteReader());

				ArrayList currentSteps = new ArrayList();
				IList stepIds=new ArrayList();

				while (rset.Read())
				{
					long id = rset.GetInt32(this.stepId);
					stepIds.Add(id);
					int _stepId = rset.GetInt32(this.stepStepId);
					int actionId = rset.GetInt32(this.stepActionId);
					String owner = rset.GetString(this.stepOwner);
					DateTime startDate = rset.GetDateTime(this.stepStartDate);
					DateTime dueDate = rset.GetDateTime(this.stepDueDate);
					DateTime finishDate = rset.GetDateTime(this.stepFinishDate);
					String status =rset.GetString(this.stepStatus);
					String caller =rset.GetString(this.stepCaller);
					SimpleStep step = new SimpleStep(id, entryId, _stepId, actionId, owner, startDate, dueDate, finishDate, status, null, caller);

					currentSteps.Add(step);
				}
				rset.Close();
				for(int j=0;j<stepIds.Count;j++){
					long id=(long)stepIds[j];
					ArrayList prevIdsList = new ArrayList();
					stmt2.Parameters.Clear();
					stmt2.Parameters.Add(createDataParameter(stepId, id));
					SafeDataReader rs =new SafeDataReader( stmt2.ExecuteReader());

					while (rs.Read())
					{
						long prevId =rs.GetInt32(this.stepPreviousId);
						prevIdsList.Add(prevId);
					}
					rs.Close();
					long[] prevIds = new long[prevIdsList.Count];
					prevIdsList.CopyTo(prevIds);
					(currentSteps[j] as SimpleStep).PreviousStepIds=prevIds;
					
				
				}

				return currentSteps;
			}
			catch (Exception e)
			{
				throw new StoreException("Unable to locate history steps for workflow instance #" + entryId, e);
			}
			finally
			{
				cleanup(null, stmt2, null);
				cleanup(conn, stmt, rset);
			}
		}

		public virtual void Init(IDictionary props)
		{
			entryTable = getInitProperty(props, "entry.table", "OS_WFENTRY");
			entryId = getInitProperty(props, "entry.id", "ID");
			entryName = getInitProperty(props, "entry.name", "NAME");
			entryState = getInitProperty(props, "entry.state", "STATE");
			historyTable = getInitProperty(props, "history.table", "OS_HISTORYSTEP");
			currentTable = getInitProperty(props, "current.table", "OS_CURRENTSTEP");
			currentPrevTable = getInitProperty(props, "currentPrev.table", "OS_CURRENTSTEP_PREV");
			historyPrevTable = getInitProperty(props, "historyPrev.table", "OS_HISTORYSTEP_PREV");
			stepId = getInitProperty(props, "step.id", "ID");
			stepEntryId = getInitProperty(props, "step.entryId", "ENTRY_ID");
			stepStepId = getInitProperty(props, "step.stepId", "STEP_ID");
			stepActionId = getInitProperty(props, "step.actionId", "ACTION_ID");
			stepOwner = getInitProperty(props, "step.owner", "OWNER");
			stepCaller = getInitProperty(props, "step.caller", "CALLER");
			stepStartDate = getInitProperty(props, "step.startDate", "START_DATE");
			stepFinishDate = getInitProperty(props, "step.finishDate", "FINISH_DATE");
			stepDueDate = getInitProperty(props, "step.dueDate", "DUE_DATE");
			stepStatus = getInitProperty(props, "step.status", "STATUS");
			stepPreviousId = getInitProperty(props, "step.previousId", "PREVIOUS_ID");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -