feat: grow main
This commit is contained in:
1 parent
862de87af6
commit
02c5e6da3a
1 file changed
+196
-2
+196
-2
@@ -585,16 +585,150 @@ pub fn main() !void {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-select")) {
|
||||||
|
// Reuses the <dir> slot as a host:port to connect to, exactly like
|
||||||
|
// `verify` reuses it as the directory under test - `remote-select`
|
||||||
|
// never opens a local Db at all.
|
||||||
|
try runRemoteSelect(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-join")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteJoin(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-aggregate")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteAggregate(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-window")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteWindow(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-publish")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemotePublish(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-subscribe")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteSubscribe(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-unsubscribe")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteUnsubscribe(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-explain")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteExplain(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-update")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteUpdate(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-delete")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteDelete(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-export")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteExport(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-import")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteImport(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-user")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select` - never opens a local Db.
|
||||||
|
try runRemoteUser(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-stats")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select`/`remote-user` - never opens a local Db.
|
||||||
|
try runRemoteStats(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-ttl")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-select`/`remote-user`/`remote-stats` - never opens a
|
||||||
|
// local Db.
|
||||||
|
try runRemoteTtl(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-coll-ttl")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-ttl` - never opens a local Db.
|
||||||
|
try runRemoteCollTtl(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-coll")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as
|
||||||
|
// `remote-coll-ttl` - never opens a local Db.
|
||||||
|
try runRemoteColl(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (std.mem.eql(u8, command, "remote-txn")) {
|
||||||
|
// Same "<dir> slot is really host:port" convention as every other
|
||||||
|
// remote-* command - never opens a local Db.
|
||||||
|
try runRemoteTxn(allocator, stdout, stderr, dir, rest);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var db = try cobalt.Db.open(allocator, dir, .{});
|
var db = try cobalt.Db.open(allocator, dir, .{});
|
||||||
defer db.close();
|
defer db.close();
|
||||||
|
|
||||||
if (std.mem.eql(u8, command, "put")) {
|
if (std.mem.eql(u8, command, "put")) {
|
||||||
if (rest.len < 2) return fail(stderr, "put needs <key> <value>");
|
if (rest.len < 2) return fail(stderr, "put needs <key> <value>");
|
||||||
try db.put(rest[0], rest[1]);
|
try db.put(rest[0], rest[1]);
|
||||||
|
if (rest.len >= 4 and std.mem.eql(u8, rest[2], "--ttl")) {
|
||||||
|
const seconds = std.fmt.parseInt(u64, rest[3], 10) catch return fail(stderr, "--ttl needs a whole number of seconds");
|
||||||
|
try cobalt.ttl.setExpireSeconds(&db, allocator, rest[0], std.time.nanoTimestamp(), seconds);
|
||||||
|
} else if (rest.len > 2) {
|
||||||
|
return fail(stderr, "put takes <key> <value> [--ttl <seconds>]");
|
||||||
|
}
|
||||||
try db.maybeCompact();
|
try db.maybeCompact();
|
||||||
} else if (std.mem.eql(u8, command, "get")) {
|
} else if (std.mem.eql(u8, command, "get")) {
|
||||||
if (rest.len < 1) return fail(stderr, "get needs <key>");
|
if (rest.len < 1) return fail(stderr, "get needs <key>");
|
||||||
if (try db.get(allocator, rest[0])) |value| {
|
if (try cobalt.ttl.getLive(&db, allocator, rest[0], std.time.nanoTimestamp())) |value| {
|
||||||
defer allocator.free(value);
|
defer allocator.free(value);
|
||||||
try stdout.print("{s}\n", .{value});
|
try stdout.print("{s}\n", .{value});
|
||||||
} else {
|
} else {
|
||||||
@@ -603,7 +737,27 @@ pub fn main() !void {
|
|||||||
} else if (std.mem.eql(u8, command, "del")) {
|
} else if (std.mem.eql(u8, command, "del")) {
|
||||||
if (rest.len < 1) return fail(stderr, "del needs <key>");
|
if (rest.len < 1) return fail(stderr, "del needs <key>");
|
||||||
try db.delete(rest[0]);
|
try db.delete(rest[0]);
|
||||||
|
try cobalt.ttl.clearExpire(&db, allocator, rest[0]);
|
||||||
try db.maybeCompact();
|
try db.maybeCompact();
|
||||||
|
} else if (std.mem.eql(u8, command, "expire")) {
|
||||||
|
if (rest.len < 2) return fail(stderr, "expire needs <key> <seconds>");
|
||||||
|
const seconds = std.fmt.parseInt(u64, rest[1], 10) catch return fail(stderr, "expire needs a whole number of seconds");
|
||||||
|
const existing = try db.get(allocator, rest[0]) orelse return fail(stderr, "no such key");
|
||||||
|
allocator.free(existing);
|
||||||
|
try cobalt.ttl.setExpireSeconds(&db, allocator, rest[0], std.time.nanoTimestamp(), seconds);
|
||||||
|
} else if (std.mem.eql(u8, command, "persist")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "persist needs <key>");
|
||||||
|
try cobalt.ttl.clearExpire(&db, allocator, rest[0]);
|
||||||
|
} else if (std.mem.eql(u8, command, "ttl")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "ttl needs <key>");
|
||||||
|
switch (try cobalt.ttl.remaining(&db, allocator, rest[0], std.time.nanoTimestamp())) {
|
||||||
|
.noKey => try stdout.writeAll("-2\n"),
|
||||||
|
.noExpiry => try stdout.writeAll("-1\n"),
|
||||||
|
.seconds => |s| try stdout.print("{d}\n", .{s}),
|
||||||
|
}
|
||||||
|
} else if (std.mem.eql(u8, command, "expire-sweep")) {
|
||||||
|
const reaped = try cobalt.ttl.sweepExpired(&db, allocator, std.time.nanoTimestamp());
|
||||||
|
try stdout.print("reaped: {d}\n", .{reaped});
|
||||||
} else if (std.mem.eql(u8, command, "scan")) {
|
} else if (std.mem.eql(u8, command, "scan")) {
|
||||||
const start: ?[]const u8 = if (rest.len >= 1) rest[0] else null;
|
const start: ?[]const u8 = if (rest.len >= 1) rest[0] else null;
|
||||||
const end: ?[]const u8 = if (rest.len >= 2) rest[1] else null;
|
const end: ?[]const u8 = if (rest.len >= 2) rest[1] else null;
|
||||||
@@ -625,7 +779,47 @@ pub fn main() !void {
|
|||||||
try db.compact();
|
try db.compact();
|
||||||
try stdout.print("sstables after compaction: {d}\n", .{db.sstables.items.len});
|
try stdout.print("sstables after compaction: {d}\n", .{db.sstables.items.len});
|
||||||
} else if (std.mem.eql(u8, command, "stats")) {
|
} else if (std.mem.eql(u8, command, "stats")) {
|
||||||
try db.stats().print(stdout);
|
if (rest.len >= 1 and std.mem.eql(u8, rest[0], "--prom")) {
|
||||||
|
try cobalt.metrics.formatDbStats(stdout, "cobalt", db.stats());
|
||||||
|
} else {
|
||||||
|
try db.stats().print(stdout);
|
||||||
|
}
|
||||||
|
} else if (std.mem.eql(u8, command, "serve")) {
|
||||||
|
const bind = if (rest.len >= 1) rest[0] else "127.0.0.1:6380";
|
||||||
|
const serveRest = if (rest.len >= 1) rest[1..] else rest;
|
||||||
|
try runServe(allocator, stdout, &db, bind, serveRest);
|
||||||
|
} else if (std.mem.eql(u8, command, "backup")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "backup needs <file>");
|
||||||
|
const snap = try db.snapshot();
|
||||||
|
const count = try cobalt.backup.dumpToFile(allocator, snap, rest[0]);
|
||||||
|
try stdout.print("backup written: {d} entries, seq={d}, file={s}\n", .{ count, snap.seq, rest[0] });
|
||||||
|
} else if (std.mem.eql(u8, command, "restore")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "restore needs <file>");
|
||||||
|
const info = cobalt.backup.restoreFromFile(allocator, &db, rest[0], 500) catch |err| {
|
||||||
|
try stderr.print("restore failed: {s}\n", .{@errorName(err)});
|
||||||
|
std.process.exit(1);
|
||||||
|
};
|
||||||
|
try stdout.print("restore applied: {d} entries from seq={d}\n", .{ info.entryCount, info.seq });
|
||||||
|
} else if (std.mem.eql(u8, command, "coll")) {
|
||||||
|
try runColl(allocator, stdout, stderr, &db, rest);
|
||||||
|
} else if (std.mem.eql(u8, command, "table")) {
|
||||||
|
try runTable(allocator, stdout, stderr, &db, rest);
|
||||||
|
} else if (std.mem.eql(u8, command, "user")) {
|
||||||
|
try runUser(allocator, stdout, stderr, &db, rest);
|
||||||
|
} else if (std.mem.eql(u8, command, "txn")) {
|
||||||
|
try runTxn(allocator, stdout, stderr, &db, rest);
|
||||||
|
} else if (std.mem.eql(u8, command, "replicate")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "replicate needs <replica-dir>");
|
||||||
|
try runReplicate(allocator, stdout, &db, rest[0], rest[1..]);
|
||||||
|
} else if (std.mem.eql(u8, command, "repl")) {
|
||||||
|
try runRepl(allocator, stdout, stderr, &db, rest);
|
||||||
|
} else if (std.mem.eql(u8, command, "backup-info")) {
|
||||||
|
if (rest.len < 1) return fail(stderr, "backup-info needs <file>");
|
||||||
|
const info = cobalt.backup.inspectFile(allocator, rest[0]) catch |err| {
|
||||||
|
try stderr.print("invalid backup: {s}\n", .{@errorName(err)});
|
||||||
|
std.process.exit(1);
|
||||||
|
};
|
||||||
|
try stdout.print("entries={d} seq={d}\n", .{ info.entryCount, info.seq });
|
||||||
} else {
|
} else {
|
||||||
try stderr.print("unknown command: {s}\n", .{command});
|
try stderr.print("unknown command: {s}\n", .{command});
|
||||||
try stderr.writeAll(usage);
|
try stderr.writeAll(usage);
|
||||||
|
|||||||
Reference in new issue
Block a user