CentOS 7에 C++ ODBC Lib 빌드

사전 준비

unixodbc 빌드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$ 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 설치
1
2
3
4
5
6
$ 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 빌드
1
2
3
4
5
6
7
8
$ 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
샘플 코드 실행
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
$ 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)    ()