feat: initial BaraDB — multimodal database engine in Nim

- LSM-Tree storage engine with WAL, bloom filter, MemTable
- BaraQL query language: lexer (80+ tokens), recursive descent parser, AST
- Vector engine: HNSW + IVF-PQ indexes, 4 distance metrics
- Graph engine: adjacency list, BFS/DFS, Dijkstra, PageRank
- Full-Text Search: inverted index, BM25 ranking, stemming, stop words
- Type system: 17 types (int/float/string/uuid/json/vector/...)
- Async TCP server
- 21 passing tests
This commit is contained in:
2026-05-06 00:22:12 +03:00
commit 6935889877
18 changed files with 2676 additions and 0 deletions
+25
View File
@@ -0,0 +1,25 @@
type
BaraConfig* = object
address*: string
port*: int
dataDir*: string
maxConnections*: int
walEnabled*: bool
compactionStrategy*: CompactionStrategy
CompactionStrategy* = enum
csSizeTiered = "size_tiered"
csLeveled = "leveled"
proc defaultConfig*(): BaraConfig =
BaraConfig(
address: "127.0.0.1",
port: 5432,
dataDir: "./data",
maxConnections: 1000,
walEnabled: true,
compactionStrategy: csLeveled,
)
proc loadConfig*(): BaraConfig =
result = defaultConfig()
+48
View File
@@ -0,0 +1,48 @@
## BaraDB Server — async TCP server
import std/asyncdispatch
import std/asyncnet
import std/strutils
import config
type
Server* = ref object
config: BaraConfig
running: bool
ClientConnection = ref object
socket: AsyncSocket
id: int
proc newServer*(config: BaraConfig): Server =
Server(config: config, running: false)
proc handleClient(server: Server, client: AsyncSocket, clientId: int) {.async.} =
echo "Client ", clientId, " connected"
try:
while true:
let line = await client.recvLine()
if line.len == 0:
break
echo "[", clientId, "] ", line
await client.send("OK\n")
except:
discard
finally:
echo "Client ", clientId, " disconnected"
client.close()
proc run*(server: Server) {.async.} =
server.running = true
var clientId = 0
let sock = newAsyncSocket()
sock.setSockOpt(OptReuseAddr, true)
sock.bindAddr(Port(server.config.port), server.config.address)
sock.listen()
echo "BaraDB listening on ", server.config.address, ":", server.config.port
while server.running:
let client = await sock.accept()
inc clientId
asyncCheck server.handleClient(client, clientId)
proc stop*(server: Server) =
server.running = false
+126
View File
@@ -0,0 +1,126 @@
import std/times
import std/oids
import std/monotimes
type
ValueKind* = enum
vkNull
vkBool
vkInt8
vkInt16
vkInt32
vkInt64
vkFloat32
vkFloat64
vkString
vkBytes
vkUuid
vkDateTime
vkJson
vkArray
vkObject
vkVector
Value* = object
case kind*: ValueKind
of vkNull: discard
of vkBool: boolVal*: bool
of vkInt8: int8Val*: int8
of vkInt16: int16Val*: int16
of vkInt32: int32Val*: int32
of vkInt64: int64Val*: int64
of vkFloat32: float32Val*: float32
of vkFloat64: float64Val*: float64
of vkString: strVal*: string
of vkBytes: bytesVal*: seq[byte]
of vkUuid: uuidVal*: Oid
of vkDateTime: dtVal*: DateTime
of vkJson: jsonVal*: string
of vkArray: arrayVal*: seq[Value]
of vkObject: objVal*: seq[(string, Value)]
of vkVector: vecVal*: seq[float32]
RecordId* = distinct uint64
Record* = object
id*: RecordId
data*: seq[(string, Value)]
SchemaKind* = enum
skScalar
skObject
skLink
skCollection
ScalarType* = enum
stBool = "bool"
stInt8 = "int8"
stInt16 = "int16"
stInt32 = "int32"
stInt64 = "int64"
stFloat32 = "float32"
stFloat64 = "float64"
stString = "str"
stBytes = "bytes"
stUuid = "uuid"
stDateTime = "datetime"
stJson = "json"
stVector = "vector"
Cardinality* = enum
One
Many
PropertyDef* = object
name*: string
typ*: ScalarType
required*: bool
default*: Value
computed*: bool
expr*: string
LinkDef* = object
name*: string
target*: string
cardinality*: Cardinality
required*: bool
properties*: seq[PropertyDef]
onDelete*: DeleteAction
DeleteAction* = enum
daRestrict
daDeleteSource
daAllow
daDeferredRestrict
ObjectTypeDef* = object
name*: string
bases*: seq[string]
properties*: seq[PropertyDef]
links*: seq[LinkDef]
indexes*: seq[IndexDef]
constraints*: seq[ConstraintDef]
IndexDef* = object
name*: string
expr*: string
kind*: IndexKind
IndexKind* = enum
ikBTree
ikHash
ikGiST
ikGIN
ikHNSW
ikIVFPQ
ikFullText
ConstraintDef* = object
name*: string
expr*: string
proc newRecordId*(): RecordId =
RecordId(uint64(getMonoTime().ticks()))
proc `==`*(a, b: RecordId): bool {.borrow.}
proc `$`*(r: RecordId): string = $uint64(r)