mirror of
https://github.com/logos-storage/nim-leveldb.git
synced 2026-02-04 05:43:08 +00:00
Compare commits
No commits in common. "master" and "0.1.0" have entirely different histories.
7
.github/workflows/main.yml
vendored
7
.github/workflows/main.yml
vendored
@ -8,15 +8,14 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macOS-latest, windows-latest]
|
os: [ubuntu-latest, macOS-latest, windows-latest]
|
||||||
nim: [stable, 1.6.18, 2.0.12]
|
nim: [stable, 1.6.18]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
submodules: true
|
submodules: true
|
||||||
- uses: jiro4989/setup-nim-action@v2
|
- uses: iffy/install-nim@v4
|
||||||
with:
|
with:
|
||||||
nim-version: ${{matrix.nim}}
|
version: ${{ matrix.nim }}
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: nimble install -y
|
run: nimble install -y
|
||||||
- name: Test
|
- name: Test
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@ -8,5 +8,4 @@ leveldbtool
|
|||||||
*.html
|
*.html
|
||||||
*.css
|
*.css
|
||||||
build
|
build
|
||||||
nimbledeps
|
|
||||||
*.exe
|
|
||||||
|
|||||||
24
README.md
24
README.md
@ -6,8 +6,6 @@ Original nim LevelDB wrapper: [HERE](https://github.com/zielmicha/leveldb.nim)
|
|||||||
|
|
||||||
Replacing of system library dependency with self-contained C/CPP interoperability by (Codex.Storage)[https://codex.storage]
|
Replacing of system library dependency with self-contained C/CPP interoperability by (Codex.Storage)[https://codex.storage]
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
Create a database:
|
Create a database:
|
||||||
```Nim
|
```Nim
|
||||||
import leveldbstatic
|
import leveldbstatic
|
||||||
@ -51,25 +49,3 @@ Iterate over subset of database content:
|
|||||||
|
|
||||||
db.close()
|
db.close()
|
||||||
```
|
```
|
||||||
|
|
||||||
## Compiling with optimizations
|
|
||||||
|
|
||||||
CMake is used during compilation to determine which of the following optimization options are enabled. You can set the following nim compiler flags to 0 or 1 to override them:
|
|
||||||
- fdatasync from <unistd.h> `--passC:-DHAVE_FDATASYNC=1`
|
|
||||||
- F_FULLSYNC from <fcntl.h> `--passC:-DHAVE_FULLFSYNC=1`
|
|
||||||
- O_CLOEXEC from <fcntl.h> `--passC:-DHAVE_O_CLOEXEC=1`
|
|
||||||
- crc32c from <crc32c/crc32c.h> `--passC:-DHAVE_CRC32C=1`
|
|
||||||
- snappy from <snappy.h> `--passC:-DHAVE_SNAPPY=1`
|
|
||||||
- zstd from <zstd.h> `--passC:-DHAVE_ZSTD=1`
|
|
||||||
|
|
||||||
## Updating
|
|
||||||
|
|
||||||
When you want to update this library to a new version of LevelDB, follow these steps:
|
|
||||||
- Update LevelDB submodule to new version.
|
|
||||||
- Run 'build.sh'.
|
|
||||||
- Run 'nimble build' and 'nimble test'.
|
|
||||||
- Make sure everything's working.
|
|
||||||
- Increment version of this library in 'leveldbstatic.nimble'.
|
|
||||||
- Commit the changes.
|
|
||||||
- Tag the commit with the new version number.
|
|
||||||
- Push.
|
|
||||||
|
|||||||
4
build.sh
4
build.sh
@ -21,7 +21,7 @@ rm -Rf "${sourceDir}/benchmarks"
|
|||||||
rm "${sourceDir}/util/testutil.cc"
|
rm "${sourceDir}/util/testutil.cc"
|
||||||
|
|
||||||
# Prelude:
|
# Prelude:
|
||||||
cat "${root}/leveldbstatic/prelude.nim" > "${output}"
|
cat "${root}/leveldb/prelude.nim" > "${output}"
|
||||||
echo >> "${output}"
|
echo >> "${output}"
|
||||||
|
|
||||||
# assemble files to be compiled:
|
# assemble files to be compiled:
|
||||||
@ -47,8 +47,10 @@ toast \
|
|||||||
--includeDirs="${sourceDir}/helpers/memenv" \
|
--includeDirs="${sourceDir}/helpers/memenv" \
|
||||||
--includeDirs="${sourceDir}/port" \
|
--includeDirs="${sourceDir}/port" \
|
||||||
--includeDirs="${sourceDir}/include" \
|
--includeDirs="${sourceDir}/include" \
|
||||||
|
--includeDirs="${buildDir}/include" \
|
||||||
"${sourceDir}/include/leveldb/c.h" >> "${output}"
|
"${sourceDir}/include/leveldb/c.h" >> "${output}"
|
||||||
|
|
||||||
sed -i 's/\bpassC\b/passc/g' "${output}"
|
sed -i 's/\bpassC\b/passc/g' "${output}"
|
||||||
sed -i 's/{\.compile\:\ \"\./{\.compile\:\ root\ \&\ \"/g' "${output}"
|
sed -i 's/{\.compile\:\ \"\./{\.compile\:\ root\ \&\ \"/g' "${output}"
|
||||||
sed -i 's/{\.passc\:\ \"-I\./{\.passc\:\ \"-I\"\ \&\ root\ \&\ \"/g' "${output}"
|
sed -i 's/{\.passc\:\ \"-I\./{\.passc\:\ \"-I\"\ \&\ root\ \&\ \"/g' "${output}"
|
||||||
|
|
||||||
|
|||||||
38
build/include/port/port_config.h
Normal file
38
build/include/port/port_config.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright 2017 The LevelDB Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file. See the AUTHORS file for names of contributors.
|
||||||
|
|
||||||
|
#ifndef STORAGE_LEVELDB_PORT_PORT_CONFIG_H_
|
||||||
|
#define STORAGE_LEVELDB_PORT_PORT_CONFIG_H_
|
||||||
|
|
||||||
|
// Define to 1 if you have a definition for fdatasync() in <unistd.h>.
|
||||||
|
#if !defined(HAVE_FDATASYNC)
|
||||||
|
#define HAVE_FDATASYNC 1
|
||||||
|
#endif // !defined(HAVE_FDATASYNC)
|
||||||
|
|
||||||
|
// Define to 1 if you have a definition for F_FULLFSYNC in <fcntl.h>.
|
||||||
|
#if !defined(HAVE_FULLFSYNC)
|
||||||
|
#define HAVE_FULLFSYNC 0
|
||||||
|
#endif // !defined(HAVE_FULLFSYNC)
|
||||||
|
|
||||||
|
// Define to 1 if you have a definition for O_CLOEXEC in <fcntl.h>.
|
||||||
|
#if !defined(HAVE_O_CLOEXEC)
|
||||||
|
#define HAVE_O_CLOEXEC 1
|
||||||
|
#endif // !defined(HAVE_O_CLOEXEC)
|
||||||
|
|
||||||
|
// Define to 1 if you have Google CRC32C.
|
||||||
|
#if !defined(HAVE_CRC32C)
|
||||||
|
#define HAVE_CRC32C 0
|
||||||
|
#endif // !defined(HAVE_CRC32C)
|
||||||
|
|
||||||
|
// Define to 1 if you have Google Snappy.
|
||||||
|
#if !defined(HAVE_SNAPPY)
|
||||||
|
#define HAVE_SNAPPY 0
|
||||||
|
#endif // !defined(HAVE_SNAPPY)
|
||||||
|
|
||||||
|
// Define to 1 if you have Zstd.
|
||||||
|
#if !defined(HAVE_Zstd)
|
||||||
|
#define HAVE_ZSTD 0
|
||||||
|
#endif // !defined(HAVE_ZSTD)
|
||||||
|
|
||||||
|
#endif // STORAGE_LEVELDB_PORT_PORT_CONFIG_H_
|
||||||
@ -76,13 +76,6 @@ type
|
|||||||
|
|
||||||
LevelDbException* = object of CatchableError
|
LevelDbException* = object of CatchableError
|
||||||
|
|
||||||
IterNext* = proc(): (string, string) {.gcsafe, closure, raises: [LevelDbException].}
|
|
||||||
IterDispose* = proc() {.gcsafe, closure, raises: [].}
|
|
||||||
LevelDbQueryIter* = ref object
|
|
||||||
finished*: bool
|
|
||||||
next*: IterNext
|
|
||||||
dispose*: IterDispose
|
|
||||||
|
|
||||||
const
|
const
|
||||||
version* = block:
|
version* = block:
|
||||||
const configFile = "leveldbstatic.nimble"
|
const configFile = "leveldbstatic.nimble"
|
||||||
@ -413,81 +406,6 @@ iterator iterRange*(self: LevelDb, start, limit: string): (string, string) =
|
|||||||
break
|
break
|
||||||
yield (key, value)
|
yield (key, value)
|
||||||
|
|
||||||
|
|
||||||
proc getIterKey(iterPtr: ptr leveldb_iterator_t): string =
|
|
||||||
var len: csize_t
|
|
||||||
var str: cstring
|
|
||||||
|
|
||||||
str = leveldb_iter_key(iterPtr, addr len)
|
|
||||||
return newString(str, len)
|
|
||||||
|
|
||||||
proc getIterValue(iterPtr: ptr leveldb_iterator_t): string =
|
|
||||||
var len: csize_t
|
|
||||||
var str: cstring
|
|
||||||
|
|
||||||
str = leveldb_iter_value(iterPtr, addr len)
|
|
||||||
return newString(str, len)
|
|
||||||
|
|
||||||
proc seekToQueryStart(iterPtr: ptr leveldb_iterator_t, prefix: string, skip: int) =
|
|
||||||
if prefix.len > 0:
|
|
||||||
leveldb_iter_seek(iterPtr, prefix, prefix.len.csize_t)
|
|
||||||
else:
|
|
||||||
leveldb_iter_seek_to_first(iterPtr)
|
|
||||||
for i in 0..<skip:
|
|
||||||
leveldb_iter_next(iterPtr)
|
|
||||||
|
|
||||||
proc closeIter(iter: LevelDbQueryIter, iterPtr: ptr leveldb_iterator_t) =
|
|
||||||
iter.finished = true
|
|
||||||
leveldb_iter_destroy(iterPtr)
|
|
||||||
|
|
||||||
proc queryIter*(self: LevelDb, prefix: string = "", keysOnly: bool = false, skip: int = 0, limit: int = 0): LevelDbQueryIter =
|
|
||||||
var iterPtr = leveldb_create_iterator(self.db, self.readOptions)
|
|
||||||
|
|
||||||
seekToQueryStart(iterPtr, prefix, skip)
|
|
||||||
|
|
||||||
var
|
|
||||||
iter = LevelDbQueryIter()
|
|
||||||
remaining = limit
|
|
||||||
let emptyResponse = ("", "")
|
|
||||||
|
|
||||||
proc getNext(): (string, string) {.gcsafe, closure.} =
|
|
||||||
if iter.finished:
|
|
||||||
return emptyResponse
|
|
||||||
|
|
||||||
if leveldb_iter_valid(iterPtr) == levelDbFalse or (limit > 0 and remaining == 0):
|
|
||||||
iter.closeIter(iterPtr)
|
|
||||||
return emptyResponse
|
|
||||||
if limit > 0:
|
|
||||||
dec remaining
|
|
||||||
|
|
||||||
let
|
|
||||||
keyStr = getIterKey(iterPtr)
|
|
||||||
valueStr = if keysOnly: "" else: getIterValue(iterPtr)
|
|
||||||
|
|
||||||
var err: cstring = nil
|
|
||||||
leveldb_iter_get_error(iterPtr, addr err)
|
|
||||||
checkError(err)
|
|
||||||
|
|
||||||
leveldb_iter_next(iterPtr)
|
|
||||||
|
|
||||||
if prefix.len > 0:
|
|
||||||
if keyStr.startsWith(prefix):
|
|
||||||
return (keyStr, valueStr)
|
|
||||||
else:
|
|
||||||
iter.closeIter(iterPtr)
|
|
||||||
return emptyResponse
|
|
||||||
else:
|
|
||||||
return (keyStr, valueStr)
|
|
||||||
|
|
||||||
proc dispose() {.gcsafe, closure.} =
|
|
||||||
if not iter.finished:
|
|
||||||
iter.closeIter(iterPtr)
|
|
||||||
|
|
||||||
iter.finished = false
|
|
||||||
iter.next = getNext
|
|
||||||
iter.dispose = dispose
|
|
||||||
return iter
|
|
||||||
|
|
||||||
proc removeDb*(name: string) =
|
proc removeDb*(name: string) =
|
||||||
## Remove the database `name`.
|
## Remove the database `name`.
|
||||||
var err: cstring = nil
|
var err: cstring = nil
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.2.1"
|
version = "0.1.0"
|
||||||
author = "leveldbstatic authors"
|
author = "leveldbstatic authors"
|
||||||
description = "Statically linked LevelDB wrapper for Nim"
|
description = "Statically linked LevelDB wrapper for Nim"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
|
|||||||
@ -1,46 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
const
|
const root = currentSourcePath.parentDir.parentDir
|
||||||
root = currentSourcePath.parentDir.parentDir
|
const envWindows = root/"vendor"/"util"/"env_windows.cc"
|
||||||
envWindows = root/"vendor"/"util"/"env_windows.cc"
|
const envPosix = root/"vendor"/"util"/"env_posix.cc"
|
||||||
envPosix = root/"vendor"/"util"/"env_posix.cc"
|
|
||||||
|
|
||||||
LevelDbCMakeFlags {.strdefine.} =
|
|
||||||
when defined(macosx):
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
elif defined(windows):
|
|
||||||
"-G\"MSYS Makefiles\" -DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
else:
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
|
|
||||||
LevelDbCMakeCommonFlags = " -DCMAKE_POLICY_VERSION_MINIMUM=3.31"
|
|
||||||
|
|
||||||
LevelDbDir {.strdefine.} = $(root/"vendor")
|
|
||||||
buildDir = $(root/"build")
|
|
||||||
|
|
||||||
proc buildLevelDb() =
|
|
||||||
if fileExists(buildDir/"Makefile"):
|
|
||||||
echo "LevelDB already build. Delete '" & buildDir & "' to force rebuild."
|
|
||||||
return
|
|
||||||
|
|
||||||
echo "Initializing submodule..."
|
|
||||||
discard gorge "git submodule deinit -f \"" & root & "\""
|
|
||||||
discard gorge "git submodule update --init --recursive --checkout \"" & root & "\""
|
|
||||||
|
|
||||||
echo "\nClean dir: \"" & buildDir & "\""
|
|
||||||
discard gorge "rm -rf " & buildDir
|
|
||||||
discard gorge "mkdir -p " & buildDir
|
|
||||||
|
|
||||||
let cmd = "cmake -S \"" & LevelDbDir & "\" -B \"" & buildDir & "\" " & LevelDbCMakeFlags & LevelDbCMakeCommonFlags
|
|
||||||
echo "\nBuilding LevelDB: " & cmd
|
|
||||||
let (output, exitCode) = gorgeEx cmd
|
|
||||||
if exitCode != 0:
|
|
||||||
discard gorge "rm -rf " & buildDir
|
|
||||||
echo output
|
|
||||||
raise (ref Defect)(msg: "Failed to build LevelDB")
|
|
||||||
|
|
||||||
static:
|
|
||||||
buildLevelDb()
|
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
{.compile: envWindows.}
|
{.compile: envWindows.}
|
||||||
@ -51,3 +13,13 @@ when defined(windows):
|
|||||||
when defined(posix):
|
when defined(posix):
|
||||||
{.compile: envPosix.}
|
{.compile: envPosix.}
|
||||||
{.passc: "-DLEVELDB_PLATFORM_POSIX".}
|
{.passc: "-DLEVELDB_PLATFORM_POSIX".}
|
||||||
|
|
||||||
|
|
||||||
|
{.passc: "-DHAVE_FDATASYNC=0".}
|
||||||
|
{.passc: "-DHAVE_FULLFSYNC=0".}
|
||||||
|
{.passc: "-DHAVE_O_CLOEXEC=0".}
|
||||||
|
{.passc: "-DHAVE_CRC32C=0".}
|
||||||
|
{.passc: "-DHAVE_SNAPPY=0".}
|
||||||
|
{.passc: "-DHAVE_ZSTD=0".}
|
||||||
|
{.passc: "-DHAVE_Zstd=0".}
|
||||||
|
|
||||||
|
|||||||
@ -1,46 +1,8 @@
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
const
|
const root = currentSourcePath.parentDir.parentDir
|
||||||
root = currentSourcePath.parentDir.parentDir
|
const envWindows = root/"vendor"/"util"/"env_windows.cc"
|
||||||
envWindows = root/"vendor"/"util"/"env_windows.cc"
|
const envPosix = root/"vendor"/"util"/"env_posix.cc"
|
||||||
envPosix = root/"vendor"/"util"/"env_posix.cc"
|
|
||||||
|
|
||||||
LevelDbCMakeFlags {.strdefine.} =
|
|
||||||
when defined(macosx):
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
elif defined(windows):
|
|
||||||
"-G\"MSYS Makefiles\" -DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
else:
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release -DLEVELDB_BUILD_BENCHMARKS=OFF"
|
|
||||||
|
|
||||||
LevelDbCMakeCommonFlags = " -DCMAKE_POLICY_VERSION_MINIMUM=3.31"
|
|
||||||
|
|
||||||
LevelDbDir {.strdefine.} = $(root/"vendor")
|
|
||||||
buildDir = $(root/"build")
|
|
||||||
|
|
||||||
proc buildLevelDb() =
|
|
||||||
if fileExists(buildDir/"Makefile"):
|
|
||||||
echo "LevelDB already build. Delete '" & buildDir & "' to force rebuild."
|
|
||||||
return
|
|
||||||
|
|
||||||
echo "Initializing submodule..."
|
|
||||||
discard gorge "git submodule deinit -f \"" & root & "\""
|
|
||||||
discard gorge "git submodule update --init --recursive --checkout \"" & root & "\""
|
|
||||||
|
|
||||||
echo "\nClean dir: \"" & buildDir & "\""
|
|
||||||
discard gorge "rm -rf " & buildDir
|
|
||||||
discard gorge "mkdir -p " & buildDir
|
|
||||||
|
|
||||||
let cmd = "cmake -S \"" & LevelDbDir & "\" -B \"" & buildDir & "\" " & LevelDbCMakeFlags & LevelDbCMakeCommonFlags
|
|
||||||
echo "\nBuilding LevelDB: " & cmd
|
|
||||||
let (output, exitCode) = gorgeEx cmd
|
|
||||||
if exitCode != 0:
|
|
||||||
discard gorge "rm -rf " & buildDir
|
|
||||||
echo output
|
|
||||||
raise (ref Defect)(msg: "Failed to build LevelDB")
|
|
||||||
|
|
||||||
static:
|
|
||||||
buildLevelDb()
|
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
{.compile: envWindows.}
|
{.compile: envWindows.}
|
||||||
@ -52,9 +14,19 @@ when defined(posix):
|
|||||||
{.compile: envPosix.}
|
{.compile: envPosix.}
|
||||||
{.passc: "-DLEVELDB_PLATFORM_POSIX".}
|
{.passc: "-DLEVELDB_PLATFORM_POSIX".}
|
||||||
|
|
||||||
# Generated @ 2024-12-09T16:35:09+01:00
|
|
||||||
|
{.passc: "-DHAVE_FDATASYNC=0".}
|
||||||
|
{.passc: "-DHAVE_FULLFSYNC=0".}
|
||||||
|
{.passc: "-DHAVE_O_CLOEXEC=0".}
|
||||||
|
{.passc: "-DHAVE_CRC32C=0".}
|
||||||
|
{.passc: "-DHAVE_SNAPPY=0".}
|
||||||
|
{.passc: "-DHAVE_ZSTD=0".}
|
||||||
|
{.passc: "-DHAVE_Zstd=0".}
|
||||||
|
|
||||||
|
|
||||||
|
# Generated @ 2024-05-13T12:00:58+02:00
|
||||||
# Command line:
|
# Command line:
|
||||||
# /home/arnaud/.nimble/pkgs2/nimterop-0.6.13-a93246b2ad5531db11e51de7b2d188c42d95576a/nimterop/toast --compile=./vendor/util/bloom.cc --compile=./vendor/util/arena.cc --compile=./vendor/util/env.cc --compile=./vendor/util/filter_policy.cc --compile=./vendor/util/histogram.cc --compile=./vendor/util/hash.cc --compile=./vendor/util/comparator.cc --compile=./vendor/util/options.cc --compile=./vendor/util/logging.cc --compile=./vendor/util/status.cc --compile=./vendor/util/coding.cc --compile=./vendor/util/cache.cc --compile=./vendor/util/crc32c.cc --compile=./vendor/table/table.cc --compile=./vendor/table/format.cc --compile=./vendor/table/table_builder.cc --compile=./vendor/table/block_builder.cc --compile=./vendor/table/merger.cc --compile=./vendor/table/block.cc --compile=./vendor/table/filter_block.cc --compile=./vendor/table/iterator.cc --compile=./vendor/table/two_level_iterator.cc --compile=./vendor/helpers/memenv/memenv.cc --compile=./vendor/db/filename.cc --compile=./vendor/db/dbformat.cc --compile=./vendor/db/c.cc --compile=./vendor/db/memtable.cc --compile=./vendor/db/version_set.cc --compile=./vendor/db/repair.cc --compile=./vendor/db/builder.cc --compile=./vendor/db/write_batch.cc --compile=./vendor/db/version_edit.cc --compile=./vendor/db/dumpfile.cc --compile=./vendor/db/db_impl.cc --compile=./vendor/db/log_reader.cc --compile=./vendor/db/table_cache.cc --compile=./vendor/db/db_iter.cc --compile=./vendor/db/log_writer.cc --pnim --preprocess --noHeader --includeDirs=./vendor --includeDirs=./vendor/helpers --includeDirs=./vendor/helpers/memenv --includeDirs=./vendor/port --includeDirs=./vendor/include ./vendor/include/leveldb/c.h
|
# /home/ben/.nimble/pkgs/nimterop-0.6.13/nimterop/toast --compile=./vendor/db/log_writer.cc --compile=./vendor/db/db_impl.cc --compile=./vendor/db/db_iter.cc --compile=./vendor/db/dumpfile.cc --compile=./vendor/db/c.cc --compile=./vendor/db/builder.cc --compile=./vendor/db/filename.cc --compile=./vendor/db/write_batch.cc --compile=./vendor/db/table_cache.cc --compile=./vendor/db/version_edit.cc --compile=./vendor/db/dbformat.cc --compile=./vendor/db/log_reader.cc --compile=./vendor/db/memtable.cc --compile=./vendor/db/version_set.cc --compile=./vendor/db/repair.cc --compile=./vendor/table/block.cc --compile=./vendor/table/two_level_iterator.cc --compile=./vendor/table/table_builder.cc --compile=./vendor/table/iterator.cc --compile=./vendor/table/block_builder.cc --compile=./vendor/table/merger.cc --compile=./vendor/table/format.cc --compile=./vendor/table/filter_block.cc --compile=./vendor/table/table.cc --compile=./vendor/util/hash.cc --compile=./vendor/util/arena.cc --compile=./vendor/util/options.cc --compile=./vendor/util/histogram.cc --compile=./vendor/util/crc32c.cc --compile=./vendor/util/env.cc --compile=./vendor/util/filter_policy.cc --compile=./vendor/util/bloom.cc --compile=./vendor/util/logging.cc --compile=./vendor/util/coding.cc --compile=./vendor/util/status.cc --compile=./vendor/util/cache.cc --compile=./vendor/util/comparator.cc --compile=./vendor/helpers/memenv/memenv.cc --pnim --preprocess --noHeader --includeDirs=./vendor --includeDirs=./vendor/helpers --includeDirs=./vendor/helpers/memenv --includeDirs=./vendor/port --includeDirs=./vendor/include --includeDirs=./build/include ./vendor/include/leveldb/c.h
|
||||||
|
|
||||||
{.push hint[ConvFromXtoItselfNotNeeded]: off.}
|
{.push hint[ConvFromXtoItselfNotNeeded]: off.}
|
||||||
import macros
|
import macros
|
||||||
@ -107,44 +79,45 @@ macro defineEnum(typ: untyped): untyped =
|
|||||||
{.passc: "-I" & root & "/vendor/helpers/memenv".}
|
{.passc: "-I" & root & "/vendor/helpers/memenv".}
|
||||||
{.passc: "-I" & root & "/vendor/port".}
|
{.passc: "-I" & root & "/vendor/port".}
|
||||||
{.passc: "-I" & root & "/vendor/include".}
|
{.passc: "-I" & root & "/vendor/include".}
|
||||||
{.compile: root & "/vendor/util/bloom.cc".}
|
{.passc: "-I" & root & "/build/include".}
|
||||||
{.compile: root & "/vendor/util/arena.cc".}
|
{.compile: root & "/vendor/db/log_writer.cc".}
|
||||||
{.compile: root & "/vendor/util/env.cc".}
|
{.compile: root & "/vendor/db/db_impl.cc".}
|
||||||
{.compile: root & "/vendor/util/filter_policy.cc".}
|
{.compile: root & "/vendor/db/db_iter.cc".}
|
||||||
{.compile: root & "/vendor/util/histogram.cc".}
|
{.compile: root & "/vendor/db/dumpfile.cc".}
|
||||||
{.compile: root & "/vendor/util/hash.cc".}
|
|
||||||
{.compile: root & "/vendor/util/comparator.cc".}
|
|
||||||
{.compile: root & "/vendor/util/options.cc".}
|
|
||||||
{.compile: root & "/vendor/util/logging.cc".}
|
|
||||||
{.compile: root & "/vendor/util/status.cc".}
|
|
||||||
{.compile: root & "/vendor/util/coding.cc".}
|
|
||||||
{.compile: root & "/vendor/util/cache.cc".}
|
|
||||||
{.compile: root & "/vendor/util/crc32c.cc".}
|
|
||||||
{.compile: root & "/vendor/table/table.cc".}
|
|
||||||
{.compile: root & "/vendor/table/format.cc".}
|
|
||||||
{.compile: root & "/vendor/table/table_builder.cc".}
|
|
||||||
{.compile: root & "/vendor/table/block_builder.cc".}
|
|
||||||
{.compile: root & "/vendor/table/merger.cc".}
|
|
||||||
{.compile: root & "/vendor/table/block.cc".}
|
|
||||||
{.compile: root & "/vendor/table/filter_block.cc".}
|
|
||||||
{.compile: root & "/vendor/table/iterator.cc".}
|
|
||||||
{.compile: root & "/vendor/table/two_level_iterator.cc".}
|
|
||||||
{.compile: root & "/vendor/helpers/memenv/memenv.cc".}
|
|
||||||
{.compile: root & "/vendor/db/filename.cc".}
|
|
||||||
{.compile: root & "/vendor/db/dbformat.cc".}
|
|
||||||
{.compile: root & "/vendor/db/c.cc".}
|
{.compile: root & "/vendor/db/c.cc".}
|
||||||
|
{.compile: root & "/vendor/db/builder.cc".}
|
||||||
|
{.compile: root & "/vendor/db/filename.cc".}
|
||||||
|
{.compile: root & "/vendor/db/write_batch.cc".}
|
||||||
|
{.compile: root & "/vendor/db/table_cache.cc".}
|
||||||
|
{.compile: root & "/vendor/db/version_edit.cc".}
|
||||||
|
{.compile: root & "/vendor/db/dbformat.cc".}
|
||||||
|
{.compile: root & "/vendor/db/log_reader.cc".}
|
||||||
{.compile: root & "/vendor/db/memtable.cc".}
|
{.compile: root & "/vendor/db/memtable.cc".}
|
||||||
{.compile: root & "/vendor/db/version_set.cc".}
|
{.compile: root & "/vendor/db/version_set.cc".}
|
||||||
{.compile: root & "/vendor/db/repair.cc".}
|
{.compile: root & "/vendor/db/repair.cc".}
|
||||||
{.compile: root & "/vendor/db/builder.cc".}
|
{.compile: root & "/vendor/table/block.cc".}
|
||||||
{.compile: root & "/vendor/db/write_batch.cc".}
|
{.compile: root & "/vendor/table/two_level_iterator.cc".}
|
||||||
{.compile: root & "/vendor/db/version_edit.cc".}
|
{.compile: root & "/vendor/table/table_builder.cc".}
|
||||||
{.compile: root & "/vendor/db/dumpfile.cc".}
|
{.compile: root & "/vendor/table/iterator.cc".}
|
||||||
{.compile: root & "/vendor/db/db_impl.cc".}
|
{.compile: root & "/vendor/table/block_builder.cc".}
|
||||||
{.compile: root & "/vendor/db/log_reader.cc".}
|
{.compile: root & "/vendor/table/merger.cc".}
|
||||||
{.compile: root & "/vendor/db/table_cache.cc".}
|
{.compile: root & "/vendor/table/format.cc".}
|
||||||
{.compile: root & "/vendor/db/db_iter.cc".}
|
{.compile: root & "/vendor/table/filter_block.cc".}
|
||||||
{.compile: root & "/vendor/db/log_writer.cc".}
|
{.compile: root & "/vendor/table/table.cc".}
|
||||||
|
{.compile: root & "/vendor/util/hash.cc".}
|
||||||
|
{.compile: root & "/vendor/util/arena.cc".}
|
||||||
|
{.compile: root & "/vendor/util/options.cc".}
|
||||||
|
{.compile: root & "/vendor/util/histogram.cc".}
|
||||||
|
{.compile: root & "/vendor/util/crc32c.cc".}
|
||||||
|
{.compile: root & "/vendor/util/env.cc".}
|
||||||
|
{.compile: root & "/vendor/util/filter_policy.cc".}
|
||||||
|
{.compile: root & "/vendor/util/bloom.cc".}
|
||||||
|
{.compile: root & "/vendor/util/logging.cc".}
|
||||||
|
{.compile: root & "/vendor/util/coding.cc".}
|
||||||
|
{.compile: root & "/vendor/util/status.cc".}
|
||||||
|
{.compile: root & "/vendor/util/cache.cc".}
|
||||||
|
{.compile: root & "/vendor/util/comparator.cc".}
|
||||||
|
{.compile: root & "/vendor/helpers/memenv/memenv.cc".}
|
||||||
defineEnum(Enum_ch1)
|
defineEnum(Enum_ch1)
|
||||||
const
|
const
|
||||||
leveldb_no_compression* = (0).cint
|
leveldb_no_compression* = (0).cint
|
||||||
|
|||||||
282
tests/test.nim
282
tests/test.nim
@ -21,10 +21,7 @@ proc execNimble(args: varargs[string]): tuple[output: string, exitCode: int] =
|
|||||||
quotedArgs.insert("-y")
|
quotedArgs.insert("-y")
|
||||||
quotedArgs.insert("--nimbleDir:" & tmpNimbleDir)
|
quotedArgs.insert("--nimbleDir:" & tmpNimbleDir)
|
||||||
quotedArgs.insert("nimble")
|
quotedArgs.insert("nimble")
|
||||||
quotedArgs = quotedArgs.map(
|
quotedArgs = quotedArgs.map(proc (x: string): string = "\"" & x & "\"")
|
||||||
proc(x: string): string =
|
|
||||||
"\"" & x & "\""
|
|
||||||
)
|
|
||||||
|
|
||||||
let cmd = quotedArgs.join(" ")
|
let cmd = quotedArgs.join(" ")
|
||||||
result = execCmdEx(cmd)
|
result = execCmdEx(cmd)
|
||||||
@ -36,10 +33,7 @@ proc execTool(args: varargs[string]): tuple[output: string, exitCode: int] =
|
|||||||
quotedArgs.insert(tmpDbDir)
|
quotedArgs.insert(tmpDbDir)
|
||||||
quotedArgs.insert("--database")
|
quotedArgs.insert("--database")
|
||||||
quotedArgs.insert(findExe(tmpNimbleDir / "bin" / "leveldbtool"))
|
quotedArgs.insert(findExe(tmpNimbleDir / "bin" / "leveldbtool"))
|
||||||
quotedArgs = quotedArgs.map(
|
quotedArgs = quotedArgs.map(proc (x: string): string = "\"" & x & "\"")
|
||||||
proc(x: string): string =
|
|
||||||
"\"" & x & "\""
|
|
||||||
)
|
|
||||||
|
|
||||||
if not dirExists(tmpDbDir):
|
if not dirExists(tmpDbDir):
|
||||||
createDir(tmpDbDir)
|
createDir(tmpDbDir)
|
||||||
@ -50,6 +44,7 @@ proc execTool(args: varargs[string]): tuple[output: string, exitCode: int] =
|
|||||||
checkpoint(result.output)
|
checkpoint(result.output)
|
||||||
|
|
||||||
suite "leveldb":
|
suite "leveldb":
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
let env = leveldb_create_default_env()
|
let env = leveldb_create_default_env()
|
||||||
let dbName = $(leveldb_env_get_test_directory(env))
|
let dbName = $(leveldb_env_get_test_directory(env))
|
||||||
@ -102,27 +97,33 @@ suite "leveldb":
|
|||||||
|
|
||||||
test "iter reverse":
|
test "iter reverse":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iter(reverse = true)) == @[("bb", "3"), ("ba", "2"), ("aa", "1")])
|
check(toSeq(db.iter(reverse = true)) ==
|
||||||
|
@[("bb", "3"), ("ba", "2"), ("aa", "1")])
|
||||||
|
|
||||||
test "iter seek":
|
test "iter seek":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iter(seek = "ab")) == @[("ba", "2"), ("bb", "3")])
|
check(toSeq(db.iter(seek = "ab")) ==
|
||||||
|
@[("ba", "2"), ("bb", "3")])
|
||||||
|
|
||||||
test "iter seek reverse":
|
test "iter seek reverse":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iter(seek = "ab", reverse = true)) == @[("ba", "2"), ("aa", "1")])
|
check(toSeq(db.iter(seek = "ab", reverse = true)) ==
|
||||||
|
@[("ba", "2"), ("aa", "1")])
|
||||||
|
|
||||||
test "iter prefix":
|
test "iter prefix":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iterPrefix(prefix = "b")) == @[("ba", "2"), ("bb", "3")])
|
check(toSeq(db.iterPrefix(prefix = "b")) ==
|
||||||
|
@[("ba", "2"), ("bb", "3")])
|
||||||
|
|
||||||
test "iter range":
|
test "iter range":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iterRange(start = "a", limit = "ba")) == @[("aa", "1"), ("ba", "2")])
|
check(toSeq(db.iterRange(start = "a", limit = "ba")) ==
|
||||||
|
@[("aa", "1"), ("ba", "2")])
|
||||||
|
|
||||||
test "iter range reverse":
|
test "iter range reverse":
|
||||||
initData(db)
|
initData(db)
|
||||||
check(toSeq(db.iterRange(start = "bb", limit = "b")) == @[("bb", "3"), ("ba", "2")])
|
check(toSeq(db.iterRange(start = "bb", limit = "b")) ==
|
||||||
|
@[("bb", "3"), ("ba", "2")])
|
||||||
|
|
||||||
test "iter with 0x00":
|
test "iter with 0x00":
|
||||||
db.put("\0z1", "\0ff")
|
db.put("\0z1", "\0ff")
|
||||||
@ -200,265 +201,21 @@ suite "leveldb":
|
|||||||
test "no compress":
|
test "no compress":
|
||||||
db.close()
|
db.close()
|
||||||
let nc = leveldb.open(dbName, compressionType = ctNoCompression)
|
let nc = leveldb.open(dbName, compressionType = ctNoCompression)
|
||||||
defer:
|
defer: nc.close()
|
||||||
nc.close()
|
|
||||||
nc.put("a", "1")
|
nc.put("a", "1")
|
||||||
check(toSeq(nc.iter()) == @[("a", "1")])
|
check(toSeq(nc.iter()) == @[("a", "1")])
|
||||||
|
|
||||||
suite "leveldb queryIter":
|
|
||||||
setup:
|
|
||||||
let env = leveldb_create_default_env()
|
|
||||||
let dbName = $(leveldb_env_get_test_directory(env))
|
|
||||||
let db = leveldb.open(dbName)
|
|
||||||
let
|
|
||||||
k1 = "k1"
|
|
||||||
k2 = "k2"
|
|
||||||
k3 = "l3"
|
|
||||||
v1 = "v1"
|
|
||||||
v2 = "v2"
|
|
||||||
v3 = "v3"
|
|
||||||
empty = ("", "")
|
|
||||||
|
|
||||||
db.put(k1, v1)
|
|
||||||
db.put(k2, v2)
|
|
||||||
db.put(k3, v3)
|
|
||||||
|
|
||||||
teardown:
|
|
||||||
db.close()
|
|
||||||
removeDb(dbName)
|
|
||||||
|
|
||||||
test "iterates all keys and values":
|
|
||||||
let iter = db.queryIter()
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k3, v3)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterate until disposed":
|
|
||||||
let iter = db.queryIter()
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
|
|
||||||
iter.dispose()
|
|
||||||
|
|
||||||
check:
|
|
||||||
iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "skip":
|
|
||||||
let iter = db.queryIter(skip = 1)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k3, v3)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "limit":
|
|
||||||
let iter = db.queryIter(limit = 2)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterates only keys":
|
|
||||||
let iter = db.queryIter(keysOnly = true)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, "")
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, "")
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k3, "")
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterates only 'k', both keys and values":
|
|
||||||
let iter = db.queryIter(prefix = "k")
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterates only 'k', skip":
|
|
||||||
let iter = db.queryIter(prefix = "k", skip = 1)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterate only 'k', limit":
|
|
||||||
let iter = db.queryIter(prefix = "k", limit = 1)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "iterates only 'k', only keys":
|
|
||||||
let iter = db.queryIter(prefix = "k", keysOnly = true)
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, "")
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, "")
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
test "concurrent iterators - 1":
|
|
||||||
let
|
|
||||||
iter1 = db.queryIter()
|
|
||||||
iter2 = db.queryIter()
|
|
||||||
|
|
||||||
check:
|
|
||||||
# 1, then 2
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k1, v1)
|
|
||||||
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k1, v1)
|
|
||||||
|
|
||||||
# 1, 1, then 2, 2
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k2, v2)
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k3, v3)
|
|
||||||
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k2, v2)
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k3, v3)
|
|
||||||
|
|
||||||
# finish 1, then finish 2
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == empty
|
|
||||||
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == empty
|
|
||||||
|
|
||||||
iter1.finished
|
|
||||||
iter2.finished
|
|
||||||
|
|
||||||
test "concurrent iterators - 2":
|
|
||||||
let
|
|
||||||
iter1 = db.queryIter()
|
|
||||||
iter2 = db.queryIter()
|
|
||||||
|
|
||||||
check:
|
|
||||||
# 1, then 2
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k1, v1)
|
|
||||||
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k1, v1)
|
|
||||||
|
|
||||||
# finish 1
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k2, v2)
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k3, v3)
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == empty
|
|
||||||
iter1.finished
|
|
||||||
|
|
||||||
# finish 2
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k2, v2)
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k3, v3)
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == empty
|
|
||||||
iter2.finished
|
|
||||||
|
|
||||||
test "concurrent iterators - dispose":
|
|
||||||
let
|
|
||||||
iter1 = db.queryIter()
|
|
||||||
iter2 = db.queryIter()
|
|
||||||
|
|
||||||
check:
|
|
||||||
# 1, then 2
|
|
||||||
not iter1.finished
|
|
||||||
iter1.next() == (k1, v1)
|
|
||||||
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k1, v1)
|
|
||||||
|
|
||||||
# dispose 1
|
|
||||||
iter1.dispose()
|
|
||||||
|
|
||||||
check:
|
|
||||||
iter1.finished
|
|
||||||
iter1.next() == empty
|
|
||||||
iter1.finished
|
|
||||||
|
|
||||||
# finish 2
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k2, v2)
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == (k3, v3)
|
|
||||||
not iter2.finished
|
|
||||||
iter2.next() == empty
|
|
||||||
iter2.finished
|
|
||||||
|
|
||||||
test "modify while iterating":
|
|
||||||
let iter = db.queryIter()
|
|
||||||
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k1, v1)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k2, v2)
|
|
||||||
|
|
||||||
# insert
|
|
||||||
let
|
|
||||||
k4 = "k4"
|
|
||||||
v4 = "v4"
|
|
||||||
db.put(k4, v4)
|
|
||||||
|
|
||||||
check:
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == (k3, v3)
|
|
||||||
not iter.finished
|
|
||||||
iter.next() == empty
|
|
||||||
iter.finished
|
|
||||||
|
|
||||||
suite "package":
|
suite "package":
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
removeDir(tmpDir)
|
removeDir(tmpDir)
|
||||||
|
|
||||||
test "import as package":
|
test "import as package":
|
||||||
let (output, exitCode) = execNimble("install")
|
let (output, exitCode) = execNimble("install")
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
check output.contains("leveldbstatic installed successfully.") or
|
check output.contains("leveldbstatic installed successfully.")
|
||||||
output.contains("LevelDB already build")
|
|
||||||
|
|
||||||
cd "tests" / "packagetest":
|
cd "tests"/"packagetest":
|
||||||
var (output, exitCode) = execNimble("build")
|
var (output, exitCode) = execNimble("build")
|
||||||
check exitCode == QuitSuccess
|
check exitCode == QuitSuccess
|
||||||
check output.contains("Building")
|
check output.contains("Building")
|
||||||
@ -469,6 +226,7 @@ suite "package":
|
|||||||
check output.contains("leveldb works.")
|
check output.contains("leveldb works.")
|
||||||
|
|
||||||
suite "tool":
|
suite "tool":
|
||||||
|
|
||||||
setup:
|
setup:
|
||||||
removeDir(tmpDir)
|
removeDir(tmpDir)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user