1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 */ 7 8/* 9 * Alexg 23-4-06 10 * Based on scr016 TestAssociate test application. 11 */ 12 13package com.sleepycat.db.test; 14 15import org.junit.Before; 16import org.junit.After; 17import org.junit.AfterClass; 18import org.junit.BeforeClass; 19import org.junit.Test; 20import static org.junit.Assert.assertEquals; 21import static org.junit.Assert.fail; 22 23import java.io.File; 24import java.io.FileNotFoundException; 25import com.sleepycat.db.*; 26 27import com.sleepycat.db.DatabaseException; 28 29import com.sleepycat.db.test.TestUtils; 30 31public class AssociateTest { 32 33 public static final String ASSOCTEST_DBNAME = "associatetest.db"; 34 35 public static final String[] DATABASETEST_SAMPLE_DATA = {"abc", "def", "ghi", "JKL", "MNO", "pqrst", "UVW", "y", "Z"}; 36 37 public static Database savedPriDb = null; 38 public static Database savedSecDb = null; 39 40 int callback_count = 0; 41 boolean callback_throws = false; 42 43 @BeforeClass public static void ClassInit() { 44 TestUtils.loadConfig(null); 45 TestUtils.check_file_removed(TestUtils.getDBFileName(ASSOCTEST_DBNAME), true, true); 46 TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ASSOCTEST_DBNAME)); 47 } 48 49 @AfterClass public static void ClassShutdown() { 50 TestUtils.removeall(true, true, TestUtils.BASETEST_DBDIR, TestUtils.getDBFileName(ASSOCTEST_DBNAME)); 51 } 52 53 @Before public void PerTestInit() 54 throws Exception { 55 } 56 57 @After public void PerTestShutdown() 58 throws Exception { 59 } 60 61 /* 62 * Test creating a new database. 63 */ 64 @Test public void test1() 65 throws DatabaseException, FileNotFoundException 66 { 67 int i; 68 EnvironmentConfig envc = new EnvironmentConfig(); 69 envc.setAllowCreate(true); 70 envc.setInitializeCache(true); 71 Environment dbEnv = new Environment(TestUtils.BASETEST_DBFILE, envc); 72 73 DatabaseConfig dbConfig = new DatabaseConfig(); 74 dbConfig.setErrorStream(TestUtils.getErrorStream()); 75 dbConfig.setErrorPrefix("AssociateTest"); 76 dbConfig.setType(DatabaseType.BTREE); 77 dbConfig.setAllowCreate(true); 78 79 Database priDb = dbEnv.openDatabase(null, ASSOCTEST_DBNAME, null, dbConfig); 80 81 SecondaryConfig secConfig = new SecondaryConfig(); 82 secConfig.setAllowCreate(true); 83 secConfig.setType(DatabaseType.BTREE); 84 secConfig.setSortedDuplicates(true); 85 secConfig.setKeyCreator(new Capitalize()); 86 SecondaryDatabase secDb = dbEnv.openSecondaryDatabase(null, ASSOCTEST_DBNAME+"2", null, 87 priDb, secConfig); 88 savedPriDb = priDb; 89 savedSecDb = secDb; 90 91 // Insert records into the database 92 for(i =0; i < DATABASETEST_SAMPLE_DATA.length; i++) 93 { 94 String curdata = DATABASETEST_SAMPLE_DATA[i]; 95 String reversed = (new StringBuffer(curdata)).reverse().toString(); 96 97 DatabaseEntry key = new DatabaseEntry(curdata.getBytes()); 98 key.setReuseBuffer(false); 99 DatabaseEntry data = new DatabaseEntry(reversed.getBytes()); 100 data.setReuseBuffer(false); 101 try { 102 if (priDb.putNoOverwrite(null, key, data) == OperationStatus.KEYEXIST) { 103 // should not in this - since we control the data. 104 TestUtils.DEBUGOUT(2, "Key: " + curdata + " already exists\n"); 105 } 106 } catch(DatabaseException dbe) { 107 TestUtils.ERR("Caught DatabaseException: " + dbe); 108 } 109 } 110 111 DatabaseEntry readkey = new DatabaseEntry(); 112 readkey.setReuseBuffer(false); 113 DatabaseEntry readdata = new DatabaseEntry(); 114 readdata.setReuseBuffer(false); 115 Cursor dbcp = priDb.openCursor(null, CursorConfig.DEFAULT); 116 while (dbcp.getNext(readkey, readdata, LockMode.DEFAULT) == OperationStatus.SUCCESS) { 117 String keystring = new String(readkey.getData()); 118 String datastring = new String(readdata.getData()); 119 String expecteddata = (new StringBuffer(keystring)).reverse().toString(); 120 121 boolean found = false; 122 for(i = 0; i < DATABASETEST_SAMPLE_DATA.length; i++) 123 { 124 if(DATABASETEST_SAMPLE_DATA[i].compareTo(keystring) == 0) 125 found = true; 126 } 127 if(!found) 128 TestUtils.ERR("Key: " + keystring + " retrieved from DB, but never added!"); 129 if(datastring.compareTo(expecteddata) != 0) 130 TestUtils.ERR("Data: " + datastring + " does not match expected data: " + expecteddata); 131 } 132 133 // Test secondary get functionality. 134 DatabaseEntry seckey = new DatabaseEntry(); 135 seckey.setReuseBuffer(false); 136 DatabaseEntry secpkey = new DatabaseEntry(); 137 secpkey.setReuseBuffer(false); 138 DatabaseEntry secdata = new DatabaseEntry(); 139 secdata.setReuseBuffer(false); 140 141 seckey.setData("BC".getBytes()); 142 if(secDb.get(null, seckey, secdata, null) == OperationStatus.SUCCESS) 143 { 144 TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + 145 new String(secdata.getData())); 146 } else { 147 TestUtils.ERR("Secondary get of key: " + new String(seckey.getData()) + " did not succeed."); 148 } 149 // pget 150 if(secDb.get(null, seckey, secpkey, secdata, null) == OperationStatus.SUCCESS) 151 { 152 TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + 153 new String(secdata.getData()) + " pkey: " + new String(secpkey.getData())); 154 155 // ensure that the retrievals are consistent using both primary and secondary keys. 156 DatabaseEntry tmpdata = new DatabaseEntry(); 157 priDb.get(null, secpkey, tmpdata, null); 158 String tmpstr = new String(tmpdata.getData()); 159 if(tmpstr.compareTo(new String(secdata.getData())) != 0) 160 TestUtils.ERR("Data retrieved from matching primary secondary keys is not consistent. secdata: " + new String(secdata.getData()) + 161 " pridata: " + new String(tmpdata.getData())); 162 } else { 163 TestUtils.ERR("Secondary pget of key: " + new String(seckey.getData()) + " did not succeed."); 164 } 165 seckey.setData("KL".getBytes()); 166 if(secDb.get(null, seckey, secdata, null) == OperationStatus.SUCCESS) 167 { 168 TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + 169 new String(secdata.getData())); 170 } else { 171 TestUtils.ERR("Secondary get of key: " + new String(seckey.getData()) + " did not succeed."); 172 } 173 // pget 174 if(secDb.get(null, seckey, secpkey, secdata, null) == OperationStatus.SUCCESS) 175 { 176 TestUtils.DEBUGOUT(2, "seckey: " + new String(seckey.getData()) + " secdata: " + 177 new String(secdata.getData()) + " pkey: " + new String(secpkey.getData())); 178 179 // ensure that the retrievals are consistent using both primary and secondary keys. 180 DatabaseEntry tmpdata = new DatabaseEntry(); 181 priDb.get(null, secpkey, tmpdata, null); 182 String tmpstr = new String(tmpdata.getData()); 183 if(tmpstr.compareTo(new String(secdata.getData())) != 0) 184 TestUtils.ERR("Data retrieved from matching primary secondary keys is not consistent. secdata: " + new String(secdata.getData()) + 185 " pridata: " + new String(tmpdata.getData())); 186 } else { 187 TestUtils.ERR("Secondary pget of key: " + new String(seckey.getData()) + " did not succeed."); 188 } 189 190 } 191 192/************************************************************************************** 193 ************************************************************************************** 194 **************************************************************************************/ 195 /* creates a stupid secondary index as follows: 196 For an N letter key, we use N-1 letters starting at 197 position 1. If the new letters are already capitalized, 198 we return the old array, but with offset set to 1. 199 If the letters are not capitalized, we create a new, 200 capitalized array. This is pretty stupid for 201 an application, but it tests all the paths in the runtime. 202 */ 203 public static class Capitalize implements SecondaryKeyCreator 204 { 205 public boolean createSecondaryKey(SecondaryDatabase secondary, 206 DatabaseEntry key, 207 DatabaseEntry data, 208 DatabaseEntry result) 209 throws DatabaseException 210 { 211 key.setReuseBuffer(false); 212 data.setReuseBuffer(false); 213 result.setReuseBuffer(false); 214 String which = "unknown db"; 215 if (savedPriDb.equals(secondary)) { 216 which = "primary"; 217 } 218 else if (savedSecDb.equals(secondary)) { 219 which = "secondary"; 220 } 221 String keystring = new String(key.getData()); 222 String datastring = new String(data.getData()); 223 TestUtils.DEBUGOUT(2, "secondaryKeyCreate, Db: " + TestUtils.shownull(secondary) + "(" + which + "), key: " + keystring + ", data: " + datastring); 224 int len = key.getSize(); 225 byte[] arr = key.getData(); 226 boolean capped = true; 227 228 if (len < 1) 229 throw new DatabaseException("bad key"); 230 231 result.setSize(len - 1); 232 for (int i=1; capped && i<len; i++) { 233 if (!Character.isUpperCase((char)arr[i])) 234 capped = false; 235 } 236 if (capped) { 237 TestUtils.DEBUGOUT(2, " creating key(1): " + new String(arr, 1, len-1)); 238 result.setData(arr); 239 result.setOffset(1); 240 result.setSize(result.getSize() -1); 241 } 242 else { 243 TestUtils.DEBUGOUT(2, " creating key(2): " + (new String(arr)).substring(1). 244 toUpperCase()); 245 result.setData((new String(arr)).substring(1). 246 toUpperCase().getBytes()); 247 } 248 return true; 249 } 250 } 251 252} 253