postgres init

This commit is contained in:
Ben Wilson
2023-12-04 00:34:33 -05:00
parent f7303d73af
commit 39c4c033e2
11 changed files with 305 additions and 85 deletions
@@ -11,7 +11,7 @@ export class AddressSettingsEntity extends TrackedEntity {
@Column({ default: 0 })
shares: number;
@Column({ type: 'real', default: 0 })
@Column({ type: 'decimal', default: 0 })
bestDifficulty: number;
@Column({ nullable: true })
@@ -2,7 +2,7 @@ import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
import { TrackedEntity } from '../utils/TrackedEntity.entity';
@Entity({ withoutRowid: true })
@Entity()
//Index for the heartbeat update
@Index(["address", "clientName", "sessionId", "time"])
export class ClientStatisticsEntity extends TrackedEntity {
@@ -21,13 +21,13 @@ export class ClientStatisticsEntity extends TrackedEntity {
sessionId: string;
@Index()
@Column({ type: 'integer' })
@Column({ type: 'bigint' })
time: number;
@Column({ type: 'real' })
@Column({ type: 'decimal' })
shares: number;
@Column({ default: 0, type: 'integer' })
@Column({ default: 0, type: 'bigint' })
acceptedCount: number;
@@ -67,7 +67,7 @@ export class ClientStatisticsService {
return result.map(res => {
res.label = new Date(res.label).toISOString();
res.label = new Date(parseInt(res.label)).toISOString();
return res;
}).slice(0, result.length - 1)
@@ -84,7 +84,7 @@ export class ClientStatisticsService {
// FROM
// client_statistics_entity AS entry
// WHERE
// entry.address = ? AND entry.time > ${oneHour}
// entry.address = $1 AND entry.time > ${oneHour}
// `;
// const result = await this.clientStatisticsRepository.query(query, [address]);
@@ -101,12 +101,12 @@ export class ClientStatisticsService {
const query = `
SELECT
time label,
time AS label,
(SUM(shares) * 4294967296) / 600 AS data
FROM
client_statistics_entity AS entry
WHERE
entry.address = ? AND entry.time > ${yesterday.getTime()}
entry.address = $1 AND entry.time > $2
GROUP BY
time
ORDER BY
@@ -115,10 +115,10 @@ export class ClientStatisticsService {
`;
const result = await this.clientStatisticsRepository.query(query, [address]);
const result = await this.clientStatisticsRepository.query(query, [address, yesterday.getTime()]);
return result.map(res => {
res.label = new Date(res.label).toISOString();
res.label = new Date(parseInt(res.label)).toISOString();
return res;
}).slice(0, result.length - 1);
@@ -136,7 +136,7 @@ export class ClientStatisticsService {
FROM
client_statistics_entity AS entry
WHERE
entry.address = ? AND entry.clientName = ? AND entry.time > ${oneHour.getTime()}
entry.address = $1 AND entry.clientName = $2 AND entry.time > ${oneHour.getTime()}
`;
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
@@ -153,12 +153,12 @@ export class ClientStatisticsService {
const query = `
SELECT
time label,
time AS label,
(SUM(shares) * 4294967296) / 600 AS data
FROM
client_statistics_entity AS entry
WHERE
entry.address = ? AND entry.clientName = ? AND entry.time > ${yesterday.getTime()}
entry.address = $1 AND entry."clientName" = $2 AND entry.time > ${yesterday.getTime()}
GROUP BY
time
ORDER BY
@@ -169,7 +169,7 @@ export class ClientStatisticsService {
const result = await this.clientStatisticsRepository.query(query, [address, clientName]);
return result.map(res => {
res.label = new Date(res.label).toISOString();
res.label = new Date(parseInt(res.label)).toISOString();
return res;
}).slice(0, result.length - 1);
@@ -181,13 +181,13 @@ export class ClientStatisticsService {
const query = `
SELECT
createdAt,
updatedAt,
"createdAt",
"updatedAt",
shares
FROM
client_statistics_entity AS entry
WHERE
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ?
entry.address = $1 AND entry."clientName" = $2 AND entry."sessionId" = $3
ORDER BY time DESC
LIMIT 2;
`;
@@ -227,7 +227,7 @@ export class ClientStatisticsService {
FROM
client_statistics_entity AS entry
WHERE
entry.address = ? AND entry.clientName = ? AND entry.sessionId = ? AND entry.time > ${yesterday.getTime()}
entry.address = $1 AND entry."clientName" = $2 AND entry."sessionId" = $3 AND entry.time > ${yesterday.getTime()}
GROUP BY
time
ORDER BY
@@ -238,7 +238,7 @@ export class ClientStatisticsService {
const result = await this.clientStatisticsRepository.query(query, [address, clientName, sessionId]);
return result.map(res => {
res.label = new Date(res.label).toISOString();
res.label = new Date(parseInt(res.label)).toISOString();
return res;
}).slice(0, result.length - 1);
+4 -9
View File
@@ -1,14 +1,9 @@
import { Column, Entity, Index, PrimaryColumn } from 'typeorm';
import { DateTimeTransformer } from '../utils/DateTimeTransformer';
import { TrackedEntity } from '../utils/TrackedEntity.entity';
//https://www.sqlite.org/withoutrowid.html
//The WITHOUT ROWID optimization is likely to be helpful for tables that have non-integer
// or composite (multi-column) PRIMARY KEYs and that do not store large strings or BLOBs.
//WITHOUT ROWID tables work best when individual rows are not too large.
@Entity({ withoutRowid: true })
@Entity()
@Index(['address', 'clientName', 'sessionId'], { unique: true })
export class ClientEntity extends TrackedEntity {
@@ -28,13 +23,13 @@ export class ClientEntity extends TrackedEntity {
@Column({ type: 'datetime', transformer: new DateTimeTransformer() })
@Column({ type: 'timestamp' })
startTime: Date;
@Column({ type: 'real', default: 0 })
@Column({ type: 'decimal', default: 0 })
bestDifficulty: number
@Column({ default: 0 })
@Column({ default: 0, type: 'decimal' })
hashRate: number;
}
+5 -30
View File
@@ -1,8 +1,6 @@
import { Injectable } from '@nestjs/common';
import { Interval } from '@nestjs/schedule';
import { InjectRepository } from '@nestjs/typeorm';
import { BehaviorSubject, firstValueFrom } from 'rxjs';
import { ObjectLiteral, Repository } from 'typeorm';
import { Repository } from 'typeorm';
import { ClientEntity } from './client.entity';
@@ -12,8 +10,6 @@ import { ClientEntity } from './client.entity';
export class ClientService {
public insertQueue: { result: BehaviorSubject<ObjectLiteral | null>, partialClient: Partial<ClientEntity> }[] = [];
constructor(
@InjectRepository(ClientEntity)
@@ -22,26 +18,13 @@ export class ClientService {
}
@Interval(1000 * 5)
public async insertClients() {
const queueCopy = [...this.insertQueue];
this.insertQueue = [];
const results = await this.clientRepository.insert(queueCopy.map(c => c.partialClient));
queueCopy.forEach((c, index) => {
c.result.next(results.generatedMaps[index]);
});
}
public async killDeadClients() {
var fiveMinutes = new Date(new Date().getTime() - (5 * 60 * 1000)).toISOString();
return await this.clientRepository
.createQueryBuilder()
.update(ClientEntity)
.set({ deletedAt: () => "DATETIME('now')" })
.where("deletedAt IS NULL AND updatedAt < DATETIME(:fiveMinutes)", { fiveMinutes })
.set({ deletedAt: () => "NOW()" })
.where("deletedAt IS NULL AND updatedAt < NOW() + interval '5 minutes' ")
.execute();
}
@@ -55,19 +38,11 @@ export class ClientService {
public async insert(partialClient: Partial<ClientEntity>): Promise<ClientEntity> {
const result = new BehaviorSubject(null);
this.insertQueue.push({ result, partialClient });
// const insertResult = await this.clientRepository.insert(partialClient);
const generatedMap = await firstValueFrom(result);
const insertResult = await this.clientRepository.insert(partialClient);
const client = {
...partialClient,
...generatedMap
...insertResult.generatedMaps[0]
};
return client as ClientEntity;
+3 -5
View File
@@ -1,14 +1,12 @@
import { CreateDateColumn, DeleteDateColumn, UpdateDateColumn } from 'typeorm';
import { DateTimeTransformer } from './DateTimeTransformer';
export abstract class TrackedEntity {
@DeleteDateColumn({ nullable: true, type: 'datetime', transformer: new DateTimeTransformer() })
@DeleteDateColumn({ nullable: true, type: 'timestamp' })
public deletedAt?: Date;
@CreateDateColumn({ type: 'datetime', transformer: new DateTimeTransformer() })
@CreateDateColumn({ type: 'timestamp' })
public createdAt?: Date
@UpdateDateColumn({ type: 'datetime', transformer: new DateTimeTransformer() })
@UpdateDateColumn({ type: 'timestamp' })
public updatedAt?: Date
}