1#!/usr/bin/env python 2# 3# Public Domain 2014-2018 MongoDB, Inc. 4# Public Domain 2008-2014 WiredTiger, Inc. 5# 6# This is free and unencumbered software released into the public domain. 7# 8# Anyone is free to copy, modify, publish, use, compile, sell, or 9# distribute this software, either in source code form or as a compiled 10# binary, for any purpose, commercial or non-commercial, and by any 11# means. 12# 13# In jurisdictions that recognize copyright laws, the author or authors 14# of this software dedicate any and all copyright interest in the 15# software to the public domain. We make this dedication for the benefit 16# of the public at large and to the detriment of our heirs and 17# successors. We intend this dedication to be an overt act of 18# relinquishment in perpetuity of all present and future rights to this 19# software under copyright law. 20# 21# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 22# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 23# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 24# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 25# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 26# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 27# OTHER DEALINGS IN THE SOFTWARE. 28 29import wiredtiger, wttest 30from wtscenario import make_scenarios 31 32# test_base04.py 33# Cursor operations 34class test_cursor04(wttest.WiredTigerTestCase): 35 """ 36 Test cursor search and search_near 37 """ 38 table_name1 = 'test_cursor04' 39 nentries = 20 40 41 scenarios = make_scenarios([ 42 ('row', dict(tablekind='row', uri='table')), 43 ('lsm-row', dict(tablekind='row', uri='lsm')), 44 ('col', dict(tablekind='col', uri='table')), 45 ('fix', dict(tablekind='fix', uri='table')) 46 ]) 47 48 def config_string(self): 49 """ 50 Return any additional configuration. 51 This method may be overridden. 52 """ 53 return '' 54 55 def session_create(self, name, args): 56 """ 57 session.create, but report errors more completely 58 """ 59 try: 60 self.session.create(name, args) 61 except: 62 print('**** ERROR in session.create("' + name + '","' + args + '") ***** ') 63 raise 64 65 def create_session_and_cursor(self): 66 tablearg = self.uri + ":" + self.table_name1 67 if self.tablekind == 'row': 68 keyformat = 'key_format=S' 69 else: 70 keyformat = 'key_format=r' # record format 71 if self.tablekind == 'fix': 72 valformat = 'value_format=8t' 73 else: 74 valformat = 'value_format=S' 75 create_args = keyformat + ',' + valformat + self.config_string() 76 self.pr('creating session: ' + create_args) 77 self.session_create(tablearg, create_args) 78 self.pr('creating cursor') 79 return self.session.open_cursor(tablearg, None, None) 80 81 def genkey(self, i): 82 if self.tablekind == 'row': 83 return 'key' + str(i).zfill(5) # return key00001, key00002, etc. 84 else: 85 return long(i+1) 86 87 def genvalue(self, i): 88 if self.tablekind == 'fix': 89 return int(i & 0xff) 90 else: 91 return 'value' + str(i) 92 93 def expect_either(self, cursor, lt, gt): 94 origkey = cursor.get_key() 95 direction = cursor.search_near() 96 self.assertNotEqual(direction, wiredtiger.WT_NOTFOUND) 97 98 # Deletions for 'fix' clear the value, they 99 # do not remove the key, so we expect '0' direction 100 # (that is key found) for fix. 101 if self.tablekind != 'fix': 102 self.assertTrue(direction == 1 or direction == -1) 103 else: 104 self.assertEqual(direction, 0) 105 106 if direction == 1: 107 self.assertEqual(cursor.get_key(), self.genkey(gt)) 108 self.assertEqual(cursor.get_value(), self.genvalue(gt)) 109 elif direction == -1: 110 self.assertEqual(cursor.get_key(), self.genkey(lt)) 111 self.assertEqual(cursor.get_value(), self.genvalue(lt)) 112 else: 113 self.assertEqual(direction, 0) 114 self.assertEqual(cursor.get_key(), origkey) 115 self.assertEqual(cursor.get_value(), 0) 116 117 def test_searches(self): 118 """ 119 Create entries, and read back in a cursor: key=string, value=string 120 """ 121 cursor = self.create_session_and_cursor() 122 123 # Some tests below expect keys between 0-10 to be available 124 self.assertTrue(self.nentries > 10) 125 126 # 0. Populate the key space 127 for i in range(0, self.nentries): 128 cursor[self.genkey(i)] = self.genvalue(i) 129 130 # 1. Calling search for a value that exists 131 self.assertEqual(cursor[self.genkey(5)], self.genvalue(5)) 132 133 # 2. Calling search for a value that does not exist 134 self.assertRaises(KeyError, lambda: cursor[self.genkey(self.nentries)]) 135 136 # 2. Calling search_near for a value beyond the end 137 cursor.set_key(self.genkey(self.nentries)) 138 cmp = cursor.search_near() 139 self.assertEqual(cmp, -1) 140 self.assertEqual(cursor.get_key(), self.genkey(self.nentries-1)) 141 self.assertEqual(cursor.get_value(), self.genvalue(self.nentries-1)) 142 143 # 2.a calling search_near for an existing value 144 cursor.set_key(self.genkey(7)) 145 cmp = cursor.search_near() 146 self.assertEqual(cmp, 0) 147 self.assertEqual(cursor.get_key(), self.genkey(7)) 148 self.assertEqual(cursor.get_value(), self.genvalue(7)) 149 150 # 3. Delete some keys 151 # Deletions for 'fix' clear the value, they 152 # do not remove the key 153 cursor.set_key(self.genkey(0)) 154 cursor.remove() 155 cursor.set_key(self.genkey(5)) 156 cursor.remove() 157 cursor.set_key(self.genkey(9)) 158 cursor.remove() 159 cursor.set_key(self.genkey(10)) 160 cursor.remove() 161 162 #cursor.reset() 163 #for key, value in cursor: 164 # print('key: ' + str(key)) 165 # print('value: ' + str(value)) 166 167 cursor.set_key(self.genkey(0)) 168 cmp = cursor.search_near() 169 if self.tablekind != 'fix': 170 self.assertEqual(cmp, 1) 171 self.assertEqual(cursor.get_key(), self.genkey(1)) 172 self.assertEqual(cursor.get_value(), self.genvalue(1)) 173 else: 174 self.assertEqual(cmp, 0) 175 self.assertEqual(cursor.get_key(), self.genkey(0)) 176 self.assertEqual(cursor.get_value(), 0) 177 178 cursor.set_key(self.genkey(5)) 179 self.expect_either(cursor, 4, 6) 180 181 cursor.set_key(self.genkey(9)) 182 self.expect_either(cursor, 8, 11) 183 184 cursor.set_key(self.genkey(10)) 185 self.expect_either(cursor, 8, 11) 186 187 cursor.close() 188 189if __name__ == '__main__': 190 wttest.run() 191