기타

CUBRID 데이터베이스와 연동하여 Qt어플리케이션 개발하기 - 2

by 김대진 posted Jan 27, 2010
안녕하세요. 김대진 입니다.
홈페이지( http://www.qt-dev.com )

이전에 우리는 QT에 대해 알아보았습니다.  이번에는 CUBRID 데이터베이스에
접속하여 테이블을 검색하는 어플리케이션을 만들어 보도록 하겠습니다. 
 
 
 
앞의 그림은 CUBRID의 demodb 데이터베이스에 저장된 record테이블의 데이터를 검색하여 TableVive 위젯에 출력한
어플리케이션입니다.

데이터의 검색은 CCI API를 사용하였습니다. CCI API 는 CUBRID에서 제공하는 API로써 어플리케이션 프로그램을 직접 개발할 수
있도록 API를 제공합니다.
 
QT에서는 아직 공식적으로 CUBRID 라이브러리를 제공하지 않으므로 qmake로 생성된 Makefile 에 라이브러리 PATH 를 설정해야
합니다. Makefile의 수정은 추후 설명하기로 하고 소스부터 살펴보도록 하겠습니다.
 
mainwindow.h
 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#define kor(str) QString::fromLocal8Bit(str)
class QAction;
class QTableView;
class QStandardItemModel;
class QAbstractItemModel;
class QItemSelectionModel;
class QModelIndex;
class QComboBox;
class QLineEdit;
class QPushButton;
class MainWindow : public QMainWindow
{
 Q_OBJECT
 
public:
 MainWindow();
  
private:
 QString host, user, passwd, database;
 QTextCodec *codec;
 
 QWidget  *main_page;
 
 QTableView *table_view;
 QAbstractItemModel  *tab_model;
 QItemSelectionModel *tab_selectionModel;
 
 void init();
 
 void create_amainWidget();
 void db_query();
};
#endif

 
 
mainwindow.cpp
#include <QtGui>
#include <QtSql>
#include <stdio.h>
#include <cas_cci.h>
#include "mainwindow.h"

MainWindow::MainWindow()
{
 init();
 setWindowTitle(codec->toUnicode("RECORD"));
 
 create_mainWidget();
 db_query();
}

void MainWindow::init()
{
 codec = QTextCodec::codecForName("eucKR");
 QFont font( "unifont", 10, QFont::Bold);
}

void MainWindow::create_mainWidget()
{
 tab_model = new QStandardItemModel(0, 6, this);
 table_view = new QTableView;
 table_view->setModel(tab_model);
 
 tab_model->setHeaderData(0, Qt::Horizontal,
   codec->toUnicode("host_year") );
 tab_model->setHeaderData(1, Qt::Horizontal,
   codec->toUnicode("event_code") );
 tab_model->setHeaderData(2, Qt::Horizontal,
   codec->toUnicode("athlete_code") );
 tab_model->setHeaderData(3, Qt::Horizontal,
   codec->toUnicode("medal") );
 tab_model->setHeaderData(4, Qt::Horizontal,
   codec->toUnicode("score") ); 
 tab_model->setHeaderData(5, Qt::Horizontal,
   codec->toUnicode("unit") ); 
 
 
 table_view->setColumnWidth(0,90);
 table_view->setColumnWidth(1,90);
 table_view->setColumnWidth(2,90);
 table_view->setColumnWidth(3,90);
 table_view->setColumnWidth(4,90);
 table_view->setColumnWidth(5,90);
   
 tab_selectionModel = new QItemSelectionModel(tab_model);
 table_view->setSelectionModel(tab_selectionModel);
 table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
    
 main_page = new QWidget();
 QVBoxLayout *mainLayout = new QVBoxLayout(main_page);
 mainLayout->setSpacing(1);
        mainLayout->setMargin(1);
   
 mainLayout->addWidget(table_view);
 setCentralWidget(main_page);

}
void MainWindow::db_query()
{
int con = 0, req = 0, res, ind, i, col_count, lines=0;
    T_CCI_ERROR error;
    T_CCI_COL_INFO *res_col_info;
    T_CCI_SQLX_CMD cmd_type;
    char *buffer;

    // DB에 접속하기 위한 연결함수
    if ((con=cci_connect("localhost",30000,"demodb","PUBLIC",""))<0) {
        qDebug( "%s(%d): cci_connect fail "
            , __FILE__, __LINE__);
    }else{
     qDebug("CUBRID Connection OK. %s(%d)",__FILE__, __LINE__);
    }

// SQL문을 준비한다. 바인딩에 대한 정보와 컬럼에 대한 정보를 얻을 수 있다.
if ((req=cci_prepare(con, "select * from record", 0,&error))<0) {
                qDebug( "%s(%d): cci_prepare fail(%d)"
           , __FILE__, __LINE__, error.err_code);
                goto cubrid_error;
    }
 
printf("Prepare OK (%d) ",req);
   
// cci_prepare 함수에 의해 준비된 SELECT 문의 컬럼 정보에 대한 포인터를 얻어옴
res_col_info = cci_get_result_info(req, &cmd_type, &col_count);
    if (!res_col_info) {
        qDebug( "%s(%d): cci_get_result_info fail "
           , __FILE__, __LINE__);
        goto cubrid_error;
    }
 
 if ((res=cci_execute(req, 0, 0, &error))<0) {
        qDebug( "%s(%d): cci_execute fail(%d) "
           , __FILE__, __LINE__,error.err_code);
        goto cubrid_error;
    }

    // cci_fetch를 통해 서버에서 클라이언트로 전송되는 튜플의 개수를 정한다
    if ((res=cci_fetch_size(req, 100))<0) {
        qDebug( "%s(%d): cci_fetch_size fail ", __FILE__, __LINE__);
        goto cubrid_error;
    }
   
while (1) {
// 요청 핸들러에 설정되어 있는 커서를 이동시킨다.
       res = cci_cursor(req, 1, CCI_CURSOR_CURRENT, &error);
       if (res == CCI_ER_NO_MORE_DATA) {
         qDebug("Query END! ");
         break;
       }
       if (res<0) {
            qDebug( "%s(%d): cci_cursor fail(%d) "
            , __FILE__, __LINE__,error.err_code);
            goto cubrid_error;
       }
       // 클라이언트 버퍼로 결과를 받는다
       if ((res=cci_fetch(req, &error))<0) {
               qDebug( "%s(%d): cci_fetch fail(%d) "
                  , __FILE__, __LINE__,error.err_code);
               goto cubrid_error;
       }
  
tab_model->insertRows(lines, 1, QModelIndex());
        
      for (i=1; i<=col_count; i++) {
            // 현재 fetch된 결과에 대해서 변수 i번째의  결과를 가져온다.
            if ((res=cci_get_data(req, i, CCI_A_TYPE_STR
, &buffer, &ind))<0) {
                printf( "%s(%d): cci_get_data fail ", __FILE__, __LINE__);
                goto cubrid_error;
            }

            tab_model->setData(tab_model->index(lines, i-1
, QModelIndex()) , codec->toUnicode(buffer));
            }
       
            lines++;
       }

cubrid_error:;
 
}

 
main.cpp
 
#include <QApplication>
#include <QDesktopWidget>
#include <QSplashScreen>
#include <QStyleFactory>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
 QApplication app(argc, argv);
 
 QStringList styles = QStyleFactory::keys();
 app.setStyle( styles[3] );
 MainWindow mainWin;
 mainWin.resize(600,500);
 
 QDesktopWidget *desktop = QApplication::desktop();
 int w = desktop->width();
 int h = desktop->height();
 
 mainWin.move( (w-600)/2, (h-500)/2);
 
 mainWin.show();
 return app.exec();
}

위와 같이 소스를 작성한 다음 Makefile 을 다음과 같이 INCLUDE 와 LIBRARY PATH를 추가합니다.
 

CFLAGS   = -pipe -O2 -Wall -W -D_REENTRANT -I/usr/local/src/CUBRID/include $(DEFINES)
CXXFLAGS = -pipe -O2 -Wall -W -D_REENTRANT -I/usr/local/src/CUBRID/include $(DEFINES)
 
LIBS          = $(SUBLIBS)  -L/usr/local/qt/lib -lQtSql -L/usr/local/qt/lib -pthread -pthread -lQtGui -L/usr/X11R6/lib -pthread -lpng -lfreetype -lgobject-2.0 -lSM -lICE -pthread -pthread -lXrender -lfontconfig -lXext -lX11 -lQtCore -lz -lm -pthread -lgthread-2.0 -lrt -lglib-2.0 -ldl -lpthread -L/usr/local/src/CUBRID/lib -lcascci -lnsl

 
 

 
 
 
 
 
 
 
CFLAGS CXXFLAGS 변수에 헤더파일에 -I/usr/local/src/CUBRID/include”를 추가하고, LIBS 변수에
“-L/usr/local/src/CUBRID/lib -lcascci –lnsl” 옵션을 추합니다.
 
여기까지 CUBRID데이터베이스를 연동하여 Qt어플리케이션을 개발하는 방법에 대해 알아보았습니다.
CUBRID데이터베이스가 활성화 되길 바라며 여기서 이만 줄이도록하겠습니다.
 
허접해도 끝까지 읽어주셔서 갑니다. ^^;

Articles

1 2 3 4 5 6 7 8 9