Skip to content

Commit

Permalink
feat: .zoid-meta virtual file
Browse files Browse the repository at this point in the history
  • Loading branch information
divyenduz committed Nov 10, 2023
1 parent 6c67416 commit 8842a74
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 4 deletions.
4 changes: 4 additions & 0 deletions packages/fuse-client/syscalls/flush.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ export const flush: (backend: SQLiteBackend) => MountOptions["flush"] = (
) => {
return async (path, fd, cb) => {
console.info("flush(%s, %d)", path, fd);
if (backend.isVirtualFile(path)) {
cb(0);
return;
}
await backend.flush(path);
cb(0);
};
Expand Down
7 changes: 7 additions & 0 deletions packages/fuse-client/syscalls/getattr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ export const getattr: (backend: SQLiteBackend) => MountOptions["getattr"] = (
) => {
return async (path, cb) => {
console.info("getattr(%s)", path);

if (backend.isVirtualFile(path)) {
const virtualFile = backend.getVirtualFile(path);
cb(0, virtualFile.getAttr());
return;
}

const r = await backend.getFile(path);
await match(r)
.with({ status: "ok" }, async (r) => {
Expand Down
8 changes: 7 additions & 1 deletion packages/fuse-client/syscalls/open.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ export const open: (backend: SQLiteBackend) => MountOptions["open"] = (
) => {
return async (path, flags, cb) => {
console.info("open(%s, %d)", path, flags);
const r = await backend.getFile(path);

if (backend.isVirtualFile(path)) {
const virtualFile = backend.getVirtualFile(path);
cb(0, virtualFile.fileId);
return;
}

const r = await backend.getFile(path);
match(r)
.with({ status: "ok" }, (r) => {
cb(0, r.file.id);
Expand Down
9 changes: 9 additions & 0 deletions packages/fuse-client/syscalls/read.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ export const read: (backend: SQLiteBackend) => MountOptions["read"] = (
) => {
return async (path, fd, buf, len, pos, cb) => {
console.info("read(%s, %d, %d, %d)", path, fd, len, pos);

if (backend.isVirtualFile(path)) {
const virtualFile = backend.getVirtualFile(path);
const bufChunk = virtualFile.getBuffer();
buf.write(bufChunk.toString("binary"), "binary");
cb(Buffer.byteLength(bufChunk));
return;
}

const r = await backend.getFileChunks(fd, pos, len);
await match(r)
.with({ status: "ok" }, async (r) => {
Expand Down
8 changes: 5 additions & 3 deletions packages/fuse-client/syscalls/readdir.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@ export const readdir: (backend: SQLiteBackend) => MountOptions["readdir"] = (
return async (path, cb) => {
console.info("readdir(%s)", path);

// TODO: figure out how are these directories in output of ls -la
const dotDirs = [".", ".."];

const metaFiles: string[] = backend.getVirtualFilePaths(path);
const links = await backend.getLinks(path);
const fileNames = dotDirs.concat(links.map((link) => link.name));
const fileNames = dotDirs
// Note: trim the first / of /.zoid-meta returning .zoid-meta
.concat(metaFiles.map((metaFile) => metaFile.slice(1)))
.concat(links.map((link) => link.name));

return cb(0, fileNames);
};
Expand Down
30 changes: 30 additions & 0 deletions packages/sqlite-backend/SQLiteBackend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { rawCreateMany } from "./prismaRawUtil";
import { WriteBuffer } from "./WriteBuffer";
import mmmagic, { Magic } from "mmmagic";
import { promisify } from "util";
import { VirtualFiles } from "./VirtualFiles";
import { VirtualFile } from "./VirtualFile";

export type ContentChunk = {
content: Buffer;
Expand All @@ -19,6 +21,7 @@ export class SQLiteBackend implements Backend {
private readonly writeBuffers: Map<string, WriteBuffer<ContentChunk>> =
new Map();
private readonly prisma: PrismaClient;
private readonly virtualFiles: VirtualFiles;
constructor(prismaOrDbUrl?: PrismaClient | string) {
if (prismaOrDbUrl instanceof PrismaClient) {
this.prisma = prismaOrDbUrl;
Expand All @@ -35,6 +38,33 @@ export class SQLiteBackend implements Backend {

this.prisma.$connect();
}

const virtualFile = new VirtualFile(
999,
"/.zoid-meta",
JSON.stringify(
{
databaseUrl: process.env.DATABASE_URL,
},
null,
2
) + "\n"
);
const virtualFileMap = new Map();
virtualFileMap.set(virtualFile.path, virtualFile);
this.virtualFiles = new VirtualFiles(virtualFileMap);
}

isVirtualFile(filepath: string) {
return this.virtualFiles.isVirtualFile(filepath);
}

getVirtualFile(filepath: string) {
return this.virtualFiles.getVirtualFile(filepath)!;
}

getVirtualFilePaths(filepath: string) {
return this.virtualFiles.filePaths(filepath);
}

async write(filepath: string, chunk: ContentChunk) {
Expand Down
39 changes: 39 additions & 0 deletions packages/sqlite-backend/VirtualFile.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
export class VirtualFile {
private _date = new Date();
constructor(
private _fileId: number,
private _path: string,
private _content: string
) {}

get path() {
return this._path;
}

get fileId() {
return this._fileId;
}

getBuffer() {
return Buffer.from(this._content);
}

getSize() {
return Buffer.byteLength(this.getBuffer());
}

getAttr() {
return {
mtime: this._date,
atime: this._date,
ctime: this._date,
blocks: 1,
ino: this.fileId,
nlink: 1,
size: this.getSize(),
mode: 33188,
uid: process.getuid ? process.getuid() : 0,
gid: process.getgid ? process.getgid() : 0,
};
}
}
21 changes: 21 additions & 0 deletions packages/sqlite-backend/VirtualFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { VirtualFile } from "./VirtualFile";

export class VirtualFiles {
constructor(private _files: Map<string, VirtualFile>) {}

filePaths(path: string) {
if (path === "/") {
return Array.from(this._files.keys());
}
return [];
}

isVirtualFile(path: string) {
// TODO: find correct directory
return this._files.has(path);
}

getVirtualFile(path: string) {
return this._files.get(path);
}
}

0 comments on commit 8842a74

Please sign in to comment.