Skip to content
Snippets Groups Projects
Commit 7da8524b authored by alrwasheda's avatar alrwasheda :speech_balloon:
Browse files

Refactoring ( new Structure, same functionality)

parent 207d12c4
No related branches found
No related tags found
No related merge requests found
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"@types/node": {
"version": "16.11.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.11.tgz",
"integrity": "sha512-KB0sixD67CeecHC33MYn+eYARkqTheIRNuu97y2XMjR7Wu3XibO1vaY6VBV6O/a89SPI81cEUIYT87UqUWlZNw=="
},
"@types/pg": {
"version": "8.6.1",
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz",
"integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==",
"dev": true,
"requires": {
"@types/node": "*",
"pg-protocol": "*",
"pg-types": "^2.2.0"
}
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"packet-reader": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz",
"integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ=="
},
"pg": {
"version": "8.7.1",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.7.1.tgz",
"integrity": "sha512-7bdYcv7V6U3KAtWjpQJJBww0UEsWuh4yQ/EjNf2HeO/NnvKjpvhEIe/A/TleP6wtmSKnUnghs5A9jUoK6iDdkA==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.4.1",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
}
},
"pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-pool": {
"version": "3.4.1",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.4.1.tgz",
"integrity": "sha512-TVHxR/gf3MeJRvchgNHxsYsTCHQ+4wm3VIHSS19z8NC0+gioEhq1okDY1sm/TYbfoP6JLFx01s0ShvZ3puP/iQ=="
},
"pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.4.tgz",
"integrity": "sha512-YmuA56alyBq7M59vxVBfPJrGSozru8QAdoNlWuW3cz8l+UX3cWge0vTvjKhsSHSJpo3Bom8/Mm6hf0TR5GY0+w==",
"requires": {
"split2": "^3.1.1"
}
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha1-AntTPAqokOJtFy1Hz5zOzFIazTU="
},
"postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
}
},
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
},
"split2": {
"version": "3.2.2",
"resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz",
"integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==",
"requires": {
"readable-stream": "^3.0.0"
}
},
"string_decoder": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"requires": {
"safe-buffer": "~5.2.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
}
}
}
This diff is collapsed.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
"devDependencies": { "devDependencies": {
"@types/express": "^4.17.13", "@types/express": "^4.17.13",
"@types/node": "^16.11.6", "@types/node": "^16.11.6",
"@types/pg": "^8.6.1",
"@types/validator": "^13.6.6", "@types/validator": "^13.6.6",
"nodemon": "^2.0.14", "nodemon": "^2.0.14",
"ts-node": "^10.4.0", "ts-node": "^10.4.0",
......
import { Dialect, Sequelize } from "sequelize"; import { Dialect, Sequelize } from "sequelize";
const envVars = { const envVars = {
dbName: process.env.DB_NAME, DB_NAME: process.env.DB_NAME,
dbUser: process.env.DB_USER, DB_USER: process.env.DB_USER,
dbHost: process.env.DB_HOST, DB_HOST: process.env.DB_HOST,
dbDriver: process.env.DB_DRIVER as Dialect, DB_DRIVER: process.env.DB_DRIVER as Dialect,
dbPassword: process.env.DB_PASSWORD, DB_PASSWORD: process.env.DB_PASSWORD,
} }
if (!envVars.dbName || !envVars.dbUser || !envVars.dbHost || !envVars.dbDriver || !envVars.dbPassword) { if (!envVars.DB_NAME || !envVars.DB_USER || !envVars.DB_HOST || !envVars.DB_DRIVER || !envVars.DB_PASSWORD) {
console.error(`Error while reading DB Environment variables! Is maybe the .env file missing? console.error(`Error while reading DB Environment variables! Is maybe the .env file missing?
DB Name: "${envVars.dbName}", Host: "${envVars.dbHost}", User: "${envVars.dbUser}", DB Driver(e.g. postgres): "${envVars.dbDriver}"`); DB Name: "${envVars.DB_NAME}", Host: "${envVars.DB_HOST}", User: "${envVars.DB_USER}", DB Driver(e.g. postgres): "${envVars.DB_DRIVER}"`);
process.exit(9); process.exit(9);
} }
......
import Customer from "./models/Customer";
import Boat from "./models/Boat";
import Worker from "./models/Worker";
import CheckIn from "./models/CheckIn";
import { createTableIfNotExists } from "./seqConnection";
const isDev = process.env.NODE_ENV === "development";
const dbInit = async () => {
await Customer.sync({ alter: isDev });
await Boat.sync({ alter: isDev });
await Worker.sync({ alter: isDev });
await CheckIn.sync({ alter: isDev });
};
const connectAndInit = async () => {
await createTableIfNotExists();
await dbInit();
};
export default connectAndInit;
import { Client } from "pg";
import { Dialect, Sequelize } from "sequelize";
import envVars from "../config";
import { initBoat } from "./models/Boat";
import {initCheckIn} from "./models/CheckIn";
import {initCustomer} from "./models/Customer";
import {initWorker} from "./models/Worker";
const initializeDatabase = async () => {
const client = new Client({
host: envVars.DB_HOST,
user: envVars.DB_USER,
password: envVars.DB_PASSWORD,
});
// https://stackoverflow.com/questions/18389124/simulate-create-database-if-not-exists-for-postgresql
await client.connect();
console.log(envVars.DB_NAME);
const isDatabaseExistingQuery = await client.query(
`SELECT * FROM pg_database WHERE datname='${envVars.DB_NAME}'`
);
console.log(isDatabaseExistingQuery);
const isDatabaseExisting = isDatabaseExistingQuery.rowCount === 1;
if (!isDatabaseExisting) {
await client.query(`CREATE DATABASE "${envVars.DB_NAME}"`);
}
client.end();
const sequelize = new Sequelize(envVars.DB_NAME, envVars.DB_USER, envVars.DB_PASSWORD, {
host: envVars.DB_HOST,
dialect: envVars.DB_DRIVER as Dialect,
logging: false,
});
await initBoat(sequelize);
await initCheckIn(sequelize);
await initCustomer(sequelize);
await initWorker(sequelize);
await sequelize.sync();
return sequelize;
};
export default initializeDatabase;
import sequelizeConnection from "../seqConnection"; import { Sequelize, DataTypes, Model, Optional } from "sequelize";
import { DataTypes, Model, Optional } from "sequelize";
interface BoatAttributes { interface BoatAttributes {
id: number; id: number;
...@@ -21,7 +20,8 @@ class Boat extends Model<BoatAttributes> implements BoatAttributes { ...@@ -21,7 +20,8 @@ class Boat extends Model<BoatAttributes> implements BoatAttributes {
public readonly createdAt!: Date; public readonly createdAt!: Date;
public readonly updatedAt!: Date; public readonly updatedAt!: Date;
} }
Boat.init( export const initBoat = async (sequelizeConnection: Sequelize) => {
Boat.init(
{ {
id: { id: {
type: DataTypes.INTEGER, type: DataTypes.INTEGER,
...@@ -49,6 +49,7 @@ Boat.init( ...@@ -49,6 +49,7 @@ Boat.init(
sequelize: sequelizeConnection, sequelize: sequelizeConnection,
} }
); );
}
export const create = async (payload: Boat): Promise<BoatAttributesOutput> => { export const create = async (payload: Boat): Promise<BoatAttributesOutput> => {
return await Boat.create(payload); return await Boat.create(payload);
......
import sequelizeConnection from "../seqConnection";
import { DataTypes, Model, Optional } from "sequelize"; import { DataTypes, Model, Optional , Sequelize} from "sequelize";
interface CheckInAttributes { interface CheckInAttributes {
id: number; id: number;
...@@ -25,46 +25,49 @@ class CheckIn extends Model<CheckInAttributes> implements CheckInAttributes { ...@@ -25,46 +25,49 @@ class CheckIn extends Model<CheckInAttributes> implements CheckInAttributes {
public readonly createdAt!: Date; public readonly createdAt!: Date;
public readonly updatedAt!: Date; public readonly updatedAt!: Date;
} }
CheckIn.init(
{ export const initCheckIn = async (sequelizeConnection: Sequelize) => {
id: { CheckIn.init(
type: DataTypes.INTEGER, {
primaryKey: true, id: {
}, type: DataTypes.INTEGER,
checkin: { primaryKey: true,
type: DataTypes.DATE,
allowNull: false,
},
checkout: {
type: DataTypes.DATE,
allowNull: false,
},
clientID: {
type: DataTypes.INTEGER,
references: {
model: "customer",
key: "id",
}, },
}, checkin: {
boatID: { type: DataTypes.DATE,
type: DataTypes.INTEGER, allowNull: false,
references: { },
model: "boat", checkout: {
key: "id", type: DataTypes.DATE,
allowNull: false,
},
clientID: {
type: DataTypes.INTEGER,
references: {
model: "customer",
key: "id",
},
},
boatID: {
type: DataTypes.INTEGER,
references: {
model: "boat",
key: "id",
},
},
destination: {
type: new DataTypes.STRING(),
},
note: {
type: new DataTypes.STRING(),
}, },
}, },
destination: { {
type: new DataTypes.STRING(), tableName: "checkIn",
}, sequelize: sequelizeConnection,
note: { }
type: new DataTypes.STRING(), );
}, }
},
{
tableName: "checkIn",
sequelize: sequelizeConnection,
}
);
export const create = async ( export const create = async (
payload: CheckIn payload: CheckIn
......
import sequelizeConnection from "../seqConnection";
import { DataTypes, Model, Optional } from "sequelize"; import { DataTypes, Model, Optional, Sequelize } from "sequelize";
interface CustomerAttributes { interface CustomerAttributes {
id: number; id: number;
...@@ -18,6 +18,9 @@ class Customer extends Model<CustomerAttributes> implements CustomerAttributes { ...@@ -18,6 +18,9 @@ class Customer extends Model<CustomerAttributes> implements CustomerAttributes {
public readonly createdAt!: Date; public readonly createdAt!: Date;
public readonly updatedAt!: Date; public readonly updatedAt!: Date;
} }
export const initCustomer = async (sequelizeConnection: Sequelize) => {
Customer.init( Customer.init(
{ {
id: { id: {
...@@ -44,6 +47,7 @@ Customer.init( ...@@ -44,6 +47,7 @@ Customer.init(
sequelize: sequelizeConnection, sequelize: sequelizeConnection,
} }
); );
}
export const create = async (payload: Customer): Promise<CustomerOutput> => { export const create = async (payload: Customer): Promise<CustomerOutput> => {
return await Customer.create(payload); return await Customer.create(payload);
......
import sequelizeConnection from "../seqConnection"; import { DataTypes, Model, Optional, Sequelize } from "sequelize";
import { DataTypes, Model, Optional } from "sequelize";
interface WorkerAttributes { interface WorkerAttributes {
email: string; email: string;
...@@ -20,6 +19,8 @@ class Worker extends Model<WorkerAttributes> implements WorkerAttributes { ...@@ -20,6 +19,8 @@ class Worker extends Model<WorkerAttributes> implements WorkerAttributes {
public readonly createdAt!: Date; public readonly createdAt!: Date;
public readonly updatedAt!: Date; public readonly updatedAt!: Date;
} }
export const initWorker = async (sequelizeConnection: Sequelize) => {
Worker.init( Worker.init(
{ {
email: { email: {
...@@ -50,6 +51,7 @@ Worker.init( ...@@ -50,6 +51,7 @@ Worker.init(
sequelize: sequelizeConnection, sequelize: sequelizeConnection,
} }
); );
}
export const create = async (payload: Worker): Promise<WorkerOutput> => { export const create = async (payload: Worker): Promise<WorkerOutput> => {
return await Worker.create(payload); return await Worker.create(payload);
......
import { Sequelize } from "sequelize";
import envVars from "./config";
const pg = require("pg");
const { Client, QueryResult } = pg;
let sequelizeConnection = new Sequelize(
envVars.dbName,
envVars.dbUser,
envVars.dbPassword,
{
host: envVars.dbHost,
dialect: envVars.dbDriver,
logging: false,
}
);
//check if DB in env exists. If not, create a one
export const createTableIfNotExists = async () => {
const client = new Client({
host: envVars.dbHost,
port: 5432, //envVars.dbPort does not exist!
user: envVars.dbUser,
password: envVars.dbPassword,
});
await client.connect();
//search for db in pg-catalog. if not found, create a one
const tables = client
.query(`SELECT * FROM pg_database WHERE datname = '${envVars.dbName}'`)
.then((res: typeof QueryResult) => {
//------------------------------------------------then
if (res.rows.length === 0) {
//given db not found
console.log(
`${envVars.dbName} not found!\n${envVars.dbName} created..!`
);
client.query(`CREATE DATABASE "${envVars.dbName}"`);
sequelizeConnection = new Sequelize(
envVars.dbName,
envVars.dbUser,
envVars.dbPassword,
{
host: envVars.dbHost,
dialect: envVars.dbDriver,
logging: false,
}
);
}
});
};
export default sequelizeConnection;
import sequelizeConnection from "./seqConnection"; import { QueryTypes, Sequelize } from "sequelize";
import { QueryTypes } from "sequelize";
const showAllDBs = async () => { const showAllDBs = async (sequelizeConnection: Sequelize) => {
await sequelizeConnection await sequelizeConnection
.query("SELECT datname FROM pg_database", { type: QueryTypes.SELECT }) .query("SELECT datname FROM pg_database", { type: QueryTypes.SELECT })
.then((res) => { .then((res) => {
......
import sequelizeConnection from "./seqConnection";
import { QueryTypes } from "sequelize";
import envVars from "./config";
const showTables = async () => { import { QueryTypes, Sequelize } from "sequelize";
import envVars from "../config";
const showTables = async (sequelizeConnection: Sequelize) => {
//list all tables of the actual database //list all tables of the actual database
sequelizeConnection sequelizeConnection
.query( .query(
`SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='${envVars.dbName}' AND TABLE_SCHEMA='public';`, `SELECT TABLE_NAME FROM information_schema.tables WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_CATALOG='${envVars.DB_NAME}' AND TABLE_SCHEMA='public';`,
{ type: QueryTypes.SELECT } { type: QueryTypes.SELECT }
) )
.then((res) => { .then((res) => {
//------------------------------------------------then //------------------------------------------------then
console.log(`TABELS IN ${envVars.dbName}\n-------------\n`, res); console.log(`TABELS IN ${envVars.DB_NAME}\n-------------\n`, res);
}); });
}; };
......
import "dotenv/config"; import "dotenv/config";
import express from "express"; import express from "express";
import connectAndInit from "./db/db_init"; // import connectAndInit from "./db/db_init";
import showAllDBs from "./db/showAllDBs"; import showAllDBs from "./db/showAllDBs";
import showTables from "./db/showDBTables"; import showTables from "./db/showDBTables";
import initializeDatabase from './db';
let init = async () => { let init = async () => {
await connectAndInit(); const sequelize = await initializeDatabase();
const app = express(); const app = express();
app.use(express.json()); app.use(express.json());
...@@ -13,8 +14,8 @@ let init = async () => { ...@@ -13,8 +14,8 @@ let init = async () => {
app.listen(port, () => console.log(`Server listening on port: ${port}\n`)); app.listen(port, () => console.log(`Server listening on port: ${port}\n`));
app.get("/", (req, res) => res.send("hello in server")); app.get("/", (req, res) => res.send("hello in server"));
await showAllDBs(); await showAllDBs(sequelize);
await showTables(); await showTables(sequelize);
}; };
init().then(() => {}); init().then(() => {});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment