prisma pretty noice
This commit is contained in:
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
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -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");
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Vendored
+17
-17
@@ -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,
|
||||
// }
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
Reference in new issue
Block a user