설치 및 셋팅

CentOS 7에 C++ ODBC Lib 빌드

약올랑 2016. 9. 23. 11:42

사전 준비

unixodbc 빌드
$ wget http://www.unixodbc.org/unixODBC-2.3.4.tar.gz $ tar xvf unixODBC-2.3.4.tar.gz $ cd unixODBC-2.3.4 $ ./configure $ make $ make install # 버전 확인 $ odbcinst -j unixODBC 2.3.4 DRIVERS............: /usr/local/etc/odbcinst.ini SYSTEM DATA SOURCES: /usr/local/etc/odbc.ini FILE DATA SOURCES..: /usr/local/etc/ODBCDataSources USER DATA SOURCES..: /root/.odbc.ini SQLULEN Size.......: 8 SQLLEN Size........: 8 SQLSETPOSIROW Size.: 8
mysql odbc driver 설치
$ yum -y install mysql-connector-odbc.x86_64 $ vi /usr/local/etc/odbcinst.ini [mysql] Description = Mysql ODBC Driver Driver64 = /usr/lib64/libmyodbc5.so Setup64 = /usr/lib64/libodbcmyS.so

본론

odbc lib 빌드
$ git clone https://github.com/lexicalunit/nanodbc $ cd nanodbc/ $ git checkout v2.12.4 $ mkdir build.release $ cd build.release $ cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local .. $ make $ make install
샘플 코드
#include <nanodbc.h>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
using namespace nanodbc;
void show(nanodbc::result& results);
int main(int argc, char *argv[])
{
const char* connection_string =
"DRIVER={mysql};SERVER=172.20.30.142;DATABASE=yourdb;USER=yourid;PASSWORD=yourpw;OPTION=3;";
// Establishing connections
nanodbc::connection connection(connection_string);
// or connection(connection_string, timeout_seconds);
// or connection("data source name", "username", "password");
// or connection("data source name", "username", "password", timeout_seconds);
cout << "Connected with driver " << connection.driver_name() << endl;
// Setup
execute(connection, "drop table if exists simple_test;");
execute(connection, "create table simple_test (a int, b varchar(10));");
// Direct execution
{
execute(connection, "insert into simple_test values (1, 'one');");
execute(connection, "insert into simple_test values (2, 'two');");
execute(connection, "insert into simple_test values (3, 'tri');");
execute(connection, "insert into simple_test (b) values ('z');");
nanodbc::result results = execute(connection, "select * from simple_test;");
show(results);
}
// Accessing results by name, or column number
{
nanodbc::result results = execute(
connection,
"select a as first, b as second from simple_test where a = 1;");
results.next();
cout << endl << results.get<int>("first") << ", " << results.get<string>(1) << endl;
}
// Binding parameters
{
nanodbc::statement statement(connection);
// Inserting values
prepare(statement, "insert into simple_test (a, b) values (?, ?);");
const int eight_int = 8;
statement.bind(0, &eight_int);
const string eight_str = "eight";
statement.bind(1, eight_str.c_str());
execute(statement);
// Inserting null values
prepare(statement, "insert into simple_test (a, b) values (?, ?);");
statement.bind_null(0);
statement.bind_null(1);
execute(statement);
// Inserting multiple null values
prepare(statement, "insert into simple_test (a, b) values (?, ?);");
statement.bind_null(0, 2);
statement.bind_null(1, 2);
execute(statement, 2);
prepare(statement, "select * from simple_test;");
nanodbc::result results = execute(statement);
show(results);
}
// Transactions
{
{
cout << "\ndeleting all rows ... " << flush;
nanodbc::transaction transaction(connection);
execute(connection, "delete from simple_test;");
// transaction will be rolled back if we don't call transaction.commit()
}
nanodbc::result results = execute(connection, "select count(1) from simple_test;");
results.next();
cout << "still have " << results.get<int>(0) << " rows!" << endl;
}
// Batch inserting
{
nanodbc::statement statement(connection);
execute(connection, "drop table if exists batch_test;");
execute(connection, "create table batch_test (x varchar(10), y int, z float);");
prepare(statement, "insert into batch_test (x, y, z) values (?, ?, ?);");
const size_t elements = 4;
char xdata[elements][10] = { "this", "is", "a", "test" };
statement.bind_strings(0, xdata);
int ydata[elements] = { 1, 2, 3, 4 };
statement.bind(1, ydata, elements);
float zdata[elements] = { 1.1f, 2.2f, 3.3f, 4.4f };
statement.bind(2, zdata, elements);
transact(statement, elements);
nanodbc::result results = execute(connection, "select * from batch_test;", 3);
show(results);
execute(connection, "drop table if exists batch_test;");
}
// Dates and Times
{
execute(connection, "drop table if exists date_test;");
execute(connection, "create table date_test (x datetime);");
execute(connection, "insert into date_test values (current_timestamp);");
nanodbc::result results = execute(connection, "select * from date_test;");
results.next();
nanodbc::date date = results.get<nanodbc::date>(0);
cout << endl << date.year << "-" << date.month << "-" << date.day << endl;
results = execute(connection, "select * from date_test;");
show(results);
execute(connection, "drop table if exists date_test;");
}
// Inserting NULL values with a sentry
{
nanodbc::statement statement(connection);
prepare(statement, "insert into simple_test (a, b) values (?, ?);");
const int elements = 5;
const int a_null = 0;
const char* b_null = "";
int a_data[elements] = { 0, 88, 0, 0, 0 };
char b_data[elements][10] = { "", "non-null", "", "", "" };
statement.bind(0, a_data, elements, &a_null);
statement.bind_strings(1, b_data, b_null);
execute(statement, elements);
nanodbc::result results = execute(connection, "select * from simple_test;");
show(results);
}
// Inserting NULL values with flags
{
nanodbc::statement statement(connection);
prepare(statement, "insert into simple_test (a, b) values (?, ?);");
const int elements = 2;
int a_data[elements] = { 0, 42 };
char b_data[elements][10] = { "", "every" };
bool nulls[elements] = { true, false };
statement.bind(0, a_data, elements, nulls);
statement.bind_strings(1, b_data, nulls);
execute(statement, elements);
nanodbc::result results = execute(connection, "select * from simple_test;");
show(results);
}
// Cleanup
execute(connection, "drop table if exists simple_test;");
return 0;
}
void show(nanodbc::result& results)
{
const short columns = results.columns();
long rows_displayed = 0;
cout << "\nDisplaying " << results.affected_rows() << " rows "
<< "(" << results.rowset_size() << " fetched at a time):" << endl;
// show the column names
cout << "row\t";
for (short i = 0; i < columns; ++i)
cout << results.column_name(i) << "\t";
cout << endl;
// show the column data for each row
while (results.next())
{
cout << rows_displayed++ << "\t";
for (short col = 0; col < columns; ++col)
cout << "(" << results.get<string>(col, "null") << ")\t";
cout << endl;
}
}
view raw helloodbc.cpp hosted with ❤ by GitHub
샘플 코드 실행
$ g++ -std=c++11 helloodbc.cpp -o helloodbc -lnanodbc $ ./helloodbc Connected with driver libmyodbc5w.so Displaying 4 rows (1 fetched at a time): row a b 0 (1) (one) 1 (2) (two) 2 (3) (tri) 3 (null) (z) 1, one Displaying 8 rows (1 fetched at a time): row a b 0 (1) (one) 1 (2) (two) 2 (3) (tri) 3 (null) (z) 4 (8) (eight) 5 (null) (null) 6 (null) (null) 7 (null) (null) deleting all rows ... still have 8 rows! Displaying 4 rows (3 fetched at a time): row x y z 0 (this) (1) (1) 1 (P) (2) (2) 2 (libmyodb) (3) (3) 3 p�Ó«) (4) (4) 2016-9-23 Displaying -1 rows (1 fetched at a time): row x 0 (2016-09-23 15:45:28 +0000) Displaying 13 rows (1 fetched at a time): row a b 0 (1) (one) 1 (2) (two) 2 (3) (tri) 3 (null) (z) 4 (8) (eight) 5 (null) (null) 6 (null) (null) 7 (null) (null) 8 (null) (null) 9 (88) (I¯p) 10 (null) (null) 11 (null) (null) 12 (null) (null) Displaying 15 rows (1 fetched at a time): row a b 0 (1) (one) 1 (2) (two) 2 (3) (tri) 3 (null) (z) 4 (8) (eight) 5 (null) (null) 6 (null) (null) 7 (null) (null) 8 (null) (null) 9 (88) (I¯p) 10 (null) (null) 11 (null) (null) 12 (null) (null) 13 (null) (null) 14 (42) ()