From fc2ba4a836b6b47ae1b17d1c45801c7e06585e19 Mon Sep 17 00:00:00 2001 From: web3-developer <51288821+web3-developer@users.noreply.github.com> Date: Thu, 7 Mar 2024 09:02:24 +0800 Subject: [PATCH] Update open procs to support adding the default column family if it is missing from the columnFamilies list. (#39) --- rocksdb/rocksdb.nim | 37 ++++++++++++++++++------------------ rocksdb/transactiondb.nim | 17 +++++++++-------- tests/test_helper.nim | 8 ++++---- tests/test_transactiondb.nim | 22 +-------------------- 4 files changed, 33 insertions(+), 51 deletions(-) diff --git a/rocksdb/rocksdb.nim b/rocksdb/rocksdb.nim index 501e57a..0a4eb41 100644 --- a/rocksdb/rocksdb.nim +++ b/rocksdb/rocksdb.nim @@ -68,22 +68,22 @@ proc openRocksDb*( dbOpts = defaultDbOptions(), readOpts = defaultReadOptions(), writeOpts = defaultWriteOptions(), - columnFamilies = @[defaultColFamilyDescriptor()]): RocksDBResult[RocksDbReadWriteRef] = + columnFamilies: openArray[ColFamilyDescriptor] = []): RocksDBResult[RocksDbReadWriteRef] = ## Open a RocksDB instance in read-write mode. If `columnFamilies` is empty ## then it will open the default column family. If `dbOpts`, `readOpts`, or ## `writeOpts` are not supplied then the default options will be used. ## By default, column families will be created if they don't yet exist. ## All existing column families must be specified if the database has - ## previously created any column families. This means that the list of column - ## families must always at least contain the default column family. + ## previously created any column families. - if columnFamilies.len == 0: - return err("rocksdb: no column families") + var cfs = columnFamilies.toSeq() + if DEFAULT_COLUMN_FAMILY_NAME notin columnFamilies.mapIt(it.name()): + cfs.add(defaultColFamilyDescriptor()) var - cfNames = columnFamilies.mapIt(it.name().cstring) - cfOpts = columnFamilies.mapIt(it.options.cPtr) - columnFamilyHandles = newSeq[ColFamilyHandlePtr](columnFamilies.len) + cfNames = cfs.mapIt(it.name().cstring) + cfOpts = cfs.mapIt(it.options.cPtr) + cfHandles = newSeq[ColFamilyHandlePtr](cfs.len) errors: cstring let rocksDbPtr = rocksdb_open_column_families( dbOpts.cPtr, @@ -91,7 +91,7 @@ proc openRocksDb*( cfNames.len().cint, cast[cstringArray](cfNames[0].addr), cfOpts[0].addr, - columnFamilyHandles[0].addr, + cfHandles[0].addr, cast[cstringArray](errors.addr)) bailOnErrors(errors) @@ -104,14 +104,14 @@ proc openRocksDb*( writeOpts: writeOpts, ingestOptsPtr: rocksdb_ingestexternalfileoptions_create(), defaultCfName: DEFAULT_COLUMN_FAMILY_NAME, - cfTable: newColFamilyTable(cfNames.mapIt($it), columnFamilyHandles)) + cfTable: newColFamilyTable(cfNames.mapIt($it), cfHandles)) ok(db) proc openRocksDbReadOnly*( path: string, dbOpts = defaultDbOptions(), readOpts = defaultReadOptions(), - columnFamilies = @[defaultColFamilyDescriptor()], + columnFamilies: openArray[ColFamilyDescriptor] = [], errorIfWalFileExists = false): RocksDBResult[RocksDbReadOnlyRef] = ## Open a RocksDB instance in read-only mode. If `columnFamilies` is empty ## then it will open the default column family. If `dbOpts` or `readOpts` are @@ -120,13 +120,14 @@ proc openRocksDbReadOnly*( ## contains any column families, then all or a subset of the existing column ## families can be opened for reading. - if columnFamilies.len == 0: - return err("rocksdb: no column families") + var cfs = columnFamilies.toSeq() + if DEFAULT_COLUMN_FAMILY_NAME notin columnFamilies.mapIt(it.name()): + cfs.add(defaultColFamilyDescriptor()) var - cfNames = columnFamilies.mapIt(it.name().cstring) - cfOpts = columnFamilies.mapIt(it.options.cPtr) - columnFamilyHandles = newSeq[ColFamilyHandlePtr](columnFamilies.len) + cfNames = cfs.mapIt(it.name().cstring) + cfOpts = cfs.mapIt(it.options.cPtr) + cfHandles = newSeq[ColFamilyHandlePtr](cfs.len) errors: cstring let rocksDbPtr = rocksdb_open_for_read_only_column_families( dbOpts.cPtr, @@ -134,7 +135,7 @@ proc openRocksDbReadOnly*( cfNames.len().cint, cast[cstringArray](cfNames[0].addr), cfOpts[0].addr, - columnFamilyHandles[0].addr, + cfHandles[0].addr, errorIfWalFileExists.uint8, cast[cstringArray](errors.addr)) bailOnErrors(errors) @@ -146,7 +147,7 @@ proc openRocksDbReadOnly*( dbOpts: dbOpts, readOpts: readOpts, defaultCfName: DEFAULT_COLUMN_FAMILY_NAME, - cfTable: newColFamilyTable(cfNames.mapIt($it), columnFamilyHandles)) + cfTable: newColFamilyTable(cfNames.mapIt($it), cfHandles)) ok(db) proc isClosed*(db: RocksDbRef): bool {.inline.} = diff --git a/rocksdb/transactiondb.nim b/rocksdb/transactiondb.nim index 6b59e6e..8bfe896 100644 --- a/rocksdb/transactiondb.nim +++ b/rocksdb/transactiondb.nim @@ -49,18 +49,19 @@ proc openTransactionDb*( path: string, dbOpts = defaultDbOptions(), txDbOpts = defaultTransactionDbOptions(), - columnFamilies = @[defaultColFamilyDescriptor()]): RocksDBResult[TransactionDbRef] = + columnFamilies: openArray[ColFamilyDescriptor] = []): RocksDBResult[TransactionDbRef] = ## Open a `TransactionDbRef` with the given options and column families. ## If no column families are provided the default column family will be used. ## If no options are provided the default options will be used. - if columnFamilies.len == 0: - return err("rocksdb: no column families") + var cfs = columnFamilies.toSeq() + if DEFAULT_COLUMN_FAMILY_NAME notin columnFamilies.mapIt(it.name()): + cfs.add(defaultColFamilyDescriptor()) var - cfNames = columnFamilies.mapIt(it.name().cstring) - cfOpts = columnFamilies.mapIt(it.options.cPtr) - columnFamilyHandles = newSeq[ColFamilyHandlePtr](columnFamilies.len) + cfNames = cfs.mapIt(it.name().cstring) + cfOpts = cfs.mapIt(it.options.cPtr) + cfHandles = newSeq[ColFamilyHandlePtr](cfs.len) errors: cstring let txDbPtr = rocksdb_transactiondb_open_column_families( @@ -70,7 +71,7 @@ proc openTransactionDb*( cfNames.len().cint, cast[cstringArray](cfNames[0].addr), cfOpts[0].addr, - columnFamilyHandles[0].addr, + cfHandles[0].addr, cast[cstringArray](errors.addr)) bailOnErrors(errors) @@ -80,7 +81,7 @@ proc openTransactionDb*( path: path, dbOpts: dbOpts, txDbOpts: txDbOpts, - cfTable: newColFamilyTable(cfNames.mapIt($it), columnFamilyHandles)) + cfTable: newColFamilyTable(cfNames.mapIt($it), cfHandles)) ok(db) proc isClosed*(db: TransactionDbRef): bool {.inline.} = diff --git a/tests/test_helper.nim b/tests/test_helper.nim index 208317a..a844064 100644 --- a/tests/test_helper.nim +++ b/tests/test_helper.nim @@ -18,7 +18,7 @@ import proc initReadWriteDb*( path: string, - columnFamilyNames = @["default"]): RocksDbReadWriteRef = + columnFamilyNames: openArray[string] = @[]): RocksDbReadWriteRef = let res = openRocksDb( path, @@ -30,7 +30,7 @@ proc initReadWriteDb*( proc initReadOnlyDb*( path: string, - columnFamilyNames = @["default"]): RocksDbReadOnlyRef = + columnFamilyNames: openArray[string] = @[]): RocksDbReadOnlyRef = let res = openRocksDbReadOnly( path, @@ -48,7 +48,7 @@ proc initBackupEngine*(path: string): BackupEngineRef = proc initTransactionDb*( path: string, - columnFamilyNames = @["default"]): TransactionDbRef = + columnFamilyNames: openArray[string] = @[]): TransactionDbRef = let res = openTransactionDb( path, @@ -56,4 +56,4 @@ proc initTransactionDb*( if res.isErr(): echo res.error() doAssert res.isOk() - res.value() \ No newline at end of file + res.value() diff --git a/tests/test_transactiondb.nim b/tests/test_transactiondb.nim index fbd8ba9..03cb66f 100644 --- a/tests/test_transactiondb.nim +++ b/tests/test_transactiondb.nim @@ -32,7 +32,7 @@ suite "TransactionDbRef Tests": setup: let dbPath = mkdtemp() / "data" - var db = initTransactionDb(dbPath, columnFamilyNames = @[CF_DEFAULT, CF_OTHER]) + var db = initTransactionDb(dbPath, columnFamilyNames = @[CF_OTHER]) teardown: db.close() @@ -111,26 +111,6 @@ suite "TransactionDbRef Tests": tx.get(key2, CF_OTHER).error() == "" tx.get(key3, CF_OTHER).get() == val3 - test "Test setting column family using withDefaultColFamily": - var tx = db.beginTransaction().withDefaultColFamily(CF_OTHER) - defer: tx.close() - check not tx.isClosed() - - check: - tx.put(key1, val1).isOk() - tx.put(key2, val2).isOk() - tx.put(key3, val3).isOk() - - tx.delete(key2).isOk() - not tx.isClosed() - - check: - tx.get(key1, CF_DEFAULT).error() == "" - tx.get(key2, CF_DEFAULT).error() == "" - tx.get(key3, CF_DEFAULT).error() == "" - tx.get(key1, CF_OTHER).get() == val1 - tx.get(key2, CF_OTHER).error() == "" - tx.get(key3, CF_OTHER).get() == val3 test "Test rollback and commit with multiple transactions": var tx1 = db.beginTransaction(columnFamily = CF_DEFAULT)