prisma pretty noice

This commit is contained in:
ntr committed 2022-07-28 00:18:11 +10:00
1 parent eb04fdb9a5
commit adcc19564f
11 files changed
+125 -177

No files matched your search

@@ -1,8 +0,0 @@
# #!/bin/bash
# set -e
# psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" <<-EOSQL
# CREATE USER mcrates;
# CREATE DATABASE mcrates;
# GRANT ALL PRIVILEGES ON DATABASE mcrates TO mcrates;
# EOSQL
+7 -4
View File
@@ -1,13 +1,15 @@
import fs from 'fs/promises';
import _ from 'lodash';
import Promise from 'bluebird';
import { PrismaClient } from '@prisma/client'
import discogsService from './src/discogs';
import pgService from './src/pg';
import { logAxiosError } from './src/utils';
async function start() {
const pg = pgService();
const prisma = new PrismaClient();
const pg = pgService(prisma);
const discogs = discogsService(pg);
const usernames = [
@@ -47,9 +49,10 @@ async function start() {
// return listings;
}
return Promise.resolve(usernames)
.map(u => discogs.user(u))
.map(populateUserListings);
for (const u of usernames) {
const user = await discogs.user(u)
await populateUserListings(user);
}
// return Promise.map(releases, async w => {
// try {
-17
View File
@@ -1,17 +0,0 @@
exports.up = async knex => {
await knex.schema.createTable('users', table => {
table.uuid('id')
.primary()
.defaultTo(knex.raw('gen_random_uuid()'));
table.string('discogs')
.unique();
table.jsonb('data')
.notNullable();
table.timestamps(true, true);
});
};
exports.down = async () => true;
-27
View File
@@ -1,27 +0,0 @@
exports.up = async knex => {
await knex.schema.createTable('wants', table => {
table.uuid('id')
.primary()
.defaultTo(knex.raw('gen_random_uuid()'));
table.integer('release')
.notNullable()
.index();
table.uuid('user')
table.foreign('user')
.references('id')
.inTable('users')
.onDelete('CASCADE');
table.jsonb('data')
.notNullable();
// user can only want a release once
table.unique(['user', 'release']);
table.timestamps(true, true);
});
};
exports.down = async () => true;
-23
View File
@@ -1,23 +0,0 @@
exports.up = async knex => {
await knex.schema.createTable('listings', table => {
table.integer('id')
.primary();
table.uuid('want')
table.foreign('want')
.references('id')
.inTable('wants')
.onDelete('CASCADE');
table.integer('seller')
.notNullable()
.index();
table.jsonb('data')
.notNullable();
table.timestamps(true, true);
});
};
exports.down = async () => true;
@@ -1,13 +0,0 @@
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"discogs" TEXT,
"data" JSONB NOT NULL,
"creaedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_discogs_key" ON "User"("discogs");
-3
View File
@@ -1,3 +0,0 @@
# Please do not edit this file manually
# It should be added in your version-control system (i.e. Git)
provider = "postgresql"
+35 -5
View File
@@ -1,6 +1,3 @@
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
@@ -10,11 +7,44 @@ datasource db {
url = env("DATABASE_URL")
}
model Listing {
id Int @id
seller Int
data Json
wantId String @db.Uuid
want Want @relation(fields: [wantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([seller])
}
model User {
id String @id @default(uuid())
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
discogs String? @unique
data Json
creaedAt DateTime @default(now())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
wants Want[]
}
model Want {
id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid
release Int?
data Json
userId String @db.Uuid
user User @relation(fields: [userId], references: [id], onDelete: Cascade, onUpdate: Cascade)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
listings Listing[]
@@unique([userId, release])
@@index([release])
}
+7 -4
View File
@@ -2,6 +2,7 @@ import fs from 'fs/promises';
import axios from 'axios';
import cheerio from 'cheerio';
import type { PrismaClient, Want, User, Listing } from '@prisma/client';
import { logAxiosError } from './utils';
import { Pg } from './pg';
@@ -25,17 +26,19 @@ export default function discogs(pg: Pg) {
}
async function user(discogs: string) {
const user = await pg.userGetName(discogs);
const user = await pg.userFindName(discogs);
if (user) return user;
console.log('fetching user', discogs);
const res = await api.get(`${apiBase}/users/${discogs}`);
return pg.userUpsert(res.data);
}
async function wantlist(user: User): Promise<Want[]> {
const stored = await pg.userWants(user);
if (stored.length) return stored;
const { data: { wants, pagination }} = await api.get(`${apiBase}/users/${user.data.username}/wants`);
const { username } = user.data as { username: string };
const { data: { wants, pagination }} = await api.get(`${apiBase}/users/${username}/wants`);
return Promise.all(wants.map(r => pg.wantUpsert(r, user)))
}
@@ -44,7 +47,7 @@ export default function discogs(pg: Pg) {
return res.data.listings;
}
async function listings(want: Want): Promise<Listing[]> {
async function listings(want: Want) {
const res = await api.get(`https://www.discogs.com/sell/release/${want.release}`);
const $ = cheerio.load(res.data);
const ids = $('.item_description_title[href]')
@@ -57,7 +60,7 @@ export default function discogs(pg: Pg) {
}
async function listing(id, want) {
const listing = await pg.listingGet(id);
const listing = await pg.listingFind(id);
if (listing) return listing;
try {
+17 -17
View File
@@ -1,21 +1,21 @@
type UUID = string;
type User = {
id: UUID,
discogs: string,
data: any,
}
// type User = {
// id: UUID,
// discogs: string,
// data: any,
// }
type Listing = {
id: number,
want: UUID,
seller: number,
data: any,
}
// type Listing = {
// id: number,
// want: UUID,
// seller: number,
// data: any,
// }
type Want = {
id: UUID,
release: number,
user: UUID,
data: any,
}
// type Want = {
// id: UUID,
// release: number,
// user: UUID,
// data: any,
// }
+59 -56
View File
@@ -1,98 +1,101 @@
import Knex from 'knex';
import config from '../knexfile';
import type { PrismaClient, Want, User, Listing, Prisma } from '@prisma/client';
export interface Pg {
userGetId: (id: UUID) => Promise<User>,
userGetName: (name: string) => Promise<User>,
userFindId: (id: UUID) => Promise<User>,
userFindName: (name: string) => Promise<User>,
userUpsert: (user: User) => Promise<User>,
userWants: (user: User) => Promise<Want[]>,
wantUpsert: (want: Want, user: User) => Promise<Want>,
listingUpsert: (listing: Listing, want: Want) => Promise<Listing>,
listingGet: (id: number) => Promise<Listing>,
listingFind: (id: number) => Promise<Listing>,
}
export default function createPg(): Pg {
const pg = Knex(config);
export default function createPg(prisma: PrismaClient): Pg {
// const pg = Knex(config);
async function userGetId(id): Promise<User> {
return pg('users')
.where({ id })
.first();
async function userFindId(id) {
return prisma.user.findUnique({ where: { id }});
}
async function userGetName(name): Promise<User> {
return pg('users')
.where({ discogs: name })
.first();
async function userFindName(name) {
return prisma.user.findUnique({ where: { discogs: name }});
}
async function userWants(user: User): Promise<Want[]> {
return pg('wants')
.where({ user: user.id });
async function userWants(user: User) {
return prisma.want.findMany({ where: { userId: user.id }});
}
async function userUpsert(user): Promise<User> {
const [row] = await pg('users')
.insert({
async function userUpsert(user) {
const data = {
discogs: user.username,
data: user,
})
.onConflict('id')
.merge()
.onConflict('discogs')
.merge()
.returning('*');
data: user as Prisma.JsonObject,
};
return row;
return prisma.user.upsert({
where: {
discogs: user.username,
},
update: data,
create: data,
});
}
async function wantUpsert(want, user): Promise<Want> {
const [row] = await pg('wants')
.insert({
data: want,
release: want.id,
user: user.id,
})
.onConflict('id')
.merge()
.onConflict(['user', 'release'])
.merge()
.returning('*');
async function wantUpsert(dcWant, user) {
const values: { userId: string, release: number, data: any } = {
data: dcWant,
release: dcWant.id,
userId: user.id,
};
return row;
return prisma.want.upsert({
// get these from the generated types
// ./node_modules/.prisma/client/index.d.ts
where: { userId_release: {
userId: values.userId,
release: values.release || null,
}},
update: values,
create: values,
});
}
async function listingUpsert(listing, want): Promise<Listing> {
const [row] = await pg('listings')
.insert({
async function listingUpsert(listing, want) {
const values = {
id: listing.id,
want: want.id,
wantId: want.id,
seller: listing.seller.id,
data: listing,
})
.onConflict('id')
.merge()
.returning('*');
};
return row;
return prisma.listing.upsert({
where: {
id: listing.id
},
update: values,
create: values,
});
}
async function listingGet(id): Promise<Listing> {
return pg('listings')
.where({ id })
.first();
async function listingFind(id) {
return prisma.listing.findUnique({
where: {
id,
}
});
}
return {
userGetId,
userGetName,
userFindId,
userFindName,
userUpsert,
userWants,
wantUpsert,
listingUpsert,
listingGet,
listingFind,
};
}