/// <summary> /// Serialize a DataTable to an XmlTextWriter /// </summary> /// <param name="tw"></param> /// <param name="dt"></param> public void SerializeDataTable( XmlTextWriter tw, IDataTableMx iDt) { DataTableMx dt = iDt as DataTableMx; if (dt == null) { return; // ignore if no data table } tw.WriteStartElement("DataTable"); tw.WriteAttributeString("TableName", dt.TableName); tw.WriteStartElement("DataColumns"); foreach (System.Data.DataColumn dc in dt.Columns) { if (Lex.Eq(dc.ColumnName, RowAttributesColumnName) || // don't include these in output Lex.Eq(dc.ColumnName, CheckMarkColumnName)) { continue; } tw.WriteStartElement("DataColumn"); tw.WriteAttributeString("ColumnName", dc.ColumnName); tw.WriteAttributeString("DataType", dc.DataType.FullName); tw.WriteEndElement(); } tw.WriteEndElement(); // end of DataColumns tw.WriteStartElement("DataRows"); foreach (DataRowMx dr in dt.Rows) { // put each row in a CData element object[] oa = dr.ItemArray; StringBuilder sb = VoArray.SerializeToText(oa, 2, oa.Length - 2); tw.WriteCData(sb.ToString()); } tw.WriteEndElement(); // end of DataRows tw.WriteEndElement(); // end of DataTable return; }
/// <summary> /// Write out rows from table if caching has been activated /// </summary> internal void WriteRowsToCache(bool keepLastKeyValue) { DataRowMx dr; string firstKey = "", lastKey = ""; int rowsRemovedInThisCall = 0, ri, ri2, srpi; if (!AllowCaching) { return; } if (CacheStartPosition < 0 || CacheWriter == null) { return; // just return if caching not active } if (DataTableMx.Rows.Count < CacheMiminumRowsRequiredForWriting) { return; } lock (DataTransferLock) // lock the DataTable while changing { if (DataTableFetchPosition < CacheStartPosition) { return; // only cache if fetching beyond start position } if (DataTableFetchPosition < DataTableMx.Rows.Count - 1) { return; // can only cache out if at end of available rows } dr = DataTableMx.Rows[CacheStartPosition]; firstKey = dr[KeyValueVoPos] as string; ri = DataTableMx.Rows.Count - 1; dr = DataTableMx.Rows[ri]; lastKey = dr[KeyValueVoPos] as string; // key we want to keep if (QueryManager.MoleculeGrid != null) { QueryManager.MoleculeGrid.BeginUpdate(); } ri = CacheStartPosition; // start deleting here while (ri < DataTableMx.Rows.Count) { // delete anything with key other than end value dr = DataTableMx.Rows[ri]; string key2 = dr[KeyValueVoPos] as string; // end key with possibly partial data that we want to keep if (keepLastKeyValue && key2 == lastKey) { break; } bool doCacheIO = !PurgeDataTableWithoutWritingToCacheFile; if (doCacheIO) { object[] oa = dr.ItemArray; StringBuilder sb = VoArray.SerializeToText(oa, KeyValueVoPos, oa.Length - KeyValueVoPos); string lenStr = String.Format("{0,8:00000000}", sb.Length); CacheWriter.Write(lenStr); // write length CacheWriter.Write(sb); // write record RowsWrittenToCache++; } DataTableMx.Rows.Remove(dr); RowsRemovedFromDataTable++; rowsRemovedInThisCall++; } DataTableFetchPosition -= rowsRemovedInThisCall; // adjust fetch position for (ri2 = CacheStartPosition; ri2 < DataTableMx.Rows.Count; ri2++) { // adjust row indexes held the row attributes in rows below those paged out DataRowAttributes dra = GetRowAttributes(ri2); if (dra == null) { continue; } dra.FirstRowForKey -= rowsRemovedInThisCall; if (dra.SubRowPos == null) { continue; } for (srpi = 0; srpi < dra.SubRowPos.Length; srpi++) { dra.SubRowPos[srpi] -= rowsRemovedInThisCall; } } } // end of locked section if (QueryManager.MoleculeGrid != null) { QueryManager.MoleculeGrid.EndUpdate(); QueryManager.MoleculeGrid.Refresh(); Application.DoEvents(); } if (DebugCaching) { ClientLog.Message( "CachedRows - DataTable.Rows.Count: " + DataTableMx.Rows.Count + ", FirstKey: " + firstKey + ", LastKey: " + lastKey + ", RowsRemovedFromDataTable (This Call): " + rowsRemovedInThisCall + ", RowsRemovedFromDataTable (Total): " + RowsRemovedFromDataTable + ", RowsWrittenToCache (Total): " + RowsWrittenToCache + ", DataTableFetchPosition: " + DataTableFetchPosition); } return; }