layout: "../layouts/BlogPost.astro" title: "Run MySQL locally and some Node.js operations" slug: run-mysql-locally-and-some-nodejs-operations description: "" added: "Aug 7 2024" tags: [code]
This is a text version of Tejas Kumar's video, "How to run MySQL locally and query it with Express".
# allowing MySQL to start without a root password
docker run -e MYSQL_ALLOW_EMPTY_PASSWORD=yes -p 3306:3306 mysql:latest
# docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
docker ps
# start an interactive bash shell session in the running Docker container
docker exec -it ba76bef03590 bash -l
[root@ba76bef03590 /]# mysql
mysql> SHOW DATABASES;
mysql> CREATE DATABASE todos;
mysql> USE todos;
mysql> CREATE TABLE todos (
id INT NOT NULL AUTO_INCREMENT,
label TEXT NOT NULL,
is_done BOOLEAN DEFAULT FALSE,
PRIMARY KEY (id)
);
mysql> SHOW TABLES;
mysql> INSERT INTO todos (label) VALUES ('Walk the dog');
mysql> INSERT INTO todos (label) VALUES ('Wash the car');
mysql> SELECT * FROM todos;
mkdir hello-prisma
cd hello-prisma
npm init -y
npm install prisma
npx prisma init
// Set the DATABASE_URL in the `.env` file to point to your existing database.
DATABASE_URL="mysql://root:@localhost:3306/todos"
// Set the provider of the datasource block in `prisma/schema.prisma` to match your database.
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
# Turn your database schema into a Prisma schema.
npx prisma db pull
# Generate Prisma Client. You can then start querying your database.
npx prisma generate
import express from "express";
import { PrismaClient } from "@prisma/client";
const app = express();
const client = new PrismaClient();
app.use(express.json());
app.get("/todos", async (req, res) => {
const todos = await client.todos.findMany();
res.json(todos);
});
app.get("/todos/:id", async (req, res) => {
const { id } = req.params;
const todo = await client.todos.findUnique({
where: { id: parseInt(id) },
});
if (todo) {
res.json(todo);
} else {
res.status(404).json({ error: "Todo not found" });
}
});
app.post("/todos", async (req, res) => {
const { label } = req.body;
const newTodo = await client.todos.create({
data: { label },
});
res.status(201).json(newTodo);
});
app.listen(3000, () => {
console.log("Server started on http://localhost:3000");
});
The node:fs
module enables interacting with the file system in a way modeled on standard POSIX functions. You can either use the callback APIs or use the promise-based APIs.
A file descriptor is a way of representing an open file in a computer operating system. It's like a special number that identifies the file, and the operating system uses it to keep track of what's happening to the file. You can use the file descriptor to read, write, move around in the file, and close it. In a runtime like Node.js, the
fs
module abstracts the direct use of file descriptors by providing a more user-friendly API, but it still relies on them behind the scenes to manage file operations.
const fs = require("node:fs/promises");
async function open_file() {
try {
const file_handle = await fs.open("test.js", "r", fs.constants.O_RDONLY);
console.log(file_handle.fd); // Print the value of the file descriptor `fd`
} catch (err) {
// i.e. ENOENT error stands for "Error NO ENTry" (File in path doesn't exist)
}
}
Using __dirname
and the path
module ensures that you are referencing the correct path regardless of the current working directory you’re in. __dirname
represents the absolute path of the directory containing the current JavaScript file. path.join()
method joins all given path segments together using the platform-specific separator as a delimiter, then normalizes the resulting path.
import fs from 'node:fs/promises';
import path from 'node:path';
try {
const filePath = path.join(__dirname, 'test.txt');
const stats = await fs.stat(filePath);
stats.isFile(); // true
stats.isDirectory(); // false
stats.isSymbolicLink(); // false
stats.size; // 1024000 //= 1MB
} catch (err) {
console.log(err);
}
import fs from 'node:fs';
fs.readFile('/Users/joe/test.txt', 'utf8', (err, data) => {
if (err) {
console.error(err);
return;
}
console.log(data);
});
import fs from 'node:fs/promises';
try {
const data = await fs.readFile('/Users/joe/test.txt', { encoding: 'utf8' });
console.log(data);
} catch (err) {
console.log(err);
}
const fs = require('node:fs/promises');
try {
const content = 'Some content!';
await fs.writeFile('/Users/joe/test.txt', content);
} catch (err) {
console.log(err);
}
const fs = require('node:fs/promises');
try {
const content = 'Some content!';
await fs.appendFile('/Users/joe/test.txt', content);
} catch (err) {
console.log(err);
}
console.log('Initial Memory Usage:', process.memoryUsage());
setInterval(() => {
const memoryUsage = process.memoryUsage();
console.log(`RSS: ${memoryUsage.rss}`);
}, 1000);
// Initial Memory Usage: {
// rss: 38502400,
// heapTotal: 4702208,
// heapUsed: 2559000,
// external: 1089863,
// arrayBuffers: 10515
// }