fix: harden exception handling, break ARC cycles, sync license/client
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
Replace bare except: with CatchableError across storage, query, Raft, backup, and protocol code so Defects are not swallowed. Break uncollectable ARC cycles in server shard/gossip callbacks via Server-owned refs and cursor locals. Align package license with LICENSE (BSD-3-Clause), sync README version, and point test_all at the canonical clients/nim baradb client (parseConnectionString + aliases).
This commit is contained in:
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
**A multimodal database engine written in Nim — 100% native, zero dependencies.**
|
**A multimodal database engine written in Nim — 100% native, zero dependencies.**
|
||||||
|
|
||||||
[](baradadb.nimble)
|
[](baradadb.nimble)
|
||||||
[](docs/index.md)
|
[](docs/index.md)
|
||||||
[](https://github.com/katehonz/barabaDB)
|
[](https://github.com/katehonz/barabaDB)
|
||||||
|
|
||||||
@@ -1568,7 +1568,7 @@ reflects 100% completion across all major phases.
|
|||||||
|
|
||||||
## Changelog
|
## Changelog
|
||||||
|
|
||||||
See [CHANGELOG.md](CHANGELOG.md) for full release history. The latest release (**v1.2.0**) introduces the Unified Search Engine with heap-optimized HNSW, segment-based inverted indexing, boolean queries, phrase/proximity search, n-gram fuzzy matching, faceted search, and Porter2 stemmers for 5 languages.
|
See [CHANGELOG.md](CHANGELOG.md) for full release history. Package version is **v1.1.8**. The **v1.2.0** line (Unreleased) adds core storage hardening (hash MemTable, WAL group commit, schema persistence, ARC/wire stability) and the Unified Search Engine (heap-optimized HNSW, segment inverted index, boolean/phrase/n-gram/facets, multi-language stemmers).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
version = "1.1.8"
|
version = "1.1.8"
|
||||||
author = "BaraDB Team"
|
author = "BaraDB Team"
|
||||||
description = "BaraDB — Multimodal database written in Nim"
|
description = "BaraDB — Multimodal database written in Nim"
|
||||||
license = "Apache-2.0"
|
license = "BSD-3-Clause"
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
bin = @["baradadb", "baramcp"]
|
bin = @["baradadb", "baramcp"]
|
||||||
binDir = "build"
|
binDir = "build"
|
||||||
|
|||||||
@@ -217,4 +217,4 @@ See `examples/ormin_basic.nim` for a full sample.
|
|||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
Apache-2.0
|
BSD-3-Clause
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
author = "BaraDB Team"
|
author = "BaraDB Team"
|
||||||
description = "Official Nim client for BaraDB — async binary protocol client"
|
description = "Official Nim client for BaraDB — async binary protocol client"
|
||||||
license = "Apache-2.0"
|
license = "BSD-3-Clause"
|
||||||
srcDir = "src"
|
srcDir = "src"
|
||||||
|
|
||||||
# Dependencies — only Nim stdlib, no server code
|
# Dependencies — only Nim stdlib, no server code
|
||||||
|
|||||||
@@ -92,6 +92,26 @@ proc newClient*(config: ClientConfig = defaultConfig()): BaraClient =
|
|||||||
sendLock: initAsyncLock(),
|
sendLock: initAsyncLock(),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Aliases for older call sites / server test suite
|
||||||
|
proc defaultClientConfig*(): ClientConfig {.inline.} = defaultConfig()
|
||||||
|
proc newBaraClient*(config: ClientConfig = defaultConfig()): BaraClient {.inline.} =
|
||||||
|
newClient(config)
|
||||||
|
|
||||||
|
proc parseConnectionString*(connStr: string): ClientConfig =
|
||||||
|
## Parse space-separated key=value pairs (libpq-style subset).
|
||||||
|
result = defaultConfig()
|
||||||
|
for part in connStr.split(" "):
|
||||||
|
let kv = part.split("=", 1)
|
||||||
|
if kv.len == 2:
|
||||||
|
case kv[0].toLowerAscii()
|
||||||
|
of "host": result.host = kv[1]
|
||||||
|
of "port": result.port = parseInt(kv[1])
|
||||||
|
of "database", "dbname": result.database = kv[1]
|
||||||
|
of "user", "username": result.username = kv[1]
|
||||||
|
of "password", "pass": result.password = kv[1]
|
||||||
|
of "connect_timeout", "timeout": result.timeoutMs = parseInt(kv[1])
|
||||||
|
else: discard
|
||||||
|
|
||||||
proc nextId*(client: BaraClient): uint32 =
|
proc nextId*(client: BaraClient): uint32 =
|
||||||
inc client.requestId
|
inc client.requestId
|
||||||
client.requestId
|
client.requestId
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ proc formatTimestamp*(ts: int64): string =
|
|||||||
try:
|
try:
|
||||||
let dt = fromUnix(ts)
|
let dt = fromUnix(ts)
|
||||||
result = format(dt, "yyyy-MM-dd HH:mm:ss")
|
result = format(dt, "yyyy-MM-dd HH:mm:ss")
|
||||||
except:
|
except CatchableError:
|
||||||
result = $ts
|
result = $ts
|
||||||
|
|
||||||
proc parseBackupFilename*(filename: string): int64 =
|
proc parseBackupFilename*(filename: string): int64 =
|
||||||
@@ -163,7 +163,7 @@ proc parseBackupFilename*(filename: string): int64 =
|
|||||||
result = 0
|
result = 0
|
||||||
else:
|
else:
|
||||||
result = 0
|
result = 0
|
||||||
except:
|
except CatchableError:
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
proc getArchiveSize*(input: string): int64 =
|
proc getArchiveSize*(input: string): int64 =
|
||||||
@@ -175,7 +175,7 @@ proc getArchiveSize*(input: string): int64 =
|
|||||||
if exitCode == 0:
|
if exitCode == 0:
|
||||||
try:
|
try:
|
||||||
result = parseBiggestInt(strip(outStr))
|
result = parseBiggestInt(strip(outStr))
|
||||||
except:
|
except CatchableError:
|
||||||
result = getFileSize(input) # fallback
|
result = getFileSize(input) # fallback
|
||||||
else:
|
else:
|
||||||
result = getFileSize(input)
|
result = getFileSize(input)
|
||||||
@@ -189,7 +189,7 @@ proc getFreeSpace*(path: string): int64 =
|
|||||||
if exitCode == 0:
|
if exitCode == 0:
|
||||||
try:
|
try:
|
||||||
result = parseBiggestInt(strip(outStr))
|
result = parseBiggestInt(strip(outStr))
|
||||||
except:
|
except CatchableError:
|
||||||
result = -1
|
result = -1
|
||||||
else:
|
else:
|
||||||
result = -1
|
result = -1
|
||||||
@@ -701,14 +701,14 @@ when isMainModule:
|
|||||||
of "input", "i": target = val
|
of "input", "i": target = val
|
||||||
of "keep", "k":
|
of "keep", "k":
|
||||||
try: keepCount = parseInt(val)
|
try: keepCount = parseInt(val)
|
||||||
except: quit("ERROR: --keep must be a number", 1)
|
except CatchableError: quit("ERROR: --keep must be a number", 1)
|
||||||
of "exclude", "e": excludes.add(val)
|
of "exclude", "e": excludes.add(val)
|
||||||
of "level", "l":
|
of "level", "l":
|
||||||
try:
|
try:
|
||||||
compression = parseInt(val)
|
compression = parseInt(val)
|
||||||
if compression < 0 or compression > 9:
|
if compression < 0 or compression > 9:
|
||||||
quit("ERROR: --level must be between 0 and 9", 1)
|
quit("ERROR: --level must be between 0 and 9", 1)
|
||||||
except: quit("ERROR: --level must be a number", 1)
|
except CatchableError: quit("ERROR: --level must be a number", 1)
|
||||||
of "dry-run": dryRun = true
|
of "dry-run": dryRun = true
|
||||||
of "force", "f": force = true
|
of "force", "f": force = true
|
||||||
of "online": online = true
|
of "online": online = true
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ proc sendGossipUdp(gp: GossipProtocol, target: GossipNode, msg: GossipMessage) =
|
|||||||
let data = serialize(msg)
|
let data = serialize(msg)
|
||||||
sock.sendTo(target.host, Port(target.port), cast[string](data))
|
sock.sendTo(target.host, Port(target.port), cast[string](data))
|
||||||
sock.close()
|
sock.close()
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc broadcastGossip(gp: GossipProtocol) =
|
proc broadcastGossip(gp: GossipProtocol) =
|
||||||
@@ -298,7 +298,7 @@ proc handleIncomingGossip(gp: GossipProtocol, data: string, senderAddr: string)
|
|||||||
let parts = host.split(":")
|
let parts = host.split(":")
|
||||||
host = parts[0]
|
host = parts[0]
|
||||||
if parts[1].len > 0:
|
if parts[1].len > 0:
|
||||||
port = try: parseInt(parts[1]) except: gp.gossipPort
|
port = try: parseInt(parts[1]) except CatchableError: gp.gossipPort
|
||||||
let newNode = GossipNode(
|
let newNode = GossipNode(
|
||||||
id: msg.senderId, host: host, port: port,
|
id: msg.senderId, host: host, port: port,
|
||||||
state: nsAlive, incarnation: msg.senderIncarnation,
|
state: nsAlive, incarnation: msg.senderIncarnation,
|
||||||
@@ -306,7 +306,7 @@ proc handleIncomingGossip(gp: GossipProtocol, data: string, senderAddr: string)
|
|||||||
)
|
)
|
||||||
gp.addMember(newNode)
|
gp.addMember(newNode)
|
||||||
gp.applyGossipMessage(msg)
|
gp.applyGossipMessage(msg)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc startHealthCheck*(gp: GossipProtocol, intervalMs: int = 1000) {.async.} =
|
proc startHealthCheck*(gp: GossipProtocol, intervalMs: int = 1000) {.async.} =
|
||||||
@@ -342,14 +342,14 @@ proc startGossipListener*(gp: GossipProtocol) {.async.} =
|
|||||||
# Recreate socket after too many errors
|
# Recreate socket after too many errors
|
||||||
try:
|
try:
|
||||||
gp.sock.close()
|
gp.sock.close()
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
try:
|
try:
|
||||||
gp.sock = newAsyncSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
gp.sock = newAsyncSocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
|
||||||
gp.sock.setSockOpt(OptReuseAddr, true)
|
gp.sock.setSockOpt(OptReuseAddr, true)
|
||||||
gp.sock.bindAddr(Port(gp.gossipPort))
|
gp.sock.bindAddr(Port(gp.gossipPort))
|
||||||
consecutiveErrors = 0
|
consecutiveErrors = 0
|
||||||
except:
|
except CatchableError:
|
||||||
break
|
break
|
||||||
# Exponential backoff with cap
|
# Exponential backoff with cap
|
||||||
let delayMs = min(baseRetryDelayMs * (1 shl min(consecutiveErrors, 6)), 5000)
|
let delayMs = min(baseRetryDelayMs * (1 shl min(consecutiveErrors, 6)), 5000)
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ proc verifyToken*(server: HttpServer, tokenStr: string): (bool, string, string)
|
|||||||
let userId = token.claims["sub"].node.str
|
let userId = token.claims["sub"].node.str
|
||||||
let role = if "role" in token.claims: token.claims["role"].node.str else: "user"
|
let role = if "role" in token.claims: token.claims["role"].node.str else: "user"
|
||||||
return (true, userId, role)
|
return (true, userId, role)
|
||||||
except:
|
except CatchableError:
|
||||||
return (false, "", "")
|
return (false, "", "")
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ proc applyCommitted(node: RaftNode) =
|
|||||||
let parts = entry.command.split(":")
|
let parts = entry.command.split(":")
|
||||||
if parts.len >= 3:
|
if parts.len >= 3:
|
||||||
let action = parts[1]
|
let action = parts[1]
|
||||||
let txnId = try: parseUInt(parts[2]) except: 0'u64
|
let txnId = try: parseUInt(parts[2]) except CatchableError: 0'u64
|
||||||
if action == "PREPARE" and node.onDistTxnPrepare != nil:
|
if action == "PREPARE" and node.onDistTxnPrepare != nil:
|
||||||
discard node.onDistTxnPrepare(txnId, @[])
|
discard node.onDistTxnPrepare(txnId, @[])
|
||||||
elif action == "COMMIT" and node.onDistTxnCommit != nil:
|
elif action == "COMMIT" and node.onDistTxnCommit != nil:
|
||||||
@@ -564,7 +564,7 @@ proc connectToPeer(net: RaftNetwork, peerId: string) {.async.} =
|
|||||||
let sock = newAsyncSocket()
|
let sock = newAsyncSocket()
|
||||||
await sock.connect(host, Port(port))
|
await sock.connect(host, Port(port))
|
||||||
net.peerSockets[peerId] = sock
|
net.peerSockets[peerId] = sock
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc send*(net: RaftNetwork, peerId: string, msg: RaftMessage) {.async.} =
|
proc send*(net: RaftNetwork, peerId: string, msg: RaftMessage) {.async.} =
|
||||||
@@ -577,7 +577,7 @@ proc send*(net: RaftNetwork, peerId: string, msg: RaftMessage) {.async.} =
|
|||||||
bigEndian32(addr header[0], unsafeAddr payloadLen)
|
bigEndian32(addr header[0], unsafeAddr payloadLen)
|
||||||
try:
|
try:
|
||||||
await net.peerSockets[peerId].send(cast[string](header) & cast[string](data))
|
await net.peerSockets[peerId].send(cast[string](header) & cast[string](data))
|
||||||
except:
|
except CatchableError:
|
||||||
net.peerSockets.del(peerId)
|
net.peerSockets.del(peerId)
|
||||||
|
|
||||||
proc broadcast*(net: RaftNetwork, msgs: seq[RaftMessage]) {.async.} =
|
proc broadcast*(net: RaftNetwork, msgs: seq[RaftMessage]) {.async.} =
|
||||||
@@ -615,9 +615,9 @@ proc receiveLoop(net: RaftNetwork, client: AsyncSocket) {.async.} =
|
|||||||
let msg = deserializeRaftMessage(payload)
|
let msg = deserializeRaftMessage(payload)
|
||||||
try:
|
try:
|
||||||
await net.processMessage(msg)
|
await net.processMessage(msg)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
finally:
|
finally:
|
||||||
client.close()
|
client.close()
|
||||||
@@ -641,7 +641,7 @@ proc run*(net: RaftNetwork) {.async.} =
|
|||||||
try:
|
try:
|
||||||
let client = await net.socket.accept()
|
let client = await net.socket.accept()
|
||||||
asyncCheck net.receiveLoop(client)
|
asyncCheck net.receiveLoop(client)
|
||||||
except:
|
except CatchableError:
|
||||||
break
|
break
|
||||||
|
|
||||||
proc stop*(net: RaftNetwork) =
|
proc stop*(net: RaftNetwork) =
|
||||||
|
|||||||
@@ -266,12 +266,12 @@ proc healthCheck*(rm: ReplicationManager) =
|
|||||||
sock.readLine(response)
|
sock.readLine(response)
|
||||||
if response.strip() != "PONG":
|
if response.strip() != "PONG":
|
||||||
connected = false
|
connected = false
|
||||||
except:
|
except CatchableError:
|
||||||
connected = false
|
connected = false
|
||||||
except:
|
except CatchableError:
|
||||||
connected = false
|
connected = false
|
||||||
finally:
|
finally:
|
||||||
try: sock.close() except: discard
|
try: sock.close() except CatchableError: discard
|
||||||
|
|
||||||
if not connected:
|
if not connected:
|
||||||
acquire(rm.lock)
|
acquire(rm.lock)
|
||||||
|
|||||||
@@ -65,55 +65,53 @@ proc newServerWithRegistry*(config: BaraConfig, registry: DatabaseRegistry): Ser
|
|||||||
let tlsConfig = newTLSConfig(config.certFile, config.keyFile)
|
let tlsConfig = newTLSConfig(config.certFile, config.keyFile)
|
||||||
tls = newTLSContext(tlsConfig)
|
tls = newTLSContext(tlsConfig)
|
||||||
|
|
||||||
# Initialize sharding
|
# Initialize sharding / gossip. Server fields own the refs; locals used inside
|
||||||
let shardRouter = newShardRouter()
|
# callback closures are {.cursor.} so ARC does not form uncollectable cycles
|
||||||
|
# (local + closure env + object callback fields).
|
||||||
let localId = if config.raftNodeId.len > 0: config.raftNodeId else: "node-" & $config.port
|
let localId = if config.raftNodeId.len > 0: config.raftNodeId else: "node-" & $config.port
|
||||||
let cm = newClusterMembership(shardRouter, localId)
|
|
||||||
|
|
||||||
# Wire shard migration callbacks to LSM (use default database)
|
|
||||||
shardRouter.iterateKeys = proc(shardId: int): seq[(string, seq[byte])] {.gcsafe.} =
|
|
||||||
var entries: seq[(string, seq[byte])] = @[]
|
|
||||||
for (key, value) in db.scanAll():
|
|
||||||
if shardRouter.getShard(key) == shardId:
|
|
||||||
entries.add((key, value))
|
|
||||||
return entries
|
|
||||||
|
|
||||||
shardRouter.storeKeys = proc(shardId: int, entries: seq[(string, seq[byte])]) {.gcsafe.} =
|
|
||||||
for (key, value) in entries:
|
|
||||||
db.put(key, value)
|
|
||||||
|
|
||||||
shardRouter.deleteKeys = proc(keys: seq[string]) {.gcsafe.} =
|
|
||||||
for key in keys:
|
|
||||||
db.delete(key)
|
|
||||||
|
|
||||||
# Initialize gossip
|
|
||||||
let gossipPort = config.raftPort + 100
|
let gossipPort = config.raftPort + 100
|
||||||
let gp = newGossipProtocol(localId, config.address, config.port, gossipPort = gossipPort)
|
|
||||||
|
|
||||||
# Wire gossip → cluster membership
|
|
||||||
gp.onJoin = proc(node: GossipNode) {.gcsafe.} =
|
|
||||||
cm.onNodeJoin(node.id, node.host, node.port)
|
|
||||||
|
|
||||||
gp.onLeave = proc(nodeId: string) {.gcsafe.} =
|
|
||||||
cm.onNodeLeave(nodeId)
|
|
||||||
|
|
||||||
gp.onSuspect = proc(nodeId: string) {.gcsafe.} =
|
|
||||||
cm.onNodeSuspect(nodeId)
|
|
||||||
|
|
||||||
# Initialize rate limiter
|
|
||||||
let rl = newRateLimiter(rlaTokenBucket, config.rateLimitGlobal, config.rateLimitPerClient)
|
let rl = newRateLimiter(rlaTokenBucket, config.rateLimitGlobal, config.rateLimitPerClient)
|
||||||
|
|
||||||
result = Server(config: config, running: false, db: db, ctx: ctx,
|
result = Server(config: config, running: false, db: db, ctx: ctx,
|
||||||
registry: registry,
|
registry: registry,
|
||||||
txnManager: ctx.txnManager, distTxnManager: newDistTxnManager(),
|
txnManager: ctx.txnManager, distTxnManager: newDistTxnManager(),
|
||||||
replicationManager: newReplicationManager(),
|
replicationManager: newReplicationManager(),
|
||||||
shardRouter: shardRouter,
|
shardRouter: newShardRouter(),
|
||||||
clusterMembership: cm,
|
clusterMembership: nil,
|
||||||
gossipProtocol: gp,
|
gossipProtocol: newGossipProtocol(localId, config.address, config.port, gossipPort = gossipPort),
|
||||||
tls: tls,
|
tls: tls,
|
||||||
rateLimiter: rl)
|
rateLimiter: rl)
|
||||||
|
result.clusterMembership = newClusterMembership(result.shardRouter, localId)
|
||||||
initLock(result.activeConnectionsLock)
|
initLock(result.activeConnectionsLock)
|
||||||
|
|
||||||
|
# Wire shard migration callbacks to LSM (default database)
|
||||||
|
block:
|
||||||
|
let shardRouter {.cursor.} = result.shardRouter
|
||||||
|
let dbRef {.cursor.} = db
|
||||||
|
shardRouter.iterateKeys = proc(shardId: int): seq[(string, seq[byte])] {.gcsafe.} =
|
||||||
|
var entries: seq[(string, seq[byte])] = @[]
|
||||||
|
for (key, value) in dbRef.scanAll():
|
||||||
|
if shardRouter.getShard(key) == shardId:
|
||||||
|
entries.add((key, value))
|
||||||
|
return entries
|
||||||
|
shardRouter.storeKeys = proc(shardId: int, entries: seq[(string, seq[byte])]) {.gcsafe.} =
|
||||||
|
for (key, value) in entries:
|
||||||
|
dbRef.put(key, value)
|
||||||
|
shardRouter.deleteKeys = proc(keys: seq[string]) {.gcsafe.} =
|
||||||
|
for key in keys:
|
||||||
|
dbRef.delete(key)
|
||||||
|
|
||||||
|
# Wire gossip → cluster membership
|
||||||
|
block:
|
||||||
|
let gp {.cursor.} = result.gossipProtocol
|
||||||
|
let cm {.cursor.} = result.clusterMembership
|
||||||
|
gp.onJoin = proc(node: GossipNode) {.gcsafe.} =
|
||||||
|
cm.onNodeJoin(node.id, node.host, node.port)
|
||||||
|
gp.onLeave = proc(nodeId: string) {.gcsafe.} =
|
||||||
|
cm.onNodeLeave(nodeId)
|
||||||
|
gp.onSuspect = proc(nodeId: string) {.gcsafe.} =
|
||||||
|
cm.onNodeSuspect(nodeId)
|
||||||
|
|
||||||
proc newServerWithDb*(config: BaraConfig, db: LSMTree): Server =
|
proc newServerWithDb*(config: BaraConfig, db: LSMTree): Server =
|
||||||
let registry = newDatabaseRegistry(config)
|
let registry = newDatabaseRegistry(config)
|
||||||
let ctx = newExecutionContext(db, registry)
|
let ctx = newExecutionContext(db, registry)
|
||||||
@@ -389,7 +387,7 @@ proc handleClient(server: Server, client: AsyncSocket, clientId: int) {.async.}
|
|||||||
rest.add(more)
|
rest.add(more)
|
||||||
let parts = rest.strip().split(" ")
|
let parts = rest.strip().split(" ")
|
||||||
if parts.len >= 2:
|
if parts.len >= 2:
|
||||||
let txnId = try: uint64(parseBiggestUint(parts[0])) except: 0'u64
|
let txnId = try: uint64(parseBiggestUint(parts[0])) except CatchableError: 0'u64
|
||||||
let action = parts[1].toUpper()
|
let action = parts[1].toUpper()
|
||||||
if server.distTxnManager != nil:
|
if server.distTxnManager != nil:
|
||||||
let txn = server.distTxnManager.getTxn(txnId)
|
let txn = server.distTxnManager.getTxn(txnId)
|
||||||
@@ -428,8 +426,8 @@ proc handleClient(server: Server, client: AsyncSocket, clientId: int) {.async.}
|
|||||||
rest.add(more)
|
rest.add(more)
|
||||||
let parts = rest.strip().split(" ")
|
let parts = rest.strip().split(" ")
|
||||||
if parts.len >= 2:
|
if parts.len >= 2:
|
||||||
let lsn = try: parseUInt(parts[0]) except: 0'u64
|
let lsn = try: parseUInt(parts[0]) except CatchableError: 0'u64
|
||||||
let dataLen = try: parseInt(parts[1]) except: 0
|
let dataLen = try: parseInt(parts[1]) except CatchableError: 0
|
||||||
if dataLen > 0:
|
if dataLen > 0:
|
||||||
var data = ""
|
var data = ""
|
||||||
while data.len < dataLen:
|
while data.len < dataLen:
|
||||||
@@ -460,7 +458,7 @@ proc handleClient(server: Server, client: AsyncSocket, clientId: int) {.async.}
|
|||||||
let headerLine = "MIGRATE " & rest.strip()
|
let headerLine = "MIGRATE " & rest.strip()
|
||||||
let parts = rest.strip().split(" ")
|
let parts = rest.strip().split(" ")
|
||||||
if parts.len >= 2:
|
if parts.len >= 2:
|
||||||
let entryCount = try: parseInt(parts[1]) except: 0
|
let entryCount = try: parseInt(parts[1]) except CatchableError: 0
|
||||||
var data = ""
|
var data = ""
|
||||||
if entryCount > 0:
|
if entryCount > 0:
|
||||||
# Read all entries (each entry is key\0value\n)
|
# Read all entries (each entry is key\0value\n)
|
||||||
@@ -551,7 +549,7 @@ proc handleClient(server: Server, client: AsyncSocket, clientId: int) {.async.}
|
|||||||
# Shard-aware routing: check if this node should handle the write
|
# Shard-aware routing: check if this node should handle the write
|
||||||
var shardCheck = true
|
var shardCheck = true
|
||||||
if server.clusterMembership.nodes.len > 0:
|
if server.clusterMembership.nodes.len > 0:
|
||||||
let stmts = try: parse(tokenize(queryStr)) except: nil
|
let stmts = try: parse(tokenize(queryStr)) except CatchableError: nil
|
||||||
if stmts != nil:
|
if stmts != nil:
|
||||||
for stmt in stmts.stmts:
|
for stmt in stmts.stmts:
|
||||||
if stmt.kind in {nkInsert, nkUpdate, nkDelete}:
|
if stmt.kind in {nkInsert, nkUpdate, nkDelete}:
|
||||||
|
|||||||
@@ -337,8 +337,8 @@ proc handleMigrationMessage*(headerLine: string, data: string,
|
|||||||
if parts.len < 3:
|
if parts.len < 3:
|
||||||
return "ERR invalid migrate header\n"
|
return "ERR invalid migrate header\n"
|
||||||
|
|
||||||
let shardId = try: parseInt(parts[1]) except: -1
|
let shardId = try: parseInt(parts[1]) except CatchableError: -1
|
||||||
let entryCount = try: parseInt(parts[2]) except: 0
|
let entryCount = try: parseInt(parts[2]) except CatchableError: 0
|
||||||
|
|
||||||
if shardId < 0 or entryCount < 0:
|
if shardId < 0 or entryCount < 0:
|
||||||
return "ERR invalid shard id or entry count\n"
|
return "ERR invalid shard id or entry count\n"
|
||||||
|
|||||||
@@ -128,5 +128,5 @@ proc exportOtlp*(tracer: Tracer, endpoint: string = "http://localhost:4318/v1/tr
|
|||||||
client.close()
|
client.close()
|
||||||
tracer.spans = @[]
|
tracer.spans = @[]
|
||||||
return true
|
return true
|
||||||
except:
|
except CatchableError:
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -189,7 +189,7 @@ proc notifyClient(client: WsClient, msg: string) {.async.} =
|
|||||||
try:
|
try:
|
||||||
let frame = encodeFrame(0x1, msg)
|
let frame = encodeFrame(0x1, msg)
|
||||||
await client.socket.send(frame)
|
await client.socket.send(frame)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc broadcastToTable*(server: WsServer, table: string, msg: string) {.async.} =
|
proc broadcastToTable*(server: WsServer, table: string, msg: string) {.async.} =
|
||||||
@@ -247,7 +247,7 @@ proc handleWsClient(server: WsServer, client: AsyncSocket, id: int) {.async.} =
|
|||||||
|
|
||||||
buf = buf[consumed..^1]
|
buf = buf[consumed..^1]
|
||||||
|
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
finally:
|
finally:
|
||||||
echo "WebSocket client ", id, " disconnected"
|
echo "WebSocket client ", id, " disconnected"
|
||||||
@@ -305,7 +305,7 @@ proc handleConnection(server: WsServer, client: AsyncSocket) {.async.} =
|
|||||||
await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n")
|
await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n")
|
||||||
client.close()
|
client.close()
|
||||||
return
|
return
|
||||||
except:
|
except CatchableError:
|
||||||
await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n")
|
await client.send("HTTP/1.1 401 Unauthorized\r\n\r\n")
|
||||||
client.close()
|
client.close()
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -167,14 +167,14 @@ proc encodeRecord*(buf: var ZeroBuf, schema: ZcSchema,
|
|||||||
try:
|
try:
|
||||||
var v = int32(parseInt(value))
|
var v = int32(parseInt(value))
|
||||||
bigEndian32(addr buf.data[field.offset], unsafeAddr v)
|
bigEndian32(addr buf.data[field.offset], unsafeAddr v)
|
||||||
except:
|
except CatchableError:
|
||||||
var v: int32 = 0
|
var v: int32 = 0
|
||||||
bigEndian32(addr buf.data[field.offset], unsafeAddr v)
|
bigEndian32(addr buf.data[field.offset], unsafeAddr v)
|
||||||
of ztInt64:
|
of ztInt64:
|
||||||
try:
|
try:
|
||||||
var v = int64(parseInt(value))
|
var v = int64(parseInt(value))
|
||||||
bigEndian64(addr buf.data[field.offset], unsafeAddr v)
|
bigEndian64(addr buf.data[field.offset], unsafeAddr v)
|
||||||
except:
|
except CatchableError:
|
||||||
var v: int64 = 0
|
var v: int64 = 0
|
||||||
bigEndian64(addr buf.data[field.offset], unsafeAddr v)
|
bigEndian64(addr buf.data[field.offset], unsafeAddr v)
|
||||||
of ztString:
|
of ztString:
|
||||||
|
|||||||
@@ -232,7 +232,7 @@ proc acquireMigrationLock(ctx: ExecutionContext): bool =
|
|||||||
let (locked, lockVal) = ctx.db.get(lockKey)
|
let (locked, lockVal) = ctx.db.get(lockKey)
|
||||||
if locked:
|
if locked:
|
||||||
# Check for stale lock (older than 1 hour)
|
# Check for stale lock (older than 1 hour)
|
||||||
let lockTime = try: parseInt(cast[string](lockVal)) except: 0
|
let lockTime = try: parseInt(cast[string](lockVal)) except CatchableError: 0
|
||||||
if lockTime > 0 and (epochTime().int64 - lockTime) > 3600:
|
if lockTime > 0 and (epochTime().int64 - lockTime) > 3600:
|
||||||
# Stale lock — force release
|
# Stale lock — force release
|
||||||
ctx.db.delete(lockKey)
|
ctx.db.delete(lockKey)
|
||||||
@@ -362,7 +362,7 @@ proc parseVectorString*(value: string): seq[float32] =
|
|||||||
if p.len > 0:
|
if p.len > 0:
|
||||||
try:
|
try:
|
||||||
result.add(parseFloat(p).float32)
|
result.add(parseFloat(p).float32)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
@@ -621,10 +621,10 @@ proc evalExpr*(expr: IRExpr, row: Row, ctx: ExecutionContext = nil): Value =
|
|||||||
case expr.valueKind
|
case expr.valueKind
|
||||||
of vkInt64:
|
of vkInt64:
|
||||||
try: return Value(kind: vkInt64, int64Val: parseInt(s))
|
try: return Value(kind: vkInt64, int64Val: parseInt(s))
|
||||||
except: return Value(kind: vkNull)
|
except CatchableError: return Value(kind: vkNull)
|
||||||
of vkFloat64:
|
of vkFloat64:
|
||||||
try: return Value(kind: vkFloat64, float64Val: parseFloat(s))
|
try: return Value(kind: vkFloat64, float64Val: parseFloat(s))
|
||||||
except: return Value(kind: vkNull)
|
except CatchableError: return Value(kind: vkNull)
|
||||||
of vkBool:
|
of vkBool:
|
||||||
return Value(kind: vkBool, boolVal: s == "true")
|
return Value(kind: vkBool, boolVal: s == "true")
|
||||||
of vkNull:
|
of vkNull:
|
||||||
@@ -634,10 +634,10 @@ proc evalExpr*(expr: IRExpr, row: Row, ctx: ExecutionContext = nil): Value =
|
|||||||
if s.len == 0: return Value(kind: vkString, strVal: s)
|
if s.len == 0: return Value(kind: vkString, strVal: s)
|
||||||
try:
|
try:
|
||||||
return Value(kind: vkInt64, int64Val: parseInt(s))
|
return Value(kind: vkInt64, int64Val: parseInt(s))
|
||||||
except:
|
except CatchableError:
|
||||||
try:
|
try:
|
||||||
return Value(kind: vkFloat64, float64Val: parseFloat(s))
|
return Value(kind: vkFloat64, float64Val: parseFloat(s))
|
||||||
except:
|
except CatchableError:
|
||||||
return Value(kind: vkString, strVal: s)
|
return Value(kind: vkString, strVal: s)
|
||||||
return Value(kind: vkNull)
|
return Value(kind: vkNull)
|
||||||
of irekBinary:
|
of irekBinary:
|
||||||
@@ -803,7 +803,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
of JNull: return "null"
|
of JNull: return "null"
|
||||||
else: return $val
|
else: return $val
|
||||||
return ""
|
return ""
|
||||||
except:
|
except CatchableError:
|
||||||
return ""
|
return ""
|
||||||
of irekBinary:
|
of irekBinary:
|
||||||
let left = evalExprOld(expr.binLeft, row, ctx)
|
let left = evalExprOld(expr.binLeft, row, ctx)
|
||||||
@@ -814,30 +814,30 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
# Try numeric comparison
|
# Try numeric comparison
|
||||||
try:
|
try:
|
||||||
if parseFloat(left) == parseFloat(right): return "true"
|
if parseFloat(left) == parseFloat(right): return "true"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
return "false"
|
return "false"
|
||||||
of irNeq:
|
of irNeq:
|
||||||
if left != right: return "true"
|
if left != right: return "true"
|
||||||
# Try numeric comparison
|
# Try numeric comparison
|
||||||
try:
|
try:
|
||||||
return if parseFloat(left) != parseFloat(right): "true" else: "false"
|
return if parseFloat(left) != parseFloat(right): "true" else: "false"
|
||||||
except: return "false"
|
except CatchableError: return "false"
|
||||||
of irLt:
|
of irLt:
|
||||||
try:
|
try:
|
||||||
return if parseFloat(left) < parseFloat(right): "true" else: "false"
|
return if parseFloat(left) < parseFloat(right): "true" else: "false"
|
||||||
except: return if left < right: "true" else: "false"
|
except CatchableError: return if left < right: "true" else: "false"
|
||||||
of irLte:
|
of irLte:
|
||||||
try:
|
try:
|
||||||
return if parseFloat(left) <= parseFloat(right): "true" else: "false"
|
return if parseFloat(left) <= parseFloat(right): "true" else: "false"
|
||||||
except: return if left <= right: "true" else: "false"
|
except CatchableError: return if left <= right: "true" else: "false"
|
||||||
of irGt:
|
of irGt:
|
||||||
try:
|
try:
|
||||||
return if parseFloat(left) > parseFloat(right): "true" else: "false"
|
return if parseFloat(left) > parseFloat(right): "true" else: "false"
|
||||||
except: return if left > right: "true" else: "false"
|
except CatchableError: return if left > right: "true" else: "false"
|
||||||
of irGte:
|
of irGte:
|
||||||
try:
|
try:
|
||||||
return if parseFloat(left) >= parseFloat(right): "true" else: "false"
|
return if parseFloat(left) >= parseFloat(right): "true" else: "false"
|
||||||
except: return if left >= right: "true" else: "false"
|
except CatchableError: return if left >= right: "true" else: "false"
|
||||||
of irAnd:
|
of irAnd:
|
||||||
if left == "true" and right == "true": return "true"
|
if left == "true" and right == "true": return "true"
|
||||||
return "false"
|
return "false"
|
||||||
@@ -867,7 +867,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
try:
|
try:
|
||||||
let rePattern = re(pattern)
|
let rePattern = re(pattern)
|
||||||
if left.match(rePattern): return "true"
|
if left.match(rePattern): return "true"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
return "false"
|
return "false"
|
||||||
of irILike:
|
of irILike:
|
||||||
proc escapeRe(s: string): string =
|
proc escapeRe(s: string): string =
|
||||||
@@ -882,7 +882,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
try:
|
try:
|
||||||
let rePattern = re(pattern)
|
let rePattern = re(pattern)
|
||||||
if left.toLower().match(rePattern): return "true"
|
if left.toLower().match(rePattern): return "true"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
return "false"
|
return "false"
|
||||||
of irIn:
|
of irIn:
|
||||||
if expr.binRight.kind == irekSubquery:
|
if expr.binRight.kind == irekSubquery:
|
||||||
@@ -902,7 +902,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
let lv = parseFloat(left)
|
let lv = parseFloat(left)
|
||||||
let rv = parseFloat(right)
|
let rv = parseFloat(right)
|
||||||
return if lv == rv: "true" else: "false"
|
return if lv == rv: "true" else: "false"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
return if left == right: "true" else: "false"
|
return if left == right: "true" else: "false"
|
||||||
of irNotIn:
|
of irNotIn:
|
||||||
if expr.binRight.kind == irekSubquery:
|
if expr.binRight.kind == irekSubquery:
|
||||||
@@ -922,7 +922,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
let lv = parseFloat(left)
|
let lv = parseFloat(left)
|
||||||
let rv = parseFloat(right)
|
let rv = parseFloat(right)
|
||||||
return if lv != rv: "true" else: "false"
|
return if lv != rv: "true" else: "false"
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
return if left != right: "true" else: "false"
|
return if left != right: "true" else: "false"
|
||||||
of irFtsMatch:
|
of irFtsMatch:
|
||||||
# Check for FTS index via ctx
|
# Check for FTS index via ctx
|
||||||
@@ -986,7 +986,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
return "true"
|
return "true"
|
||||||
else:
|
else:
|
||||||
return if $(leftNode) == $(rightNode): "true" else: "false"
|
return if $(leftNode) == $(rightNode): "true" else: "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
of irJsonContainedBy:
|
of irJsonContainedBy:
|
||||||
# Check if left JSON is contained by right JSON (reverse of contains)
|
# Check if left JSON is contained by right JSON (reverse of contains)
|
||||||
@@ -1010,7 +1010,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
return "true"
|
return "true"
|
||||||
else:
|
else:
|
||||||
return if $(leftNode) == $(rightNode): "true" else: "false"
|
return if $(leftNode) == $(rightNode): "true" else: "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
of irJsonHasAny:
|
of irJsonHasAny:
|
||||||
# Check if JSON object has any of the keys in right array
|
# Check if JSON object has any of the keys in right array
|
||||||
@@ -1022,7 +1022,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
if key.kind == JString and leftNode.hasKey(key.getStr()):
|
if key.kind == JString and leftNode.hasKey(key.getStr()):
|
||||||
return "true"
|
return "true"
|
||||||
return "false"
|
return "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
of irJsonHasAll:
|
of irJsonHasAll:
|
||||||
# Check if JSON object has all of the keys in right array
|
# Check if JSON object has all of the keys in right array
|
||||||
@@ -1035,7 +1035,7 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
return "false"
|
return "false"
|
||||||
return "true"
|
return "true"
|
||||||
return "false"
|
return "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
else: return "false"
|
else: return "false"
|
||||||
of irekUnary:
|
of irekUnary:
|
||||||
@@ -1097,10 +1097,10 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
try:
|
try:
|
||||||
let idx = parseInt(key)
|
let idx = parseInt(key)
|
||||||
return if idx >= 0 and idx < node.len: "true" else: "false"
|
return if idx >= 0 and idx < node.len: "true" else: "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
return "false"
|
return "false"
|
||||||
except:
|
except CatchableError:
|
||||||
return "false"
|
return "false"
|
||||||
of "current_setting":
|
of "current_setting":
|
||||||
if expr.irFuncArgs.len < 1:
|
if expr.irFuncArgs.len < 1:
|
||||||
@@ -1460,13 +1460,13 @@ proc evalExprOld*(expr: IRExpr, row: Table[string, string], ctx: ExecutionContex
|
|||||||
try:
|
try:
|
||||||
let dt = parse(val, "yyyy-MM-dd HH:mm:ss")
|
let dt = parse(val, "yyyy-MM-dd HH:mm:ss")
|
||||||
return $(dt.toTime().toUnix())
|
return $(dt.toTime().toUnix())
|
||||||
except:
|
except CatchableError:
|
||||||
return "0"
|
return "0"
|
||||||
elif fmt == "%Y-%m-%dT%H:%M:%SZ":
|
elif fmt == "%Y-%m-%dT%H:%M:%SZ":
|
||||||
try:
|
try:
|
||||||
let dt = parse(val, "yyyy-MM-dd HH:mm:ss")
|
let dt = parse(val, "yyyy-MM-dd HH:mm:ss")
|
||||||
return format(dt, "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
return format(dt, "yyyy-MM-dd'T'HH:mm:ss'Z'")
|
||||||
except:
|
except CatchableError:
|
||||||
return ""
|
return ""
|
||||||
return ""
|
return ""
|
||||||
else:
|
else:
|
||||||
@@ -1773,7 +1773,7 @@ proc execInsert*(ctx: ExecutionContext, table: string, fields: seq[string], valu
|
|||||||
props[f] = rowVals[i]
|
props[f] = rowVals[i]
|
||||||
try:
|
try:
|
||||||
gengine.addNodeWithId(graph, nid, label, props)
|
gengine.addNodeWithId(graph, nid, label, props)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
elif table == graphName & "_edges":
|
elif table == graphName & "_edges":
|
||||||
var srcStr = ""
|
var srcStr = ""
|
||||||
@@ -1786,13 +1786,13 @@ proc execInsert*(ctx: ExecutionContext, table: string, fields: seq[string], valu
|
|||||||
elif f == "dest_id": dstStr = rowVals[i]
|
elif f == "dest_id": dstStr = rowVals[i]
|
||||||
elif f == "edge_label": label = rowVals[i]
|
elif f == "edge_label": label = rowVals[i]
|
||||||
elif f == "weight":
|
elif f == "weight":
|
||||||
try: weight = parseFloat(rowVals[i]) except: discard
|
try: weight = parseFloat(rowVals[i]) except CatchableError: discard
|
||||||
if srcStr.len > 0 and dstStr.len > 0:
|
if srcStr.len > 0 and dstStr.len > 0:
|
||||||
let srcId = gengine.NodeId(parseUInt(srcStr))
|
let srcId = gengine.NodeId(parseUInt(srcStr))
|
||||||
let dstId = gengine.NodeId(parseUInt(dstStr))
|
let dstId = gengine.NodeId(parseUInt(dstStr))
|
||||||
try:
|
try:
|
||||||
gengine.addEdgeWithId(graph, srcId, dstId, label, weight)
|
gengine.addEdgeWithId(graph, srcId, dstId, label, weight)
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
inc count
|
inc count
|
||||||
@@ -2018,10 +2018,10 @@ proc validateType*(colType: string, value: string): (bool, string) =
|
|||||||
let t = colType.toUpper()
|
let t = colType.toUpper()
|
||||||
if t == "INTEGER" or t == "INT" or t == "BIGINT" or t == "SMALLINT" or t == "SERIAL":
|
if t == "INTEGER" or t == "INT" or t == "BIGINT" or t == "SMALLINT" or t == "SERIAL":
|
||||||
try: discard parseInt(value)
|
try: discard parseInt(value)
|
||||||
except: return (false, "Type mismatch: expected " & t & " but got '" & value & "'")
|
except CatchableError: return (false, "Type mismatch: expected " & t & " but got '" & value & "'")
|
||||||
elif t == "FLOAT" or t == "REAL" or t == "DOUBLE" or t == "DOUBLE PRECISION" or t == "NUMERIC":
|
elif t == "FLOAT" or t == "REAL" or t == "DOUBLE" or t == "DOUBLE PRECISION" or t == "NUMERIC":
|
||||||
try: discard parseFloat(value)
|
try: discard parseFloat(value)
|
||||||
except: return (false, "Type mismatch: expected " & t & " but got '" & value & "'")
|
except CatchableError: return (false, "Type mismatch: expected " & t & " but got '" & value & "'")
|
||||||
elif t == "BOOLEAN" or t == "BOOL":
|
elif t == "BOOLEAN" or t == "BOOL":
|
||||||
let lv = value.toLower()
|
let lv = value.toLower()
|
||||||
if lv notin ["true", "false", "1", "0", "t", "f", "yes", "no"]:
|
if lv notin ["true", "false", "1", "0", "t", "f", "yes", "no"]:
|
||||||
@@ -2032,7 +2032,7 @@ proc validateType*(colType: string, value: string): (bool, string) =
|
|||||||
elif t == "JSON" or t == "JSONB":
|
elif t == "JSON" or t == "JSONB":
|
||||||
try:
|
try:
|
||||||
discard parseJson(value)
|
discard parseJson(value)
|
||||||
except:
|
except CatchableError:
|
||||||
return (false, "Type mismatch: expected JSON but got '" & value & "'")
|
return (false, "Type mismatch: expected JSON but got '" & value & "'")
|
||||||
elif t.startsWith("VECTOR"):
|
elif t.startsWith("VECTOR"):
|
||||||
let vec = parseVectorString(value)
|
let vec = parseVectorString(value)
|
||||||
@@ -2044,7 +2044,7 @@ proc validateType*(colType: string, value: string): (bool, string) =
|
|||||||
if dimStart >= 0 and dimEnd > dimStart:
|
if dimStart >= 0 and dimEnd > dimStart:
|
||||||
try:
|
try:
|
||||||
expectedDim = parseInt(t[dimStart+1..<dimEnd])
|
expectedDim = parseInt(t[dimStart+1..<dimEnd])
|
||||||
except:
|
except CatchableError:
|
||||||
expectedDim = 0
|
expectedDim = 0
|
||||||
if expectedDim > 0 and vec.len != expectedDim:
|
if expectedDim > 0 and vec.len != expectedDim:
|
||||||
return (false, "Vector dimension mismatch: expected " & $expectedDim & " but got " & $vec.len)
|
return (false, "Vector dimension mismatch: expected " & $expectedDim & " but got " & $vec.len)
|
||||||
@@ -2572,7 +2572,7 @@ proc compareRowsByOrder(a, b: Row, orderExprs: seq[IRExpr], orderDirs: seq[bool]
|
|||||||
let fb = parseFloat(valueToString(vb))
|
let fb = parseFloat(valueToString(vb))
|
||||||
if fa < fb: cmpRes = -1
|
if fa < fb: cmpRes = -1
|
||||||
elif fa > fb: cmpRes = 1
|
elif fa > fb: cmpRes = 1
|
||||||
except:
|
except CatchableError:
|
||||||
cmpRes = cmp(valueToString(va), valueToString(vb))
|
cmpRes = cmp(valueToString(va), valueToString(vb))
|
||||||
if cmpRes != 0:
|
if cmpRes != 0:
|
||||||
return if orderDirs.len > i and orderDirs[i]: -cmpRes else: cmpRes
|
return if orderDirs.len > i and orderDirs[i]: -cmpRes else: cmpRes
|
||||||
@@ -2592,12 +2592,12 @@ proc resolveFrameBounds(pos, partLen: int, frameStart, frameEnd: string): (int,
|
|||||||
elif frameStart.endsWith(" PRECEDING"):
|
elif frameStart.endsWith(" PRECEDING"):
|
||||||
let nStr = frameStart[0..^11]
|
let nStr = frameStart[0..^11]
|
||||||
var n = 0
|
var n = 0
|
||||||
try: n = parseInt(nStr) except: n = 0
|
try: n = parseInt(nStr) except CatchableError: n = 0
|
||||||
startPos = max(0, pos - n)
|
startPos = max(0, pos - n)
|
||||||
elif frameStart.endsWith(" FOLLOWING"):
|
elif frameStart.endsWith(" FOLLOWING"):
|
||||||
let nStr = frameStart[0..^11]
|
let nStr = frameStart[0..^11]
|
||||||
var n = 0
|
var n = 0
|
||||||
try: n = parseInt(nStr) except: n = 0
|
try: n = parseInt(nStr) except CatchableError: n = 0
|
||||||
startPos = min(partLen - 1, pos + n)
|
startPos = min(partLen - 1, pos + n)
|
||||||
|
|
||||||
# Parse end boundary
|
# Parse end boundary
|
||||||
@@ -2608,12 +2608,12 @@ proc resolveFrameBounds(pos, partLen: int, frameStart, frameEnd: string): (int,
|
|||||||
elif frameEnd.endsWith(" PRECEDING"):
|
elif frameEnd.endsWith(" PRECEDING"):
|
||||||
let nStr = frameEnd[0..^11]
|
let nStr = frameEnd[0..^11]
|
||||||
var n = 0
|
var n = 0
|
||||||
try: n = parseInt(nStr) except: n = 0
|
try: n = parseInt(nStr) except CatchableError: n = 0
|
||||||
endPos = max(0, pos - n)
|
endPos = max(0, pos - n)
|
||||||
elif frameEnd.endsWith(" FOLLOWING"):
|
elif frameEnd.endsWith(" FOLLOWING"):
|
||||||
let nStr = frameEnd[0..^11]
|
let nStr = frameEnd[0..^11]
|
||||||
var n = 0
|
var n = 0
|
||||||
try: n = parseInt(nStr) except: n = 0
|
try: n = parseInt(nStr) except CatchableError: n = 0
|
||||||
endPos = min(partLen - 1, pos + n)
|
endPos = min(partLen - 1, pos + n)
|
||||||
|
|
||||||
if startPos > endPos:
|
if startPos > endPos:
|
||||||
@@ -2668,7 +2668,7 @@ proc computeWindowValues*(rows: seq[Row], expr: IRExpr, ctx: ExecutionContext =
|
|||||||
of "ntile":
|
of "ntile":
|
||||||
var n = 1
|
var n = 1
|
||||||
if expr.wfArgs.len > 0:
|
if expr.wfArgs.len > 0:
|
||||||
try: n = parseInt(valueToString(evalExpr(expr.wfArgs[0], rows[sortedIdxs[0]], ctx))) except: n = 1
|
try: n = parseInt(valueToString(evalExpr(expr.wfArgs[0], rows[sortedIdxs[0]], ctx))) except CatchableError: n = 1
|
||||||
if n < 1: n = 1
|
if n < 1: n = 1
|
||||||
let groupSize = sortedIdxs.len div n
|
let groupSize = sortedIdxs.len div n
|
||||||
let remainder = sortedIdxs.len mod n
|
let remainder = sortedIdxs.len mod n
|
||||||
@@ -2687,7 +2687,7 @@ proc computeWindowValues*(rows: seq[Row], expr: IRExpr, ctx: ExecutionContext =
|
|||||||
var offset = 1
|
var offset = 1
|
||||||
var defaultVal = ""
|
var defaultVal = ""
|
||||||
if expr.wfArgs.len > 1:
|
if expr.wfArgs.len > 1:
|
||||||
try: offset = parseInt(valueToString(evalExpr(expr.wfArgs[1], rows[sortedIdxs[0]], ctx))) except: offset = 1
|
try: offset = parseInt(valueToString(evalExpr(expr.wfArgs[1], rows[sortedIdxs[0]], ctx))) except CatchableError: offset = 1
|
||||||
if expr.wfArgs.len > 2:
|
if expr.wfArgs.len > 2:
|
||||||
defaultVal = valueToString(evalExpr(expr.wfArgs[2], rows[sortedIdxs[0]], ctx))
|
defaultVal = valueToString(evalExpr(expr.wfArgs[2], rows[sortedIdxs[0]], ctx))
|
||||||
for pos, rowIdx in sortedIdxs:
|
for pos, rowIdx in sortedIdxs:
|
||||||
@@ -2700,7 +2700,7 @@ proc computeWindowValues*(rows: seq[Row], expr: IRExpr, ctx: ExecutionContext =
|
|||||||
var offset = 1
|
var offset = 1
|
||||||
var defaultVal = ""
|
var defaultVal = ""
|
||||||
if expr.wfArgs.len > 1:
|
if expr.wfArgs.len > 1:
|
||||||
try: offset = parseInt(valueToString(evalExpr(expr.wfArgs[1], rows[sortedIdxs[0]], ctx))) except: offset = 1
|
try: offset = parseInt(valueToString(evalExpr(expr.wfArgs[1], rows[sortedIdxs[0]], ctx))) except CatchableError: offset = 1
|
||||||
if expr.wfArgs.len > 2:
|
if expr.wfArgs.len > 2:
|
||||||
defaultVal = valueToString(evalExpr(expr.wfArgs[2], rows[sortedIdxs[0]], ctx))
|
defaultVal = valueToString(evalExpr(expr.wfArgs[2], rows[sortedIdxs[0]], ctx))
|
||||||
for pos, rowIdx in sortedIdxs:
|
for pos, rowIdx in sortedIdxs:
|
||||||
@@ -2843,14 +2843,14 @@ proc executePlan*(ctx: ExecutionContext, plan: IRPlan): seq[Row] =
|
|||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
for row in filteredRows:
|
for row in filteredRows:
|
||||||
let v = evalExpr(expr.aggArgs[0], row, ctx)
|
let v = evalExpr(expr.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)) except: discard
|
try: sum += parseFloat(valueToString(v)) except CatchableError: discard
|
||||||
newRow[alias] = $sum
|
newRow[alias] = $sum
|
||||||
of irAvg:
|
of irAvg:
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
var count = 0
|
var count = 0
|
||||||
for row in filteredRows:
|
for row in filteredRows:
|
||||||
let v = evalExpr(expr.aggArgs[0], row, ctx)
|
let v = evalExpr(expr.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)); count += 1 except: discard
|
try: sum += parseFloat(valueToString(v)); count += 1 except CatchableError: discard
|
||||||
newRow[alias] = if count > 0: $(sum / float(count)) else: "0"
|
newRow[alias] = if count > 0: $(sum / float(count)) else: "0"
|
||||||
of irMin:
|
of irMin:
|
||||||
var minVal = ""
|
var minVal = ""
|
||||||
@@ -2930,7 +2930,7 @@ proc executePlan*(ctx: ExecutionContext, plan: IRPlan): seq[Row] =
|
|||||||
let fb = parseFloat(valueToString(vb))
|
let fb = parseFloat(valueToString(vb))
|
||||||
if fa < fb: cmpRes = -1
|
if fa < fb: cmpRes = -1
|
||||||
elif fa > fb: cmpRes = 1
|
elif fa > fb: cmpRes = 1
|
||||||
except:
|
except CatchableError:
|
||||||
cmpRes = cmp(valueToString(va), valueToString(vb))
|
cmpRes = cmp(valueToString(va), valueToString(vb))
|
||||||
if not ascending: cmpRes = -cmpRes
|
if not ascending: cmpRes = -cmpRes
|
||||||
if cmpRes != 0: return cmpRes
|
if cmpRes != 0: return cmpRes
|
||||||
@@ -3022,14 +3022,14 @@ proc executePlan*(ctx: ExecutionContext, plan: IRPlan): seq[Row] =
|
|||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
for row in filteredRows:
|
for row in filteredRows:
|
||||||
let v = evalExpr(aggExpr.aggArgs[0], row, ctx)
|
let v = evalExpr(aggExpr.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)) except: discard
|
try: sum += parseFloat(valueToString(v)) except CatchableError: discard
|
||||||
aggRow[aggKey] = $sum
|
aggRow[aggKey] = $sum
|
||||||
of irAvg:
|
of irAvg:
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
var count = 0
|
var count = 0
|
||||||
for row in filteredRows:
|
for row in filteredRows:
|
||||||
let v = evalExpr(aggExpr.aggArgs[0], row, ctx)
|
let v = evalExpr(aggExpr.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)); count += 1 except: discard
|
try: sum += parseFloat(valueToString(v)); count += 1 except CatchableError: discard
|
||||||
aggRow[aggKey] = if count > 0: $(sum / float(count)) else: "0"
|
aggRow[aggKey] = if count > 0: $(sum / float(count)) else: "0"
|
||||||
of irMin:
|
of irMin:
|
||||||
var minVal = ""
|
var minVal = ""
|
||||||
@@ -3544,14 +3544,14 @@ proc executePlan*(ctx: ExecutionContext, plan: IRPlan): seq[Row] =
|
|||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
for row in matchingRows:
|
for row in matchingRows:
|
||||||
let v = evalExpr(plan.pivotAgg.aggArgs[0], row, ctx)
|
let v = evalExpr(plan.pivotAgg.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)) except: discard
|
try: sum += parseFloat(valueToString(v)) except CatchableError: discard
|
||||||
aggResult = $sum
|
aggResult = $sum
|
||||||
of irAvg:
|
of irAvg:
|
||||||
var sum = 0.0
|
var sum = 0.0
|
||||||
var count = 0
|
var count = 0
|
||||||
for row in matchingRows:
|
for row in matchingRows:
|
||||||
let v = evalExpr(plan.pivotAgg.aggArgs[0], row, ctx)
|
let v = evalExpr(plan.pivotAgg.aggArgs[0], row, ctx)
|
||||||
try: sum += parseFloat(valueToString(v)); count += 1 except: discard
|
try: sum += parseFloat(valueToString(v)); count += 1 except CatchableError: discard
|
||||||
aggResult = if count > 0: $(sum / float(count)) else: "0"
|
aggResult = if count > 0: $(sum / float(count)) else: "0"
|
||||||
of irMin:
|
of irMin:
|
||||||
var minVal = ""
|
var minVal = ""
|
||||||
@@ -3609,8 +3609,8 @@ proc executePlan*(ctx: ExecutionContext, plan: IRPlan): seq[Row] =
|
|||||||
let algo = plan.graphAlgo.toLowerAscii()
|
let algo = plan.graphAlgo.toLowerAscii()
|
||||||
let returnCols = plan.graphReturnCols
|
let returnCols = plan.graphReturnCols
|
||||||
let firstNodeId = if g.nodes.len > 0: g.nodes.keys.toSeq[0] else: gengine.NodeId(0)
|
let firstNodeId = if g.nodes.len > 0: g.nodes.keys.toSeq[0] else: gengine.NodeId(0)
|
||||||
let explicitStart = try: parseUInt(plan.graphStartNode) except: 0'u64
|
let explicitStart = try: parseUInt(plan.graphStartNode) except CatchableError: 0'u64
|
||||||
let explicitEnd = try: parseUInt(plan.graphEndNode) except: 0'u64
|
let explicitEnd = try: parseUInt(plan.graphEndNode) except CatchableError: 0'u64
|
||||||
|
|
||||||
case algo
|
case algo
|
||||||
of "bfs":
|
of "bfs":
|
||||||
@@ -4034,7 +4034,7 @@ proc executeQueryImpl(ctx: ExecutionContext, astNode: Node, params: seq[WireValu
|
|||||||
if fa < fb: return -1
|
if fa < fb: return -1
|
||||||
if fa > fb: return 1
|
if fa > fb: return 1
|
||||||
return 0
|
return 0
|
||||||
except:
|
except CatchableError:
|
||||||
return cmp(valueToString(va), valueToString(vb))
|
return cmp(valueToString(va), valueToString(vb))
|
||||||
filteredRows.sort(sortCmp, if asc: Ascending else: Descending)
|
filteredRows.sort(sortCmp, if asc: Ascending else: Descending)
|
||||||
if stmt.selLimit != nil:
|
if stmt.selLimit != nil:
|
||||||
@@ -4369,7 +4369,7 @@ proc executeQueryImpl(ctx: ExecutionContext, astNode: Node, params: seq[WireValu
|
|||||||
ctx.autoIncCounters[counterKey] = intVal + 1
|
ctx.autoIncCounters[counterKey] = intVal + 1
|
||||||
finally:
|
finally:
|
||||||
release(ctx.sharedLock.lock)
|
release(ctx.sharedLock.lock)
|
||||||
except: discard
|
except CatchableError: discard
|
||||||
|
|
||||||
applyDefaultValues(tbl, mutableFields, mutableValues)
|
applyDefaultValues(tbl, mutableFields, mutableValues)
|
||||||
|
|
||||||
|
|||||||
@@ -211,7 +211,7 @@ proc registerStdlib*(reg: UDFRegistry) =
|
|||||||
if args.len > 0 and args[0].kind == vkString:
|
if args.len > 0 and args[0].kind == vkString:
|
||||||
try:
|
try:
|
||||||
return Value(kind: vkInt64, int64Val: parseInt(args[0].strVal))
|
return Value(kind: vkInt64, int64Val: parseInt(args[0].strVal))
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
return Value(kind: vkNull))
|
return Value(kind: vkNull))
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ proc rebuildFromLSM*(cs: CompactionStrategy, db: LSMTree) =
|
|||||||
cs.clear()
|
cs.clear()
|
||||||
cs.dataDir = db.dir
|
cs.dataDir = db.dir
|
||||||
for sst in db.sstables:
|
for sst in db.sstables:
|
||||||
let size = try: int(getFileSize(sst.path)) except: sst.entryCount * 64
|
let size = try: int(getFileSize(sst.path)) except CatchableError: sst.entryCount * 64
|
||||||
cs.addTable(SSTableMeta(
|
cs.addTable(SSTableMeta(
|
||||||
path: sst.path,
|
path: sst.path,
|
||||||
level: sst.level,
|
level: sst.level,
|
||||||
@@ -143,7 +143,7 @@ proc compact*(cs: CompactionStrategy, level: int): CompactionResult =
|
|||||||
var sst = writeSSTable(final, outputPath, level + 1)
|
var sst = writeSSTable(final, outputPath, level + 1)
|
||||||
|
|
||||||
# Use actual file size instead of rough guess
|
# Use actual file size instead of rough guess
|
||||||
let actualSize = try: getFileSize(outputPath) except: final.len * 64
|
let actualSize = try: getFileSize(outputPath) except CatchableError: final.len * 64
|
||||||
|
|
||||||
let outputMeta = SSTableMeta(
|
let outputMeta = SSTableMeta(
|
||||||
path: outputPath,
|
path: outputPath,
|
||||||
@@ -159,7 +159,7 @@ proc compact*(cs: CompactionStrategy, level: int): CompactionResult =
|
|||||||
let (ok, msg) = verifySSTable(outputPath)
|
let (ok, msg) = verifySSTable(outputPath)
|
||||||
if not ok:
|
if not ok:
|
||||||
echo "[ERROR] Compaction output verification failed: ", msg
|
echo "[ERROR] Compaction output verification failed: ", msg
|
||||||
try: removeFile(outputPath) except: discard
|
try: removeFile(outputPath) except CatchableError: discard
|
||||||
return CompactionResult()
|
return CompactionResult()
|
||||||
|
|
||||||
# Remove old SSTable files
|
# Remove old SSTable files
|
||||||
|
|||||||
@@ -18,13 +18,15 @@ var
|
|||||||
|
|
||||||
proc initStorageGate*() =
|
proc initStorageGate*() =
|
||||||
## Idempotent when called from a single thread at startup.
|
## Idempotent when called from a single thread at startup.
|
||||||
|
## Must run before multi-threaded accept (HTTP workers / TCP).
|
||||||
if not gInited:
|
if not gInited:
|
||||||
initLock(gGate)
|
initLock(gGate)
|
||||||
gInited = true
|
gInited = true
|
||||||
|
|
||||||
proc acquireStorageGate*() {.inline.} =
|
proc acquireStorageGate*() {.inline.} =
|
||||||
## Prefer calling initStorageGate() once at process start (main).
|
## Prefer calling initStorageGate() once at process start (main).
|
||||||
## Lazy-init is allowed for unit tests (single-threaded).
|
## Lazy-init is only safe for single-threaded unit tests — concurrent
|
||||||
|
## first-time init races on gInited / initLock.
|
||||||
if not gInited:
|
if not gInited:
|
||||||
initStorageGate()
|
initStorageGate()
|
||||||
acquire(gGate)
|
acquire(gGate)
|
||||||
|
|||||||
@@ -473,7 +473,7 @@ proc listLegacySSTables*(dir: string): seq[(string, uint32)] =
|
|||||||
let sst = loadSSTable(path)
|
let sst = loadSSTable(path)
|
||||||
if sst.fileVersion < SSTableVersion:
|
if sst.fileVersion < SSTableVersion:
|
||||||
result.add((path, sst.fileVersion))
|
result.add((path, sst.fileVersion))
|
||||||
except:
|
except CatchableError:
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc migrateSSTable*(path: string): bool =
|
proc migrateSSTable*(path: string): bool =
|
||||||
@@ -595,7 +595,7 @@ proc checkStorageConsistency*(db: LSMTree): seq[string] =
|
|||||||
let j = parseJson(readFile(manifestPath))
|
let j = parseJson(readFile(manifestPath))
|
||||||
for node in j{"sstables"}:
|
for node in j{"sstables"}:
|
||||||
manifestPaths.add(node{"path"}.getStr())
|
manifestPaths.add(node{"path"}.getStr())
|
||||||
except:
|
except CatchableError:
|
||||||
result.add("MANIFEST is corrupt or unreadable")
|
result.add("MANIFEST is corrupt or unreadable")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ proc parseWalSequence*(filename: string): int64 =
|
|||||||
result = parseBiggestInt(numStr)
|
result = parseBiggestInt(numStr)
|
||||||
else:
|
else:
|
||||||
result = 0
|
result = 0
|
||||||
except:
|
except CatchableError:
|
||||||
result = 0
|
result = 0
|
||||||
|
|
||||||
proc listWalArchive*(dir: string): seq[WalSegment] =
|
proc listWalArchive*(dir: string): seq[WalSegment] =
|
||||||
@@ -90,7 +90,7 @@ proc listWalArchive*(dir: string): seq[WalSegment] =
|
|||||||
if kind == pcFile and path.endsWith(".log"):
|
if kind == pcFile and path.endsWith(".log"):
|
||||||
let seqNum = parseWalSequence(extractFilename(path))
|
let seqNum = parseWalSequence(extractFilename(path))
|
||||||
if seqNum > 0:
|
if seqNum > 0:
|
||||||
let size = try: getFileSize(path) except: 0
|
let size = try: getFileSize(path) except CatchableError: 0
|
||||||
result.add(WalSegment(sequence: seqNum, path: path, size: size))
|
result.add(WalSegment(sequence: seqNum, path: path, size: size))
|
||||||
result.sort(proc(a, b: WalSegment): int = cmp(a.sequence, b.sequence))
|
result.sort(proc(a, b: WalSegment): int = cmp(a.sequence, b.sequence))
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ proc maybeRotate*(wal: var WriteAheadLog) =
|
|||||||
## Rotate if current WAL exceeds max segment size.
|
## Rotate if current WAL exceeds max segment size.
|
||||||
if wal.maxSegmentSize <= 0:
|
if wal.maxSegmentSize <= 0:
|
||||||
return
|
return
|
||||||
let currentSize = try: getFileSize(wal.path) except: 0
|
let currentSize = try: getFileSize(wal.path) except CatchableError: 0
|
||||||
if currentSize >= wal.maxSegmentSize:
|
if currentSize >= wal.maxSegmentSize:
|
||||||
wal.rotate()
|
wal.rotate()
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -61,7 +61,7 @@ proc applyCompactionResult(db: LSMTree, result: compaction.CompactionResult) =
|
|||||||
var sst = loadSSTable(meta.path)
|
var sst = loadSSTable(meta.path)
|
||||||
let name = splitFile(meta.path).name
|
let name = splitFile(meta.path).name
|
||||||
# Prefer numeric id from filename; otherwise allocate
|
# Prefer numeric id from filename; otherwise allocate
|
||||||
let parsed = try: parseInt(name) except: -1
|
let parsed = try: parseInt(name) except CatchableError: -1
|
||||||
if parsed >= 0:
|
if parsed >= 0:
|
||||||
sst.id = parsed
|
sst.id = parsed
|
||||||
else:
|
else:
|
||||||
@@ -363,7 +363,7 @@ proc main() =
|
|||||||
let parts = seed.strip().split(":")
|
let parts = seed.strip().split(":")
|
||||||
if parts.len >= 2:
|
if parts.len >= 2:
|
||||||
let host = parts[0]
|
let host = parts[0]
|
||||||
let port = try: parseInt(parts[1]) except: 0
|
let port = try: parseInt(parts[1]) except CatchableError: 0
|
||||||
if port > 0:
|
if port > 0:
|
||||||
let seedNode = newGossipNode(host & ":" & $port, host, port)
|
let seedNode = newGossipNode(host & ":" & $port, host, port)
|
||||||
tcpServer.gossipProtocol.join(seedNode)
|
tcpServer.gossipProtocol.join(seedNode)
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ when isMainModule:
|
|||||||
try:
|
try:
|
||||||
discard server.init(dataDir)
|
discard server.init(dataDir)
|
||||||
server.run()
|
server.run()
|
||||||
except:
|
except CatchableError:
|
||||||
server.logToStderr("Fatal error: " & getCurrentExceptionMsg())
|
server.logToStderr("Fatal error: " & getCurrentExceptionMsg())
|
||||||
finally:
|
finally:
|
||||||
server.close()
|
server.close()
|
||||||
|
|||||||
@@ -1 +1,2 @@
|
|||||||
--path:"../src"
|
--path:"../src"
|
||||||
|
--path:"../clients/nim/src"
|
||||||
|
|||||||
+5
-1
@@ -31,7 +31,11 @@ import barabadb/query/udf
|
|||||||
import barabadb/vector/simd
|
import barabadb/vector/simd
|
||||||
import barabadb/core/crossmodal
|
import barabadb/core/crossmodal
|
||||||
import barabadb/core/gossip
|
import barabadb/core/gossip
|
||||||
import barabadb/client/client
|
# Canonical Nim client (not the deprecated src/barabadb/client).
|
||||||
|
# Selective import avoids WireValue clash with barabadb/protocol/wire.
|
||||||
|
from baradb/client import parseConnectionString, defaultClientConfig, newBaraClient,
|
||||||
|
newQueryBuilder, newSyncClient, BaraClient, QueryBuilder, ClientConfig, SyncClient,
|
||||||
|
select, `from`, where, join, leftJoin, groupBy, having, orderBy, limit, offset, build, exec
|
||||||
import barabadb/client/fileops
|
import barabadb/client/fileops
|
||||||
import barabadb/fts/multilang as mlang
|
import barabadb/fts/multilang as mlang
|
||||||
import barabadb/protocol/zerocopy
|
import barabadb/protocol/zerocopy
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import std/tables
|
|||||||
import barabadb/storage/lsm
|
import barabadb/storage/lsm
|
||||||
import barabadb/query/executor
|
import barabadb/query/executor
|
||||||
import barabadb/query/parser
|
import barabadb/query/parser
|
||||||
import barabadb/query/ast
|
|
||||||
|
|
||||||
proc execSql(ctx: ExecutionContext, sql: string): ExecResult =
|
proc execSql(ctx: ExecutionContext, sql: string): ExecResult =
|
||||||
let node = parse(sql)
|
let node = parse(sql)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
## Focused storage hardening tests (avoids full suite compile issues)
|
## Focused storage hardening tests (avoids full suite compile issues)
|
||||||
import std/unittest
|
import std/unittest
|
||||||
import std/os
|
import std/os
|
||||||
import std/strutils
|
|
||||||
import std/locks
|
import std/locks
|
||||||
import barabadb/storage/lsm
|
import barabadb/storage/lsm
|
||||||
import barabadb/storage/rwlock
|
import barabadb/storage/rwlock
|
||||||
|
|||||||
Reference in New Issue
Block a user