Add a database connection, get the bcrypt library installed, implement a simple user repository.

This commit is contained in:
Dave Smith-Hayes 2024-04-04 22:13:32 -04:00
parent bfe8ba71ae
commit b031d83a7d
8 changed files with 107 additions and 7 deletions

Binary file not shown.

View File

@ -10,6 +10,8 @@
}, },
"dependencies": { "dependencies": {
"@types/express": "^4.17.21", "@types/express": "^4.17.21",
"express": "^4.19.2" "bcrypt": "^5.1.1",
"express": "^4.19.2",
"mariadb": "^3.3.0"
} }
} }

19
app/src/domain/entity.ts Normal file
View File

@ -0,0 +1,19 @@
export type EntityId = number|string;
export class Entity<T> {
protected readonly id: EntityId;
protected model: T;
public constructor(id: EntityId, model: T) {
this.id = id;
this.model = model;
}
public getId(): EntityId {
return this.id;
}
public getModel(): T {
return this.model;
}
}

View File

@ -1,7 +1,9 @@
import { Entity, type EntityId } from '@slovo/domain/entity';
export interface Repository<T> { export interface Repository<T> {
get(id: any): Promise<T>; get(id: EntityId): Promise<Entity<T>>;
save(model: T): Promise<void>; save(model: T): Promise<Entity<T>>;
update(model: T): Promise<void>; update(model: Entity<T>): Promise<Entity<T>>;
delete(model: T): Promise<void>; delete(model: Entity<T>): Promise<boolean>;
} }

View File

@ -0,0 +1,63 @@
import { type Repository } from '@slovo/domain/repository';
import { Entity, type EntityId } from '@slovo/domain/entity';
import { type User } from '@slovo/models/user';
import { type PoolConnection } from 'mariadb';
import connectionPool from '@slovo/infrastructure/database-pool';
export class UserRepository implements Repository<User> {
public async get(id: EntityId): Promise<Entity<User>> {
const conn: PoolConnection = await connectionPool.getConnection();
const query = `SELECT * FROM users WHERE id = ?`;
const rows = await conn.query(query, [ id ]);
if (!rows.length) {
throw Error("Unable to find User");
}
const row = rows.shift();
const user: User = {
name: row.name,
email: row.email,
password: row.password
};
await conn.release();
return new Entity(id, user);
}
public async save(user: User): Promise<Entity<User>> {
const conn: PoolConnection = await connectionPool.getConnection();
const query = `INSERT INTO users (name, email, password) VALUES (?, ?, ?)`;
const rows = await conn.query(query, [ user.name, user.email, user.password ]);
if (!rows.length) {
throw Error("Unable to create User");
}
await conn.release();
return new Entity(rows.insertId, user);
}
public async update(user: Entity<User>): Promise<Entity<User>> {
const conn: PoolConnection = await connectionPool.getConnection();
const query = `UPDATE user SET name = ?, email = ?, password = ? WHERE id = ?`;
const results = await conn.query(query, [
user.getModel().name,
user.getModel().email,
user.getModel().password,
user.getId()
]);
await conn.release();
}
public async delete(user: Entity<User>): Promise<boolean> {
const conn: PoolConnection = await connectionPool.getConnection();
await conn.release();
}
}

View File

@ -0,0 +1,10 @@
import { createPool } from 'mariadb';
const connectionPool = createPool({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_SCHEMA
});
export default connectionPool;

View File

@ -1,6 +1,6 @@
export type Image = { export type Image = {
url: URL, url: URL,
title: string, title?: string,
width: number, width: number,
height: number, height: number,
}; };

View File

@ -1,4 +1,8 @@
import express, { Express, type Request, type Response } from "express"; import express, {
type Express,
type Request,
type Response
} from "express";
const server: Express = express(); const server: Express = express();