1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2009 Oracle. All rights reserved. 5 * 6 */ 7using System; 8using System.Collections; 9using System.Collections.Generic; 10using System.IO; 11using System.Text; 12using System.Threading; 13using System.Xml; 14using NUnit.Framework; 15using BerkeleyDB; 16 17namespace CsharpAPITest 18{ 19 [TestFixture] 20 public class JoinCursorTest 21 { 22 private string testFixtureHome; 23 private string testFixtureName; 24 private string testName; 25 private string testHome; 26 27 [TestFixtureSetUp] 28 public void RunBeforeTests() 29 { 30 testFixtureName = "JoinCursorTest"; 31 testFixtureHome = "./TestOut/" + testFixtureName; 32 33 Configuration.ClearDir(testFixtureHome); 34 } 35 36 [Test] 37 public void TestJoin() 38 { 39 testName = "TestJoin"; 40 testHome = testFixtureHome + "/" + testName; 41 string dbFileName = testHome + "/" + testName + ".db"; 42 string secFileName1 = testHome + "/" + "sec_" + testName + "1.db"; 43 string secFileName2 = testHome + "/" + "sec_" + testName + "2.db"; 44 45 Configuration.ClearDir(testHome); 46 47 // Open a primary database. 48 BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig(); 49 dbCfg.Creation = CreatePolicy.IF_NEEDED; 50 BTreeDatabase db = BTreeDatabase.Open(dbFileName, dbCfg); 51 52 /* 53 * Open two databases, their secondary databases and 54 * secondary cursors. 55 */ 56 SecondaryBTreeDatabase secDB1, secDB2; 57 SecondaryCursor[] cursors = new SecondaryCursor[2]; 58 GetSecCursor(db, secFileName1, 59 new SecondaryKeyGenDelegate(KeyGenOnBigByte), 60 out secDB1, out cursors[0], false, null); 61 GetSecCursor(db, secFileName2, 62 new SecondaryKeyGenDelegate(KeyGenOnLittleByte), 63 out secDB2, out cursors[1], true, null); 64 65 // Get join cursor. 66 JoinCursor joinCursor = db.Join(cursors, true); 67 68 // Close all. 69 joinCursor.Close(); 70 cursors[0].Close(); 71 cursors[1].Close(); 72 secDB1.Close(); 73 secDB2.Close(); 74 db.Close(); 75 } 76 77 [Test] 78 public void TestMoveJoinCursor() 79 { 80 testName = "TestMoveJoinCursor"; 81 testHome = testFixtureHome + "/" + testName; 82 string dbFileName = testHome + "/" + testName + ".db"; 83 string secFileName1 = testHome + "/" + "sec_" + testName + "1.db"; 84 string secFileName2 = testHome + "/" + "sec_" + testName + "2.db"; 85 86 Configuration.ClearDir(testHome); 87 88 // Open a primary database. 89 BTreeDatabaseConfig dbCfg = new BTreeDatabaseConfig(); 90 dbCfg.Creation = CreatePolicy.IF_NEEDED; 91 BTreeDatabase db = BTreeDatabase.Open(dbFileName, dbCfg); 92 93 /* 94 * Open a secondary database on high byte of 95 * its data and another secondary database on 96 * little byte of its data. 97 */ 98 SecondaryBTreeDatabase secDB1, secDB2; 99 SecondaryCursor[] cursors = new SecondaryCursor[2]; 100 byte[] byteValue = new byte[1]; 101 102 byteValue[0] = 0; 103 GetSecCursor(db, secFileName1, 104 new SecondaryKeyGenDelegate(KeyGenOnBigByte), 105 out secDB1, out cursors[0], false, 106 new DatabaseEntry(byteValue)); 107 108 byteValue[0] = 1; 109 GetSecCursor(db, secFileName2, 110 new SecondaryKeyGenDelegate(KeyGenOnLittleByte), 111 out secDB2, out cursors[1], true, 112 new DatabaseEntry(byteValue)); 113 114 // Get join cursor. 115 JoinCursor joinCursor = db.Join(cursors, true); 116 117 /* 118 * MoveNextJoinItem do not use data value found 119 * in all of the cursor so the data in Current won't be 120 * changed. 121 */ 122 Assert.IsTrue(joinCursor.MoveNextItem()); 123 Assert.AreEqual(0, joinCursor.Current.Key.Data[ 124 joinCursor.Current.Key.Data.Length - 1]); 125 Assert.AreEqual(1, joinCursor.Current.Key.Data[0]); 126 Assert.IsNull(joinCursor.Current.Value.Data); 127 128 // Iterate on join cursor. 129 foreach (KeyValuePair<DatabaseEntry, DatabaseEntry> pair in joinCursor) 130 { 131 /* 132 * Confirm that the key got by join cursor has 0 at 133 * its highest byte and 1 at its lowest byte. 134 */ 135 Assert.AreEqual(0, pair.Key.Data[pair.Key.Data.Length - 1]); 136 Assert.AreEqual(1, pair.Key.Data[0]); 137 } 138 139 Assert.IsFalse(joinCursor.MoveNext()); 140 141 // Close all. 142 joinCursor.Close(); 143 cursors[0].Close(); 144 cursors[1].Close(); 145 secDB1.Close(); 146 secDB2.Close(); 147 db.Close(); 148 } 149 150 public void GetSecCursor(BTreeDatabase db, 151 string secFileName, SecondaryKeyGenDelegate keyGen, 152 out SecondaryBTreeDatabase secDB, 153 out SecondaryCursor cursor, bool ifCfg, 154 DatabaseEntry data) 155 { 156 // Open secondary database. 157 SecondaryBTreeDatabaseConfig secCfg = 158 new SecondaryBTreeDatabaseConfig(db, keyGen); 159 secCfg.Creation = CreatePolicy.IF_NEEDED; 160 secCfg.Duplicates = DuplicatesPolicy.SORTED; 161 secDB = SecondaryBTreeDatabase.Open(secFileName, secCfg); 162 163 int[] intArray = new int[4]; 164 intArray[0] = 0; 165 intArray[1] = 1; 166 intArray[2] = 2049; 167 intArray[3] = 65537; 168 for (int i = 0; i < 4; i++) 169 { 170 DatabaseEntry record = new DatabaseEntry( 171 BitConverter.GetBytes(intArray[i])); 172 db.Put(record, record); 173 } 174 175 // Get secondary cursor on the secondary database. 176 if (ifCfg == false) 177 cursor = secDB.SecondaryCursor(); 178 else 179 cursor = secDB.SecondaryCursor(new CursorConfig()); 180 181 // Position the cursor. 182 if (data != null) 183 Assert.IsTrue(cursor.Move(data, true)); 184 } 185 186 public DatabaseEntry KeyGenOnLittleByte( 187 DatabaseEntry key, DatabaseEntry data) 188 { 189 byte[] byteArr = new byte[1]; 190 byteArr[0] = data.Data[0]; 191 DatabaseEntry dbtGen = new DatabaseEntry(byteArr); 192 return dbtGen; 193 } 194 195 public DatabaseEntry KeyGenOnBigByte( 196 DatabaseEntry key, DatabaseEntry data) 197 { 198 byte[] byteArr = new byte[1]; 199 byteArr[0] = data.Data[data.Data.Length - 1]; 200 DatabaseEntry dbtGen = new DatabaseEntry(byteArr); 201 return dbtGen; 202 } 203 } 204} 205