From 87f77990e675150676f6d9e8ccc5e582a3a2fc1f Mon Sep 17 00:00:00 2001 From: Gisle Aune Date: Mon, 4 Apr 2022 13:59:17 +0200 Subject: [PATCH] blurgh. --- scripts/goose-mysql/20220326173144_stat.sql | 18 +++++ .../goose-mysql/20220326174046_project.sql | 18 +++++ src/lib/database/interfaces.ts | 6 ++ src/lib/database/mysql/scopes.ts | 53 +++++++++++++-- src/lib/models/project.ts | 11 +--- src/lib/models/scope.ts | 2 +- src/routes/[scope].json.ts | 66 ++----------------- src/routes/[scope]/__layout.svelte | 6 +- 8 files changed, 104 insertions(+), 76 deletions(-) create mode 100644 scripts/goose-mysql/20220326173144_stat.sql create mode 100644 scripts/goose-mysql/20220326174046_project.sql diff --git a/scripts/goose-mysql/20220326173144_stat.sql b/scripts/goose-mysql/20220326173144_stat.sql new file mode 100644 index 0000000..e915484 --- /dev/null +++ b/scripts/goose-mysql/20220326173144_stat.sql @@ -0,0 +1,18 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE stat ( + `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT, + `scope_id` INT NOT NULL, + `name` VARCHAR(255) NOT NULL, + `description` TEXT NOT NULL, + `weight` FLOAT NOT NULL, + `allowed_amounts` JSON, + + UNIQUE (`scope_id`, `name`) +); +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +SELECT 'down SQL query'; +-- +goose StatementEnd diff --git a/scripts/goose-mysql/20220326174046_project.sql b/scripts/goose-mysql/20220326174046_project.sql new file mode 100644 index 0000000..52f3287 --- /dev/null +++ b/scripts/goose-mysql/20220326174046_project.sql @@ -0,0 +1,18 @@ +-- +goose Up +-- +goose StatementBegin +CREATE TABLE IF NOT EXISTS 'project' ( + `id` INT NOT NULL AUTO_INCREMENT, + `scope_id` INT NOT NULL, + `author_id` CHAR(36) NOT NULL, + `name` VARCHAR(255) NOT NULL, + `status` INT NOT NULL, + `description` TEXT NOT NULL, + + UNIQUE (`scope_id`, `name`) +) +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +SELECT 'down SQL query'; +-- +goose StatementEnd diff --git a/src/lib/database/interfaces.ts b/src/lib/database/interfaces.ts index 699f8b5..f48c7ae 100644 --- a/src/lib/database/interfaces.ts +++ b/src/lib/database/interfaces.ts @@ -3,6 +3,12 @@ import type Scope from "$lib/models/scope"; import type { StatEntry } from "$lib/models/stat"; import type Stat from "$lib/models/stat"; +export class NotFoundError extends Error { + constructor(subject: string) { + super(`${subject} not found`); + } +} + export interface Database { userId: string diff --git a/src/lib/database/mysql/scopes.ts b/src/lib/database/mysql/scopes.ts index 58c0928..676d0c5 100644 --- a/src/lib/database/mysql/scopes.ts +++ b/src/lib/database/mysql/scopes.ts @@ -1,6 +1,6 @@ import type {Pool} from "mysql2/promise"; -import type scope from "$lib/models/scope"; +import type Scope from "$lib/models/scope"; import type { ScopeEntry, ScopeInput } from "$lib/models/scope"; import type { ScopeRepo } from "../interfaces"; @@ -13,8 +13,51 @@ export default class MysqlDBScopes implements ScopeRepo { this.userId = userId; } - find(id: number): Promise { - throw new Error("Method not implemented."); + async find(id: number): Promise { + const [[scopeRows], [projectRows], [statRows]] = await Promise.all([ + this.connection.execute(` + SELECT scope.*, scope_member.name as display_name + FROM scope + INNER JOIN scope_member ON scope.id = scope_member.scope_id + WHERE scope.id = ? + `, [id]), + this.connection.execute(` + SELECT id,name,status + FROM project + WHERE scope_id = ? + `, [id]).catch(() => []), + this.connection.execute(` + SELECT * + FROM stats + WHERE scope_id = ? + `, [id]).catch(() => []), + ]); + + console.log(scopeRows, statRows, statRows) + + const r = scopeRows[0] as any; + if (!r) { + return null; + } + + return { + id: r.id, + name: r.name, + abbreviation: r.abbreviation, + displayName: r.display_name, + projects: ((projectRows||[]) as any[]).map((p:any) => ({ + id: p.id, + name: p.name, + status: p.status, + })), + stats: ((statRows||[]) as any[]).map((s:any) => ({ + id: s.id, + name: s.name, + weight: s.weight, + description: s.description, + allowedAmounts: s.allowed_amounts || void(0), + })), + } } async list(): Promise { const [rows] = await this.connection.execute(` @@ -31,10 +74,10 @@ export default class MysqlDBScopes implements ScopeRepo { displayName: r.display_name, })) } - create(input: ScopeInput): Promise { + create(input: ScopeInput): Promise { throw new Error("Method not implemented."); } - update(id: number, input: Partial): Promise { + update(id: number, input: Partial): Promise { throw new Error("Method not implemented."); } delete(id: number): Promise { diff --git a/src/lib/models/project.ts b/src/lib/models/project.ts index 553f9e8..2a9fe6e 100644 --- a/src/lib/models/project.ts +++ b/src/lib/models/project.ts @@ -1,15 +1,10 @@ -import type Item from "./item"; -import type Scope from "./scope"; import type { ScopeEntry } from "./scope"; -import type { StatAggregate, StatEntry, StatProgressEntry } from "./stat"; -import type Stat from "./stat"; +import type { StatProgressEntry } from "./stat"; import type Status from "./status"; -export default interface Project { - id: number - name: string +export default interface Project extends ProjectEntry { description: string - status: Status + author: string scope: ScopeEntry requirements: Requirement[] diff --git a/src/lib/models/scope.ts b/src/lib/models/scope.ts index ccaeeed..0a1deeb 100644 --- a/src/lib/models/scope.ts +++ b/src/lib/models/scope.ts @@ -2,7 +2,7 @@ import type { ProjectEntry } from "./project"; import type Stat from "./stat"; export default interface Scope extends ScopeEntry { - activeProjects: ProjectEntry[] + projects: ProjectEntry[] stats: Stat[] } diff --git a/src/routes/[scope].json.ts b/src/routes/[scope].json.ts index c624bcc..dd586d2 100644 --- a/src/routes/[scope].json.ts +++ b/src/routes/[scope].json.ts @@ -1,10 +1,12 @@ -import type { RequestHandler } from "@sveltejs/kit" -import Status from "$lib/models/status" -import type Scope from "$lib/models/scope" +import type { RequestHandler } from "@sveltejs/kit"; -export const get: RequestHandler = async({params}) => { +import config from "$lib/config"; + +export const get: RequestHandler = async({params, locals}) => { const scopeId = parseInt(params.scope); - const scope = scopes.find(s => s.id === scopeId); + + const db = await config.database(); + const scope = await db.withUser(locals.user.id).scopes().find(scopeId) if (scope === null) { return { status: 404, @@ -27,57 +29,3 @@ export const get: RequestHandler = async({params}) => { }), } } - -const scopes: Scope[] = [ - { - id: 1, name: "3D Modeling", abbreviation: "3D", displayName: "Test", - stats: [ - {id: 101, name: "Asset", weight: 0.1, description: "Some description"}, - {id: 102, name: "Tweak", weight: 0.2, description: "Some description"}, - { - id: 103, name: "Complexity", weight: 1, description: "Some description", - allowedAmounts: { - "Basic": 1, - "Medium": 3, - "Complex": 6, - "Excessive": 12, - } - }, - {id: 104, name: "Hard Surface", weight: 0.4, description: "Some description"}, - {id: 105, name: "UV Mapping", weight: 0.2, description: "Some description"}, - {id: 106, name: "Third-Party Asset", weight: 0.1, description: "Some description"}, - {id: 107, name: "Material", weight: 0.1, description: "Some description"}, - ], - activeProjects: [ - {id: 1001, name: "3D Maps: Proving the Concept", status: Status.Active}, - {id: 1002, name: "Redrock HQ", status: Status.Active}, - {id: 1003, name: "Tutorial: Realistic Environments", status: Status.Background}, - ] - }, - { - id: 2, name: "Roleplay", abbreviation: "RP", displayName: "Test", - stats: [ - {id: 201, name: "Story", weight: 3, description: "Some description"}, - {id: 202, name: "Story Word", weight: 0.002, description: "Some description"}, - {id: 203, name: "Worldbuilding", weight: 0.50, description: "Some description"}, - {id: 204, name: "Characterbuilding", weight: 0.50, description: "Some description"}, - {id: 205, name: "Note", weight: 1, description: "Some description"}, - {id: 206, name: "Wiki Section", weight: 1, description: "Some description"}, - {id: 207, name: "Wiki Research", weight: 0.5, description: "Some description"}, - {id: 208, name: "Wiki Complexity", weight: 0.5, description: "Some description"}, - ], - activeProjects: [ - {id: 2001, name: "Ilyna: The Morning After", status: Status.Active}, - {id: 2002, name: "Renala: Finding Her Voice", status: Status.Active}, - {id: 2003, name: "General Stories", status: Status.Background}, - {id: 2004, name: "Uvena: Finish Wiki Page", status: Status.Active}, - {id: 2005, name: "Va'ynna: Cracking at the Seams", status: Status.Active}, - {id: 2006, name: "Witch Hunt: Sala's Backlog", status: Status.Active}, - {id: 2007, name: "Ilyna: Complete Wiki Page", status: Status.Completed}, - {id: 2008, name: "Renala: Complete Wiki Page", status: Status.Active}, - ] - }, - //{id: 3, name: "Minecraft", abbreviation: "MC"}, - //{id: 4, name: "Coding", abbreviation: "CODE"}, - //{id: 5, name: "System Administration", abbreviation: "SA"}, -] \ No newline at end of file diff --git a/src/routes/[scope]/__layout.svelte b/src/routes/[scope]/__layout.svelte index 85a1058..783496f 100644 --- a/src/routes/[scope]/__layout.svelte +++ b/src/routes/[scope]/__layout.svelte @@ -17,7 +17,7 @@ }; } - return; + return {fallthrough: true}; } const STATUS_ORDER = [ @@ -37,11 +37,11 @@ import Status from "$lib/models/status"; import MenuCategory from "$lib/components/layout/MenuCategory.svelte"; import type { ProjectEntry } from "$lib/models/project"; -import MenuItem from "$lib/components/layout/MenuItem.svelte"; + import MenuItem from "$lib/components/layout/MenuItem.svelte"; export let scope: Scope; - let projects = scope.activeProjects; + let projects = scope.projects; let projectsByStatus: Record; $: projectsByStatus = projects.reduce((p, c) => ({...p, [c.status]: [...p[c.status], c]}), {