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