Background Image
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

개요. 
     ●Callback과 Promise 패턴을 이야기 앞서 동기식과 비동기식 프로그래밍을 소개하겠습니다.

 

1. 동기식 프로그래밍 vs 비동기식 프로그래밍 

     1-1) 동기식 프로그래밍

      ● 어떤 작업을 요청한 후 그 작업이 완료되기까지 기다렸다가 응답을 받아 처리하는 것을 말합니다.

 

      <예제 코드>

      1-2) 동기식 예제 코드.PNG

 

      <예제 결과> 

     1-2) 동기식 예제 결과.PNG

 

동기식 프로그래밍
function addition(x){
        return x+x;
    }
    
 var num = addition(2);
 console.log(num);    //4

 

     * 순차적으로 해당 덧셈작업이 완료되기 까지 기다렸다가 결과 값을 보여주게 됩니다.

 

     1-2) 비동기식 프로그래밍

      ● 어떤 작업을 요청한 후 다른 작업을 수행하다가 이벤트가 발생하면 그에 대한 응답을 받아 처리하는 것을 말합니다.

 

      <예제 코드>

      1-2) 비동기식 예제 코드.PNG

 

      <예제 결과>

      1-2) 비동기식 예제 결과.PNG

 

비동기식 프로그래밍

function addition(x, callback){
        setTimeout(callback, 100, x+x);
    }
    
var num = 0;
addition(2,function(x){
    num = x;
});


console.log(num);    //0

 

     * setTimeout은 비동기를 표현하기 위해 사용하였습니다. 

 

     * 0.1초 후 callback 함수가 실행되는 코드입니다.
        해당 코드를 동기식으로 바라보면, console.log에는 4라는 결과 값이 출력되어야 하지만, 결과는 0이 됩니다.
        그 이유로 console.log로 0으로 초기화된 num 값을 먼저 출력하고, 0.1초가 지난 뒤, 콜백함수 안에 num = x로 num 값이 저장됩니다.

 

2. Callback 패턴 이란?

     2-1) 개념

      ● 자바스크립트 코드의 실행환경은 싱글쓰레드 기반으로 동작하고, 동기적인 코드를 사용할 때 블록킹(blocking) 현상이 발생합니다.

           이러한 현상을 방지하기 위해 비동기식 프로그래밍을 사용하게 됩니다.


      ● 비동기식 프로그래밍을 하기 위해 Callback 패턴을 이용하게 되는데, 콜백(Callback)이란 옵저버(Observer) 디자인 패턴에서 나온 개념으로

           객체의 상태 변화(이벤트)가 발생하였을 경우에 이러한 사실을 함수를 통해 전달하는 것을 의미합니다.

 

3. Callback 패턴의 문제점

     3-1) Callback Hell

      ● 자바스크립트에서 비동기 식으로 개발을 하다 보면, Callback 함수로 인해 코드의 복잡성이 증가하고 가독성이 떨어지는 경우가 종종 생기게 됩니다.

           이를, Callback Hell이라고 부릅니다.
   
     3-2) Callback Hell 예제

 

      <예제 코드>

      3-1) 콜백헬 예제 코드.PNG

 

      <예제 결과>

      3-1) 콜백헬 예제 결과.PNG

 

Callback Hell
function addition(x, callback) {
    setTimeout(callback, 100, x+x);
}
    
addition(2, function(x) {
    addition(x, function(x2) {
        addition(x2, function(x3) {
            console.log(x3);    //16
        });
    });
});

 

     * Callback Hell을 설명해 드리기 위해 addition 함수를 3번 사용한 간단한 Callback Hell 예제입니다.
        addition 함수를 비동기로 처리하면서 콜백 안에 콜백을 계속 무는 형식으로 코딩이 되, 이러한 코드 구조는 가독성을 떨어트리고 로직을 변경하기 어렵습니다.

 

4. Promise 패턴

     4-1) promise란

      ● callback 함수의 문제를 해결하기 위해 사용하게 됩니다. 그 이유로 Promise의 3가지 states로 Promise의 처리 과정을 소개하겠습니다.

          ① pending(대기) : 비동기 처리 로직이 아직 완료되지 않은 상태

 

          ② fulfilled(이행) : 비동기 처리가 완료되어 Promise가 결과 값을 반환해준 상태

 

          ③ rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

 

     * 다음과 같은 3가지 상태를 이용해 비동기 작업을 순차적으로 진행하거나, 병렬로 진행하는 등의 컨트롤이 보다 수해지고 코드의 가독성이 좋아지며,

        내부적으로 예외처리에 대한 구조가 탄탄해져 오류가 발생했을 때 오류 처리 등에 대해 보다 가시적으로 관리해 줄 수 있는 장점이 있습니다.

 

     4-2) promise 예제

 

      <예제 코드>

      4-2) 프로미스 예제 코드.PNG

 

      <예제 결과>

      5. 프로미스 체이닝 예제 결과.PNG

 

promise

var addition = function(flag, num) {
    return new Promise(function (resolve, reject) {
        setTimeout(function () {
        if (flag) {
            resolve({ result: "성공", num: num+num });
        } else {
            reject({ result: "실패" });
        }
    }, 1000);
  });
};

 

// resolve()의 결과 값 num를 result 받음
addition(true, 2)
.then(function (result) {
    console.log(result); // 4
}, function(err){
    console.log(err);
});

 

     * addition 함수에 new Promise() 메소드를 호출하여 Pending(대기) 상태가 되며, Promise의 인자인 resolve를 실행하면 Fulfilled(이행) 상태가 됩니다. 

        그리고 .then()을 이용하여 처리 결과 값을 받을 수 있습니다.

 

     * 반대로, Promise의 인자인 reject를 실행하면 Rejected(실패) 상태가 되며, 실패 처리의 결과 값을 .catch()로 받을 수 있습니다.

 

     4-3) Promise API 소개

      ● Promise API 세 종류 소개하겠습니다.
         ① Constructor

             - new 연산자를 선언하여 Promise 인스턴스 객체를 생성해 사용한다.

                
                var promise = new Promise(function(resolve, reject) {
                    // 비동기 처리 작성
                    // 처리가 끝나면 두 가지 인자를 호출하여 사용할 수 있습니다.
                    // 1) resolve: 해당 인자로 resolve() 메소드를 실행하면 Fulfilled(이행) 상태가 됩니다.
                    // 2) reject: 해당 인자로 reject() 메소드를 실행하면 Rejected(실패) 상태가 됩니다.
                })

 

         ② Instance Method
            - new 연산자로 생성한 Promise의 인스턴스 객체에는 성공(resolve) 또는 실패(reject)했을 때 호출될 콜백 함수를 등록하는

               promise.then(onFulfilled, onRejected)이라고 하는 인스턴스의 메소드가 있습니다.
        
            - 만약 오류만 처리하려면 promise.catch(onRejected)를 사용하면 됩니다.

 

         ③ Static Method
            - 전역 객체인 Promise에는 Promise.all()이나 Promise.resolve() 같은 정적 메소드가 있으며, 이 메소드는 Promise를 다루는 데 필요한 보조 메드입니다.

 

5. 여러 개의 Promise 연결하기 (Promise Chaining)

     ● then과 catch를 이용하여 여러개의 비동기 동작을 연결 할 수 있습니다.

 

     5-1) Promise Chaining 예제

 

      <예제 코드>

      5. 프로미스 체이닝 예제 코드.PNG

 

      <예제 결과>

      5. 프로미스 체이닝 예제 결과.PNG

 

Promise Chaining
var addition = function (flag, num) {
    return new Promise(function (resolve, reject) {
        if (flag) {
            resolve(num+num);
        } else {
            reject("실패");
        }
    });
};
     
addition(true, 2)                               // addition1
    .then(function (num) {
        console.log("First Success : " + num);
        return addition(true, num);    // addition2
    })
    .then(function (num) {
        console.log("Second Success : " + num);
        return addition(false, num);  // addition3
    })
    .catch(function (e) {
        console.log("First Fail : " + e);
        return addition(true, 0);        // additionFail1
    })
    .then(function (num) {
        console.log("Third Success : " + num);
        return addition(true, num);  // addition4
    })
    .catch(function (e) {
        console.log("Second Fail : " + e);    // additionFail2
    })
    .then(function (num) {
        console.log("Complete : " + num);  //complete
    });

 

 

      Chaining 순서도.PNG

 

     * 초록색 선은 resolve 되었을 때, 빨간색 선은 reject 되었을 때, 보라색 선은 addition4에서 reject 되었을 경우의 흐름을 나타냅니다.

 

* 이상 3탄에서는 동기와 비동기식 프로그래밍, Callback과 Promise 패턴의 간단한 개념을 소개했습니다.
    다음 마지막 4탄에서는 Node.js에서 커넥션풀(Connection Pool)을 이용해 CUBRID와 연동하는 방법을 소개하겠습니다.


  1. Doxygen으로 소스코드 문서화 해보기

    오픈소스 프로젝트를 이용해서 개발을 해보신 분들은 소스코드를 문서화한 레퍼런스 문서(또는 개발자 매뉴얼)을 참고해서 개발해 본 경험이 있을 것 같습니다. 개발자를 위한 이러한 문서는 기본적으로 프로젝트 빌드 방법, 주요 아키텍쳐 설명 등의 내용들을 담기도 하고 소스코드에서 정의한 변수나 구조체와 함수 같은 것들이 소스 파일을 직접 열어서 찾아보지 않아도 보기 좋게 정리하거나 변수나 함수 간의 관계를 정리해서 보여주기도 합니다. 다음과 같은 프로젝트의 문서를 예시로 참고해 볼 수 있겠네요. CGAL : https://doc.cgal.org/4.2/CGAL.CGAL/html/index.html Eigen : http://eigen.tuxfamily.org/dox/ Xerces-C++ : http://xerces.apache.org/xerces-c/apiDocs-3/classes.html 공개 되어있는 코드를 한줄한줄 따라가보며 파악할 수도 있지만 프로젝트의 규모가 커지고, 코드의 복잡도가 증가할수록 개발자를 위한 문서는 중요해집니다. 왜냐하면 문서를 읽으면 소스코드를 훨씬 빠르게 파악할 수 있기 때문입니다. 이러한 문서 덕분에 다른 개발자가 조금 더 쉽게 내 프로젝트에 기여할 수 있게 된다면 내 프로젝트에 참여하고 기여해주는 사람들이 더 많아...
    Date2019.09.30 Category나머지... Byhgryoo Views65
    Read More
  2. No Image

    DB2, Informix, Sybase ASE, Postgres DBMS 데이터를 CUBRID로 이관하는 방안에 대하여...

    DBMS 보급과 관련하여 과거와는 달리 민간 및 공공기업에서 서비스 중요도 및 비용등을 고려하여 다양한 제품을 도입하여 사용하고 있다. 뿐만 아니라 시스템 사용연한 도래, 유지보수 비용절감, 클라우드 전환 및 차세대 시스템 도입을 통해서 기존 DBMS를 다른 DBMS로 변환하는 경우가 빈번하게 발생하고 있다. DBMS 변경으로 응용체계 전환 및 데이터 전환, 운영 및 사용자 기술전환등이 수행되는데 기술적 측면 및 비용적인 부분에서 예상보다 많은 리스크를 직면하게 되기도 한다. 성공과 실패는 면밀한 전환환경에 대한 분석 및 계획과 수행하는 기술자들의 자질에(기술 및 도전적 & 긍정적 마인드) 의해 결정된다. 이러한 여러 요소들 중에서 여기서 다루고자 하는 부분은 전환에 있어 기본이면서 중요한 데이터 전환에 대한 부분이다. 큐브리드는 국산을 제외한 외산 DBMS중에 민간 및 공공기간을 통틀어 점유율이 높다고 볼 수 있는 Oracle 및 MS-SQL, MySQL에 대해서 데이터 이관 툴을 제공하고 있다. 해당 제품명은 CMT(Cubrid Migration Toolkit)이며 Linux 및 Windows 버전을 기본으로 GUI 및 Terminal 방식을 지원하고 있다. 그 이외에도 비록 시장 점유율은...
    Date2019.07.15 Category나머지... By김창휘 Views181
    Read More
  3. CUBRID GRANT ALL TABLES

    CUBRID GRANT.... 큐브리드에서는 GRANT ... ON ALL TABLES 구문을 아쉽게도 제공 하지 않습니다. 현재는 수동으로 GRANT 구문을 작성하여, 사용하여야 합니다. "이러한 불편함을 자동으로 작성해주면 어떨까" 라는 생각으로 스크립트를 작성하였습니다. HOW to do GRANT ... ON ALL TABLES .....? $ sh cub_grant.sh -------------------------------------------------------------------------------------------------------- CUBRID DBMS, auto-generator for grant all tables usage : sh cub_grant.sh <dbname> <grantee user> <grantor user> <grantor user password> <option> <option> -view : grantee user all grant view -dml : default SELECT, DELETE, UPDATE, INSERT -ddl : default ALTER, INDEX, EXECUTE -all : ALL PRIVILEGES(dml+ddl) <file creation info> default path : . -dml : ./GRANT_DML.sql -ddl : ./GRANT_DDL.sql -all : ./GRANT_ALL.sql -------------------------------------------------------------------------------------------------------- 1. Linux 환경에서만 사용 가능합니다. 2. bash 스크립트로 작성 되었습니다. 3. CUBRID 엔...
    Date2019.06.25 Category제품 여행 By윤준수 Views267
    Read More
  4. CUBRID 슬랏 페이지(slotted page) 구조 살펴보기

    내가 INSERT한 레코드는 어떤 구조로 파일에 저장될까? 운전을 하다 보면 가끔 엔진이나 미션 등이 어떻게 동작하는지 궁금할 때가 있다. 연료가 어떻게 엔진에 전달되는지, 엔진은 어떻게 연료를 연소하여 동력을 얻는지, 또 이를 미션에 전달하여 어떻게 차를 움직이게 하는지 등에 대해 말이다. CUBRID를 사용하는 사용자들도 가끔 이런 호기심이 생기지 않을까? 이런 호기심 많은 사용자를 위한 첫번째로 "사용자가 INSERT한 레코드는 어떤 구조로 파일에 저장될까?"란 주제로 이야기 해보려고 한다. 티타임을 이용해 가벼운 마음으로 읽을 수 있도록 작성하였으니 여유 시간에 재미로 읽을 수 있길 바래본다. 슬랏 페이지(slotted page) 구조 CUBRID도 OS나 다른 DBMS와 같이 성능상의 이유로 페이지(page) 단위 디스크 I/O를 수행한다. CUBRID 페이지 크기는 최소 4KB ~ 최대 16KB 이며, 디폴트로 16KB 디스크 페이지 크기를 사용한다. 슬랏 페이지 구조란 이런 페이지에 데이터 저장을 구조화하는 하나의 방식을 말한다. CUBRID 사용자가 INSERT 구문을 사용하여 데이터(레코드)를 입력하게 되면, 여러 처리를 거친 후 결국 디스크 페이지에 입력된 데이터가 쓰여지게 ...
    Date2019.06.18 Category제품 여행 By민준 Views275
    Read More
  5. Node.js 사용자들을 위한 CUBIRD 연동 방법 [4탄(최종)-CUBRID와 Node.js 커넥션 풀(Connection Pool)설정]

    1. 환경소개 OS CentOS7 64비트 Node.js 10.15.3 버전 Npm 6.4.1 버전 java 1.8.0_201 버전 Editer Eclipse DB CUBRID 10.1 (10.1.2.7694-64632b2)(64비트) 2. 커넥션 풀 (Connection Pool) 이란? 2-1) 개념 ● 데이터베이스와 연결된 커넥션을 미리 만들어서 풀(pool) 속에 저장해 두고 있다가 필요할 때 커넥션을 풀에서 쓰고 다시 풀에 반환하는 기법을 말합니다. ● 커넥션 풀을 사용하면 커넥션을 생성하고 닫는 시간이 소모되지 않기 때문에 애플리케이션의 실행 속도가 빨라지며, 또한 한 번에 생성될 수 있는 커넥션 수를 제어하기 때문에 동시 접속자 수가 몰려도 웹 애플리케이션이 쉽게 다운되지 않습니다. ● 웹 컨테이너가 실행되면 커넥션(Connection) 객체를 미리 풀(pool)에 생성해 둡니다. ● DB와 연결된 커넥션(Connection)을 미리 생성하고, 풀(pool) 속에 저장했다가 필요할 때에 가져다 쓰고 반환합니다. ● 미리 커넥션(Connection)을 생성했기 때문에 데이터베이스에 부하를 줄이고 유동적으로 연결을 관리할 수 있습니다. 3. 커넥션 풀 (Connection Pool) 환경 설정 ● node-cubrid는 자체적인 커넥션 풀(Connection Pool) 기능을 제공하고 있지는 않습니다...
    Date2019.06.13 Category제품 여행 By원종민 Views335
    Read More
  6. Node.js 사용자들을 위한 CUBIRD 연동 방법 [3탄-Callback과 Promise 패턴 개념 소개]

    개요. ●Callback과 Promise 패턴을 이야기 앞서 동기식과 비동기식 프로그래밍을 소개하겠습니다. 1. 동기식 프로그래밍 vs 비동기식 프로그래밍 1-1) 동기식 프로그래밍 ● 어떤 작업을 요청한 후 그 작업이 완료되기까지 기다렸다가 응답을 받아 처리하는 것을 말합니다. <예제 코드> <예제 결과> 동기식 프로그래밍 function addition(x){ return x+x; } var num = addition(2); console.log(num); //4 * 순차적으로 해당 덧셈작업이 완료되기 까지 기다렸다가 결과 값을 보여주게 됩니다. 1-2) 비동기식 프로그래밍 ● 어떤 작업을 요청한 후 다른 작업을 수행하다가 이벤트가 발생하면 그에 대한 응답을 받아 처리하는 것을 말합니다. <예제 코드> <예제 결과> 비동기식 프로그래밍 function addition(x, callback){ setTimeout(callback, 100, x+x); } var num = 0; addition(2,function(x){ num = x; }); console.log(num); //0 * setTimeout은 비동기를 표현하기 위해 사용하였습니다. * 0.1초 후 callback 함수가 실행되는 코드입니다. 해당 코드를 동기식으로 바라보면, console.log에는 4라는 결과 값이 출력되어야 하지만, 결과는 0이 됩니다. 그 이유로 console.log...
    Date2019.06.11 Category제품 여행 By원종민 Views79
    Read More
  7. Node.js 사용자들을 위한 CUBIRD 연동 방법 [2탄-CUBRID와 Node.js 연동]

    1. test 디렉토리 & 파일 생성 1-1) 라우터 파일 생성 ● /routes/test.js 1-2) view 디렉토리& 파일 생성 ● views/test 디렉토리 생성 ● views/test/test_view.ejs 파일 생성 1-3) 프로젝트 최종 결과 2. node-cubrid 드라이버 모듈 설치 ● 모듈 공식 사이트 : https://www.npmjs.com/package/node-cubrid 2-1) node-cubrid 모듈 설치 ● npm install node-cubrid --save ● package.json 에서 node-cubrid 모듈 설치 확인 3. node-cubrid 모듈 적용 및 DB 연동 3-1) 컨트롤러(app.js)에서 라우팅(test.js) 설정. - app.js의 25번째 줄과 동일하게 app.use('/test',require('./routes/test')); 추가 app.js var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); // 접속한 클라이언트의 쿠키 정보에 접근하기 위한 모듈 var logger = require('morgan'); // 클라이언트의 HTTP 요청 정보를 로깅하기 위한 모듈 var indexRouter = require('./routes/index'); var usersRouter = require('./ro...
    Date2019.06.04 Category제품 여행 By원종민 Views219
    Read More
  8. Node.js 사용자들을 위한 CUBIRD 연동 방법 [1탄-Node.js 환경 설치 및 개념 소개]

    1. 환경소개 OS Window 10 64비트 Node.js 10.15.3 버전 Npm 6.4.1 버전 java 1.8.0_201 버전 Editer Eclipse DB CUBRID 10.1 (Window 10 64비트) / CUBRID Manager 10.1 (Window 10 64비트) 2. Node.js 소개 Node.js란? 1) 개념 - Node.js는 확장성 있는 네트워크 애플리케이션 개발에 사용되는 소프트웨어 플랫폼입니다. - 자바스크립트를 서버에서도 사용을 할 수가 있도록 설계가 되어 있는 서버개발을 위해서 나온 언어로 v8이라는 자바스크립트 엔진 위에서 동작하는 이벤트 처리 I/O 프레임워크로 웹서버와 같이 확장성 있는 네트워크 프로그램을 제작하기 위하여 고안이 된 것입니다. 2) 사용 이유 - 간단히 Node.js를 소개하면, 이전까지 Server-Clint 웹사이트를 만들 때 웹에서 표시되는 부분은 javascript를 사용하여 만들어야만 했으며, 서버는 ruby, java 등 다른 언어를 써서 만들어야 했는데, 마침내 한가지 언어로 전체 웹페이지를 만들 수 있게 된 것입니다. express란? 1) 개념 - 노드(NodeJS) 상에서 동작하는 웹 개발 프레임워크로 간편하게 사용하기 위해 사용합니다. * 프레임워크(Framework)란 : 소프트웨어의 구체적인 부분에 해당하는 설계와 구현을...
    Date2019.06.03 Category제품 여행 By원종민 Views306
    Read More
  9. No Image

    분산 시스템으로서의 DBMS, 그리고 큐브리드

    가끔 퇴근길에 서점에 들르곤 한다. 직업이 직업이라 그런진 몰라도 항상 IT코너에 머물러 어떤 새로운 책들이 출간되었나 보게 된다. 그러다보면 최근 유행하는 컨셉이나 아키텍쳐, 프로그래밍 언어나 개발방법론 등에 대해 트렌드가 뭔지 관찰하려고 안해도 자연히 접하게 되는 것 같다. 그 중 최근 유행처럼 사람들 입에 오르내리기도 하고 책으로 소개되기도 하는 개념들 중 MSA(Micro Service Architecture)라는 것이 있다. 뭔가 하고 들여다보니 MSA 개념에서 다루고 있는 '독립적으로 수행되는 최소단위의 서비스' 그리고 그 서비스들의 집합으로서의 시스템과 시스템의 분할에 관한 관점 및 해석은 십수년전 주목받던 SOA(Service Oriented Architecture)가 지향하는 서비스를 구성하는 기능별 시스템의 분할과 크게 다르지 않다. 이 글은 MSA와 SOA가 얼마나 비슷한 사상으로 소개된 개념인지를 이야기하고자 함이 아니다. 예전에도 의미있게 다뤄졌고 지금도 의미있게 받아들여지는 이러한 개념들이 시스템의 관점에서 더 좁게는 DBMS라는 시스템 소프트웨어적 관점에서 어떻게 해석될 수 있는가를 간단하게 짚어보고자 함이다. MSA의 개념이 제대로 구현되기 위해서...
    Date2019.03.29 Category나머지... By조성룡 Views360
    Read More
  10. [CUBRID 유틸리티] restoreslave에 대하여 알아보자.

    CUBRID는 10.1 version 이상부터 restoreslave란 명령어를 제공한다. CUBRID 9.3.x version 까지는 온라인 재구성을 위해 자체적으로 제공되는 shell script를 사용하였으나, 10.1 version 이상부터는 restoreslave 명령을 통해 보다 편하게 작업을 할 수있다. 해당 명령어를 통해 master의 구동 상태와는 상관 없이, slave를 재구축 할 수 있으며, 시나리오는 아래와 같다. 1. HA 서비스 중, 이중화가 깨졌을때. (1) 필요 환경 : master - slave의 이중화 환경. (2) 필요 파일 : master 서버의 backup file (3) 시나리오 - DB의 이중화가 깨지는 것을 재연하기 위해 slave의 db_ha_apply_info의 데이터를 삭제한다. - slave의 heartbeat를 종료한다. slave) $> csql -S -u dba --sysadm demodb sysadm> delete from db_ha_apply_info; - 위의 이중화 로그를 삭제하였을 경우, 동기화는 더이상 이루어지지 않는다. - 위의 행위로 인하여 DB 이중화가 깨졌다고 판단하고 이중화복구를 진행하여보자. - master에서 backup 받은 backup file은 slave에 옮겨놓은 상태이다. slave) $> cubrid service stop -- cubrid sevice 종료 $> ps -ef | grep cubrid -- CUBRID process가 모두...
    Date2019.03.29 Category제품 여행 By박동윤 Views185
    Read More
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 Next
/ 11

Contact Cubrid

대표전화 070-4077-2110 / 기술문의 070-4077-2147 / 영업문의 070-4077-2112 / Email. contact_at_cubrid.com
Contact Sales