본문 바로가기
코딩

[Node.js] 데이터베이스 직접 만들기 1편

by KRonae 2022. 11. 5.
반응형

웹서버 만들기에서 이어집니다... 1편 2편 3편

 

안녕하세요 크로네입니다.

오늘은 웹서버 만들기 편에 이어서 데이터베이스를 직접 만들어 보겠습니다.

 

 

1. 데이터베이스란?

데이터베이스는 말 그대로 데이터를 저장하는 공간입니다.

데이터베이스는 대표적으로 SQL, MongoDB 등이 있는데

이번에는 새로운 데이터 베이스를 직접 만들어 보겠습니다.

 

"아니, SQL 같이 더 좋은것도 있는데 왜 굳이 새로운걸 만드나요?"

왜냐하면 부족한 점이 있을때, 필요한 것이 있을때

업데이트를 기다리는게 아니라, 코딩을 해서 원하는 기능을

바로바로 추가하기 위해서입니다.

2. 모듈이 필요한가?

원래는 db-local 이라는 모듈을 사용하려고 했으나,

기능이 제 마음에 안들어서^^ 그냥 이것도 직접 만들어 보겠습니다.

(참고로 제가 만든 데이터베이스 파일은 다른 데이터베이스 프로그램과 호환되지 않습니다)

3. 실습 - 1

일단 현제 app.js의 코드는 이렇습니다.

const http = require("http");
const fs = require("fs");

app = http.createServer(function(request, response) {
  if(request.url == "/") {
    response.writeHead(200, { "Content-Type" : "text/html;charset=utf-8" });
    response.end(fs.readFileSync("./index.html"));
  } else if(request.url == "/hi") {
    response.writeHead(200, { "Content-Type" : "text/html;charset=utf-8" });
    response.end(fs.readFileSync("./hi.html"));
  } else {
    response.writeHead(404, { "Content-Type": "text/html;charset=utf-8" });
    response.end(fs.readFileSync("./404.html"));
  }
});
app.listen(80);

같은 폴더에 dbms.js 파일을 만듭니다. (DBMS 는 DataBaseManageSystem 의 약자입니다)

그리고 아래와 같은 코드를 씁니다. (파일도 첨부 해놨습니다)

※주의※

해당 파일은 절대 2차 배포를 절대로 하며,

다른사람에게 알려줄때에는 다음과 같은 주소를 이용해야 합니다. https://github.com/KR-onae/KRonDBMS/releases/

마지막으로 수정시에는 msg.kronae@gmail.com 으로 수정후 코드함께 메일을 보내 주시기 바랍니다.

// Require
const fs = require("fs");

// DB 라는 새로운 타입
module.exports.DB = function() {
    return {
        "data": null
    }
};
module.exports.DB.prototype = Object.prototype;
module.exports.DB.prototype.open = function($DB_Path, encoding) {
    if(encoding == undefined) {
        var encoding = module.exports.settings.encoding;
    }
    if(fs.existsSync($DB_Path)) {
        try {
            var file = fs.readFileSync($DB_Path, encoding).toString(); // 파일을 읽음
        } catch(error) {
            console.error(error);
            throw Error("DBMS: DB.prototype.open(DB_Path): Can't read the database file.");
        }
        try {
            var decoded = decodeURIComponent(Buffer.from(file, "base64").toString()); // 암호화를 품
        } catch(error) {
            console.error(error);
            throw Error("DBMS: DB.prototype.open(DB_Path): Can't decode the database file.");
        }
        try {
            var data = JSON.parse(decoded); // JSON 파싱을 함
        } catch(error) {
            console.error(error);
            throw Error("DBMS: DB.prototype.open(DB_Path): Can't JSON parse the database file.");
        }
        this.path = $DB_Path;
        this.data = data;
        this.encoding = encoding;
        return this;
    } else {
        throw Error("DBMS: DB.prototype.open(DB_Path): Can't find the database file.");
    }
};
module.exports.DB.prototype.createDB = function($DB_Name) {
    return this.data[$DB_Name] = {};
}
module.exports.DB.prototype.readDB = function($DB_Name) {
    return this.data[$DB_Name];
}
module.exports.DB.prototype.createCollection = function($DB_Name, $Col_Name) {
    return this.data[$DB_Name][$Col_Name] = [];
}
module.exports.DB.prototype.readCollection = function($DB_Name, $Col_Name) {
    return this.data[$DB_Name][$Col_Name];
}
module.exports.DB.prototype.writeData = function($DB_Name, $Col_Name, $data) {
    return this.data[$DB_Name][$Col_Name].push($data);
}
module.exports.DB.prototype.writeDataAt = function($DB_Name, $Col_Name, $Nth, $data) {
    return this.data[$DB_Name][$Col_Name][$Nth] = $data;
}
module.exports.DB.prototype.readData = function($DB_Name, $Col_Name, $Nth) {
    return this.data[$DB_Name][$Col_Name][$Nth];
}

module.exports.DB.prototype.find = async function($condition, callback) {
    var out = [];
    var DBs = this.data
    for(var i = 0; i < Object.keys(DBs).length; i++) {
        var COLs = this.data[Object.keys(this.data)[i]];
        for(var ii = 0; ii < Object.keys(COLs).length; ii++) {
            var datas = COLs[Object.keys(COLs)[ii]];
            for(var iii = 0; iii < datas.length; iii++) {
                var data = datas[iii];
                var config = {
                    "db": Object.keys(DBs)[i],
                    "collection": Object.keys(COLs)[ii],
                    "nth": iii,
                    "data": data
                };
                if($condition(this, config, out)) {
                    out.push(config);
                }
            }
        }
    }
    callback(this, out);
}
module.exports.DB.prototype.save = async function(callback) {
    fs.writeFileSync(this.path, Buffer.from(encodeURIComponent(JSON.stringify(this.data)), "binary").toString("base64"), this.encoding);
    if(typeof(callback) == "function") {
        callback(this);
    }
    return this;
}

// 설정
module.exports.settings = {
    "path": "./database.KronDB",
    "encoding": "utf-8"
};
module.exports.setting = function($key, value) {
    if(key == undefined) {
        throw Error("DBMS: DBMS.setting(key, value): Please write key arg.");
    } else {
        if(value == undefined) {
            return module.exports.settings[$key];
        } else {
            return module.exports.settings[$key] = value;
        }
    }
};

// 데이터베이스 열기
module.exports.open = function(DB_Path, encoding) {
    var db = new module.exports.DB();
    if(DB_Path == undefined) {
        db.open(module.exports.settings.path, encoding);
    } else {
        db.open(DB_Path, encoding);
    }
    return db;
};
module.exports.write = function(DB_Path, encoding) {
    fs.writeFileSync(DB_Path == undefined ? module.exports.settings.path : DB_Path, "JTdCJTdE", encoding == undefined ? module.exports.settings.encoding : encoding);
    return function() {
        return module.exports.open(DB_Path, encoding);
    };
}

dbms.js
0.00MB

설명하고 싶은데... 너무 길어서 도저히 설명을 못하겠습니다.

간단하게 말하자면 그냥 하나의 모듈입니다.

 

주요 기능은 데이터베이스를 암호화 해서 파일에 저장하는것입니다.

기호, 영어, 한글, 한자등을 값으로 사용할 수 있습니다.

 

같은 폴더에 있는 경우 아래와 같은 코드를 통해 불러올 수 있습니다.

const DBMS = require("./dbms.js"); // ./ 꼭 써야함!

사용법은......

 

다음편에 계속!

반응형

댓글