/// <summary> /// Converts a DataTable2 into a DataTable /// </summary> /// <returns></returns> /// <remarks>Can lead to invalid typed data</remarks> //[Obsolete] public DataTable ToDataTable() { DataTable2 dt2 = this; DataTable dt = dt2.SchemaOnly.Clone(); dt.TableName = ""; dt.BeginLoadData(); dt.MinimumCapacity = dt2.Rows.Length; for (int RowIndex = 0; RowIndex < dt2.Rows.Length; RowIndex++) { dt.Rows.Add((object[])dt2.Rows[RowIndex]); } dt.AcceptChanges(); dt.EndLoadData(); return(dt); }
/// <summary> /// Internal use /// </summary> /// <returns></returns> public object Clone() { DataTable2 dt2 = new DataTable2(null, null); dt2.SchemaOnly = SchemaOnly.Clone(); dt2.Rows = new object[Rows.Length]; for (int n = 0; n < Rows.Length; n++) { object[] row = (Rows[n] as Object[]); dt2.Rows[n] = new object[row.Length]; for (int m = 0; m < row.Length; m++) { (dt2.Rows[n] as object[])[m] = row[m]; } } return(dt2); }
/// <summary> /// Called from select when a physical query has been done /// </summary> /// <param name="Fields"></param> /// <param name="From_TableName"></param> /// <param name="Where_NameCondValue"></param> /// <param name="dt"></param> private void QueryCacheSet(string[] Fields, string From_TableName, object[,] Where_NameCondValue,DataTable2 dt) { lock(QueryCache) { if(QueryCache.Count>=QueryCacheMaxLen) QueryCache.RemoveAt(0); QueryCacheEntry q = new QueryCacheEntry(); q.Fields=(string[])Fields.Clone(); q.From_TableName=From_TableName; q.Where_NameCondValue= new object[Where_NameCondValue.GetLength(0),3]; for(int n=0;n<Where_NameCondValue.GetLength(0);n++) { q.Where_NameCondValue[n,0]=Where_NameCondValue[n,0]; q.Where_NameCondValue[n,1]=Where_NameCondValue[n,1]; q.Where_NameCondValue[n,2]=Where_NameCondValue[n,2]; } q.dt=dt; QueryCache.Add(q); } }
/// <summary> /// The same as Select but uses a faster DataTable class for large datasets. /// </summary> /// <param name="Fields"></param> /// <param name="From_TableName"></param> /// <param name="Where_NameCondValue"></param> /// <returns></returns> public DataTable2 Select2(string[] Fields, string From_TableName, object[,] Where_NameCondValue) { if(Fields==null) Fields = new string[]{"*"}; if(Where_NameCondValue==null) Where_NameCondValue = new object[0,0]; lock(this.TableBlocking) { string TableName=From_TableName; //CheckTable(TableName,false); Field[] flds = GetFields(TableName); // map of fields in table Hashtable FieldMap = new Hashtable(); foreach(Field f in flds) { FieldMap[f.Name]=f; } // Columns not existent bool Asterisk=false; ArrayList SelectedFields = new ArrayList(); for(int n=0;n<Fields.Length;n++) { bool bFound=false; if(Fields[n]=="*") { Asterisk=true; break; } foreach(Field f in flds) { if(f.Name==Fields[n]) { bFound=true; SelectedFields.Add(f); break; } } if(!bFound) throw new Exception("Column "+Fields[n]+" unrecognized"); } if(Asterisk) { SelectedFields = new ArrayList(flds); } // Consult cache DataTable2 cacheTable = QueryCacheGet(Fields,From_TableName,Where_NameCondValue); if(cacheTable!=null) return cacheTable; // // Remove deletion field // if(SelectedFields.Contains(DeletedFieldName)) // SelectedFields.Remove(DeletedFieldName); Set ROWIDS; ExecuteWhere(From_TableName,Where_NameCondValue,out ROWIDS); // Build datatable ICollection dataTableFields; if(Asterisk) { ArrayList al = new ArrayList(flds); al.RemoveAt(0);// delete field dataTableFields=al; } else { dataTableFields=SelectedFields; } DataTable2 dt2=null; DataTable dt = new DataTable(TableName); foreach(Field f in dataTableFields) { System.Type t=null; switch(f.type) { case FieldType.ftBoolean: t=typeof(bool); break; case FieldType.ftDecimal: t=typeof(decimal); break; case FieldType.ftDateTime: t=typeof(DateTime); break; case FieldType.ftInt32: t=typeof(int); break; case FieldType.ftInt64: t=typeof(long); break; case FieldType.ftString: t=typeof(string); break; } dt.Columns.Add(f.Name,t); } if(ROWIDS!=null) { int tid = (int)TableName2TID[TableName]; TableNameDef tnd = TID2Def[tid] as TableNameDef; object[][] result = new object[ROWIDS.Count][]; int fnum=0; foreach(Field f in dataTableFields) { if((!f.bIndexed)||(ROWIDS.Count<2)) { int valSize = (int)f.DataSize(); long Capacity = (PageSize-ContentPageDataOffset)/valSize; ArrayList pages = f.DataFID; if((pages.Count*Capacity)<tnd.rownum) throw new Exception("Row num corrupted."); int rownum=0; foreach(long rowid in ROWIDS) { if(fnum==0) result[rownum] = new object[dataTableFields.Count]; long npage = rowid / Capacity; long offset = rowid % Capacity; int page = (int)pages[(int)npage]; //br.BaseStream.Position = (page*PageSize)+ContentPageDataOffset+offset*valSize; //object oldkey = f.ReadData(br); object oldkey = f.ReadData( this.PageReader(page,ContentPageDataOffset+offset*valSize) ); result[rownum][fnum]=oldkey; rownum++; } } else {// accelerator for large rows Index ndx = GetIndex(TableName,f); SortedList sl = null; try { sl = ndx.Row2KeySL(); } catch(Exception ex) { this.Close(); this.LogToFile(ex.Message,ex.StackTrace); throw new Exception("Reverse index error in "+TableName+"."+f.Name+" ."); } int rownum=0; foreach(long rowid in ROWIDS) { if(fnum==0) result[rownum] = new object[dataTableFields.Count]; object oldkey = sl[rowid]; result[rownum][fnum]=oldkey; rownum++; } } fnum++; } dt2 = new DataTable2(dt,result); } else dt2 = new DataTable2(dt,new object[0]); QueryCacheSet(Fields,From_TableName,Where_NameCondValue,dt2); return dt2; } }
/// <summary> /// Internal use /// </summary> /// <returns></returns> public object Clone() { DataTable2 dt2 = new DataTable2(null, null); dt2.SchemaOnly = SchemaOnly.Clone(); dt2.Rows = new object[Rows.Length]; for (int n = 0; n < Rows.Length; n++) { object[] row = (Rows[n] as Object[]); dt2.Rows[n] = new object[row.Length]; for (int m = 0; m < row.Length; m++) { (dt2.Rows[n] as object[])[m] = row[m]; } } return dt2; }