/// <summary> /// Creates default cursor type on category with default options. /// </summary> /// <param name="cmc">Native FormOA (Commence) reference.</param> /// <param name="pName">Commence category name.</param> /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param> internal CommenceCursor(FormOA.ICommenceDB cmc, string pName, IRcwReleasePublisher rcwReleasePublisher) { // default cursor type, on category, default flag _cur = cmc.GetCursor(0, pName, 0); _rcwReleasePublisher = rcwReleasePublisher; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Creates custom Category cursor. /// </summary> /// <param name="cmc">Native FormOA (Commence) reference.</param> /// <param name="pCursorType">CmcCursorType.</param> /// <param name="pName">Commence category or view name.</param> /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="pCursorFlags">CmcOptionFlags.</param> internal CommenceCursor(FormOA.ICommenceDB cmc, CmcCursorType pCursorType, string pName, IRcwReleasePublisher rcwReleasePublisher, CmcOptionFlags pCursorFlags) { CursorType = pCursorType; Flags = pCursorFlags; _cur = cmc.GetCursor((int)pCursorType, pName, (int)pCursorFlags); // notice the type conversion _rcwReleasePublisher = rcwReleasePublisher; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Constructor that creates QueryRowSet with set number of items. /// </summary> /// <param name="cur">FormOA.ICommenceCursor reference.</param> /// <param name="nCount">Number of items to query.</param> /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="flags">option flags, must be 0.</param> internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, int nCount, IRcwReleasePublisher rcwpub, CmcOptionFlags flags) { // queryrowset with set number of rows _qrs = cur.GetQueryRowSet(nCount, (int)flags); if (_qrs == null) { throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence."); } _rcwReleasePublisher = rcwpub; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Constructor that creates EditRowSet for particular row identified by RowID. /// </summary> /// <param name="cur">FormOA.ICommenceCursor reference.</param> /// <param name="pRowID">row id.</param> /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="flags">option flags, must be 0.</param> internal CommenceEditRowSet(FormOA.ICommenceCursor cur, string pRowID, IRcwReleasePublisher rcwpub, CmcOptionFlags flags) { // editrowset by ID _ers = cur.GetEditRowSetByID(pRowID, (int)flags); if (_ers == null) { throw new CommenceCOMException("Unable to obtain a EditRowSet from Commence."); } _rcwReleasePublisher = rcwpub; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Constructor that creates DeleteRowSet with all items. /// </summary> /// <param name="cur">FormOA.ICommenceCursor reference.</param> /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="flags">Option flags, must be 0.</param> internal CommenceDeleteRowSet(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwpub, CmcOptionFlags flags) { // deleterowset with all rows _drs = cur.GetDeleteRowSet(cur.RowCount, (int)flags); if (_drs == null) { throw new CommenceCOMException("Unable to obtain a DeleteRowSet from Commence."); } _rcwReleasePublisher = rcwpub; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Creates custom View cursor. /// </summary> /// <param name="cmc">Native FormOA (Commence) reference.</param> /// <param name="pCursorType">CmcCursorType.</param> /// <param name="pName">Commence category or view name.</param> /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="pCursorFlags">CmcOptionFlags.</param> /// <param name="viewType">Viewtype.</param> internal CommenceCursor(FormOA.ICommenceDB cmc, CmcCursorType pCursorType, string pName, IRcwReleasePublisher rcwReleasePublisher, CmcOptionFlags pCursorFlags, string viewType) { CursorType = pCursorType; Flags = pCursorFlags; if (CursorType == CmcCursorType.View) { _viewName = pName; //_viewType = Utils.GetValueFromEnumDescription<CommenceViewType>(viewType); _viewType = Utils.EnumFromAttributeValue <CommenceViewType, StringValueAttribute>(nameof(StringValueAttribute.StringValue), viewType); } _cur = cmc.GetCursor((int)pCursorType, pName, (int)pCursorFlags); // notice the type conversion _rcwReleasePublisher = rcwReleasePublisher; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Public constructor. /// </summary> public CommenceDatabase() { _app = new CommenceApp(); // when we call this first, the next line does not fail when called from COM. // we also want this call to CommenceApp because it contains the check to see if commence.exe is running. _db = _app.Db; /* We create a publisher object so any classes created from this instance can use it. * The idea is that this way, COM clients can create and close the several COM-visible components (CommenceApp, Export) safely. * It would be easier to use a static event notifying all classes that consume a COM resource to release it. * This leads to unwanted behaviour because all instances will be notified. * The down-side of the current approach is that we have to pass the event publisher to all classes that will subscribe to it. * There must be a better way? */ _rcwReleasePublisher = new RcwReleasePublisher(); _rcwReleasePublisher.RCWRelease += _app.RCWReleaseHandler; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Constructor that creates QueryRowSet with all items. /// </summary> /// <param name="cur">FormOA.ICommenceCursor reference.</param> /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="flags">option flags, must be 0.</param> internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwpub, CmcOptionFlags flags) { // queryrowset with all rows try { _qrs = cur.GetQueryRowSet(cur.RowCount, (int)flags); } catch (Exception) { // swallow all exceptions and throw our own. } if (_qrs == null) { throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence."); } _rcwReleasePublisher = rcwpub; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
/// <summary> /// Constructor that creates QueryRowSet for particular row identified by RowID. /// </summary> /// <param name="cur">FormOA.ICommenceCursor reference.</param> /// <param name="pRowID">row or thid id.</param> /// <param name="rcwpub">RCWReleasePublisher object used for COM Interop object cleanup.</param> /// <param name="flags">option flags, must be 0.</param> /// <param name="identifier"><see cref="RowSetIdentifier"/></param> internal CommenceQueryRowSet(FormOA.ICommenceCursor cur, string pRowID, IRcwReleasePublisher rcwpub, CmcOptionFlags flags = CmcOptionFlags.Default, RowSetIdentifier identifier = RowSetIdentifier.RowId) { switch (identifier) { case RowSetIdentifier.RowId: _qrs = cur.GetQueryRowSetByID(pRowID, (int)flags); break; case RowSetIdentifier.Thid: // _qrs = cur.GetQueryRowSetByThid(pRowID, (int)flags); throw new NotSupportedException("GetQueryRowSetByThid no longer supported by Commence API"); //break; } if (_qrs == null) { throw new CommenceCOMException("Unable to obtain a QueryRowSet from Commence."); } _rcwReleasePublisher = rcwpub; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }
private FormOA.ICommenceDB _cmc; // The exposed root level name of Commence is 'FormOA' for reasons unknown to me #region Constructors /// <summary> /// Constructor. /// </summary> /// <exception cref="CommenceNotRunningException">Commence is not running (COM error: 0x80131500).</exception> /// <exception cref="CommenceMultipleInstancesException">Commence is running more than 1 instance (COM error: 0x80131500).</exception> /// <remarks>If the constructor fails because either Commence is not running, /// or Commence is running multiple instances in the same userprofile, an exception is thrown. /// COM users (VBScript, VBA, etc.) will not get a useful error message. /// This is a bit of a problem that I am unsure how to solve. /// We could incorporate a lazy initialization routine and call that as soon as any of the properties are called, /// then return a more useful error to a consumer, but that is very messy from a .NET point of view. /// <para>Note that this behaviour may change in future releases.</para> /// <para>Note that if you want to execute a PowerShell of VBScript script, and Commence is started as administrator (or vice-versa), /// the script will prompt to start another instance of Commence. The userlevel of the user of the assembly must match the userlevel of the Commence instance. /// </para> /// </remarks> public CommenceApp() { /* Commence does not register itself in the ROT (Running Object Table) * Therefore, we can not tell which database to talk to from COM * This is a serious problem that Commence refuses to fix. * Most of the third-party utilities built for Commence do not take this into account, * they will happily try to talk to the first instance they encounter. * Calling CommenceDB when no commence.exe instance is running will fire up commence.exe and an arbitrary database, usually the last one opened. * This can be very much unwanted, especially in TS-like environments, so I tried to eliminate that possibility as much as possible * This assembly will simply not run if commence.exe is not running * The downside of this is that COM users will get an unintelligible error when no or multiple instances are running. * It will also not run if multiple commence.exe processes were started by the same user * It *should* run when different users started the commence.exe process * In that case, it *should* talk to the instance fired by the same user who calls the assembly * This behaviour may be subject to errors when Commence.DB has a non-standard DCOM settings defined. * This has yet to be tested. */ rw = new RcwReleasePublisher(); rw.RCWRelease += RCWReleaseHandler; }
/// <summary> /// Constructor that takes the raw FormOA.ICommenceCursor as parameter /// For use with the *RowSet CommitGetCursor methods /// </summary> /// <param name="cur">FormOA.ICommenceCursor.</param> /// <param name="rcwReleasePublisher">RCWReleasePublisher object used for COM Interop object cleanup.</param> internal CommenceCursor(FormOA.ICommenceCursor cur, IRcwReleasePublisher rcwReleasePublisher) { _cur = cur; // can be used with CommitGetCursor, or use SetCursor to re-use this object _rcwReleasePublisher = rcwReleasePublisher; _rcwReleasePublisher.RCWRelease += this.RCWReleaseHandler; }