// generate a set of random data for a record using the given recordID and random number seed private byte[][] GenerateColumnData(int recordID, int seed) { var data = new byte[this.columnInfos.Length][]; for (int i = 0; i < this.columnInfos.Length; ++i) { if (this.IsColumnAutoinc(this.columnInfos[i].Grbit)) { // don't overwrite autoinc columns data[i] = null; } else if (string.Equals( this.columnInfos[i].Name, "recordID", StringComparison.InvariantCultureIgnoreCase)) { // this is the primary index column, set it to the recordID data[i] = BitConverter.GetBytes(recordID); } else if (this.IsColumnSeparatedLV(this.columnInfos[i])) { var rand = new Random(seed + this.columnInfos[i].Name.GetHashCode()); data[i] = new byte[rand.Next(5, 1024)]; rand.NextBytes(data[i]); } else { var rand = new Random(seed + this.columnInfos[i].Name.GetHashCode()); // get some data if (0 == rand.Next(4)) { // null column data[i] = null; } else { data[i] = DataGenerator.GetRandomColumnData( this.columnInfos[i].Coltyp, this.columnInfos[i].Cp, rand); } } } return(data); }
/// <summary> /// Run the test. /// </summary> public void Run() { JET_SESID sesid; Api.JetBeginSession(this.instance, out sesid, null, null); Console.WriteLine("Temporary table tests"); Api.JetBeginTransaction(sesid); var ci = new CultureInfo("en-us"); var tt = new JET_OPENTEMPORARYTABLE { prgcolumndef = (from coltyp in this.coltyps select new JET_COLUMNDEF { coltyp = coltyp, cp = JET_CP.Unicode }). ToArray(), pidxunicode = new JET_UNICODEINDEX { lcid = ci.LCID, dwMapFlags = Conversions.LCMapFlagsFromCompareOptions(CompareOptions.IgnoreCase) }, grbit = TempTableGrbit.Indexed, }; tt.ccolumn = tt.prgcolumndef.Length; tt.prgcolumnid = new JET_COLUMNID[tt.prgcolumndef.Length]; tt.prgcolumndef[0].grbit = ColumndefGrbit.TTKey; tt.prgcolumndef[1].grbit = ColumndefGrbit.TTKey | ColumndefGrbit.TTDescending; tt.prgcolumndef[2].grbit = ColumndefGrbit.TTKey; tt.prgcolumndef[3].grbit = ColumndefGrbit.TTKey | ColumndefGrbit.TTDescending; VistaApi.JetOpenTemporaryTable(sesid, tt); int numrecords = 500; var rand = new Random(); Stopwatch stopwatch = Stopwatch.StartNew(); foreach (int i in Randomize(Enumerable.Range(0, numrecords))) { using (var update = new Update(sesid, tt.tableid, JET_prep.Insert)) { for (int j = 0; j < tt.prgcolumndef.Length; ++j) { Api.SetColumn( sesid, tt.tableid, tt.prgcolumnid[j], DataGenerator.GetRandomColumnData(tt.prgcolumndef[j].coltyp, tt.prgcolumndef[j].cp, rand)); } // overwrite the first column, which is an integer key. this will be used to validate // the sorting of the objects Api.SetColumn(sesid, tt.tableid, tt.prgcolumnid[0], BitConverter.GetBytes(i)); update.Save(); } } stopwatch.Stop(); Console.WriteLine("\tInserted {0} records in {1}", numrecords, stopwatch.Elapsed); // iterate over the table to force materialization stopwatch = Stopwatch.StartNew(); BasicClass.Assert( Enumerable.Range(0, numrecords).SequenceEqual(GetColumns(sesid, tt.tableid, tt.prgcolumnid[0])), "Didn't get expected keys"); stopwatch.Stop(); Console.WriteLine("\tRetrieved {0} records in {1}", numrecords, stopwatch.Elapsed); numrecords = 10000; stopwatch = Stopwatch.StartNew(); IEnumerable <int> sortedData = Enumerable.Range(0, numrecords); BasicClass.Assert( sortedData.SequenceEqual(SortWithTempTable(sesid, Randomize(sortedData))), "Data isn't sorted"); stopwatch.Stop(); Console.WriteLine("\tSorted {0} numbers in {1}", numrecords, stopwatch.Elapsed); Console.WriteLine("\tSeeking"); SeekWithTempTable(sesid); Api.JetCommitTransaction(sesid, CommitTransactionGrbit.LazyFlush); Api.JetCloseTable(sesid, tt.tableid); Api.JetEndSession(sesid, EndSessionGrbit.None); }
// insert a record and update its long-values private void UpdateLongValues() { Console.WriteLine("\tUpdate Long-Values"); JET_TABLEID tableid; Api.JetOpenTable(this.sesid, this.dbid, this.table, null, 0, OpenTableGrbit.None, out tableid); int recordID = NumRecords + 17; var rand = new Random(recordID); var data = new byte[this.columnInfos.Length][]; Api.JetBeginTransaction(this.sesid); // insert the record using (var update = new Update(this.sesid, tableid, JET_prep.Insert)) { for (int i = 0; i < this.columnInfos.Length; ++i) { data[i] = null; if (string.Equals( this.columnInfos[i].Name, "recordID", StringComparison.InvariantCultureIgnoreCase)) { // this is the primary index column, set it to the recordID data[i] = BitConverter.GetBytes(recordID); } else if (this.columnInfos[i].Coltyp == JET_coltyp.LongBinary || this.columnInfos[i].Coltyp == JET_coltyp.LongText) { data[i] = DataGenerator.GetRandomColumnData( this.columnInfos[i].Coltyp, this.columnInfos[i].Cp, rand); } if (null != data[i]) { Api.SetColumn(this.sesid, tableid, this.columnInfos[i].Columnid, data[i]); } } update.SaveAndGotoBookmark(); } this.CheckColumns(this.sesid, tableid, data); // update the record using (var update = new Update(this.sesid, tableid, JET_prep.Replace)) { for (int i = 0; i < this.columnInfos.Length; ++i) { if (this.columnInfos[i].Coltyp == JET_coltyp.LongBinary || this.columnInfos[i].Coltyp == JET_coltyp.LongText) { int size = Api.RetrieveColumnSize(this.sesid, tableid, this.columnInfos[i].Columnid).Value; BasicClass.Assert(size == data[i].Length, "Invalid column size"); var setinfo = new JET_SETINFO(); setinfo.ibLongValue = size / 2; setinfo.itagSequence = 1; // the data that will be added to the column byte[] newdata = DataGenerator.GetRandomColumnData( this.columnInfos[i].Coltyp, this.columnInfos[i].Cp, rand); // what the final data should be byte[] finaldata = null; switch (rand.Next(2)) { case 0: // append Api.SetColumn( this.sesid, tableid, this.columnInfos[i].Columnid, newdata, SetColumnGrbit.AppendLV); finaldata = new byte[size + newdata.Length]; Array.Copy(data[i], finaldata, size); Array.Copy(newdata, 0, finaldata, size, newdata.Length); break; case 1: // overwrite and set size Api.JetSetColumn( this.sesid, tableid, this.columnInfos[i].Columnid, newdata, newdata.Length, SetColumnGrbit.SizeLV | SetColumnGrbit.OverwriteLV, setinfo); finaldata = new byte[setinfo.ibLongValue + newdata.Length]; Array.Copy(data[i], finaldata, setinfo.ibLongValue); Array.Copy(newdata, 0, finaldata, setinfo.ibLongValue, newdata.Length); break; } data[i] = finaldata; } } update.SaveAndGotoBookmark(); } this.CheckColumns(this.sesid, tableid, data); Api.JetCommitTransaction(this.sesid, CommitTransactionGrbit.LazyFlush); Api.JetCloseTable(this.sesid, tableid); }