Initial commit
This commit is contained in:
commit
24f0a28a3c
25 changed files with 3190 additions and 0 deletions
245
db/index.js
Normal file
245
db/index.js
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
import pgPkg from 'pg';
|
||||
const { Pool } = pgPkg;
|
||||
|
||||
const pool = new Pool();
|
||||
|
||||
const parseVoter = (voter) => ({
|
||||
id: parseInt(voter.id),
|
||||
login: voter.login,
|
||||
password: voter.password,
|
||||
full_name: voter.full_name,
|
||||
vgroup_id: parseInt(voter.vgroup_id),
|
||||
is_admin: JSON.parse(voter.is_admin),
|
||||
registration_date: voter.registration_date,
|
||||
});
|
||||
|
||||
const parseVgroup = (vgroup) => ({
|
||||
id: parseInt(vgroup.id),
|
||||
name: vgroup.name,
|
||||
description: vgroup.description,
|
||||
});
|
||||
|
||||
const parseVote = (vote) => ({
|
||||
id: parseInt(vote.id),
|
||||
health: parseInt(vote.health),
|
||||
love: parseInt(vote.love),
|
||||
sex: parseInt(vote.sex),
|
||||
rest: parseInt(vote.rest),
|
||||
finances: parseInt(vote.finances),
|
||||
meaning_of_life: parseInt(vote.meaning_of_life),
|
||||
serenity: parseInt(vote.serenity),
|
||||
relations: parseInt(vote.relations),
|
||||
pers_growth: parseInt(vote.pers_growth),
|
||||
work: parseInt(vote.work),
|
||||
vote_date: vote.vote_date,
|
||||
voter_id: parseInt(vote.voter_id),
|
||||
});
|
||||
|
||||
// TODO: implement
|
||||
const parseVoteResult = (voteResult) => ({
|
||||
|
||||
});
|
||||
|
||||
|
||||
export class DBAccess {
|
||||
static async tableExists(table) {
|
||||
const res = await pool.query("SELECT 1 FROM pg_database WHERE datname = $1", [table]);
|
||||
return res.rows.length > 0;
|
||||
}
|
||||
|
||||
static async scaffold() {
|
||||
await pool.query(`CREATE TABLE IF NOT EXISTS vgroup (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
description VARCHAR(255) NOT NULL DEFAULT ''
|
||||
)`);
|
||||
await pool.query(`CREATE TABLE IF NOT EXISTS voter (
|
||||
id SERIAL PRIMARY KEY,
|
||||
login VARCHAR(255) UNIQUE NOT NULL,
|
||||
password VARCHAR(255) NOT NULL,
|
||||
vgroup_id INT,
|
||||
full_name VARCHAR(255) NOT NULL DEFAULT '',
|
||||
is_admin BOOLEAN NOT NULL DEFAULT false,
|
||||
registration_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT fk_vgroup FOREIGN KEY(vgroup_id) REFERENCES vgroup(id)
|
||||
)`);
|
||||
await pool.query(`CREATE TABLE IF NOT EXISTS vote (
|
||||
id SERIAL PRIMARY KEY,
|
||||
health INT NOT NULL,
|
||||
love INT NOT NULL,
|
||||
sex INT NOT NULL,
|
||||
rest INT NOT NULL,
|
||||
finances INT NOT NULL,
|
||||
meaning_of_life INT NOT NULL,
|
||||
serenity INT NOT NULL,
|
||||
relations INT NOT NULL,
|
||||
pers_growth INT NOT NULL,
|
||||
work INT NOT NULL,
|
||||
vote_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
voter_id INT NOT NULL,
|
||||
CONSTRAINT voter FOREIGN KEY(voter_id) REFERENCES voter(id)
|
||||
)`);
|
||||
}
|
||||
|
||||
static async dropAll() {
|
||||
await pool.query("DROP TABLE IF EXISTS vote");
|
||||
await pool.query("DROP TABLE IF EXISTS voter");
|
||||
await pool.query("DROP TABLE IF EXISTS vgroup");
|
||||
}
|
||||
|
||||
static query(text, params, callback) {
|
||||
return pool.query(text, params, callback);
|
||||
}
|
||||
|
||||
static async queryAsync(text, params) {
|
||||
return pool.query(text, params);
|
||||
}
|
||||
|
||||
static async countVoters() {
|
||||
const res = await pool.query("SELECT COUNT(*) FROM voter");
|
||||
return parseInt(res.rows[0].count);
|
||||
}
|
||||
|
||||
static async findVoterByLogin(login) {
|
||||
const res = await pool.query("SELECT * FROM voter WHERE login = $1", [login]);
|
||||
if (res.rows.length != 0) {
|
||||
return parseVoter(res.rows[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async validateVoter(login, password) {
|
||||
const res = await pool.query("SELECT * FROM voter WHERE login = $1 AND password = $2", [login, password]);
|
||||
if (res.rows.length != 0) {
|
||||
return parseVoter(res.rows[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async createVoter(login, password, full_name, is_admin) {
|
||||
let res = await pool.query(
|
||||
"INSERT INTO voter(login, password, full_name, is_admin) VALUES ($1, $2, $3, $4) RETURNING *",
|
||||
[login, password, full_name, is_admin]
|
||||
);
|
||||
if (res.rows.length != 0) {
|
||||
if (is_admin) {
|
||||
let adminGroup = await pool.query("SELECT * FROM vgroup WHERE name = $1", ["admin"]);
|
||||
if (adminGroup.rows.length === 0) {
|
||||
adminGroup = await pool.query("INSERT INTO vgroup(name, description) VALUES ($1, $2) RETURNING *", ["admin", "Администраторы"]);
|
||||
}
|
||||
res = await pool.query("UPDATE voter SET vgroup_id = $1 WHERE login = $2 RETURNING *", [adminGroup.rows[0].id, login]);
|
||||
}
|
||||
if (res.rows.length != 0) {
|
||||
return parseVoter(res.rows[0]);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async getVoters() {
|
||||
const res = await pool.query("SELECT * FROM voter ORDER BY registration_date");
|
||||
return res.rows.map(parseVoter);
|
||||
}
|
||||
|
||||
static async getVoterById(id) {
|
||||
const res = await pool.query("SELECT * FROM voter WHERE id = $1", [id]);
|
||||
if (res.rows.length != 0) {
|
||||
return parseVoter(res.rows[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async deleteVoterVotes(id) {
|
||||
await pool.query("DELETE FROM vote WHERE voter_id = $1", [id]);
|
||||
}
|
||||
|
||||
static async deleteVoter(id) {
|
||||
await this.deleteVoterVotes(id);
|
||||
await pool.query("DELETE FROM voter WHERE id = $1", [id]);
|
||||
}
|
||||
|
||||
static async promoteVoter(id, vgroup_id, setAdmin) {
|
||||
const user = await this.getVoterById(id);
|
||||
const admCount = (await this.getVoters()).reduce((acc, item) => acc + (item.is_admin ? 1 : 0), 0);
|
||||
if (user) {
|
||||
if (user.is_admin && admCount === 1) {
|
||||
throw new Error("Нельзя удалить последнего администратора");
|
||||
}
|
||||
if (setAdmin) {
|
||||
await pool.query("UPDATE voter SET vgroup_id = $1, is_admin = true WHERE id = $2", [vgroup_id, id]);
|
||||
} else {
|
||||
await pool.query("UPDATE voter SET vgroup_id = $1, is_admin = false WHERE id = $2", [vgroup_id, id]);
|
||||
}
|
||||
} else {
|
||||
throw new Error("Такого пользователя нет");
|
||||
}
|
||||
}
|
||||
|
||||
static async getVgroups() {
|
||||
const res = await pool.query("SELECT * FROM vgroup");
|
||||
return res.rows.map(parseVgroup);
|
||||
}
|
||||
|
||||
static async createVgroup(name, description) {
|
||||
const res = await pool.query("INSERT INTO vgroup(name, description) VALUES ($1, $2) RETURNING *", [name, description]);
|
||||
if (res.rows.length != 0) {
|
||||
return parseVgroup(res.rows[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async deleteVgroup(id) {
|
||||
await pool.query("DELETE FROM vgroup WHERE id = $1", [id]);
|
||||
}
|
||||
|
||||
static async createVote(vote) {
|
||||
const res = await pool.query(`INSERT INTO vote(
|
||||
health, love, sex, rest, relations, pers_growth, work,
|
||||
finances, meaning_of_life, serenity, voter_id
|
||||
) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING *`, [
|
||||
vote.health, vote.love, vote.sex, vote.rest, vote.relations, vote.pers_growth, vote.work,
|
||||
vote.finances, vote.meaning_of_life, vote.serenity, vote.voter_id
|
||||
]);
|
||||
if (res.rows.length != 0) {
|
||||
return parseVote(res.rows[0]);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static async getVotes() {
|
||||
const res = await pool.query("SELECT * FROM vote ORDER BY vote.vote_date desc");
|
||||
return res.rows.map(parseVote);
|
||||
}
|
||||
|
||||
static async getVotesByVoterId(voter_id) {
|
||||
const res = await pool.query("SELECT * FROM vote WHERE voter_id = $1", [voter_id]);
|
||||
return res.rows.map(parseVote);
|
||||
}
|
||||
|
||||
static async deleteVote(id) {
|
||||
await pool.query("DELETE FROM vote WHERE id = $1", [id]);
|
||||
}
|
||||
|
||||
static async getGrouppedVotes() {
|
||||
const res = await pool.query(`
|
||||
select
|
||||
array_agg(v.health) as health, array_agg(v.love) as love, array_agg(v.sex) as sex, array_agg(v.rest) as rest, array_agg(v.finances) as finances,
|
||||
array_agg(v.meaning_of_life) as meaning_of_life, array_agg(v.serenity) as serenity, array_agg(v.relations) as relations,
|
||||
array_agg(v.pers_growth) as pers_growth, array_agg(v.work) as work,
|
||||
v1.vgroup_id, to_char(v.vote_date, 'mm.yyyy') as vote_date
|
||||
from vote as v
|
||||
inner join voter v1 on v1.id = v.voter_id
|
||||
group by v1.vgroup_id, to_char(v.vote_date, 'mm.yyyy')
|
||||
order by to_char(v.vote_date, 'mm.yyyy') asc`.trim());
|
||||
return res.rows;//.map(parseVote);
|
||||
}
|
||||
|
||||
static async didUserBotedThisMonth(voter_id) {
|
||||
const res = await pool.query("SELECT * FROM vote WHERE voter_id = $1 AND vote_date >= date_trunc('month', now())", [voter_id]);
|
||||
return res.rows.length != 0;
|
||||
}
|
||||
|
||||
static async shutdown() {
|
||||
return await pool.end();
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue