OCILIB (C and C++ Driver for Oracle)  4.1.0
Some OCILIB C++ sample codes

Here are some C++ samples code. More samples can be found under the demo folder of ocilib packages.

Fetching data
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
int main(void)
{
try
{
Connection con("db", "usr", "pwd");
Statement st(con);
st.Execute("select * from all_users");
Resultset rs = st.GetResultset();
while (rs++)
{
std::cout << "UserName:" << rs.Get<ostring>("username") << " Created:" << rs.Get<ostring>("created") << std::endl;
}
std::cout << "=> Total fetched rows : " << rs.GetCount() << std::endl;
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Binding vectors
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
const int ArraySize = 1000;
int main(void)
{
try
{
Connection con("db", "usr", "pwd");
std::vector<int> ints;
std::vector<ostring> strs;
Statement st(con);
st.Prepare("insert into products values(:i, :s)");
st.SetBindArraySize(ArraySize);
st.Bind(":i", ints, BindInfo::In);
st.Bind(":s", strs, 20, BindInfo::In);
for (int i = 0; i<ArraySize; i++)
{
ostring str;
str += "Name";
str += ((i + 1) + '0');
ints.push_back(i + 1);
strs.push_back(str);
}
st.ExecutePrepared();
std::cout << "row processed : " << st.GetAffectedRows() << std::endl;
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Using collections
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
int main(void)
{
try
{
Connection con("db", "usr", "pwd");
Statement st(con);
/* bind local collection to a PL/SQL procedure */
Collection<ostring> coll1(TypeInfo(con, "varray_type", TypeInfo::Type));
st.Prepare("begin load_array(:coll); end;");
st.Bind(":coll", coll1, BindInfo::In);
st.ExecutePrepared();
Collection<ostring>::iterator it2 = coll1.end();
for (; it1 != it2; ++it1)
{
std::cout << "value " << static_cast<ostring>(*it1) << std::endl;
}
/* query on a table with varray column */
st.Execute("SELECT products from items");
Resultset rs = st.GetResultset();
while (rs++)
{
Collection<Object> coll2 = rs.Get<Collection<Object>>("products");
for (; it1 != it2; ++it1)
{
Object obj = *it1;
std::cout << "... product id : " << obj.Get<int>("Id") << ", name : " << obj.Get<ostring>("Name") << std::endl;
}
}
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Using connection pools
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
const int MaxThreads = 50;
const int MaxConnnections = 10;
void worker(ThreadHandle handle, void *data)
{
Connection con = ((Pool *)data)->GetConnection();
Statement st(con);
st.Execute("select to_char(sysdate, 'YYYYMMDD HH24:MI:SS') from dual");
Resultset rs = st.GetResultset();
rs.Next();
std::cout << handle << " - " << rs.Get<ostring>(1) << std::endl;
con.Close();
}
int main(void)
{
try
{
Environment::Initialize(Environment::Threaded);
Pool pool("db", "usr", "pwd", Pool::ConnectionPool, 0, MaxConnnections);
std::vector<ThreadHandle> threads;
for (int i = 0; i < MaxThreads; i++)
{
threads.push_back(th);
Thread::Run(th, worker, &pool);
}
for (int i = 0; i < MaxThreads; i++)
{
Thread::Join(threads[i]);
Thread::Destroy(threads[i]);
}
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Oracle 12g Implicit resultsets
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
int main(void)
{
try
{
Connection con("db", "usr", "pwd");
Statement st(con);
st.Execute("declare"
" c1 sys_refcursor;"
" c2 sys_refcursor;"
" begin"
" open c1 for select username from all_users;"
" dbms_sql.return_result (c1); "
" open c2 for select table_name from all_tables;"
" dbms_sql.return_result (c2); "
"end;");
Resultset rs = st.GetResultset();
while (rs)
{
while (rs++)
{
std::cout << "Fetch column name:" << rs.GetColumn(1).GetName() << ", Value:" << rs.Get<ostring>(1) << std::endl;
}
std::cout << "=> Total fetched rows : " << rs.GetCount() << std::endl;
rs = st.GetNextResultset();
}
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Using Oracle objects
#include <iostream>
#include "ocilib.hpp"
/*
DML for the test
create type t_vendor as object
(
code number,
name varchar2(30)
);
/
create type t_sale as object
(
code number,
price float,
name varchar2(30),
ref varchar2(30),
date_sale date,
vendor t_vendor
);
/
create table sales(item t_sale);
*/
using namespace ocilib;
int main(void)
{
try
{
Connection con("db", "usr", "pwd");
Date date;
date.SysDate();
Object sale(TypeInfo(con, "t_sale", TypeInfo::Type));
Object vendor(TypeInfo(con, "t_vendor", TypeInfo::Type));
vendor.Set<int>("CODE", 134);
vendor.Set<ostring>("NAME", "JOHN SMITH");
sale.Set<int>("CODE", 1);
sale.Set<double>("PRICE", 12.99);
sale.Set<ostring>("NAME", "USB KEY 2go");
sale.Set<ostring>("REF", "A56547WSAA");
sale.Set<Date>("DATE_SALE", date);
sale.Set<Object>("VENDOR", vendor);
Statement st(con);
st.Prepare("insert into sales values(:obj)");
st.Bind(":obj", sale, BindInfo::In);
st.ExecutePrepared();
std::cout << "Rows inserted : " << st.GetAffectedRows() << std::endl;
con.Commit();
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
return EXIT_SUCCESS;
}
Database notifications
#include <iostream>
#include "ocilib.hpp"
using namespace ocilib;
#ifdef _WINDOWS
#define sleep(x) Sleep(x*1000)
#endif
#define WaitForEvents() sleep(5)
#define WaitForDatabase() sleep(60)
static std::map<unsigned int, ostring> EventTypes;
static std::map<unsigned int, ostring> ObjectEvents;
void EventHandler(Event &evt);
void SetupNames();
int main(int argc, char* argv[])
{
SetupNames();
try
{
Connection con("db", "usr", "pwd");
con.SetAutoCommit(true);
Statement st(con);
st.Execute("create table table1(code number)");
st.Execute("create table table2(str varchar2(10))");
sub.Register(con, "sub-00", Subscription::AllChanges, EventHandler, 5468, 0);
sub.Watch("select * from table1");
sub.Watch("select * from table2");
st.Execute("alter table table1 add price number");
WaitForEvents();
st.Execute("insert into table1 values(1, 10.5)");
st.Execute("insert into table2 values('shoes')");
WaitForEvents();
st.Execute("update table1 set price = 13.5 where code = 1");
st.Execute("delete from table2 ");
WaitForEvents();
st.Execute("drop table table1");
st.Execute("drop table table2");
WaitForEvents();
con.Close();
/* start remote instance */
/* shutdown remote instance */
WaitForDatabase();
sub.Unregister();
}
catch (std::exception &ex)
{
std::cout << ex.what() << std::endl;
}
}
void SetupNames()
{
EventTypes[Event::DatabaseStart] = "Startup";
EventTypes[Event::DatabaseShutdown] = "Shutdown";
EventTypes[Event::DatabaseShutdownAny] = "Shutdown Any";
EventTypes[Event::DatabaseDrop] = "Drop Database";
EventTypes[Event::Unregister] = "Unregister";
EventTypes[Event::ObjectChanged] = "Object Changed";
ObjectEvents[Event::ObjectInserted] = "Insert";
ObjectEvents[Event::ObjectUpdated] = "Update";
ObjectEvents[Event::ObjectDeleted] = "Delete";
ObjectEvents[Event::ObjectAltered] = "Alter";
ObjectEvents[Event::ObjectDropped] = "Drop";
ObjectEvents[Event::ObjectGeneric] = "Generic";
}
void EventHandler(Event &evt)
{
std::cout << "** Notification : " << evt.GetSubscription().GetName() << std::endl;
std::cout << "** Database : " << evt.GetDatabaseName() << std::endl;
std::cout << "** Event : " << EventTypes[evt.GetType()] << std::endl;
{
std::cout << ".... Object : " << evt.GetObjectName() << std::endl;
std::cout << ".... Action : " << ObjectEvents[evt.GetObjectEvent()] << std::endl;
std::cout << ".... RowID : " << evt.GetRowID() << std::endl;
}
std::cout << std::endl;
}