Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created January 17, 2021 14:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mizchi/90a7bae4b3cf8a3139ff0fd3e704b05e to your computer and use it in GitHub Desktop.
Save mizchi/90a7bae4b3cf8a3139ff0fd3e704b05e to your computer and use it in GitHub Desktop.
import { PrismaClient } from "@prisma/client";
import { minifyCode, expandCode, calcHash } from "../src/lib/minifier";
import { v4 as uuid } from "uuid";
async function createSnippet(authorId: string, files: { [k: string]: string }) {
const snippetId = uuid();
return await prisma.snippet.create({
data: {
id: snippetId,
title: "test-snippet",
author: {
connect: {
id: authorId,
},
},
chunkOwnerships: {
connectOrCreate: Object.entries(files).map(([filepath, content]) => {
const minified = minifyCode(content, filepath);
const hash = calcHash(filepath);
return {
where: {
snippetId_filepath: {
snippetId,
filepath,
},
},
create: {
filepath,
chunk: {
connectOrCreate: {
where: {
hash,
},
create: {
hash,
content: minified,
},
},
},
},
};
}),
},
},
});
}
async function updateSnippetFiles(
snippetId: string,
files: { [k: string]: string }
) {
const old = await prisma.snippet.findFirst({
where: {
id: snippetId,
},
select: {
chunkOwnerships: {
select: {
filepath: true,
},
},
},
});
if (old == null) {
return {
ok: false,
};
}
const newFilepaths = Object.keys(files);
const oldFilepaths = old.chunkOwnerships.map((i) => i.filepath);
let deletedFilepaths: string[] = [];
oldFilepaths.forEach((oldFilepath) => {
if (!newFilepaths.includes(oldFilepath)) {
deletedFilepaths.push(oldFilepath);
}
});
await prisma.snippet.update({
where: {
id: snippetId,
},
data: {
chunkOwnerships: {
delete: oldFilepaths.map((oldFilepath) => {
return {
snippetId_filepath: {
snippetId,
filepath: oldFilepath,
},
};
}),
upsert: Object.entries(files).map(([filepath, content]) => {
const minified = minifyCode(content);
const hash = calcHash(minified);
return {
where: {
snippetId_filepath: {
snippetId,
filepath,
},
},
update: {
filepath,
chunk: {
connectOrCreate: {
where: {
hash,
},
create: {
hash,
content: minified,
},
},
},
},
create: {
filepath,
chunk: {
connectOrCreate: {
where: {
hash,
},
create: {
hash,
content: minified,
},
},
},
},
};
}),
},
},
});
return {
ok: true,
};
}
async function getSnippetFiles(snippetId: string) {
const data = await prisma.snippet.findFirst({
where: {
id: snippetId,
},
include: {
chunkOwnerships: {
include: {
chunk: true,
},
},
},
});
if (data == null) {
return;
}
const files = data.chunkOwnerships.reduce((acc, next) => {
return { ...acc, [next.filepath]: expandCode(next.chunk.content) };
}, {} as { [k: string]: string });
return files;
}
const prisma = new PrismaClient({
// log: ["query", "error", "info", "warn"],
});
(async () => {
let testUser = await prisma.user.upsert({
where: {
name: "testuser",
},
create: {
name: "testuser",
},
update: {
name: "testuser",
},
});
console.log("test user", testUser);
const files: { [k: string]: string } = {
"/foo.ts": expandCode("export const foo = 1;"),
"/index.tsx": expandCode(`import { foo } from "./foo";console.log(foo);`),
};
const snippet = await createSnippet(testUser.id, files);
const savedFiles = await getSnippetFiles(snippet.id);
console.log(savedFiles);
await updateSnippetFiles(snippet.id, { "/index.tsx": "export default 1;" });
const savedFilesAfter = await getSnippetFiles(snippet.id);
console.log("after", savedFilesAfter);
process.exit(0);
})()
.catch((err) => {
console.error(err);
})
.finally(() => {
prisma.$disconnect();
});
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "sqlite"
url = "file:./dev.db"
}
model User {
id String @id @default(uuid())
name String @unique @default(uuid())
snippets Snippet[]
}
model Chunk {
hash String @id
content String
referencedBy ChunkOwnership[]
}
model ChunkOwnership {
filepath String
hash String
snippetId String
chunk Chunk @relation(fields: [hash], references: [hash])
snippet Snippet @relation(fields: [snippetId], references: [id])
@@id([snippetId, filepath])
}
model Snippet {
id String @id @default(uuid())
title String
authorId String?
author User? @relation(fields: [authorId], references: [id])
chunkOwnerships ChunkOwnership[]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment