2009/03/31

MySQL Connector/C++ 1.0.4 Beta Library

MySQL Connector/C++ 1.0.4 버전을 MySQL Connector/C++ 1.0.1 Alpha 컴파일 하기에 따라 라이브러리를 만들었다.



컴파일러는 Visual C++ 2005를 사용하였고 MySQL은 5.0.77버전을 사용하여 Win32용과 Win64용을 만들었다.


이번 버전은 컴파일을 하면 두개의 새로운 파일( config.h build_config.h )이 생기는데 Connector/C++ 을 포함한 프로젝트를 수행시 필요하다.


간단하게 테스트를 해 보았는데 동정라이브러니는 정상 동작을 하였는데 정적라이브러리는 링크에러가 발생하였다.






Visual SVN Server/Client 1.7 Released!!



Subversion 1.6 공개에 따라 VisualSVN 도 subversion 1.6을 포함하는 새로운 버전을 공개하였고, 홈페이지도 새 단장을 하였다.



Version 1.7 (March 24, 2009)


  • Updated to Subversion 1.6.

  • Updated to OpenSSL 0.9.8j.





VisualSVN 1.7 Release Notes

VisualSVN 1.7 Download


VisualSVN Server 1.7 Release Notes

VisualSVN Server 1.7 Download
Original Post :
http://neodreamer-dev.tistory.com/279

TortoiseSVN-1.6.0.15855 Released!!

What's New in TortoiseSVN 1.6


  • file:/// access to BDB repositories

  • handling of tree conflicts

  • log cache

  • revision graph

  • IBugtraq provider plugin enhancements

  • Misc changes

자세한 변경사항 보기



TortoriseSVN website

TortoiseSVN 1.6 Release Note
TortoiseSVN 1.6 Change Logs

Download : TortoiseSVN-1.6.0.15855-win32-svn-1.6.0.msi
Download : TortoiseSVN-1.6.0.15855-x64-svn-1.6.0.msi

Original Post : http://neodreamer-dev.tistory.com/278

Subversion 1.6 Released!!

What's New in Subversion 1.6


  • Improved handling of authentication data

  • Repository root relative URLs

  • Improvements to svn:externals

  • Detection of tree conflicts

  • Filesystem storage improvements

  • Ctypes Python Bindings

  • Improved interactive conflict resolution

  • Sparse directory exclusion

  • Logging support for svnserve

  • New public HTTP URI syntax for examining history

  • Command-line client improvements

  • API changes, improvements, and much language bindings work

  • More than 65 new bug fixes, enhancements



Subversion website
Subversion 1.6 Release Note
Original Post :
http://neodreamer-dev.tistory.com/277

MySQL Connector/C++ 1.04 beta 버전이 공개 되었다.

기나긴 Alpha 딱지를 떼고 Beta 딱지를 붙이고 나왔다.

공개된 일정데로라면 다음 버전인 1.05 버전에서 Beta 딱지도 떼고 정식이 된다.

이번 버전에서 바뀐 점은 아래와 같다. (출처: MySQL site)


  • Prepared support for upcoming Connector/C. (Georg)

  • Added Windows GUI (MSI) installer (Georg)

  • Bumping up CMake minimum version requirement from 2.4.2 to 2.6.2. We need the latest version for Windows. (Lawrin)

  • Added "metadataUseInfoSchema" to connection propery map which allows you to control the use of the INFORMATION_SCHEMA for meta data. (Andrey)

  • Fixed a bug in all implementations of ResultSet::relative() which was giving wrong return value although positioning was working correctly. (Andrey)

  • Fixed a leak in MySQL_PreparedResultSet when the result was containing a BLOB column. Andrey)

  • Implemented MySQL_ConnectionMetaData::supportsConvert(from, to). (Andrey)

  • Introduced sql::DataType::YEAR to complement MySQL's YEAR type. (Andrey)

  • Introduced PreparedStatement::getMetaData(). (Andrey)

  • Introduced ResultSetMetaData::isZerofill(), which is not in the JDBC specification. (Andrey)

  • Fixed all implementations of ResultSet::isNull() to check whether the current position is on a real row, not isBeforeFirst() nor isAfterLast(), like all getXXX methods do. (Andrey)

  • Implementation for MySQL_DatabaseMetaData::getProcedures() when INFORMATION_SCHEMA is asked not to be used. (Andrey)

  • Removed MySQL_DatabaseMetaData::getProcedureColumns() from the interface. Until now it was returning always an empty result set. Full implementation will be added at a later stage. (Andrey)

  • Changed a bunch of methods of DatabaseMetaData()::getXXX, which returned `int` to return `unsigned int` because it makes more sense. (Andrey)


이번 버전 부터는 윈도우즈 상에서 Installer 를 지원한다. 어떤 형식으로 설치가 되는지는 실험을 해 봐야겠다.

MySQL Connector/C++
MySQL Connector/C++ Download
Original Post :
http://neodreamer-dev.tistory.com/276

2009/03/30

윈도우가 보여지고 사라질때 에니메이션 효과 주기

AnimateWindow

윈도우에 효과를 주어 사라지고 등장하게 해 주는 API 이다.



함수 설명 ( 출처 : MSDN )

Syntax

BOOL AnimateWindow(
HWND hwnd,
DWORD dwTime,
DWORD dwFlags
);

Parameter 설명 보기



첫 번째 인자인 hwnd 는 효과를 적용하기위한 윈도우의 핸들이다.

두 번째 인자인 dwTime 은 지정된 효과를 수행할 시간으로 밀리세컨드 단위로 입력한다. 입력값이 작을 수록 에니메이션 효과의 시간이 짧아 지므로 에니메이션이 빠르게 동작한다.

세 번째 인자는 효과의 종류이다.


  • AW_SLIDE : 기본 인자로 에니메이션 효과를 의미하며 생략해도 슬리이딩 효과가 있는 것 같다. AW_CENTER 가 함께 적용되면 무시된다.

  • AW_ACTIVATE : 윈도우을 활성화 한다. AW_HIDE와 사용하지 않는다.

  • AW_BLEND : Fading 효과

  • AW_HIDE : 윈도우를 사라지게 한다.

  • AW_CENTER : 윈도우의 가운데 점을 기준으로 효과를 적용한다.

  • AW_HOR_POSITIVE : 윈도우를 좌에서 우로 사라지게 또는 보이게 함.

  • AW_HOR_NEGATIVE : 윈도우를 우에서 좌로 사라지게 또는 보이게 함.

  • AW_VER_POSITIVE : 윈도우를 위에서 아래로 사라지게 또는 보이게 함.

  • AW_VER_NEGATIVE : 윈도우를 아래에서 위로 사라지게 또는 보이게 함.


아래 소스는 이 글 위에 포함되어 있는 플래시를 만들면서 작성한 코드이다.

//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnBlendClick(TObject *Sender)
{
// Blending
AnimateWindow( Handle, 1000, AW_HIDE | AW_BLEND );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_BLEND );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnCenterClick(TObject *Sender)
{
// Center
AnimateWindow( Handle, 1000, AW_HIDE | AW_CENTER );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_CENTER );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnHPosClick(TObject *Sender)
{
// Horizontal Positive
AnimateWindow( Handle, 1000, AW_HIDE | AW_HOR_POSITIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_HOR_POSITIVE );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnHNegClick(TObject *Sender)
{
// Horizontal Negative
AnimateWindow( Handle, 1000, AW_HIDE | AW_HOR_NEGATIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_HOR_NEGATIVE );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnVPosClick(TObject *Sender)
{
// Vertical Positive
AnimateWindow( Handle, 1000, AW_HIDE | AW_VER_POSITIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_VER_POSITIVE );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnVNegClick(TObject *Sender)
{
// Vertical Negative
AnimateWindow( Handle, 1000, AW_HIDE | AW_VER_NEGATIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_VER_NEGATIVE );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnHPosVPosClick(TObject *Sender)
{
AnimateWindow( Handle, 1000, AW_HIDE | AW_HOR_POSITIVE | AW_VER_POSITIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_HOR_POSITIVE | AW_VER_POSITIVE );
}
//---------------------------------------------------------------------------
void __fastcall TfrmMain::btnHNegVNegClick(TObject *Sender)
{
AnimateWindow( Handle, 1000, AW_HIDE | AW_HOR_NEGATIVE | AW_VER_NEGATIVE );
Sleep(1000);
AnimateWindow( Handle, 1000, AW_SLIDE | AW_HOR_NEGATIVE | AW_VER_NEGATIVE );
}
//---------------------------------------------------------------------------



Original Post : http://neodreamer-dev.tistory.com/275

2009/03/23

OpenGL 로 간단하게 2D Drawing 하는 기본 소스

OpenGL 로 간단하게 2D 드로잉 하는 걸 공부하고 있는데 진도가 느리다.



아래 소스는 Visual C++ 에서 OpenGL을 이용하여 간단하게 2D 드로잉을 하는 기본 소스이다.



// stdafx.h
////////////////////////////////////////////////////////////////////////////////
// for OpenGL
#pragma comment (lib, "opengl32.lib")
#pragma comment (lib, "glu32.lib")
#pragma comment (lib, "glaux.lib")

#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/GLAux.h>
// for OpenGL
////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////
// Header
HGLRC m_hRC; //Rendering Context
CDC* m_pDC; //Device Context
int m_nPixelFormat;

BOOL InitializeOpenGL();
void RenderScene();


////////////////////////////////////////////////////////////////////////////////
// Source
int CGLTestView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;

InitializeOpenGL();

return 0;
}

BOOL CGLTestView::InitializeOpenGL()
{
//Get a DC for the Client Area
m_pDC = new CClientDC(this);

//Failure to Get DC
if(m_pDC == NULL)
{
MessageBox( _T("Error Obtaining DC") );
return FALSE;
}

////////////////////////////////////////////////////////////////////////////////
// Setup Pixel Format
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
32, // color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accumulation bits ignored
32, // z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};

int m_nPixelFormat = ::ChoosePixelFormat( m_pDC->GetSafeHdc(), &pfd );

if ( m_nPixelFormat == 0 )
{
return FALSE;
}

if ( ::SetPixelFormat( m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd ) == FALSE )
{
return FALSE;
}
////////////////////////////////////////////////////////////////////////////////

//Create Rendering Context
m_hRC = ::wglCreateContext( m_pDC->GetSafeHdc() );

//Failure to Create Rendering Context
if( m_hRC == 0 )
{
MessageBox( _T("Error Creating RC") );
return FALSE;
}

//Make the RC Current
if( ::wglMakeCurrent ( m_pDC->GetSafeHdc (), m_hRC ) == FALSE )
{
MessageBox( _T("Error making RC Current") );
return FALSE;
}

//Specify Black as the clear color
::glClearColor( 0.0f, 0.0f, 0.0f, 0.0f);

//Specify the back of the buffer as clear depth
//::glClearDepth( 1.0f );

//Enable Depth Testing
//::glEnable( GL_DEPTH_TEST );
::glDisable( GL_DEPTH_TEST ); // For 2D

return TRUE;
}

void CGLTestView::OnDraw(CDC* /*pDC*/)
{
CGLTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// 컬러버퍼와 깊이버퍼를 초기화
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

RenderScene();

// Tell OpenGL to flush its pipeline
::glFinish();

// Now Swap the buffers
::SwapBuffers( m_pDC->GetSafeHdc() );
}

void CGLTestView::RenderScene()
{
glBegin(GL_TRIANGLES);
{
glVertex2f( 0.0f, 0.0f );
glVertex2f( 20.0f, 0.0f );
glVertex2f( 0.0f, 20.0f );
}
glEnd();
}

void CGLTestView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);

GLdouble aspect_ratio; // width/height ratio

if ( 0 >= cx || 0 >= cy )
{
return;
}

// select the full client area
::glViewport(0, 0, cx, cy);

// compute the aspect ratio
// this will keep all dimension scales equal
aspect_ratio = (GLdouble)cx/(GLdouble)cy;

// select the projection matrix and clear it
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();

// select the viewing volume
//::gluPerspective(45.0f, aspect_ratio, .01f, 200.0f);

GLfloat nRange = 50.0f;
if (cx <= cy)
{
glOrtho(-nRange, nRange, -nRange * cy / cx,
nRange * cy / cx, -nRange, nRange );
}
else
{
glOrtho(-nRange * cx / cy,
nRange * cx / cy,
-nRange, nRange, -nRange, nRange);
}

// switch back to the modelview matrix and clear it
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();
}




결과 화면

결과 화면



glut를 사용하지 않고 기본으로 포함되어있는 OpenGL 만을 이용한 소스이다. 분석을 하여 나중에는 glut까지 이용하는 코드를 작성해 보아야겠다.


SQLite 64비트에서 테스트...

직접 만든 SQLite 64비트용 정적라이브러리가 정상 동작을 하는지 테스트 해 보았다.

컴파일과 링크에서 경고 메세지가 나오기는 하지만 동작은 하였다.

아래 코드는 테스트에 사용한 코드이다.
이전에 C++Builder 에서 테스트한 코드와 크게 다르지 않다.


void CSQLiteTestView::OnSqliteTest()
{
sqlite3* pSQLite3 = NULL;
sqlite3_stmt* pStmt = NULL;
char* szErrMsg = NULL;
const char* szErr;

CString strMsg;

// Open Database
int rst = sqlite3_open( "test.db", &pSQLite3 );

TRACE( L"Test Start...\n" );

if ( rst )
{
strMsg.Format( L" Can't open database: %s\n",
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}
else
{
TRACE( L" Database (test.db) Opened...\n" );

std::string strQuery;

// 테이블 생성
strQuery = "CREATE TABLE IF NOT EXISTS TestTable ("
" name VARCHAR(20)"
" ,age int"
" ,country VARCHAR(20)"
")";
rst = sqlite3_exec(pSQLite3, strQuery.c_str(), NULL, 0, &szErrMsg);

if ( rst == SQLITE_OK )
{
TRACE( L" Test Table Created... OK\n" );
}
else
{
TRACE( L" Test Table Created... FAILE\n" );

strMsg.Format( L" Error %d : %s",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

// Inserting...
TRACE( L" Inserting... \n" );
strQuery = "INSERT INTO TestTable ( name, age, country) VALUES ( ?, ?, ? );";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(),
(int)strQuery.size(), &pStmt, &szErr ) == SQLITE_OK )
{
for ( int i = 0; i < 10; ++i )
{
CStringA str;

std::string strName;
str.Format( "name%d", i );

strName = str;

sqlite3_bind_text( pStmt, 1, strName.c_str(),
(int)strName.size(), NULL );
sqlite3_bind_int( pStmt, 2, i );

std::string strCountry;
sqlite3_bind_text( pStmt, 3, strCountry.c_str(),
(int)strCountry.size(), NULL );

sqlite3_step( pStmt );

INT64 nLast = sqlite3_last_insert_rowid( pSQLite3 );

strMsg.Format( L" Inserted... OK (%d)\n", nLast );
TRACE( strMsg );

sqlite3_reset( pStmt );
}

sqlite3_finalize( pStmt );
}
else
{
TRACE( L" Inserting... FAILE\n" );

strMsg.Format( L" Error %d : %s",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

TRACE( L" Selecting... \n" );
strQuery = "SELECT COUNT(*) FROM TestTable;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(),
(int)strQuery.size(), &pStmt, &szErr ) == SQLITE_OK )
{
int nRow = sqlite3_data_count( pStmt );
int nCol = sqlite3_column_count( pStmt );

const char* col1name = sqlite3_column_name( pStmt, 0 );

int nRowCnt = 0;
while ( sqlite3_step( pStmt ) == SQLITE_ROW )
{
++nRowCnt;

int Count = sqlite3_column_int( pStmt, 0 );

strMsg.Format( L" Row Count ... %d\n", Count );
TRACE( strMsg );
}
}
else
{
TRACE( L" Selecting... FAILE\n" );

strMsg.Format( L" Error %d : %s",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

// Updating...
TRACE( L" Updating... \n" );
strQuery = "UPDATE TestTable SET country = :country WHERE age < :age;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(),
(int)strQuery.size(), &pStmt, &szErr ) == SQLITE_OK )
{
sqlite3_bind_text( pStmt, 1, "KOREA", 5, NULL );
sqlite3_bind_int( pStmt, 2, 5 );

sqlite3_step( pStmt );
int nUpdated = sqlite3_changes( pSQLite3 );

strMsg.Format( L" Updated... %d Rows\n", nUpdated );
TRACE( strMsg );
}
else
{
TRACE( L" Updating... FAILE\n" );

strMsg.Format( L" Error %d : %s",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

// Deleting...
TRACE( L" Deleting... \n" );
strQuery = "DELETE FROM TestTable WHERE age < :age;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(),
(int)strQuery.size(), &pStmt, &szErr ) == SQLITE_OK )
{
sqlite3_bind_int( pStmt, 1, 2 );

sqlite3_step( pStmt );
int nUpdated = sqlite3_changes( pSQLite3 );

strMsg.Format( L" Deleted... %d Rows\n", nUpdated );
TRACE( strMsg );
}
else
{
TRACE( L" Updating... FAILE\n" );

strMsg.Format( L" Error %d : %s",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

// 테이블 삭제
strQuery = "DROP TABLE IF EXISTS TestTable;";
rst = sqlite3_exec(pSQLite3, strQuery.c_str(), NULL, 0, &szErrMsg);

if ( rst == SQLITE_OK )
{
TRACE( L" Test Table Deleted... OK\n" );
}
else
{
TRACE( L" Test Table Deleted... FAILE\n" );

strMsg.Format( L" Error %d : %s\n",
sqlite3_errcode( pSQLite3 ),
sqlite3_errmsg16( pSQLite3 ) );
TRACE( strMsg );
}

sqlite3_close( pSQLite3 );
TRACE( L" Database (test.db) Closed...\n" );

pSQLite3 = NULL;
}

TRACE( L"Test End...\n" );
}

// 결과
Test Start...
Database (test.db) Opened...
Test Table Created... OK
Inserting...
Inserted... OK (1)
Inserted... OK (2)
Inserted... OK (3)
Inserted... OK (4)
Inserted... OK (5)
Inserted... OK (6)
Inserted... OK (7)
Inserted... OK (8)
Inserted... OK (9)
Inserted... OK (10)
Selecting...
Row Count ... 10
Updating...
Updated... 5 Rows
Deleting...
Deleted... 2 Rows
Test Table Deleted... OK
Database (test.db) Closed...
Test End...



테스트에 사용 된 라이브러는 SQLite 3.6.11 버전 소스를 갖고 만든 32비트 용과 64비트용 정적라이브러리를 사용하였다. 두 버전 모두 정상 동작을 하였다

Original Post : http://neodreamer-dev.tistory.com/273

SQLite 테스트...

64bit SQLite 라이브러리를 테스트 하려고 했는데 잘 되지 않아서 우선 32bit 라이브러리를 테스트 해 보았다.

동적 라이브러리와 정적 라이브러리를 테스트 해 보았는데 문제가 없었다.

아래는 C++ Builder 에서 테스트한 소스이다.


#include "SQLite3.h"

#pragma link "sqlite3.lib"
//#pragma link "SQLite_Static.lib"

void TfrmMain::Test()
{
sqlite3* pSQLite3 = NULL;
sqlite3_stmt* pStmt = NULL;
char* szErrMsg = NULL;
const char* szErr;

String strMsg;

// Open Database
int rst = sqlite3_open( "test.db", &pSQLite3 );

memProc->Lines->Clear();
memProc->Lines->Append( L"Test Start...\n" );

if ( rst )
{
strMsg.sprintf( L" Can't open database: %s\n", sqlite3_errmsg( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}
else
{
memProc->Lines->Append( L" Database (test.db) Opened...\n" );

AnsiString strQuery;

// 테이블 생성
strQuery = "CREATE TABLE IF NOT EXISTS TestTable ("
" name VARCHAR(20)"
" ,age int"
" ,country VARCHAR(20)"
")";
rst = sqlite3_exec(pSQLite3, strQuery.c_str(), NULL, 0, &szErrMsg);

if ( rst == SQLITE_OK )
{
memProc->Lines->Append( L" Test Table Created... OK\n" );
}
else
{
memProc->Lines->Append( L" Test Table Created... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

// Inserting...
memProc->Lines->Append( L" Inserting... \n" );
strQuery = "INSERT INTO TestTable ( name, age, country) VALUES ( ?, ?, ? );";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(), strQuery.Length(), &pStmt, &szErr ) == SQLITE_OK )
{
for ( int i = 0; i < 10; ++i )
{
AnsiString strName;
strName.sprintf( "name%d", i );

sqlite3_bind_text( pStmt, 1, strName.c_str(), strName.Length(), NULL );
sqlite3_bind_int( pStmt, 2, i );

AnsiString strCountry;
sqlite3_bind_text( pStmt, 3, strCountry.c_str(), strCountry.Length(), NULL );

sqlite3_step( pStmt );

int nLast = sqlite3_last_insert_rowid( pSQLite3 );

strMsg.sprintf( L" Inserted... OK (%d)\n", nLast );
memProc->Lines->Append( strMsg );

sqlite3_reset( pStmt );
}

sqlite3_finalize( pStmt );
}
else
{
memProc->Lines->Append( L" Inserting... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

memProc->Lines->Append( L" Selecting... \n" );
strQuery = "SELECT COUNT(*) FROM TestTable;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(), strQuery.Length(), &pStmt, &szErr ) == SQLITE_OK )
{
int nRow = sqlite3_data_count( pStmt );
int nCol = sqlite3_column_count( pStmt );

const char* col1name = sqlite3_column_name( pStmt, 0 );

int nRowCnt = 0;
while ( sqlite3_step( pStmt ) == SQLITE_ROW )
{
++nRowCnt;

int Count = sqlite3_column_int( pStmt, 0 );

strMsg.sprintf( L" Row Count ... %d\n", Count );
memProc->Lines->Append( strMsg );
}
}
else
{
memProc->Lines->Append( L" Selecting... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

// Updating...
memProc->Lines->Append( L" Updating... \n" );
strQuery = "UPDATE TestTable SET country = :country WHERE age < :age;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(), strQuery.Length(), &pStmt, &szErr ) == SQLITE_OK )
{
sqlite3_bind_text( pStmt, 1, "KOREA", 5, NULL );
sqlite3_bind_int( pStmt, 2, 5 );

sqlite3_step( pStmt );
int nUpdated = sqlite3_changes( pSQLite3 );

strMsg.sprintf( L" Updated... %d Rows", nUpdated );
memProc->Lines->Append( strMsg );
}
else
{
memProc->Lines->Append( L" Updating... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

// Deleting...
memProc->Lines->Append( L" Deleting... \n" );
strQuery = "DELETE FROM TestTable WHERE age < :age;";
if ( sqlite3_prepare_v2( pSQLite3, strQuery.c_str(), strQuery.Length(), &pStmt, &szErr ) == SQLITE_OK )
{
sqlite3_bind_int( pStmt, 1, 2 );

sqlite3_step( pStmt );
int nUpdated = sqlite3_changes( pSQLite3 );

strMsg.sprintf( L" Deleted... %d Rows", nUpdated );
memProc->Lines->Append( strMsg );
}
else
{
memProc->Lines->Append( L" Updating... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

// 테이블 삭제
strQuery = "DROP TABLE IF EXISTS TestTable;";
rst = sqlite3_exec(pSQLite3, strQuery.c_str(), NULL, 0, &szErrMsg);

if ( rst == SQLITE_OK )
{
memProc->Lines->Append( L" Test Table Deleted... OK\n" );
}
else
{
memProc->Lines->Append( L" Test Table Deleted... FAILE\n" );

strMsg.sprintf( L" Error %d : %s", sqlite3_errcode( pSQLite3 ), sqlite3_errmsg16( pSQLite3 ) );
memProc->Lines->Append( strMsg );
}

sqlite3_close( pSQLite3 );
memProc->Lines->Append( L" Database (test.db) Closed...\n" );

pSQLite3 = NULL;
}

memProc->Lines->Append( L"Test End...\n" );
}
//---------------------------------------------------------------------------

// Output
Test Start...
Database (test.db) Opened...
Test Table Created... OK
Inserting...
Inserted... OK (1)
Inserted... OK (2)
Inserted... OK (3)
Inserted... OK (4)
Inserted... OK (5)
Inserted... OK (6)
Inserted... OK (7)
Inserted... OK (8)
Inserted... OK (9)
Inserted... OK (10)
Selecting...
Row Count ... 10
Updating...
Updated... 5 Rows
Deleting...
Deleted... 2 Rows
Test Table Deleted... OK
Database (test.db) Closed...
Test End...


위의 테스트 소스로 64bit 에서도 테스트를 해 보아야겠다.

테스트 프로젝트

2009/03/18

무료 SVN Server - VisualSVN Server 1.6.4 Released





이번 버전에서 바뀐 내용
Version 1.6.4 (March 16, 2009)



  • New VisualSVNServerHooks parameters: smtp-port, smtp-user, smtp-password and smtp-ssl are added.

  • mod_log_config Apache module is included into the installation package.

  • Updated to Subversion 1.5.6. For further details please see:

    http://svn.collab.net/repos/svn/tags/1.5.6/CHANGES



2008/06/19 - [Dev Story/Tips] - 그림으로 보는 간단한 개발서버 구축하기

2008/06/19 - [Dev Story/Tips] - VisualSVN Server 와 TortoiseSVN을 이용하기

VisualSVN Official website
VisualSVN Server page
VisualSVN Server Download

Original Post :
http://neodreamer-dev.tistory.com/271

2009/03/17

코드로 라이브러리 파일 포함시키기

C++ Builder 든 Visual C++ 이든 프로젝트 옵션에서 라이브러리를 포함시킬 수 있다. 프로젝트 옵션에 추가하는 방법 외에 코드로 추가하려면 #pragma 의사코드를 사용하면 된다.

#pragma link "xxx.lib"

//또는
#pragma comment ( "lib", "xxx.lib" )


위의 두 #pragma 구문은 같은 의미 이며, #pragma link 는 C++ Builder 에서만 동작을하고 #pragma comment 는 두 컴파일러 모두에서 동작을 한다.

프록젝트 옵션에 라이브러리를 추가하는 방법보다 위처럼 코드로 추가를 하면 빌드 타입에 따라 어떤 라이브러리가 링크가 되는지 쉽게 파악할 수 있다.

#ifdef _DEBUG
#pragma comment ( lib, "A_debug.lib" );
#pragma comment ( lib, "B_debug.lib" );
#pragma comment ( lib, "C_debug.lib" );
#else // _DEBUG
#pragma comment ( lib, "A_release.lib" );
#pragma comment ( lib, "B_release.lib" );
#pragma comment ( lib, "C_release.lib" );
#endif // _DEBUG


Original Post : http://neodreamer-dev.tistory.com/270

2009/03/12

C++ Builder 에서 OpenGL을 사용하기 위한 기본 뼈대

원문 주소 : http://edn.embarcadero.com/article/10528

C++ Builder 의 TForm 위에 OpenGL을 드로잉하기 위한 기본적인 뼈대 이다. C++ Builder 에서 OpenGL을 사용하기 위한 방법을 찾다가 발견한 정보이다.


/////////////////////////////////////////////////////////////////////////////
//glskeleton.h
/////////////////////////////////////////////////////////////////////////////

//---------------------------------------------------------------------------
#include <vcl/vcl.h>

//---------------------------------------------------------------------------
#ifndef GLSkeletonH
#define GLSkeletonH
//---------------------------------------------------------------------------
#include <vcl/Classes.hpp>
#include <vcl/Controls.hpp>
#include <vcl/StdCtrls.hpp>
#include <vcl/Forms.hpp>
#include <gl/gl.h>
#include <gl/glu.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
published: // IDE-managed Components
void __fastcall FormCreate(TObject *Sender);
void __fastcall FormDestroy(TObject *Sender);
void __fastcall FormResize(TObject *Sender);
void __fastcall FormPaint(TObject *Sender);
private: // User declarations
HDC hdc;
HGLRC hrc;
int PixelFormat;
public: // User declarations
fastcall TForm1(TComponent* Owner);
void __fastcall IdleLoop(TObject*, bool&);
void __fastcall RenderGLScene();
void __fastcall SetPixelFormatDescriptor();
};



/////////////////////////////////////////////////////////////////////////////
// glskeleton.cpp
/////////////////////////////////////////////////////////////////////////////

//---------------------------------------------------------------------------
extern TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

//---------------------------------------------------------------------------
#include <vcl/vcl.h>
#pragma hdrstop

#include "GLSkeleton.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"

TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
Application->OnIdle = IdleLoop;
_control87(MCW_EM, MCW_EM);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdleLoop(TObject*, bool& done)
{
done = false;
RenderGLScene();
SwapBuffers(hdc);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::RenderGLScene()
{
//Place your OpenGL drawing code here
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
hdc = GetDC(Handle);
SetPixelFormatDescriptor();
hrc = wglCreateContext(hdc);
wglMakeCurrent(hdc, hrc);
SetupRC();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SetupRC()
{
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormDestroy(TObject *Sender)
{
ReleaseDC(hdc);
wglMakeCurrent(hdc, NULL);
wglDeleteContext(hrc);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::SetPixelFormatDescriptor()
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,0,
0,0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
PixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, PixelFormat, &pfd);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormResize(TObject *Sender)
{
GLfloat nRange = 200.0f;
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();


if (ClientWidth <= ClientHeight)
glOrtho(-nRange, nRange, -nRange*ClientHeight/ClientWidth,
nRange*ClientHeight/ClientWidth, -nRange, nRange);
else
glOrtho(-nRange*ClientWidth/ClientHeight, nRange*ClientWidth/ClientHeight,
-nRange, nRange, -nRange, nRange);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
//---------------------------------------------------------------------------

Original Post : http://neodreamer-dev.tistory.com/269

Visual Studio에서 사용되는 확장자와 설명

윈도우즈 프로그램에서 사용되는 파일 확장자에 대한 설명


  • C

    C언어 소스 파일. C방식으로 컴파일된다. 만약 소스내에 C++코드가 있다면 확장자를 CPP로 변경하거나 컴파일시 옵션을 /TP로 설정한다.



  • CPP(또는 CXX)

    C++언어 소스파일. C++방식으로 컴파일된다. 만약 확장자만 CPP이고 실제 내용이 C코드이면 확장자를 C로 변경하거나 컴파일시 옵션을 /Tc로 설정한다.



  • H(또는 HPP, HXX)

    헤더 파일. 이 파일은 함수의 원형선언, 클래스 정의, 상수정의를 위해 사용된다.



  • INL

    인라인 함수 파일. 이 파일에는 인라인 함수가 정의된다.



  • RC와 RC2

    RC는 리소스 파일을 말하며 리소스 컴파일러(RC.EXE)에 의해 컴파일된다. 다이얼로그, 아이콘, 메뉴, 커서 등과 같은 리소스에 대한 정보가 기술되어 있다. RC2 또한 리소스에 대한 정보가 포함된다.



  • DEF

    모 듈 정의 파일(Module definition file). 프로젝트 유형에 따라 사용목적이 다른데 윈도우즈 또는 윈도우즈 NT 기반의 프로그램인 경우 익스포트되는 함수의 리스트, 힙(Hea p)크기, 세그먼트 속성 등을 지정한다.





Developer Studio가 생성하는 파일들에 대한 목록


  • APS

    리소스 파일에 대한 바이너리 파일. App Studio에서 리소스 파일을 로딩하는데 사용된다.(로딩 속도 향상)



  • BSC

    소스 브라우저 정보 파일(Browser database file). 이 파일은 BSCMAKER.EXE를 실행할 때 SBR파일로부터 생성된다.



  • CLW

    클래스위저드 상태 파일. 클래스위저드를 사용하여 추가되는 메시지 핸들링 함수 등과 관련된 정보들이 포함된다.



  • DSP

    메이크 파일(MAK)과 동일한 목적의 파일로 VC++5.0에서 사용한다.



  • DSW

    워크스페이스 파일. 워크스페이스내의 각 프로젝트에 대한 엔트리 정보를 포함한 파일



  • PCH

    프리컴파일 헤더 파일 (Precompiled header file). 이 파일은 컴파일 속도를 향상시키며 컴파일 옵션/Yc, /Yu 또는 /YX를 사용할 때 생성된다.



  • PDB

    프로그램 정보 파일(Program database file). 이 바이너리 파일은 컴파일링, 링킹 과정을 통해 얻어지는 디버깅 정보를 포함한다.



  • SBR

    소스 브라우저 파일(Source browser file). 이 파일은 소스 파일에 대한 상세한 정보들이 포함된다.



  • WSP

    Workspace information file(16비트 버전)은 통합 개발 환경이 종료될때의 상태 정보를 포함한다.



  • VCP

    Workspace information file(VC++ 2.X버전 또는 이후버전)은 통합개발 환경이 종료될 때의 상태 정보를 포함한다.



  • EXP

    익스포트 파일 (Export file). 익스포트되는 힘수와 데이터 정보를 포함한다.



  • MAP

    맵 파일(Map file). 프로그램의 엔트리 포인트, 심볼이름, 시작 주소, 프로그램에 링크된 정보를 포함한다.



  • RES

    리소스 파일(RC)이 컴파일된 바이너리 파일



  • HPJ

    문맥 감지형 도움말 파일(Context-sensitive help project file). AppWizard 단계 4 에서 [Context-sensitive help]를 체크하면 자동 생성된다.



  • NCB

    Parser information file. 이 파일은 클래스뷰와 컴포넌트 갤러리를 지원하기 위한 정보를 포함한다.



  • MDP

    Microsoft Developer Studio file. 이 파일은 VC++ 2.X 버전에서 사용한 VCP파일을 대체한다.



  • RCT

    리소스 템플릿 파일 (Resource template file)



  • OPT

    워크스페이스 환경설정을 보유



  • PLG

    빌드 로그 파일




[출처] 비주얼 C++ VC 확장자들 설명|작성자

Original Post :
http://neodreamer-dev.tistory.com/268

2009/03/07

[STL] std::string 대소문자 바꾸기

std::string 의 문자열을 대소문자 변환이 필요해 찾아보았는데 쉽게 처리할 수 있는 방법을 찾았다.

std::transform 함와 cctype 헤더의 tolower() 와 toupper() 함수를 이용하면 쉽게 해결이 되었다.

transform 함수는 이외에도 응용할 부분이 많아보인다. container 의 각 원소에 특정을 변형을 주어
바꾸거나 다는 container에 넣을 수도 있다. transform 함수에 대해서는 좀더 공부를 해서 나중에 포스팅을 한번 해야겠다.

#include <cctype> // for toupper & tolower
#include <string>
#include <algorithm>
using namespace std;


// 대문자로 바꾸기
string s1 = "sample string";
transform( s1.begin(), s1.end(), s1.begin(), toupper );
// 결과 : s1 "SAMPLE STRING"

// 소문자로 바꾸기
string s2 = "HELLO";
transform( s2.begin(), s2.end(), s2.begin(), tolower );
// 결과 : s2 "hello"


// 첫 문자만 대문자로 바꾸기
string s3 = "title";
transform( s3.begin(), s3.begin() + 1, s3.begin(), toupper );
// 결과 : s3 "Title"

Original Post : http://neodreamer-dev.tistory.com/267

2009/03/05

IDE Fix Pack 2009 2.5 Released!!

Rad Studio 2007/2009 의 IDE 버그를 패치하는 IDE Fix Pack 이 2.5 버전을 공개 하였다.







  • QC #47807: Error insight fails to find TObject class

  • Possible deadlock when Error Insight calls ProcessMessages

  • Error Insight defines VER190 instead of VER200

  • QC #37462: IDE may select the wrong file when performing a ctrl + left-click on a filename in the editor

  • QC #67351: Debugger invokes anonymous method by itself

  • QC #22880: Cannot resolve unit name

  • QC #58045: Component captions and component icons disappear from form designer

  • QC #50278: IDE Compiler opens all files in ReadWrite mode and blocks command line compiler

  • QC #69456: IDE dead lock when updating the editors

  • QC #55910: TDBText.Color always reverts to Parent.Color

  • QC #68647: Infinite loop in Forms.GetNonToolWindowPopupParent

  • QC #68740: Lost focus after TOpenDialog when MainFormOnTaskBar is set

  • QC #59963: Closing non-modal forms after a task switch can deactivate the application

  • QC #66892: Closing forms deactivates the application (missing “stdcall”)

  • QC #64484: SysUtils.Abort can raise an AccessViolation

  • QC #56252: TPageControl flickers a lot with active theming

  • QC #68730: TLabel is not painted on a themed, double-buffered TTabSheet in Vista



IDE Fix Pack 2009 2.5
Original Post :
http://neodreamer-dev.tistory.com/265

UTF8 문자열을 std::string 이나 CString 으로 변환하기

다국어 프로그래밍에서 RapidXML 을 이용하다가 필요하여 만들어 본 문자열 변환 함수 이다.



////////////////////////////////////////////////////////////////
// UTF8 문자열은 std::string 으로 변환하기
void CMultiLang::UTF82A( IN const char* utf8, OUT string& ansi )
{
int length = MultiByteToWideChar( CP_UTF8, 0, utf8, (int)strlen(utf8) + 1, NULL, NULL );
wchar_t* pBuf = new wchar_t[ length + 1 ];

MultiByteToWideChar( CP_UTF8, 0, utf8, (int)strlen(utf8) + 1, pBuf, length );

pBuf[length] = 0;
ansi = CStringA( pBuf );

delete [] pBuf;
}

////////////////////////////////////////////////////////////////
// UTF8 문자열은 CString 으로 변환하기
void CMultiLang::UTF82T( IN const char* utf8, OUT CString& out )
{
int length = MultiByteToWideChar( CP_UTF8, 0, utf8, (int)strlen(utf8) + 1, NULL, NULL );
wchar_t* pBuf = new wchar_t[ length + 1 ];

MultiByteToWideChar( CP_UTF8, 0, utf8, (int)strlen(utf8) + 1, pBuf, length );

pBuf[length] = 0;
out = CString( pBuf );

delete [] pBuf;
}

Original Post : http://neodreamer-dev.tistory.com/264

2009/03/04

Num Lock, Caps Lock, Scroll Lock 상태 알아내기

    bool bScrollLock = (bool)( ::GetKeyState(VK_SCROLL)  > 0 );
bool bNumLock = (bool)( ::GetKeyState(VK_NUMLOCK) > 0 );
bool bCapsLock = (bool)( ::GetKeyState(VK_CAPITAL) > 0 );

Original Post : http://neodreamer-dev.tistory.com/263

MySQL Connector/C++ 1.0.3 Alpha Library

3월 3일자로 발표된 MySQL Connector/C++ 1.0.3 을 오래전에 소개한 MySQL Connector/C++ 1.0.1 Alpha 컴파일 하기에 따라 라이브러리를 만들었다.



컴파일러는 Visual C++ 2005를 사용하였고 MySQL은 5.0.77버전을 사용하여 Win32용과 Win64용을 만들어 보았다.



오랜만에 버전업이 되어 보다 안정적이 된 것 같다. 이번 버전은 컴파일러 환경에 따라 config.h 파일의 내용이 약간 바뀌므로 아래 첨부된 라이브러리를 사용하기 위해서는 함께 첨부된 include.7z 을 이용해야한다.













위 라이브러리들은 아래의 코드로 테스트를 수행하였다.



try
{
TRACE("Test Begin!!\n");

std::string strQuery;

// Driver 인스턴스 가져오기
sql::Driver* pDriver = sql::mysql::MySQL_Driver::Instance();
//sql::Driver* pDriver = sql::mysql::get_mysql_driver_instance();

if ( pDriver )
{
sql::Connection* pConn = pDriver->connect( "127.0.0.1", "root", "");
TRACE("Database Connected!!\n");

if ( pConn )
{
sql::PreparedStatement *pPreStmt;
sql::ResultSet *res = NULL;

////////////////////////////////////////
// Statement 생성
sql::Statement *pStmt = pConn->createStatement();

////////////////////////////////////////
// 데이터베이스 생성
pStmt->execute( "CREATE DATABASE IF NOT EXISTS TESTDB" );
TRACE("Database Created!!\n");

pStmt->execute( "USE TESTDB" );
TRACE("Select Database!!\n");

////////////////////////////////////////
// Table 생성
pStmt->execute( "DROP TABLE IF EXISTS TestTable" );
strQuery = "CREATE TABLE TestTable "
"( "
" name VARCHAR(30),"
" age INT,"
" big BIGINT"
")";
pStmt->execute( strQuery );
TRACE(" Table Created!!\n");

////////////////////////////////////////
// Insert
strQuery = "INSERT INTO TestTable ( name, age, big )"
" VALUES ( 'tester', 20, 0 );";
pStmt->execute( strQuery );
TRACE(" Insert!!\n");

////////////////////////////////////////
// Select
strQuery = "SELECT name, age FROM TestTable";
res = pStmt->executeQuery( strQuery );

TRACE(" Select Begin!!\n");
while( res->next() )
{
std::string name = res->getString( "name" );
int age = res->getInt( "age" );

CString strResult;
strResult.Format( _T(" name:%s, age:%d\n"),
CString( name.c_str()), age );
TRACE( strResult );
}
TRACE(" Select End!!\n");

delete res;

////////////////////////////////////////
// Update
strQuery = "UPDATE TestTable SET age = 25"
" WHERE name = 'tester';";
int rows = pStmt->executeUpdate( strQuery );
TRACE1(" Update (%d rows)!!\n", rows );

////////////////////////////////////////
// Select
strQuery = "SELECT name, age FROM TestTable ";
res = pStmt->executeQuery( strQuery );

TRACE(" Select Begin!!\n");
while( res->next() )
{
std::string name = res->getString( "name" );
int age = res->getInt( "age" );

CString strResult;
strResult.Format( _T(" name:%s, age:%d\n"),
CString( name.c_str()), age );
TRACE( strResult );
}
TRACE(" Select End!!\n");

delete res;

////////////////////////////////////////
// Delete
strQuery = "DELETE FROM TestTable";
rows = pStmt->executeUpdate( strQuery );
TRACE1(" Delete (%d rows)!!\n", rows );

////////////////////////////////////////
// PreprareStatement Insert
strQuery = "INSERT INTO TestTable ( name, age, big ) "
"VALUES ( ?, ?, ? );";
pPreStmt = pConn->prepareStatement( strQuery );

char name[100];

for ( int i = 0; i < 10; ++i )
{
sprintf_s( name, 100, "name%03d\0", i );

// 데이터 바인딩
pPreStmt->setString( 1, name );
pPreStmt->setInt( 2, 20 + i );
pPreStmt->setInt64( 3, 202012014 );

// Prepared Statement 수행
pPreStmt->executeUpdate();
TRACE(" PrepareStatement Insert!!\n");
}

// Statement 삭제
delete pPreStmt;

////////////////////////////////////////
// Select
strQuery = "SELECT name, age, big FROM TestTable ";
res = pStmt->executeQuery( strQuery );

TRACE(" Select Begin!!\n");
while( res->next() )
{
std::string name = res->getString( "name" );
int age = res->getInt( "age" );
int64_t big = res->getInt64( "big" );

CString strResult;
strResult.Format( _T(" name:%s, age:%d, big:%d\n"),
CString( name.c_str()), age, big );
TRACE( strResult );
}
TRACE(" Select End!!\n");

delete res;

////////////////////////////////////////
// PreprareStatment Update
strQuery = "UPDATE TestTable SET age = ? WHERE name = ?;";
pPreStmt = pConn->prepareStatement( strQuery );

for ( int i = 0; i < 10; ++i )
{
sprintf_s( name, 100, "name%03d\0", i );

// 데이터 바인딩
pPreStmt->setInt( 1, 30 + i );
pPreStmt->setString( 2, name );


// Prepared Statement 수행
pPreStmt->executeUpdate();
TRACE(" PrepareStatement Update!!\n");
}

// Statement 삭제
delete pPreStmt;

////////////////////////////////////////
// Select
strQuery = "SELECT name, age, big FROM TestTable ";
res = pStmt->executeQuery( strQuery );

TRACE(" Select Begin!!\n");
while( res->next() )
{
std::string name = res->getString( "name" );
int age = res->getInt( "age" );
INT64 big = res->getInt64( "big" );

CString strResult;
strResult.Format( _T(" name:%s, age:%d, big:%d\n"),
CString( name.c_str()), age, big );
TRACE( strResult );
}
TRACE(" Select End!!\n");

delete res;

// 데이터베이스 삭제
pStmt->execute( "DROP DATABASE IF EXISTS TESTDB" );
TRACE("Drop Database\n");

delete pStmt;
}
}

TRACE("Test Finished!!\n");
}
catch ( sql::SQLException &e )
{
// 예외처리 - 에러 메시지와 에러 코드를 가져올 수 있다.
int nErrorCode = e.getErrorCode();
std::string err = e.what();

TRACE1( "Exception : %s\n", err.c_str() );
}

Original Post : http://neodreamer-dev.tistory.com/262

C 찬양가 "Write in C"



Joeny 님의 블로그에 가사도 있습니다

Original Post : http://neodreamer-dev.tistory.com/261

2009/03/03

MySQL Connector/C++ 1.0.3 Alpha Released!!

MySQL 의 C++ Connector 가 1.0.3 Alpha 버전이 공개 되었다.

MySQL Connector/C++ 1.0.3 Alpha (03.03.2009)


  • Added new tests at test/unit/classes. Those tests are mostly about code coverage. Most of the actual functionality of the driver is tested by the tests found at test/CJUnitPort. (Ulf)

  • New data types added to the list returned by DatabaseMetaData::getTypeInfo(): FLOAT UNSIGED, DECIMAL UNSIGNED, DOUBLE UNSIGNED. Those tests may not be in the JDBC specification. However, due to the change you should be able to look up every type and type name returned by, for example, ResultSetMetaData::getColumnTypeName(). (Andrey)

  • MySQL_Driver::getPatchVersion introducted. (Andrey)

  • Major performance improvements due to new buffered resultset implementation by Andrey. (Ulf)

  • Addition of test/unit/README with instructions for writing bug/regression tests. (Ulf)

  • Experimental support for STLPort. This feature may be removed again at any time later without prior warning! Check cmake -L for configuration instructions. (Andrey)

  • Fixed a bug in MySQL_PreparedResultSet::getString(). Returned string had real data but the length was random. Now, the string is initialized with correct length and thus is binary safe. (Andrey)

  • Added properties-enabled (map of key->value) methods for connecting, which add many connect options. (Andrey)

    o Driver::connect( map )

    o Connection::Connection( map )

  • New BLOB implementation. Got rid of sql::Blob in favor of std::istream. C++'s IOStream library is very powerful, similar to PHP's streams. It makes no sense to reinvent the wheel. For example one can pass a std::istringstream object to setBlob() if the data is in memory, or just open a file std::fstream and let it stream to the DB, or write own stream. Similar will be true for getBlob() where we can just copy data, if buffered result set, or stream, if we implement it. (Andrey)

  • Implemented ResultSet::getBlob() which returns std::stream. (Andrey)

  • Fixed MySQL_DatabaseMetaData::getTablePrivileges() to work correctly. Test cases added in the first unit testing framework. (Andrey)

  • Implemented MySQL_Connection::setSessionVariable() for setting variables like sql_mode. (Andrey)

  • Implemented MySQL_DatabaseMetaData::getColumnPrivileges(). (Andrey)

  • cppconn/datatype.h changed and used again. Reimplemented the type subsystem to be more usable - more types for binary and non-binary strings. (Andrey)

  • Implementation for MySQL_DatabaseMetaData::getImportedKeys() for MySQL versions before 5.1.16 using SHOW, and above using INFORMATION_SCHEMA. (Andrey)

  • Implemented MySQL_ConnectionMetaData::getProcedureColumns(). (Andrey)

  • make package_source packs now with bzip2. (Andrey)

  • Re-added getTypeInfo() with information about all types supported by MySQL and the sql::DataType. (Andrey)

  • Exchanged the implementation of MySQL_ConstructedResultSet to use more efficient non O(n) but O(1) access method. This should improve the speed with which the metadata result sets are used. Also, there is less copy during the construction of the result set, which means that all result sets returned from the metadata functions will be faster. (Andrey)

  • Introduced, internally, sql::mysql::MyVal which has implicit constructors used in mysql_metadata.cpp to create result sets with more native data instead of always string (varchar). (Andrey)

  • Renamed ResultSet::getLong() to ResultSet::getInt64(). resultset.h includes typdefs for Windows to be able to use int64_t. (Andrey)

  • Introduced ResultSet::getUInt() and ResultSet::getUInt64(). (Andrey)

  • Corrected handling of unsigned server types. Now returning correct values (Andrey)

  • Fixed handling of numeric columns in ResultSetMetaData::isCaseSensitive to return false. (Andrey)

  • Better implementation for ResultSetMetaData::isReadOnly. Values generated from views are read-only. Seems that these generated values don't have `db` in MYSQL_FIELD set, while all normal columns do have. (Andrey)

  • Implemented MySQL_DatabaseMetaData::getExportedKeys(). (Andrey)

  • Implemented MySQL_DatabaseMetaData::getCrossReference(). (Andrey)


소스는 프로젝트 페이지에서 다운 받을 수 있다.

MySQL Connector/C++ Webpage
MySQL Connector/C++ 1.0.3 Download
Original Post :
http://neodreamer-dev.tistory.com/260

2009/03/02

차기 C++ 표준 C++0x 미리보기

차기 C++ 표준에대한 문서를 깔끔하게 번역해 놓은 곳 입니다.

C++에 관심이 있다면 한번쯤 읽어 봐야 할 것 같습니다.

류광님의 C++0x 미리보기 번역 문서
Original Post :
http://neodreamer-dev.tistory.com/259

SyntaxHighlighter 2.0.296 Released!!

이번 버전에 수정된 내용.
    # Added "current" to published folder which always points to latest version.
    # Added rollover to the copy to clipboard button.
    # Fixed OSX specific line wrapping image issue.
    # Switched to LGPL v3.

SyntaxHighlighter project

2009/02/04 - [Com. Story/Tips] - Tistory에 SyntaxHighlighter 2.0 적용하기
Original Post :
http://neodreamer-dev.tistory.com/258