본문 바로가기
블록체인 backEnd

database mysql sequelize setting

by gun_poo 2023. 9. 3.

 

하드햇에서 배포 스크립트를 모두 작성하고 필요한 데이터를 데이터베이스에 저장 후 

백엔드에서 필요 데이터를 받아오려고 한다.

 

1. sequelize-cli 설치

npm i sequelize
npm i sequelize-cli
npm i mysql2

2. sequelize init

sequelize init

설치를 진행하면 다음과 같은 폴더들이 생성이 된다

.
|-- README.md      
|-- config
|   `-- config.json
|-- migrations     
|-- models
|   `-- index.js   
|-- package.json   
|-- seeders        
`-- yarn.lock
  • config : 데이터베이스 설정 파일, 사용자 이름, DB 이름, 비밀번호 등의 정보.
  • migrations : git과 비슷하게, 데이터베이스 변화하는 과정들을 추적해나가는 정보로, 실제 데이터베이스에 반영할 수도 있고 변화를 취소할 수도 있다.
  • models : 데이터베이스 각 테이블의 정보 및 필드타입을 정의하고 하나의 객체로 모은다.
  • seeders : 테이블에 기본 데이터를 넣고 싶은 경우에 사용한다.

3. mysql 설정

mysql -u root -p
create database contractDB;
use contractDB;

4. 프로젝트 세팅

config/config.js 에 DB 정보 추가

const dotenv = require("dotenv");
dotenv.config();

const contractDB = {
  username: process.env.HARDHAT_USERNAME,
  password: process.env.HARDHAT_PASSWORD,
  database: process.env.HARDHAT_NAME,
  host: process.env.HARDHAT_HOST,
  dialect: "mysql",
};

module.exports = {
  development: contractDB,
};

models/index.js 에 DB 연결

테이블 생성

sequelize migration:create --name {테이블이름}

migrations/20220729…-{테이블이름}.js 파일에 테이블 모델 선언

"use strict";

/** @type {import('sequelize-cli').Migration} */
module.exports = {
  async up(queryInterface, Sequelize) {
    await queryInterface.createTable("contract_infos", {
      id: { type: Sequelize.INTEGER, primaryKey: true, autoIncrement: true },
      chain: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      name: { type: Sequelize.STRING, allowNull: false, unique: true },
      version: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      address: {
        type: Sequelize.STRING,
        allowNull: false,
      },
      abi: {
        type: Sequelize.JSON,
        allowNull: false,
      },
      createdAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: Sequelize.DATE,
      },
    });
  },

  async down(queryInterface, Sequelize) {
    /**
     * Add reverting commands here.
     *
     * Example:
     * await queryInterface.dropTable('users');
     */
  },
};

테이블 모델 스키마 작성 완료 후 명령어

sequelize db:migrate

테이블 생성 확인 및 models/{테이블명}.js 파일에도 해당 스키마 구조 수정

module.exports = (sequelize, DataTypes) => {
  return sequelize.define(
    "contract_infos",
    {
      // id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
      chain: { type: DataTypes.STRING, allowNull: false },
      name: { type: DataTypes.STRING, allowNull: false, unique: true },
      version: { type: DataTypes.STRING, allowNull: false },
      address: { type: DataTypes.STRING, allowNull: false },
      abi: { type: DataTypes.JSON, allowNull: false },
      createdAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
      updatedAt: {
        allowNull: false,
        type: DataTypes.DATE,
      },
    },
    {}
  );
};

models/index.js 에 DB table 연결 추가

db.contract_infos = require("./contract_info.js");

src/models 하위에 각 DB 에 맞게 파일 생성후 데이터베이스 관련된 함수들 정의

const db = require("../models");
const contract = db.contract_infos;

async function saveContractInfo(chain, name, version, address, abi) {
  try {
    // Update the contract information if it exists or create a new one
    const [result, created] = await contract.upsert(
      {
        chain: chain,
        name: name,
        version: version,
        address: address,
        abi: JSON.stringify(abi),
      },
      { returning: true }
    );

    if (created) {
      console.log("Contract created successfully.");
    } else {
      console.log("Contract updated successfully.");
    }

    return result;
  } catch (err) {
    console.error("Failed to save or update contract:", err);
  }
}

async function getContractInfo(name) {
  const contractInfo = await contract.findOne({ where: { name: name } });
  return contractInfo;
}

module.exports = {
  saveContractInfo,
  getContractInfo,
};

 

controller 생성

const saveContractDB = require("../methods/saveContractInfo");
const getContractDB = require("../methods/getContractInfo");
const { sequelize } = require("../models");

module.exports = {
  contracts: {
    saveContractInfo: async (chain, name, version, address, abi) => {
      console.log("saveContractInfo", chain, name, version, address, abi);
      try {
        await sequelize.authenticate();
        console.log("connection to database");

        const result = await saveContractDB.saveContractInfo(
          chain,
          name,
          version,
          address,
          abi
        );
        console.log("result : ", result);

        return result;
      } catch (error) {
        console.log("error : ", error);
      }
    },

    getContractInfo: async (name) => {
      console.log("getContractInfo : ", name);
      try {
        await sequelize.authenticate();
        console.log("connection to database");

        const result = await getContractDB.getContractInfo(name);
        console.log("result : ", result);
        return result;
      } catch (error) {
        console.log("error : ", error);
      }
    },
  },
};

 

컨트롤러 함수들을 배포스크립트 내부에 작성해넣으면 된다.

'블록체인 backEnd' 카테고리의 다른 글

Pool : first provide Liquidity  (0) 2023.10.08
DeFi Contract 작업  (0) 2023.10.03
업그레이더블 컨트랙트 hardhat testCode.01  (0) 2023.08.28
업그레이더블 컨트랙트 샘플  (0) 2023.08.28
브릿지  (0) 2023.01.26

댓글