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:
@@ -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()
|
||||
@@ -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
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user