// notice we do not do any error checking // we just let the error pass through to Powershell // This means the end user (me!) can see pretty cryptic error messages // but I don't care for now. // TODO: we should incorporate some kind of warning mechanism // when the number of items is large; // in that case the read may take a long time // It would require a significant overhaul of this class though. public static List <List <string> > GetCmcFieldValues( string categoryName, IEnumerable <string> fieldNames, IEnumerable <ICursorFilter> filters, IEnumerable <ConnectedField> relatedColumns, bool useView, bool useThids) { var retval = new List <List <string> >(); using (var db = new CommenceDatabase()) { using (var cur = db.GetCursor(categoryName, useView ? CmcCursorType.View : CmcCursorType.Category, useThids ? CmcOptionFlags.UseThids : CmcOptionFlags.Default)) { if (filters != null) { foreach (var f in filters) { cur.Filters.Add(f); } cur.Filters.Apply(); } if (fieldNames != null) { // by default all columns are included in a cursor // the GetColumns method takes care of setting the column index cur.SetColumns(fieldNames.Cast <object>().ToArray()); } // for related columns, we need a manual way to make sure we get the correct columnnumber int columnIndex = cur.ColumnCount; // we want to start after last position by default if (relatedColumns != null) { // make sure we start at 0 if there were no fields provided // we do that because when a cursor is created, by default all columns are included if (fieldNames == null) { columnIndex = 0; } foreach (var rc in relatedColumns) { cur.SetRelatedColumn(columnIndex, rc.ConnectionName, rc.ToCategory, rc.FieldName); } columnIndex = cur.ColumnCount; } retval = cur.ReadAllRows(); // this may be slow! No CancellationToken possible } } return(retval); }
private void SetPropertiesByView(string viewName) { // if we have just a view, everything changes // we need to create the fieldnames and the connected fields from the columns in the view. // This is non-trivial, because of the mess Commence makes with representing rlated columns. // for some viewtypes it is '%%', for others it is a space. IEnumerable <ICommenceConnection> connNames; IEnumerable <string> viewColumns; List <string> directColumns = new List <string>(); List <ConnectedField> connectedColumns = new List <ConnectedField>(); using (var db = new CommenceDatabase()) using (var cur = db.GetCursor(viewName, CmcCursorType.View, CmcOptionFlags.Default)) { connNames = db.GetConnectionNames(cur.Category); viewColumns = db.GetViewColumnNames(viewName); // loop through all columns to determine if they are a direct field or a connection foreach (var vc in viewColumns) { if (vc.Contains(connDelim)) { string[] cc = vc.Split(new string[] { connDelim }, StringSplitOptions.None); if (cc.Length == 3) { connectedColumns.Add(new ConnectedField(cc[0], cc[1], cc[2])); } } else if (vc.Contains(' ')) { foreach (ICommenceConnection c in connNames) { if (vc.StartsWith(c.Name) && vc.EndsWith(c.ToCategory) && vc.Length == c.Name.Length + c.ToCategory.Length + 1) { connectedColumns.Add(new ConnectedField(c.Name, c.ToCategory, db.GetNameField(c.ToCategory))); break; } } } else // a direct column { directColumns.Add(vc); } } FieldNames = directColumns?.ToArray(); ConnectedFields = connectedColumns?.ToArray(); } }
private void ClearControlCharactersFromCategory(string categoryName, bool doCommit) { using (var db = new CommenceDatabase()) using (var cur = db.GetCursor(categoryName, CmcCursorType.Category, CmcOptionFlags.UseThids)) { rules = GetReplacementRulesForCategory(this.CategoryName); // use the keys in rules to limit our cursor // the keys represent the fieldnames to be processed cur.Columns.AddDirectColumns(rules.Keys.ToArray()); cur.Columns.Apply(); int totalRows = cur.RowCount; changeLog.DatabaseName = db.Name; for (int rows = 0; rows < totalRows; rows += maxRows) { using (var ers = cur.GetEditRowSet(maxRows)) { int rowCount = ers.RowCount; var rowsetIsDirty = ProcessRows(ers, rowCount); if (doCommit && rowsetIsDirty) { int result = ers.Commit(); if (result != 0) // database write failed { try { changeLog.WriteToFile(logFile); } finally { throw new CommenceCOMException($"Commit method failed on rowset between rows {rows} and {rows + rowCount}."); } } } // explicitly close rowset, even though it will be closed automatically. // it is just a safety precaution to prevent Commence // running out of resources before GC kicks in. ers.Close(); } if (rows % 100 == 0) { WriteProgress(new ProgressRecord(0, $"{rows} of {totalRows} ({this.CategoryName})", $"Commence rows processed.")); } } changeLog.WriteToFile(logFile); // all went peachy } }
/// <inheritdoc /> public void ExportView(string viewName, string fileName, IExportSettings settings = null) { if (settings != null) { this.Settings = settings; } // use user-supplied settings using (var db = new CommenceDatabase()) { string _viewName = string.IsNullOrEmpty(viewName) ? GetActiveViewName(db) : viewName; using (ICommenceCursor cur = db.GetCursor(_viewName, CmcCursorType.View, this.Settings.UseThids ? CmcOptionFlags.UseThids : CmcOptionFlags.Default)) { ExportCursor(cur, fileName, this.Settings); } } }
protected override void ProcessRecord() { using (var db = new CommenceDatabase()) using (var cur = db.GetCursor(Category)) // this may also fail { int total = cur.RowCount; cur.Filters.Add(Filter); try { cur.Filters.Apply(); } catch { WriteVerbose($"Could not apply filter '{Filter}' to category '{Category}'. Check the spelling of the category- and fieldname(s) and make sure filterqualifier can be applied to the fieldtypes you provided."); WriteObject(false); return; } WriteVerbose($"Succesfully applied filter '{Filter}' to category '{Category}'. {cur.RowCount} of {total} items returned."); WriteObject(true); } }
internal static void ExportCursor(string categoryName, IEnumerable <ICursorFilter> filters, string[] fieldNames, IEnumerable <ConnectedField> connectedFields, string path, IExportSettings options) { // we got fieldnames, so we have to create a custom cursor using (var db = new CommenceDatabase()) using (var cur = db.GetCursor(categoryName)) { if (fieldNames != null && fieldNames.Any()) { cur.Columns.AddDirectColumns(fieldNames); } // in this case the cursor will hold all columns, because non was exlicitly specified // we need to explicitly clear it // in this case we will do so by adding the Name field else { cur.Columns.AddDirectColumn(db.GetNameField(categoryName)); } if (connectedFields != null) { foreach (var cf in connectedFields) { cur.Columns.AddRelatedColumn(cf.ConnectionName, cf.ToCategory, cf.FieldName); } } cur.Columns.Apply(); if (filters != null) { foreach (var f in filters) { cur.Filters.Add(f); } cur.Filters.Apply(); } cur.ExportToFile(path, options); } }
private ICursorFilter CreateFilter(string categoryName, FilterType filterType) { using (ICommenceDatabase db = new CommenceDatabase()) { using (ICommenceCursor cur = db.GetCursor(categoryName)) { switch (filterType) { case FilterType.Field: return((CursorFilterTypeF)cur.Filters.Add(_model.ClauseNumber, filterType)); case FilterType.ConnectionToItem: return((CursorFilterTypeCTI)cur.Filters.Add(_model.ClauseNumber, filterType)); case FilterType.ConnectionToCategoryField: return((CursorFilterTypeCTCF)cur.Filters.Add(_model.ClauseNumber, filterType)); case FilterType.ConnectionToCategoryToItem: return((CursorFilterTypeCTCTI)cur.Filters.Add(_model.ClauseNumber, filterType)); } } } return(null); }
private IList <ConnectedItem> PopulateConnectedItemNamesList(string searchString) { IList <ConnectedItem> retval = new List <ConnectedItem>(); if (string.IsNullOrEmpty(this.SelectedConnectedCategory)) { return(retval); } using (ICommenceDatabase db = new CommenceDatabase()) { using (ICommenceCursor cur = db.GetCursor(this.SelectedConnectedCategory)) { string nameField = db.GetNameField(this.SelectedConnectedCategory); var columns = this.CategoryDefinition.Clarified ? new[] { nameField, this.CategoryDefinition.ClarifyField } : new[] { nameField }; if (!cur.SetColumns(columns)) { return(retval); } // something went wrong bad var number = cur.RowCount; if (string.IsNullOrEmpty(searchString)) { if (number == 0) { retval.Add(new ConnectedItem("(No items to display)", null, null, null)); return(retval); } else if (number < 1000) { return(GetConnectedItems(cur).ToList()); } else { retval.Add(new ConnectedItem("(Too many items to display.)", null, null, null)); return(retval); } } else { CursorFilterTypeF f = cur.Filters.Create(1, FilterType.Field); f.FieldValue = this.ConnectedItemSearchString; f.FieldName = nameField; f.Qualifier = FilterQualifier.Contains; int count = cur.Filters.Apply(); if (count > 1000) { retval.Add(new ConnectedItem("(Too many items to display)", null, null, null)); return(retval); } else if (count == 0) { retval.Add(new ConnectedItem($"(No items contain '{ this.ConnectedItemSearchString }')", null, null, null)); return(retval); } else { return(GetConnectedItems(cur).ToList()); } } } } }