๋‚˜๋งŒ์˜ ์ฒดํฌํฌ์ธํŠธ

์„ค๊ณ„ํ•˜๊ธฐ

  • ์„ค๊ณ„ - ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค โœ… 2024-08-05

  • ์„ค๊ณ„ - create โœ… 2024-08-05

  • ์„ค๊ณ„ - insert โœ… 2024-08-05

  • ์„ค๊ณ„ - delete โœ… 2024-08-05

  • ์„ค๊ณ„ - update โœ… 2024-08-05

  • ์„ค๊ณ„ - select โœ… 2024-08-05

  • ์„ค๊ณ„ - drop โœ… 2024-08-05

๊ตฌํ˜„ํ•˜๊ธฐ

  • ๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค โœ… 2024-08-06

  • create โœ… 2024-08-06

  • insert โœ… 2024-08-06

  • delete โœ… 2024-08-06

  • update โœ… 2024-08-06

  • select โœ… 2024-08-06

  • drop โœ… 2024-08-06

๋ฌธ์ œ ํ•ด๊ฒฐ ๊ณผ์ •

์„ค๊ณ„ํ•˜๊ธฐ

ํ•ด๋‹น ํ•™์Šต๋ชฉํ‘œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ํ•™์Šต์„ ์œ„ํ•œ SQL ๋ฌธ๋ฒ•๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ํŒŒ์ผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ…Œ์ด๋ธ”์„ ๊ด€๋ฆฌํ•˜๊ณ  Record๋ฅผ ์ƒ์„ฑ, ์—…๋ฐ์ดํŠธ, ์‚ญ์ œํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ๋งŒ๋“œ๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ด๋‹ค.

์ด๋Ÿฌํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์š”์ฒญ์„ ๋ณด๋‚ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ์š”์ฒญ์„ http ์š”์ฒญ๊ณผ ์‘๋‹ต ํ˜•์‹์œผ๋กœ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ http ํ†ต์‹ ์— ๋Œ€ํ•œ ์ดํ•ด๋„ ๋˜ํ•œ ํ•จ์–‘์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๋งจ ์ฒ˜์Œ ์„ค๊ณ„์—์„œ ๊ตฌํ˜„ํ•  ๋•Œ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ถ€๋ถ„์€ ์ฝ์–ด๋“ค์ด๋Š” CSV ํŒŒ์ผ์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ๊ด€๋ฆฌํ•  ๊ฒƒ์ด๋ƒ๋ฅผ ๊ณ ๋ฏผํ–ˆ๋‹ค.


singer,year,song

-----------

honux,2016,Gameover

jk,2020,I like steak

crong,2023,Milk song

ivy,2021,Butter

  

๋ฌธ์ œ์˜ ์˜ˆ์‹œ์—์„œ๋Š” CSV ํŒŒ์ผ์„ ์ฃผ์—ˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ ๋ ˆ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œ ๋“ฑ ๋‹ค์–‘ํ•œ ๋ช…๋ น์–ด๋“ค์— ๋Œ€ํ•ด์„œ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” CSV ํŒŒ์ผ์„ ์ฝ์–ด๋“ค์ธ ๋’ค์— ์ ์ ˆํ•œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ณ€ํ™˜ํ•ด์ค€ ๋‹ค์Œ์— ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ๋ณด๋‹ค ํ•ฉ๋ฆฌ์ ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

๋‚˜์˜ ๊ฒฝ์šฐ๋Š” Tableํด๋ž˜์Šค์— ๊ฐ Column(Attribute)๊ณผ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋ฐฐ์—ด๋กœ ๋”ฐ๋กœ ์ €์žฅํ•ด๋‘๋Š” ๊ฒƒ์„ ์ƒ๊ฐํ–ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฐ์ฒด๋กœ ๋”ฐ๋กœ ๋งŒ๋“ค์ง€ ์•Š์€ ์ด์œ ๋Š” ๋‚˜์ค‘์— ๊ณ„์†ํ•ด์„œ ์ •๋ณด๋ฅผ ๊ฐฑ์‹ ํ•˜๋Š” ๊ณผ์ •์—์„œ insertํ•  ๋•Œ ์ˆœ์„œ๋ฅผ ๊ฐ€์ง€๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ํ•˜๋‚˜ ๋” ๋‘ ์œผ๋กœ์จ ๊ฐ attribute๊ฐ€ ์–ด๋– ํ•œ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ง€๋Š”์ง€ ๋‚˜ํƒ€๋‚ด๋ ค๊ณ  ํ•œ๋‹ค.


classDiagram

class Table{

+attr_count

+attributes: array

+records: record[]

#parsing()

#saveToFile()

}

๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค

๊ธฐ๋ณธ ์ธํ„ฐํŽ˜์ด์Šค๋Š” ์ €๋ฒˆ mit ๋ฏธ์…˜์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ commander ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๋‚ด ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  ์‹คํ–‰์‹œํ‚ค๋ฉด ์ด์— ํ•ด๋‹นํ•˜๋Š” ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ฃผ๊ณ , ๊ฐ ๋ช…๋ น์–ด๋ฅผ ๋”ฐ๋กœ ํŒŒ์‹ฑํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ ๋‹ค์Œ์— ํ•ด๋‹น ์ฟผ๋ฆฌ์˜ ๋ช…๋ น์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ•จ์ˆ˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ œ๊ณตํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

Create

Create ์š”์ฒญ์˜ ๊ฒฝ์šฐ ํ…Œ์ด๋ธ”์„ ์ƒ์„ฑํ•˜๋Š” ์š”์ฒญ์œผ๋กœ ๋‚ด๊ฐ€ ์„ค์ •ํ•˜๋ ค๋Š” ํ…Œ์ด๋ธ”์˜ Attribute(Column)์„ ์„ค์ •ํ•œ๋‹ค.


CREATE table_name BTTP

Column: column1=datatype

Column: column2=datatype

Column: column3=datatype

create ์š”์ฒญ์˜ ๊ฒฝ์šฐ ์ƒˆ๋กญ๊ฒŒ csv ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋ฉฐ,

  1. ํ˜•์‹ ๊ฒ€์‚ฌ

  2. datatype ์ถ”์ถœํ•ด์„œ ๊ฐ์ฒด ๋งŒ๋“ค๊ธฐ

  3. ๊ฐ์ฒด ํŒŒ์ผ๋กœ ์ €์žฅ

์˜ ๊ณผ์ •์„ ๊ฑฐ์ณ attribute๋“ค๋งŒ ์žˆ๋Š” CSV ํŒŒ์ผ์„ ์ €์žฅํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ์ œ์•ฝ์‚ฌํ•ญ์œผ๋กœ 9๊ฐœ๊นŒ์ง€๋งŒ ์ง€์›ํ•˜๋„๋ก ํ•˜๋Š” ์กฐ๊ฑด๊ณผ

์—ฌ๊ธฐ์„œ ์ถ”๊ฐ€์ ์œผ๋กœ datatype์„ ๊ฒ€์‚ฌํ•ด์„œ Numeric, String๋งŒ์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์•ผ ํ•˜๊ณ , attribute์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐํƒ€์ž…์„ ๊ฒ€์‚ฌํ•ด์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ฐ attribute ๋˜ํ•œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด key:value ํ˜•ํƒœ๋กœ ๋ฐ์ดํ„ฐํƒ€์ž…์„ ๋„ฃ์–ด ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

Insert

Insert ์š”์ฒญ์€ ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.


INSERT table_name BTTP

Column: column1

Column: column2

Value: value1

Value: value2

๋ ˆ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด์„œ column๊ฐœ์ˆ˜๋ฅผ ๊ฒ€์‚ฌํ•˜์—ฌ ๊ธฐ์กด์˜ column ๊ฐœ์ˆ˜์™€ ๊ฐ™์ง€ ์•Š์œผ๋ฉด ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•œ๋‹ค.

๊ฐœ์ˆ˜๊ฐ€ ๊ฐ™๋‹ค๋ฉด column์˜ ์ˆœ์„œ๋Œ€๋กœ value๋ฅผ ๋„ฃ์–ด์ฃผ๋ฉด ๋  ๊ฒƒ ๊ฐ™๋‹ค.

Delete

delete๋Š” ํ…Œ์ด๋ธ”์˜ ๋ ˆ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์œผ๋กœ, condition์— ๋งž๋Š” ๊ฒƒ๋“ค์„ ๋ชจ๋‘ ์‚ญ์ œํ•œ๋‹ค. ์ด ๋•Œ condition์— ํ•˜๋‚˜๋งŒ ํฌํ•จํ•˜๋ฉด ๋˜๋ฏ€๋กœ attribute์™€ ์กฐ๊ฑด, ๋…ผ๋ฆฌ์—ฐ์‚ฐ์ž๋ฅผ ์ถ”์ถœํ•ด๋‚ด์–ด ๊ฒ€์‚ฌํ•œ๋‹ค.

Update

๋ ˆ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฉ”์„œ๋“œ๋กœ ์กฐ๊ฑด์— ๋งž๋Š” ๋ ˆ์ฝ”๋“œ์˜ ํŠน์ • ์ปฌ๋Ÿผ ๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฉด ๋˜๋ฏ€๋กœ ์ด ๋˜ํ•œ attribute์™€ ์กฐ๊ฑด, ๋…ผ๋ฆฌ์—ฐ์‚ฐ์ž๋ฅผ ์ถ”์ถœํ•ด๋‚ด์–ด ์ฒ˜๋ฆฌํ•˜๋ฉด ๋œ๋‹ค.

Select

ํ…Œ์ด๋ธ”์— ๋ ˆ์ฝ”๋“œ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋Š” ํ˜•์‹์œผ๋กœ, ์กฐ๊ฑด์— ๋งž๋Š” ์ปฌ๋Ÿผ๋งŒ ์ถœ๋ ฅํ•˜๋ฉด ๋œ๋‹ค.

Drop

ํ…Œ์ด๋ธ” ์ด๋ฆ„๊ณผ ๋™์ผํ•œ CSVํŒŒ์ผ์„ ํ†ต์ฑ„๋กœ ์‚ญ์ œํ•˜๋ฉด ๋œ๋‹ค.

๊ตฌํ˜„ํ•˜๊ธฐ

์ธํ„ฐํŽ˜์ด์Šค

 
#!/usr/bin/env node
 
const { program } = require("commander");
 
const { commandInterface } = require("./interface");
 
  
 
program.version("0.0.1", "-v, --version").name("commander");
 
  
 
program.command("run").action(() => {
 
commandInterface();
 
});
 
  
 
program.parse(process.argv);
 

์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ฒฝ์šฐ ์‹œ์ž‘ ์ ์—์„œ mhcsv run์„ ํ„ฐ๋ฏธ๋„์— ์ž…๋ ฅํ•˜๋ฉด ๋ช…๋ น์–ด ์ฐฝ์ด ๋‚˜์˜จ๋‹ค. ์ดํ›„์— ๋ช…๋ น์–ด๋“ค์„ ๊ณ„์†ํ•ด์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์–ด์ง€๋Š” ์ž…๋ ฅ์€ commandInterface๋ฅผ ํ†ตํ•ด ์‹คํ–‰๋˜๊ณ  ์ฒ˜๋ฆฌํ•œ๋‹ค.

 
const readline = require("readline");
 
const { parsingCommand } = require("./parsing");
 
const { handleCommand } = require("./handlecommand");
 
  
 
const rl = readline.createInterface({
 
input: process.stdin,
 
output: process.stdout,
 
});
 
const commandInterface = (command) => {
 
console.log("์‹คํ–‰ํ•  ์š”์ฒญ ํŒŒ์ผ์„ ์ž…๋ ฅํ•˜์„ธ์š”\n");
 
rl.on("line", (line) => {
 
if (!line || line === "q") rl.close();
 
try {
 
const { command, file } = parsingCommand(line);
 
console.log(">>>>>>>>>>>>\n");
 
handleCommand(file);
 
} catch (error) {
 
console.log("<<<<<<<<<<<");
 
console.log(error.message);
 
}
 
});
 
};
 
  
 
module.exports = { commandInterface };
 

๋‚˜๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๋ช…๋ น์–ด ์ฐฝ์„ ๊ณ„์† ์ผœ๋†“๊ณ  ํ•ด๋‹น ๋ช…๋ น์–ด๋ฅผ ๊ทธ๋•Œ๋งˆ๋‹ค ํŒŒ์‹ฑํ•˜์—ฌ ์•Œ๋งž์€ ์ปค๋งจ๋“œ์— ๋Œ€ํ•œ ์‹คํ–‰์„ handleCommand๊ฐ€ ๋‹ด๋‹นํ•œ๋‹ค.

 
const { readFileSync } = require("fs");
 
const { create } = require("./create");
 
const { insert } = require("./insert");
 
const { deleteRecord } = require("./delete");
 
const { update } = require("./update");
 
const { drop } = require("./drop");
 
  
 
function handleCommand(fileName) {
 
const command = readFileSync(`./${fileName}`)
 
.toString()
 
.split("\n")[0]
 
.split(" ")[0];
 
switch (command) {
 
case "CREATE":
 
create(fileName);
 
break;
 
case "INSERT":
 
insert(fileName);
 
break;
 
case "DELETE":
 
deleteRecord(fileName);
 
break;
 
case "UPDATE":
 
update(fileName);
 
break;
 
case "SELECT":
 
break;
 
case "DROP":
 
drop(fileName);
 
break;
 
default:
 
throw new Error("400 Bad Request");
 
}
 
}
 
  
 
module.exports = { handleCommand };
 

์ด์ฒ˜๋Ÿผ switch/case๋ฌธ์„ ํ†ตํ•ด ๊ฐ ๋ช…๋ น์–ด์— ๋Œ€ํ•ด์„œ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌํ˜„ํ–ˆ๋‹ค.

ํ…Œ์ด๋ธ” ํด๋ž˜์Šค

 
const { readFileSync, existsSync, writeFileSync } = require("fs");
 
const { getTableName } = require("./create");
 
  
 
class Table {
 
constructor(tableName, types, attributes, records) {
 
this.tableName = tableName;
 
this.types = types;
 
this.attributes = attributes;
 
this.attributesLen = this.attributes.length;
 
this.records = records;
 
this.currIdx = this.records.length + 1;
 
this.index = this.#getIndex();
 
}
 
static getFile(fileName) {
 
console.log(readFileSync(`./${fileName}`).toString());
 
const fileData = readFileSync(`./${fileName}`).toString().split("\n");
 
const tableName = getTableName(fileData[0]);
 
if (!existsSync(`./${tableName}.csv`) || !existsSync(`./${tableName}.json`))
 
throw new Error("404 CSV file Not Found");
 
const data = readFileSync(`./${tableName}.csv`).toString().split("\n");
 
const metaData = JSON.parse(readFileSync(`./${tableName}.json`).toString());
 
let attributes = [];
 
if (data.length > 1) {
 
attributes = data.slice(1, data.length - 1).map((attr) => {
 
let attrArr = attr.split(",");
 
attrArr = attrArr.map((attr) => {
 
if (!attr.includes('"')) return parseInt(attr);
 
return attr;
 
});
 
return attrArr;
 
});
 
}
 
console.log("<<<<<<<<<<");
 
return new Table(tableName, metaData.types, data[0].split(","), attributes);
 
}
 
  
 
#getIndex() {
 
let index = {};
 
this.attributes.forEach((attr, idx) => {
 
index[attr] = idx;
 
});
 
return index;
 
}
 
  
 
saveToFile() {
 
let fileData = this.attributes.join(",") + "\n";
 
this.records.forEach((record) => {
 
fileData += record.join(",") + "\n";
 
});
 
writeFileSync(`./${this.tableName}.csv`, fileData);
 
console.log("200 OK");
 
console.log("Content-Type: Text/JSON");
 
console.log(`Content-Length: ${fileData.length}`);
 
}
 
  
 
insert(values) {
 
if (values.length !== this.attributesLen - 1)
 
throw new Error("400 values have different length");
 
const types = Object.values(this.types);
 
const newRecord = { id: this.currIdx };
 
values.forEach((val, index) => {
 
if (types[index + 1] !== typeof val) {
 
throw new Error("400 type not matched");
 
}
 
newRecord[this.attributes[index + 1]] = val;
 
});
 
this.records.push([this.currIdx, ...values]);
 
this.currIdx++;
 
console.log(newRecord);
 
this.saveToFile();
 
}
 
delete(targetIndex, targetVal) {
 
this.records = this.records.filter((record) => {
 
record[targetIndex] !== targetVal;
 
});
 
this.saveToFile();
 
}
 
update(col, val, con_col, con_val) {
 
if (!this.index.hasOwnProperty(col))
 
throw new Error("404 column not Found");
 
if (!this.index.hasOwnProperty(con_col))
 
throw new Error("404 condition column not Found");
 
  
 
const targetCol = this.index[con_col];
 
const updateCol = this.index[col];
 
  
 
this.records.forEach((record, idx) => {
 
if (record[targetCol] == con_val) {
 
record[updateCol] = val;
 
}
 
});
 
this.saveToFile();
 
}
 
}
 
  
 
module.exports = { Table };
 

๊ธฐ์กด์— ์„ค๊ณ„ํ•˜๋˜ ํ”„๋กœํผํ‹ฐ๋“ค๊ณผ ๋ฉ”์„œ๋“œ๊ฐ„์—๋Š” ์ฐจ์ด๊ฐ€ ๋‹ค์†Œ ์žˆ๋‹ค.

\๊ณ„์†ํ•ด์„œ ์“ฐ์ด๋Š” ํŒŒ์ผ์„ ์ฝ์–ด ์ฒ˜๋ฆฌํ•˜๋Š” ๊ธฐ๋Šฅ์„ ์ •์  ๋ฉ”์„œ๋“œ๋กœ ๊ตฌํ˜„ํ•˜์—ฌ ์ƒˆ๋กœ์šด Table ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•จ์œผ๋กœ์จ ํ•ด๋‹น ํ…Œ์ด๋ธ”์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๋‘์—ˆ๋‹ค. ๊ฐ ๋ช…๋ น์–ด์˜ ๋ฉ”์„œ๋“œ๋Š” ๊ทธ์— ๋”ฐ๋ฅธ ํ•จ์ˆ˜๊ฐ€ ์žˆ์ง€๋งŒ, ์ตœ์ข…์ ์œผ๋กœ๋Š” ๋Œ€๋ถ€๋ถ„ ์ด ๋ฉ”์„œ๋“œ๋“ค์„ ํ†ตํ•ด์„œ ์ •๋ณด๊ฐ€ ๊ฐฑ์‹ ๋œ๋‹ค.

ํ”„๋กœํผํ‹ฐ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์™€ ๊ทธ ๊ธธ์ด, ๋ ˆ์ฝ”๋“œ์™€ ํ˜„์žฌ์˜ ๋ id๊ฐ’, index๋Š” ๊ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋งˆ๋‹ค ๊ฐ€์ง€๋Š” ์ธ๋ฑ์Šค๋ฅผ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ๊ธฐ๋กํ•ด๋†“์•˜๋‹ค.

ํƒ€์ž…๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๋”ฐ๋กœ ๋งŒ๋“  json ํŒŒ์ผ์„ ๊ฐ€์ง€๊ณ  ํ•ด๋‹น ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ํƒ€์ž… ํ”„๋กœํผํ‹ฐ์— ๋„ฃ์–ด์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.

Create

 
const { writeFileSync, existsSync, readFileSync, mkdir } = require("fs");
 
  
 
function create(fileName) {
 
let attributes = [`id`];
 
let metaData = { fileName: fileName, types: { id: "number" } };
 
let tableName;
 
const data = readFileSync(`./${fileName}`).toString();
 
  
 
data.split("\n").forEach((attr, idx) => {
 
console.log(attr);
 
if (idx === 0) tableName = getTableName(attr);
 
else {
 
if (!attr) return;
 
const { attribute, type } = getColumn(attr);
 
attributes.push(`${attribute}`);
 
if (type === "Numeric") metaData.types[attribute] = "number";
 
else metaData.types[attribute] = "string";
 
}
 
});
 
  
 
if (existsSync(`./${tableName}.csv`))
 
throw new Error("409 File Already Exists");
 
writeFileSync(`./${tableName}.csv`, attributes.join(",") + "\n");
 
writeFileSync(`./${tableName}.json`, JSON.stringify(metaData));
 
console.log("\n<<<<<<<<<<<");
 
console.log("201 Created");
 
}
 
  
 
const getTableName = (line) => {
 
const [_, tableName, bttp] = line.split(" ");
 
if (bttp !== "BTTP") throw new Error("400 Invalid Bttp request");
 
return tableName;
 
};
 
  
 
const getColumn = (line) => {
 
const regex = /^Column:\s(\w+)\=(String|Numeric)/;
 
if (!regex.test(line)) throw new Error("400 Invalid Column Syntax");
 
const attribute = line.match(regex)[1];
 
const type = line.match(regex)[2];
 
return { attribute, type };
 
};
 
  
 
module.exports = { create, getTableName };
 

create๋Š” ์ฒ˜์Œ bttp ํŒŒ์ผ์— ๋Œ€ํ•ด์„œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค˜์•ผ ํ•˜๋ฏ€๋กœ ๋‹ค์†Œ ๊ธด ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค.

์ฃผ์š” ๋กœ์ง์€

  1. ํŒŒ์ผ์„ ์ฝ์–ด ์ค„๋งˆ๋‹ค ์ฒ˜๋ฆฌ + ์œ ํšจ์„ฑ ๊ฒ€์ฆ

  2. numericํƒ€์ž…์ด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ typeof๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์œ ์šฉํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ number๋กœ ์น˜ํ™˜

  3. ์ƒˆ๋กœ์šด JSON ํŒŒ์ผ์— ํƒ€์ž… ์ •๋ณด๋ฅผ ๋ณด๊ด€ ๋ฐ ์ €์žฅ

์˜ ๋กœ์ง์„ ๊ฐ€์ง„๋‹ค.

์ž‘๋™๊ฒฐ๊ณผ

์•ผํ˜ธ~

insert

 
const { readFileSync, existsSync } = require("fs");
 
const { getTableName } = require("./create");
 
const { Table } = require("./table");
 
  
 
function insert(fileName) {
 
const insertData = readFileSync(`./${fileName}`)
 
.toString()
 
.split("\n")
 
.slice(1);
 
const table = Table.getFile(fileName);
 
const { attrs, values } = getAttrAndVal(insertData);
 
table.insert(values);
 
}
 
  
 
const getAttrAndVal = (insertData) => {
 
const attrs = [];
 
const values = [];
 
insertData.forEach((data) => {
 
let [colOrVal, val] = data.split(" ");
 
if (colOrVal === "Column:") {
 
if (!val.includes('"')) val = parseInt(val);
 
attrs.push(val);
 
} else if (colOrVal === "Value:") {
 
if (!val.includes('"')) val = parseInt(val);
 
values.push(val);
 
} else {
 
throw new Error("400 Bad Request");
 
}
 
});
 
if (attrs.length !== values.length)
 
throw new Error("400 Column not matched to Value");
 
return { attrs, values };
 
};
 
  
 
module.exports = { insert };
 

insert๋Š” ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์ด ๊นŒ๋‹ค๋กœ์› ๋‹ค. ์ฒ˜์Œ์—๋Š” ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ๊ฐ’๋“ค์ด ๋ฌด์ž‘์œ„๋กœ ์ฃผ์–ด์ ธ์„œ ํ•ด๋‹น ์ธ๋ฑ์Šค๊ฐ’์„ ๊ณ„์† ๋Œ€์กฐํ•˜์—ฌ ์•Œ๋งž์€ ํ˜•ํƒœ๋กœ ๋ ˆ์ฝ”๋“œ๋ฅผ ๋งŒ๋“ค์–ด ๋„ฃ์–ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ? ์ƒ๊ฐํ–ˆ๋Š”๋ฐ ์ฐพ์•„๋ดค๋”๋‹ˆ sql ์ฟผ๋ฆฌ๋ฌธ์—์„œ๋Š” ๋”ฐ๋กœ ์ˆœ์„œ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

 
INSERT INTO Temp_Table(field1, field2, field4, field3, field5, field6, field7, field8, field9, field10)
 
VALUES('data4','data4-2','data4-4','data4-3','data4-5','data4-6','data4-7','data4-8','data4-9','data4-10');
 

๋”ฐ๋ผ์„œ ๋‚˜๋Š” ๊ทธ๋ƒฅ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ ์ˆœ์„œ๋Œ€๋กœ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋“ค์–ด์˜ฌ ๊ฒƒ์ด๊ณ , ๋‚˜๋Š” ๊ทธ๋ƒฅ ํƒ€์ž… ์ฒดํฌ๋งŒ ํ•˜๋ฉด ๋˜๊ฒ ๋‹ค ์ƒ๊ฐํ•˜๊ณ  ๊ตฌํ˜„ํ–ˆ๋‹ค.

์‹คํ–‰๊ฒฐ๊ณผ

update

 
const { readFileSync } = require("fs");
 
const { Table } = require("./table");
 
  
 
function update(fileName) {
 
const table = Table.getFile(fileName);
 
const updateData = readFileSync(`./${fileName}`)
 
.toString()
 
.split("\n")
 
.slice(1);
 
const [col, colData] = updateData[0].split(" ");
 
const [val, valData] = updateData[1].split(" ");
 
let [con, conData] = updateData[2].split(" ");
 
if (col !== "Column:" || val !== "Value:" || con !== "Condition:")
 
throw new Error("400 Bad Request(command)");
 
const [conData_col, conData_val] = conData.split("=");
 
  
 
table.update(colData, valData, conData_col, conData_val);
 
}
 
  
 
module.exports = { update };
 

update๋Š” ์กฐ๊ฑด์— ํ•ด๋‹นํ•˜๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์ฐพ์•„์„œ ์„ค์ •ํ•œ column๊ฐ’์˜ ์ธ๋ฑ์Šค์— ์ง€์ •ํ•œ value๊ฐ’์„ ๋„ฃ์–ด์ฃผ๋„๋ก ํ–ˆ๋‹ค.

์กฐ๊ฑด์ด ๊นŒ๋‹ค๋กญ์ง€๋Š” ์•Š์ง€๋งŒ ๊ฐ์ข… ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์˜ ํŒŒ์‹ฑ์ด ๋งŽ๋‹ค๋ณด๋‹ˆ ๋ณต์žกํ•ด์ง„ ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค.

์‹คํ–‰๊ฒฐ๊ณผ

Delete

 
const { readFileSync } = require("fs");
 
const { Table } = require("./table");
 
  
 
function deleteRecord(filename) {
 
const file = Table.getFile(filename);
 
if (!file.records.length) throw new Error("404 record not exist");
 
const [text, condition] = readFileSync(`./${filename}`)
 
.toString()
 
.split("\n")[1]
 
.split(" ");
 
if (text !== "Condition:") throw new Error("400 Bad Request");
 
const [col, con] = condition.split("=");
 
if (!col || !con) throw new Error("400 Bad Request(Condition)");
 
console.log(col, con);
 
const targetIndex = file.index[col];
 
file.delete(targetIndex, con);
 
}
 
  
 
module.exports = { deleteRecord };
 
...
 
//ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ
 
delete(targetIndex, targetVal) {
 
this.records = this.records.filter((record) => {
 
record[targetIndex] !== targetVal;
 
});
 
this.saveToFile();
 
}
 
  
 

Delete์˜ ๊ฒฝ์šฐ์—๋Š” ์กฐ๊ฑด์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ๋ฐฉ์‹์ด update์™€ ๋น„์Šทํ•˜๊ฒŒ ์ž‘๋™ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ผ๋ถ€๋ถ„์„ ์žฌํ™œ์šฉํ–ˆ๋‹ค.

ํŠน์ดํ•œ ์ (?)์œผ๋กœ๋Š” ๊ธฐ์กด์˜ ๋ ˆ์ฝ”๋“œ ๋ฐฐ์—ด๋“ค์„ ๊ณ ์ฐจํ•จ์ˆ˜ filter๋ฅผ ํ†ตํ•ด ๊ฑธ๋Ÿฌ์ฃผ์–ด ์ฝ”๋“œ๊ฐ€ ๋ณด๋‹ค ๊นจ๋—ํ•ด์กŒ๋‹ค.

์‹คํ–‰ ๊ฒฐ๊ณผ

SELECT

ํ•ด์ปคํ†ค๋•œ์— ์ค€๋น„ํ•˜๋А๋ผ ์‹œ๊ฐ„๋ถ€์กฑ์ด์Šˆ๋กœ ๋‚ด์ผ ์‹œ๊ฐ„์ด ๋œ๋‹ค๋ฉด ๊ตฌํ˜„ํ• ๋“ฏ ์‹ถ๋‹ค..

๊ฐ€๋„ ๋นŒ๋“œํ•˜๋ฉด์„œ ๊ธฐ๋‹ค๋ฆฌ๋ฉด์„œ ์กฐ๊ธˆ์”ฉ ํ–ˆ๋‹ค.

์ž๊ณ ์‹ถ๋‹ค..

 
const { readFileSync } = require("fs");
 
const { Table } = require("./table");
 
  
 
function select(fileName) {
 
const table = Table.getFile(fileName);
 
const [con, condition] = readFileSync(`./${fileName}`)
 
.toString()
 
.split("\n")[1]
 
.split(" ");
 
if (con !== "Condition:") throw new Error("400 Bad Request(condition)");
 
console.log(condition);
 
const regex = /(\w+)([=><])([\w"]+)/;
 
const matched = condition.match(regex);
 
const col = matched[1];
 
const logic = matched[2];
 
const val = matched[3];
 
table.select_equal(col, val);
 
}
 
  
 
module.exports = { select };
 
  
 
...
 
//ํ…Œ์ด๋ธ” ํด๋ž˜์Šค ๋ฉ”์„œ๋“œ
 
select_equal(col, val) {
 
const idx = this.index[col];
 
const result = [];
 
this.records.forEach((record) => {
 
if (record[idx] === val) {
 
result.push(record);
 
}
 
});
 
this.recordToObject(result);
 
}
 
recordToObject(arr) {
 
const result = [];
 
arr.forEach((record) => {
 
let converted = {};
 
record.forEach((attr, idx) => {
 
converted[this.attributes[idx]] = attr;
 
});
 
result.push(converted);
 
});
 
console.log(result);
 
}
 

Select์˜ ๊ฒฝ์šฐ ํ˜„์žฌ๋Š” equal = ๋งŒ ๋”ฐ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๋กœ์ง์„ ๋งŒ๋“ค์–ด๋†จ๋‹ค.

์ƒ๊ฐํ•ด๋ณด๋‹ˆ ์ผ์น˜์™€ ๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ์–ด์ฐจํ”ผ index๊ฐ’์„ ํ†ตํ•ด ๊ฐ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์— ๋Œ€ํ•œ ๊ฐ’์„ ์ž˜ ๋ฝ‘์•„๋‚ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋งจ ์ฒ˜์Œ์— ์ •๊ทœํ‘œํ˜„์‹์„ ํ†ตํ•ด ๊ทธ๋ฃน์บก์ฒ˜๋ฅผ ํ•ด์„œ ํ•„์š”ํ•œ ์กฐ๊ฑด(์–ดํŠธ๋ฆฌ๋ทฐํŠธ, ๊ฐ’, ๋…ผ๋ฆฌ์—ฐ์‚ฐ์ž)๋ฅผ ๋ฝ‘์•„๋‚ด๊ณ  ๊ฐ๊ฐ ๋…ผ๋ฆฌ์—ฐ์‚ฐ์ž์— ๋”ฐ๋ผ ๋กœ์ง์„ switch/case๋ฌธ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•  ์˜ˆ์ •์ด๋‹ค.

ํ˜„์žฌ ๋“ฑํ˜ธ๋งŒ ํ•ด๋†จ๋Š”๋ฐ, ๋“ฑํ˜ธ์˜ ๊ฒฝ์šฐ์—๋Š” ๋ ˆ์ฝ”๋“œ๋ฅผ ์ „๋ถ€ ๋Œ๋ฉด์„œ ํ•ด๋‹น ๊ฐ’๊ณผ ๊ฐ™์€ ๋ ˆ์ฝ”๋“œ๋“ค๋งŒ ์ฐพ์•„๋‚ด์„œ ๋ฝ‘์•„๋‚ด๋ฉด ๋œ๋‹ค.

์‹คํ–‰๊ฒฐ๊ณผ

DROP

 
const { existsSync, readFileSync, unlinkSync } = require("fs");
 
const { Table } = require("./table");
 
  
 
function drop(fileName) {
 
if (!existsSync(`./${fileName}`)) throw new Error("404 file not found");
 
const table = Table.getFile(fileName);
 
const length = readFileSync(`./${fileName}`).toString().length;
 
if (!existsSync(`./${fileName}`)) throw new Error(`404 file not found(csv)`);
 
unlinkSync(`./${table.tableName}.csv`);
 
unlinkSync(`./${table.tableName}.json`);
 
console.log("<<<<<<<<<<<");
 
console.log("200 OK");
 
console.log(`Row-Count: ${length}`);
 
}
 
  
 
module.exports = { drop };
 

DROP์€ unlinksync๋ฅผ ์‚ฌ์šฉํ•ด์ฃผ๊ธฐ๋งŒ ํ•˜๋ฉด ๋์œผ๋ฏ€๋กœ ์ผ๋‹จ์€ ์ฒ˜์Œ์— ํ…Œ์ด๋ธ” ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜ค๋Š” ์ •์  ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ํ…Œ์ด๋ธ” ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„์˜จ ๋’ค, ํ•ด๋‹น ํŒŒ์ผ ์ด๋ฆ„์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ€์ ธ์™€ ์ด๋ฅผ ์ง€์›Œ์ฃผ๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ–ˆ๋‹ค.

์‹คํ–‰๊ฒฐ๊ณผ

ํ•™์Šต

SQL

https://medium.com/@queenskisivuli/how-sql-writes-data-insert-create-and-delete-3b5536d9370b

https://rachel0115.tistory.com/entry/SQL-%EA%B8%B0%EB%B3%B8-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-SELECT-%EC%A0%88

https://inpa.tistory.com/entry/MYSQL-%F0%9F%93%9A-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98Transaction-%EC%9D%B4%EB%9E%80-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค

https://velog.io/@hsshin0602/CS-%EC%A7%80%EC%8B%9D-%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%8B%9C%EC%8A%A4%ED%85%9C-VS-%ED%8C%8C%EC%9D%BC-%EC%B2%98%EB%A6%AC-%EC%8B%9C%EC%8A%A4%ED%85%9C

https://hongong.hanbit.co.kr/%EB%8D%B0%EC%9D%B4%ED%84%B0%EB%B2%A0%EC%9D%B4%EC%8A%A4-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0-databasedb-dbms-sql%EC%9D%98-%EA%B0%9C%EB%85%90/

ํŠธ๋žœ์žญ์…˜

https://mommoo.tistory.com/62

๊ฐœ์„ ํ•˜๊ธฐ

  • ํ•จ์ˆ˜๋ถ„๋ฆฌ ์ด๋ฒˆ ๋ฆฌํŒฉํ† ๋ง์—์„œ๋Š” ์—ฌ๋Ÿฌ ๋ฉ”์„œ๋“œ์˜ ์ฒ˜๋ฆฌ๋ฅผ ๋‹ด๋‹นํ•˜๋Š” switch๋ฌธ ์•ˆ์˜ ํ•จ์ˆ˜๋“ค์„ ๋Œ€๋ถ€๋ถ„ ๊ธธ์ด๋ฅผ ์ตœ๋Œ€ํ•œ ์ค„์ด๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์˜€๋‹ค. ํ”ผ์–ด์™€ ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์„ ํ•˜๋‚˜์”ฉ ๋ณด๋ฉด์„œ ์ข€๋” ์ง‘์ค‘ํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ๊ฐ„๋žตํ•˜๊ฒŒ ์ค„์ด๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ ๋งŽ์ด ๊ณ ์•ˆํ–ˆ๋‹ค.
function create(fileName) {
  const data = readFileSync(`./${fileName}`).toString();
  const { attributes, metaData, tableName } = parsingCreate(data, fileName);
 
  if (existsSync(`./${tableName}.csv`))
    throw new Error("409 File Already Exists");
  writeFileSync(`./${tableName}.csv`, attributes.join(",") + "\n");
  writeFileSync(`./${tableName}.json`, JSON.stringify(metaData));
  console.log("\n<<<<<<<<<<<");
  console.log(STATUS_CODE[201]);
}
...
const parsingCreate = (data) => {
  let attributes = [`id`];
  let metaData = { fileName: "", types: { id: "number" } };
  let tableName;
  data.split("\n").forEach((attr, idx) => {
    console.log(attr);
    if (idx === 0) {
      tableName = Table.getTableName(attr);
      metaData.fileName = tableName;
    } else {
      if (!attr) return;
      const { attribute, type } = getColumn(attr);
      attributes.push(attribute);
      if (type === "Numeric") metaData.types[attribute] = "number";
      else metaData.types[attribute] = "string";
    }
  });
  return { tableName, attributes, metaData };
};

๋Œ€ํ‘œ์ ์ธ create ๋ฉ”์„œ๋“œ์˜ ๊ฒฝ์šฐ, ์ด์ „๊นŒ์ง€๋Š” parsingCreate์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋”ฐ๋กœ ๋‘์ง€ ์•Š๊ณ  ์ด๋Ÿฌํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ์–ดํŠธ๋ฆฌ๋ทฐํŠธ, ํ…Œ์ด๋ธ” ์ด๋ฆ„ ๋“ฑ์„ ์ถ”์ถœํ•ด ๋‚ด๋Š”๋ฐ ํ•ด๋‹น ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋‹ค๋ณด๋‹ˆ ํ•จ์ˆ˜์˜ ๊ฐ€๋…์„ฑ ์ž์ฒด๊ฐ€ ๋งค์šฐ ๋–จ์–ด์กŒ๋‹ค. ๊ทธ๋Ÿฌ๋‹ค๋ณด๋‹ˆ ์ด๋Ÿฌํ•œ ๋ถ€๋ถ„์„ ๊ฐœ์„ ํ•ด์•ผ ํ•  ํ•„์š”์„ฑ์„ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ๊ตฌํ˜„ํ•˜๋Š” ๊ณผ์ •์—์„œ ๋А๋ผ๊ฒŒ ๋˜์—ˆ๊ณ , ์ด๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ์—์„œ ๊ณ ์ณ์•ผ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. ์‚ฌ์‹ค ์กฐ๊ธˆ ๋” ์ข‹์€ ๋ฐฉ์‹์€ ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์™€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ, ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ๋‹ค ํ•จ์ˆ˜๋กœ ๋ถ„๋ฆฌํ•œ๋‹ค๋ฉด ๋ณด๋‹ค ํ•ด๋‹น ํ•จ์ˆ˜์˜ ๊ธธ์ด๊ฐ€ ์งง์•„์งˆ ์ˆ˜๋Š” ์žˆ๊ฒ ์ง€๋งŒ, ์‚ฌ์‹คํ•œ ํ•˜๋‚˜์˜ ํŒŒ์ผ์— ๋Œ€ํ•ด ์—ฌ๋Ÿฌ๋ฒˆ ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉฐ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ผด์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ๋ฉด์—์„œ ์†ํ•ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์—ฌ ํ•˜๋‚˜์˜ ํ•จ์ˆ˜์— ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ƒ๊ฐํ–ˆ๋‹ค.

  • ์ƒํƒœ ์ฝ”๋“œ ์ƒ์ˆ˜ํ™”
const STATUS_CODE = {
  200: "200 OK",
  201: "201 CREATED",
  400: "400 BAD REQUEST",
  404: "404 FILE NOT FOUND",
  500: "500 INVALID BTTP REQUEST",
};
 
module.exports = { STATUS_CODE };
 

์ƒํƒœ ์ฝ”๋“œ ์ƒ์ˆ˜ํ™”์˜ ๊ฒฝ์šฐ ๋‹ค์–‘ํ•œ ์ƒํƒœ์ฝ”๋“œ๊ฐ€ ์žˆ์ง€๋งŒ ์ฃผ๋กœ ์‘๋‹ต ์ฝ”๋“œ์— ๋งž๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋ฅผ ๋งค์น˜ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ์ฝ”๋“œ๋ฅผ ๊ตฌ๋ณ„ํ•˜์„œ ์“ฐ๋‹ค ๋ณด๋‹ˆ ํ•ญ์ƒ ๋‚˜์˜ค๋Š” ์—๋Ÿฌ์ฝ”๋“œ๋“ค์€ ์ •ํ•ด์ ธ ์žˆ์—ˆ๋‹ค. ์ด์— ์ด๋Ÿฌํ•œ ์—๋Ÿฌ์— ๋Œ€ํ•ด ๋งค๋ฒˆ ์—๋Ÿฌ๋ฅผ throwํ•˜๋Š” ๊ณผ์ •์—์„œ ๊ตณ์ด ๋ฉ”์„ธ์ง€๋ฅผ ํ•˜๋“œ์ฝ”๋”ฉํ•˜๊ธฐ๋ณด๋‹จ, ์ƒ์ˆ˜ํ™”์‹œ์ผœ์„œ ์ด๋ฅผ importํ•ด์™€์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋ฉด ๋‚˜์ค‘์—๋„ ์˜ˆ์™ธ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๋•Œ ํŽธํ•ด์งˆ ๊ฒƒ ๊ฐ™์•„์„œ ๊ฐœ์„ ์„ ์ง„ํ–‰ํ–ˆ๋‹ค.

  • json ๊ตฌ์กฐ ๋ฐ”๊พธ๊ธฐ
{
  "fileName": "billboard",
  "types": {
    "id": "number",
    "singer": "string",
    "year": "number",
    "song": "string"
  }
}
 

๋‚˜๋Š” ๊ธฐ์กด ํŒŒ์ผ์— ํƒ€์ž…์„ ๋‹ค๋ฅธ ๊ตฌ๋ถ„์ž๋ฅผ ๋ถ™์—ฌ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์€ ์›๋ž˜์˜ ํ˜•์‹์— ๋ฒ—์–ด๋‚˜๊ธฐ๋„ ํ•˜๊ณ , ์›๋ž˜๋„ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋‘๊ณ  ๊ด€๋ฆฌํ•œ๋‹ค๋Š” ์ด์•ผ๊ธฐ๋ฅผ ๋“ค์–ด ํƒ€์ž…๊ณผ ๊ฐ™์€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋”ฐ๋กœ ๋‘๋ ค๊ณ  ํ–ˆ์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Ÿฌํ•œ ํƒ€์ž…๋งŒ์„ ๋”ฐ๋กœ ๋‘๊ธฐ์—๋Š” jsonํŒŒ์ผ์— ๋Œ€ํ•ด ์˜คํžˆ๋ ค ๋‚ญ๋น„๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์–ด, ๋‚ด๊ฐ€ ๋‚˜์ค‘์— ์ฒ˜๋ฆฌํ•ด์„œ ์“ธ๋งŒํ•œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋”ฐ๋กœ ๋ณด๊ด€ํ•˜๊ธฐ๋กœ ํ–ˆ์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๋‚˜๋Š” fileName๊ณผ type์„ ๋‘์—ˆ์œผ๋ฉฐ, fileName์˜ ๊ฒฝ์šฐ ํ›„์— json ํŒŒ์ผ์„ ์ฝ์–ด๋“ค์–ด์™€ filename์„ ์‰ฝ๊ฒŒ ๋ฝ‘์•„๋‚ด์–ด ํŒŒ์ผ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๊ฐ€ ๋ณด๋‹ค ์‰ฌ์›Œ์งˆ ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜์—ฌ json๊ตฌ์กฐ๋ฅผ ๊ธฐ์กด ํŒŒ์ผ๋ช…์„ ๋ณด๊ด€ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ํ…Œ์ด๋ธ”์˜ ์ด๋ฆ„์„ ๊ธฐ์–ตํ•˜์—ฌ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค. โ€