test_writebatchwi.nim
1 # Nim-RocksDB 2 # Copyright 2024 Status Research & Development GmbH 3 # Licensed under either of 4 # 5 # * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0) 6 # * GPL license, version 2.0, ([LICENSE-GPLv2](LICENSE-GPLv2) or https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html) 7 # 8 # at your option. This file may not be copied, modified, or distributed except according to those terms. 9 10 {.used.} 11 12 import std/os, tempfile, unittest2, ../rocksdb/[rocksdb, writebatchwi], ./test_helper 13 14 suite "WriteBatchWIRef Tests": 15 const 16 CF_DEFAULT = "default" 17 CF_OTHER = "other" 18 19 let 20 key1 = @[byte(1)] 21 val1 = @[byte(1)] 22 key2 = @[byte(2)] 23 val2 = @[byte(2)] 24 key3 = @[byte(3)] 25 val3 = @[byte(3)] 26 27 setup: 28 let 29 dbPath = mkdtemp() / "data" 30 db = initReadWriteDb(dbPath, columnFamilyNames = @[CF_DEFAULT, CF_OTHER]) 31 defaultCfHandle = db.getColFamilyHandle(CF_DEFAULT).get() 32 otherCfHandle = db.getColFamilyHandle(CF_OTHER).get() 33 34 teardown: 35 db.close() 36 removeDir($dbPath) 37 38 test "Test writing batch to the default column family": 39 let batch = db.openWriteBatchWithIndex() 40 defer: 41 batch.close() 42 check not batch.isClosed() 43 44 check: 45 batch.put(key1, val1).isOk() 46 batch.put(key2, val2).isOk() 47 batch.put(key3, val3).isOk() 48 batch.count() == 3 49 50 batch.delete(key2).isOk() 51 batch.count() == 4 52 not batch.isClosed() 53 54 batch.getFromBatch(key1).get() == val1 55 batch.getFromBatch(key2).isErr() 56 batch.getFromBatch(key3).get() == val3 57 58 let res = db.write(batch) 59 check: 60 res.isOk() 61 db.write(batch).isOk() # test that it's idempotent 62 db.get(key1).get() == val1 63 db.keyExists(key2).get() == false 64 db.get(key3).get() == val3 65 66 batch.getFromBatch(key1).get() == val1 67 batch.getFromBatch(key2).isErr() 68 batch.getFromBatch(key3).get() == val3 69 70 batch.clear() 71 check: 72 batch.count() == 0 73 not batch.isClosed() 74 75 test "Test writing batch to column family": 76 let batch = db.openWriteBatchWithIndex() 77 defer: 78 batch.close() 79 check not batch.isClosed() 80 81 check: 82 batch.put(key1, val1, otherCfHandle).isOk() 83 batch.put(key2, val2, otherCfHandle).isOk() 84 batch.put(key3, val3, otherCfHandle).isOk() 85 batch.count() == 3 86 87 batch.delete(key2, otherCfHandle).isOk() 88 batch.count() == 4 89 not batch.isClosed() 90 91 batch.getFromBatch(key1, otherCfHandle).get() == val1 92 batch.getFromBatch(key2, otherCfHandle).isErr() 93 batch.getFromBatch(key3, otherCfHandle).get() == val3 94 95 let res = db.write(batch) 96 check: 97 res.isOk() 98 db.get(key1, otherCfHandle).get() == val1 99 db.keyExists(key2, otherCfHandle).get() == false 100 db.get(key3, otherCfHandle).get() == val3 101 102 batch.getFromBatch(key1, otherCfHandle).get() == val1 103 batch.getFromBatch(key2, otherCfHandle).isErr() 104 batch.getFromBatch(key3, otherCfHandle).get() == val3 105 106 batch.clear() 107 check: 108 batch.count() == 0 109 not batch.isClosed() 110 111 test "Test writing to multiple column families in single batch": 112 let batch = db.openWriteBatchWithIndex() 113 defer: 114 batch.close() 115 check not batch.isClosed() 116 117 check: 118 batch.put(key1, val1, defaultCfHandle).isOk() 119 batch.put(key1, val1, otherCfHandle).isOk() 120 batch.put(key2, val2, otherCfHandle).isOk() 121 batch.put(key3, val3, otherCfHandle).isOk() 122 batch.count() == 4 123 124 batch.delete(key2, otherCfHandle).isOk() 125 batch.count() == 5 126 not batch.isClosed() 127 128 let res = db.write(batch) 129 check: 130 res.isOk() 131 db.get(key1, defaultCfHandle).get() == val1 132 db.get(key1, otherCfHandle).get() == val1 133 db.keyExists(key2, otherCfHandle).get() == false 134 db.get(key3, otherCfHandle).get() == val3 135 136 batch.clear() 137 check: 138 batch.count() == 0 139 not batch.isClosed() 140 141 test "Test writing to multiple column families in multiple batches": 142 let 143 batch1 = db.openWriteBatchWithIndex() 144 batch2 = db.openWriteBatchWithIndex() 145 defer: 146 batch1.close() 147 batch2.close() 148 149 check: 150 not batch1.isClosed() 151 not batch2.isClosed() 152 batch1.put(key1, val1).isOk() 153 batch1.delete(key2, otherCfHandle).isOk() 154 batch1.put(key3, val3, otherCfHandle).isOk() 155 batch2.put(key1, val1, otherCfHandle).isOk() 156 batch2.delete(key1, otherCfHandle).isOk() 157 batch2.put(key3, val3).isOk() 158 batch1.count() == 3 159 batch2.count() == 3 160 161 let res1 = db.write(batch1) 162 let res2 = db.write(batch2) 163 check: 164 res1.isOk() 165 res2.isOk() 166 db.get(key1).get() == val1 167 db.keyExists(key2).get() == false 168 db.get(key3).get() == val3 169 db.keyExists(key1, otherCfHandle).get() == false 170 db.keyExists(key2, otherCfHandle).get() == false 171 db.get(key3, otherCfHandle).get() == val3 172 173 # Write batch is unchanged after write 174 batch1.count() == 3 175 batch2.count() == 3 176 not batch1.isClosed() 177 not batch2.isClosed() 178 179 test "Test write empty batch": 180 let batch = db.openWriteBatchWithIndex() 181 defer: 182 batch.close() 183 check not batch.isClosed() 184 185 check batch.count() == 0 186 let res1 = db.write(batch) 187 check: 188 res1.isOk() 189 batch.count() == 0 190 not batch.isClosed() 191 192 test "Test multiple writes to same key": 193 let 194 batch1 = db.openWriteBatchWithIndex(overwriteKey = false) 195 batch2 = db.openWriteBatchWithIndex(overwriteKey = true) 196 defer: 197 batch1.close() 198 batch2.close() 199 check: 200 not batch1.isClosed() 201 not batch2.isClosed() 202 203 check: 204 batch1.put(key1, val1).isOk() 205 batch1.delete(key1).isOk() 206 batch1.put(key1, val3).isOk() 207 batch1.count() == 3 208 batch1.getFromBatch(key1).get() == val3 209 210 batch2.put(key1, val3).isOk() 211 batch2.put(key1, val2).isOk() 212 batch2.put(key1, val1).isOk() 213 batch2.count() == 3 214 batch2.getFromBatch(key1).get() == val1 215 216 test "Put, get and delete empty key": 217 let batch = db.openWriteBatchWithIndex() 218 defer: 219 batch.close() 220 221 let empty: seq[byte] = @[] 222 check: 223 batch.put(empty, val1).isOk() 224 batch.getFromBatch(empty).get() == val1 225 batch.delete(empty).isOk() 226 batch.getFromBatch(empty).isErr() 227 228 test "Test close": 229 let batch = db.openWriteBatchWithIndex() 230 231 check not batch.isClosed() 232 batch.close() 233 check batch.isClosed() 234 batch.close() 235 check batch.isClosed()