mirror of
https://github.com/okiba-org/backend.git
synced 2025-02-22 01:02:02 +00:00
feat: populate database function
This commit is contained in:
parent
899ffa1799
commit
68eebf1229
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,4 +2,5 @@
|
||||
node_modules/
|
||||
public/
|
||||
test/
|
||||
data/
|
||||
data/
|
||||
words.txt
|
79
src/db/index.ts
Normal file
79
src/db/index.ts
Normal file
@ -0,0 +1,79 @@
|
||||
import { logError, logSuccess, projectRoot } from "../utils";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import { Client, QueryResult } from "pg";
|
||||
|
||||
export const tableExists = async (db: Client): Promise<boolean> => {
|
||||
const result = await db
|
||||
.query(
|
||||
"SELECT EXISTS (SELECT * FROM information_schema.tables WHERE table_name = 'words');"
|
||||
)
|
||||
.catch((err) => err);
|
||||
|
||||
return result.rows[0].exists;
|
||||
};
|
||||
|
||||
// used for generating param query string
|
||||
// expand(rowCount: 3, columnCount: 2) returns "($1, $2), ($3, $4), ($5, $6)"
|
||||
function expand(rowCount: number, columnCount = 1, startAt = 1) {
|
||||
var index = startAt;
|
||||
return Array(rowCount)
|
||||
.fill(0)
|
||||
.map(
|
||||
(v) =>
|
||||
`(${Array(columnCount)
|
||||
.fill(0)
|
||||
.map((v) => `$${index++}`)
|
||||
.join(", ")})`
|
||||
)
|
||||
.join(", ");
|
||||
}
|
||||
|
||||
export const populateDB = async (db: Client) => {
|
||||
let filename = "words.txt";
|
||||
let filepath = path.join(projectRoot, filename);
|
||||
|
||||
// check for source file
|
||||
if (!fs.existsSync(filepath)) {
|
||||
logError(
|
||||
"Could not find `okiba/words.txt` for populating the database!\n"
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
await db
|
||||
.query(
|
||||
"CREATE TABLE words (id SERIAL PRIMARY KEY, val VARCHAR NOT NULL, taken BOOLEAN DEFAULT 'f');"
|
||||
)
|
||||
.catch((err) => err);
|
||||
|
||||
fs.readFile(
|
||||
filepath,
|
||||
{ encoding: "utf-8" },
|
||||
async (err: Error | null, data: string) => {
|
||||
if (err != null) {
|
||||
logError(err.message);
|
||||
throw err;
|
||||
}
|
||||
|
||||
let arr: Array<string> = data.split("\r\n");
|
||||
|
||||
// 1k entries per query
|
||||
const chunkSize = 1000;
|
||||
for (let i = 0; i < arr.length; i += chunkSize) {
|
||||
const chunk: Array<string> = arr.slice(i, i + chunkSize);
|
||||
|
||||
const queryStr = {
|
||||
text: `INSERT INTO words (val) VALUES ${expand(
|
||||
chunk.length
|
||||
)}`,
|
||||
values: chunk,
|
||||
};
|
||||
|
||||
await db.query(queryStr);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
logSuccess("Successfully populated the database!");
|
||||
};
|
11
src/main.ts
11
src/main.ts
@ -3,14 +3,15 @@ import dotenv from "dotenv";
|
||||
import BinRouter from "./routes/bin";
|
||||
import { Client, Pool } from "pg";
|
||||
import { createDataDir, errorHandler, logError, logSuccess } from "./utils";
|
||||
import { tableExists, populateDB } from "./db";
|
||||
|
||||
const main = async () => {
|
||||
dotenv.config();
|
||||
createDataDir();
|
||||
|
||||
// init db
|
||||
const pool = await new Pool();
|
||||
const client = await new Client();
|
||||
const pool = new Pool();
|
||||
const client = new Client();
|
||||
|
||||
client
|
||||
.connect()
|
||||
@ -22,6 +23,12 @@ const main = async () => {
|
||||
throw err;
|
||||
});
|
||||
|
||||
// check if `words` table exists
|
||||
// else populate db with `/okiba/words.txt`
|
||||
if (!(await tableExists(client))) {
|
||||
await populateDB(client);
|
||||
}
|
||||
|
||||
// start server
|
||||
const app: Express = express();
|
||||
const port = process.env.PORT;
|
||||
|
@ -18,7 +18,7 @@ export default function BinRouter(db: Pool) {
|
||||
const word: Word | undefined = await getAvailableWord(db);
|
||||
|
||||
if (word != undefined) {
|
||||
await fs.writeFile(
|
||||
fs.writeFile(
|
||||
path.join(projectRoot, "data", word.val + ".txt"),
|
||||
body,
|
||||
(err) => err
|
||||
|
@ -6,6 +6,7 @@ import fs from "fs";
|
||||
// logs
|
||||
export const logError = (msg: string) => console.error(chalk.bold.red(msg));
|
||||
export const logSuccess = (msg: string) => console.log(chalk.bold.green(msg));
|
||||
export const logWarning = (msg: string) => console.log(chalk.bold.yellow(msg));
|
||||
|
||||
export const projectRoot = path.join(__dirname, "..", "..");
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user